Sync app quota to correct number, reset and disable rows quota
This commit is contained in:
parent
d3a0534798
commit
ea82983ebd
|
@ -21,6 +21,7 @@ exports.StaticDatabases = {
|
||||||
name: "global-db",
|
name: "global-db",
|
||||||
docs: {
|
docs: {
|
||||||
apiKeys: "apikeys",
|
apiKeys: "apikeys",
|
||||||
|
usageQuota: "usage_quota",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// contains information about tenancy and so on
|
// contains information about tenancy and so on
|
||||||
|
@ -28,7 +29,6 @@ exports.StaticDatabases = {
|
||||||
name: "global-info",
|
name: "global-info",
|
||||||
docs: {
|
docs: {
|
||||||
tenants: "tenants",
|
tenants: "tenants",
|
||||||
usageQuota: "usage_quota",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -450,7 +450,7 @@ async function getScopedConfig(db, params) {
|
||||||
|
|
||||||
function generateNewUsageQuotaDoc() {
|
function generateNewUsageQuotaDoc() {
|
||||||
return {
|
return {
|
||||||
_id: StaticDatabases.PLATFORM_INFO.docs.usageQuota,
|
_id: StaticDatabases.GLOBAL.docs.usageQuota,
|
||||||
quotaReset: Date.now() + 2592000000,
|
quotaReset: Date.now() + 2592000000,
|
||||||
usageQuota: {
|
usageQuota: {
|
||||||
automationRuns: 0,
|
automationRuns: 0,
|
||||||
|
|
|
@ -68,4 +68,5 @@ module.exports = {
|
||||||
},
|
},
|
||||||
StaticDatabases,
|
StaticDatabases,
|
||||||
constants: require("./constants"),
|
constants: require("./constants"),
|
||||||
|
migrations: require("./migrations"),
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,13 @@ exports.MIGRATION_DBS = {
|
||||||
|
|
||||||
exports.MIGRATIONS = {
|
exports.MIGRATIONS = {
|
||||||
USER_EMAIL_VIEW_CASING: "user_email_view_casing",
|
USER_EMAIL_VIEW_CASING: "user_email_view_casing",
|
||||||
|
SYNC_APP_AND_RESET_ROWS_QUOTAS: "sync_app_and_reset_rows_quotas",
|
||||||
}
|
}
|
||||||
|
|
||||||
const DB_LOOKUP = {
|
const DB_LOOKUP = {
|
||||||
[exports.MIGRATION_DBS.GLOBAL_DB]: [
|
[exports.MIGRATION_DBS.GLOBAL_DB]: [
|
||||||
exports.MIGRATIONS.USER_EMAIL_VIEW_CASING,
|
exports.MIGRATIONS.USER_EMAIL_VIEW_CASING,
|
||||||
|
exports.MIGRATIONS.SYNC_APP_AND_RESET_ROWS_QUOTAS,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,14 +17,14 @@ const METHOD_MAP = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const DOMAIN_MAP = {
|
const DOMAIN_MAP = {
|
||||||
rows: usageQuota.Properties.ROW,
|
// rows: usageQuota.Properties.ROW, // works - disabled
|
||||||
upload: usageQuota.Properties.UPLOAD,
|
// upload: usageQuota.Properties.UPLOAD, // doesn't work yet
|
||||||
views: usageQuota.Properties.VIEW,
|
// views: usageQuota.Properties.VIEW, // doesn't work yet
|
||||||
users: usageQuota.Properties.USER,
|
// users: usageQuota.Properties.USER, // doesn't work yet
|
||||||
applications: usageQuota.Properties.APPS,
|
applications: usageQuota.Properties.APPS,
|
||||||
// this will not be updated by endpoint calls
|
// this will not be updated by endpoint calls
|
||||||
// instead it will be updated by triggerInfo
|
// instead it will be updated by triggerInfo
|
||||||
automationRuns: usageQuota.Properties.AUTOMATION,
|
// automationRuns: usageQuota.Properties.AUTOMATION, // doesn't work yet
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProperty(url) {
|
function getProperty(url) {
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
const { MIGRATIONS, MIGRATION_DBS, migrateIfRequired } =
|
||||||
|
require("@budibase/auth").migrations
|
||||||
|
const { getGlobalDB } = require("@budibase/auth/tenancy")
|
||||||
|
const { getUsageQuotaDoc } = require("../utilities/usageQuota")
|
||||||
|
const { getAllApps } = require("@budibase/auth/db")
|
||||||
|
const CouchDB = require("../db")
|
||||||
|
|
||||||
|
exports.migrate = async () => {
|
||||||
|
await migrateIfRequired(
|
||||||
|
MIGRATION_DBS.GLOBAL_DB,
|
||||||
|
MIGRATIONS.SYNC_APP_AND_RESET_ROWS_QUOTAS,
|
||||||
|
async () => {
|
||||||
|
const globalDb = getGlobalDB()
|
||||||
|
const usageDoc = await getUsageQuotaDoc(globalDb)
|
||||||
|
|
||||||
|
// reset the rows
|
||||||
|
usageDoc.usageQuota.rows = 0
|
||||||
|
|
||||||
|
// sync the apps
|
||||||
|
const apps = await getAllApps(CouchDB, { dev: true })
|
||||||
|
const appCount = apps ? apps.length : 0
|
||||||
|
usageDoc.usageQuota.apps = appCount
|
||||||
|
|
||||||
|
await globalDb.put(usageDoc)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
const { getGlobalDB } = require("@budibase/auth/tenancy")
|
||||||
|
const TestConfig = require("../../tests/utilities/TestConfiguration")
|
||||||
|
const { getUsageQuotaDoc, update, Properties } = require("../../utilities/usageQuota")
|
||||||
|
const { migrate } = require("../sync_app_and_reset_rows_quotas")
|
||||||
|
const env = require("../../environment")
|
||||||
|
|
||||||
|
describe("Sync App And Reset Rows Quotas Migration", () => {
|
||||||
|
let config = new TestConfig(false)
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await config.init()
|
||||||
|
env._set("USE_QUOTAS", 1)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(config.end)
|
||||||
|
|
||||||
|
it("migrates successfully", async () => {
|
||||||
|
// create the usage quota doc and mock usages
|
||||||
|
const db = getGlobalDB()
|
||||||
|
await getUsageQuotaDoc(db)
|
||||||
|
await update(Properties.APPS, 3)
|
||||||
|
await update(Properties.ROW, 300)
|
||||||
|
|
||||||
|
let usageDoc = await getUsageQuotaDoc(db)
|
||||||
|
expect(usageDoc.usageQuota.apps).toEqual(3)
|
||||||
|
expect(usageDoc.usageQuota.rows).toEqual(300)
|
||||||
|
|
||||||
|
// create an extra app to test the migration
|
||||||
|
await config.createApp("quota-test")
|
||||||
|
|
||||||
|
// migrate
|
||||||
|
await migrate()
|
||||||
|
|
||||||
|
// assert the migration worked
|
||||||
|
usageDoc = await getUsageQuotaDoc(db)
|
||||||
|
expect(usageDoc.usageQuota.apps).toEqual(2)
|
||||||
|
expect(usageDoc.usageQuota.rows).toEqual(0)
|
||||||
|
})
|
||||||
|
})
|
|
@ -5,24 +5,20 @@ const {
|
||||||
generateNewUsageQuotaDoc,
|
generateNewUsageQuotaDoc,
|
||||||
} = require("@budibase/auth/db")
|
} = require("@budibase/auth/db")
|
||||||
|
|
||||||
function getNewQuotaReset() {
|
|
||||||
return Date.now() + 2592000000
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.Properties = {
|
exports.Properties = {
|
||||||
ROW: "rows",
|
ROW: "rows", // mostly works - disabled - app / table deletion not yet accounted for
|
||||||
UPLOAD: "storage",
|
UPLOAD: "storage", // doesn't work yet
|
||||||
VIEW: "views",
|
VIEW: "views", // doesn't work yet
|
||||||
USER: "users",
|
USER: "users", // doesn't work yet
|
||||||
AUTOMATION: "automationRuns",
|
AUTOMATION: "automationRuns", // doesn't work yet
|
||||||
APPS: "apps",
|
APPS: "apps", // works
|
||||||
EMAILS: "emails",
|
EMAILS: "emails", // doesn't work yet
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getUsageQuotaDoc(db) {
|
exports.getUsageQuotaDoc = async db => {
|
||||||
let quota
|
let quota
|
||||||
try {
|
try {
|
||||||
quota = await db.get(StaticDatabases.PLATFORM_INFO.docs.usageQuota)
|
quota = await db.get(StaticDatabases.GLOBAL.docs.usageQuota)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// doc doesn't exist. Create it
|
// doc doesn't exist. Create it
|
||||||
quota = await db.post(generateNewUsageQuotaDoc())
|
quota = await db.post(generateNewUsageQuotaDoc())
|
||||||
|
@ -45,15 +41,7 @@ exports.update = async (property, usage) => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const db = getGlobalDB()
|
const db = getGlobalDB()
|
||||||
const quota = await getUsageQuotaDoc(db)
|
const quota = await exports.getUsageQuotaDoc(db)
|
||||||
|
|
||||||
// Check if the quota needs reset
|
|
||||||
if (Date.now() >= quota.quotaReset) {
|
|
||||||
quota.quotaReset = getNewQuotaReset()
|
|
||||||
for (let prop of Object.keys(quota.usageQuota)) {
|
|
||||||
quota.usageQuota[prop] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// increment the quota
|
// increment the quota
|
||||||
quota.usageQuota[property] += usage
|
quota.usageQuota[property] += usage
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
// UNUSED CODE
|
||||||
|
// Preserved for future use
|
||||||
|
|
||||||
|
/* eslint-disable no-unused-vars */
|
||||||
|
|
||||||
|
function getNewQuotaReset() {
|
||||||
|
return Date.now() + 2592000000
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetQuotasIfRequired(quota) {
|
||||||
|
// Check if the quota needs reset
|
||||||
|
if (Date.now() >= quota.quotaReset) {
|
||||||
|
quota.quotaReset = getNewQuotaReset()
|
||||||
|
for (let prop of Object.keys(quota.usageQuota)) {
|
||||||
|
quota.usageQuota[prop] = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -69,9 +69,7 @@ exports.adminUser = async ctx => {
|
||||||
if (!env.SELF_HOSTED) {
|
if (!env.SELF_HOSTED) {
|
||||||
// could be a scenario where it exists, make sure its clean
|
// could be a scenario where it exists, make sure its clean
|
||||||
try {
|
try {
|
||||||
const usageQuota = await db.get(
|
const usageQuota = await db.get(StaticDatabases.GLOBAL.docs.usageQuota)
|
||||||
StaticDatabases.PLATFORM_INFO.docs.usageQuota
|
|
||||||
)
|
|
||||||
if (usageQuota) {
|
if (usageQuota) {
|
||||||
await db.remove(usageQuota._id, usageQuota._rev)
|
await db.remove(usageQuota._id, usageQuota._rev)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue