@osaas/cli 4.16.1 → 4.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/cmd.d.ts.map +1 -1
- package/dist/admin/cmd.js +38 -8
- package/dist/admin/cmd.js.map +1 -1
- package/dist/admin/instance.d.ts +4 -0
- package/dist/admin/instance.d.ts.map +1 -1
- package/dist/admin/instance.js +14 -1
- package/dist/admin/instance.js.map +1 -1
- package/dist/admin/money.d.ts +13 -0
- package/dist/admin/money.d.ts.map +1 -0
- package/dist/admin/money.js +34 -0
- package/dist/admin/money.js.map +1 -0
- package/package.json +3 -3
- package/src/admin/cmd.ts +60 -13
- package/src/admin/instance.ts +19 -0
- package/src/admin/money.ts +50 -0
package/dist/admin/cmd.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cmd.d.ts","sourceRoot":"","sources":["../../src/admin/cmd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cmd.d.ts","sourceRoot":"","sources":["../../src/admin/cmd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC,MAAM,CAAC,OAAO,UAAU,QAAQ,YAwO/B"}
|
package/dist/admin/cmd.js
CHANGED
|
@@ -6,6 +6,7 @@ const client_core_1 = require("@osaas/client-core");
|
|
|
6
6
|
const instance_1 = require("./instance");
|
|
7
7
|
const util_1 = require("../user/util");
|
|
8
8
|
const subscription_1 = require("./subscription");
|
|
9
|
+
const money_1 = require("./money");
|
|
9
10
|
function cmdAdmin() {
|
|
10
11
|
const admin = new commander_1.Command('admin');
|
|
11
12
|
admin
|
|
@@ -57,6 +58,42 @@ function cmdAdmin() {
|
|
|
57
58
|
console.log(err.message);
|
|
58
59
|
}
|
|
59
60
|
});
|
|
61
|
+
admin
|
|
62
|
+
.command('remove-exceeding-tenant-instances')
|
|
63
|
+
.description('Remove all instances for all tenants with a negative usage token balance')
|
|
64
|
+
.option('--apply', 'Actually remove instances, otherwise just a dry run')
|
|
65
|
+
.action(async (options, command) => {
|
|
66
|
+
try {
|
|
67
|
+
const globalOpts = command.optsWithGlobals();
|
|
68
|
+
const environment = globalOpts?.env || 'prod';
|
|
69
|
+
const tenantPlanMap = await (0, money_1.getTenantPlanMap)(environment);
|
|
70
|
+
const tokenCounts = await (0, money_1.getTenantTokenCounts)(environment);
|
|
71
|
+
const tenantsExceeding = tokenCounts.filter((tenant) => tenant.remainingTokens < -200);
|
|
72
|
+
let instancesRemoved = 0;
|
|
73
|
+
const tenantsExceedingCount = tenantsExceeding.length;
|
|
74
|
+
for (const tenant of tenantsExceeding) {
|
|
75
|
+
if (tenantPlanMap[tenant.tenantId]?.planType === 'FREE') {
|
|
76
|
+
const instancesToRemove = await (0, instance_1.getInstancesToRemove)(tenant.tenantId, environment);
|
|
77
|
+
if (instancesToRemove.length > 0) {
|
|
78
|
+
console.log(`Tenant ${tenant.tenantId} has a negative or low token balance of ${tenant.remainingTokens} tokens and is on the 'FREE' plan`);
|
|
79
|
+
console.log('Removing all instances for this tenant...');
|
|
80
|
+
for (const item of instancesToRemove) {
|
|
81
|
+
console.log(` - ${item.serviceId}: ${item.instance}`);
|
|
82
|
+
if (options.apply) {
|
|
83
|
+
await (0, instance_1.removeInstanceForTenant)(tenant.tenantId, item.serviceId, item.instance, environment);
|
|
84
|
+
instancesRemoved++;
|
|
85
|
+
console.log('Removed');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
console.log(`${tenantsExceedingCount} / ${Object.keys(tenantPlanMap).length} tenants below threshold, removed ${instancesRemoved} instances`);
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
console.log(err.message);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
60
97
|
admin
|
|
61
98
|
.command('remove-all-instances')
|
|
62
99
|
.argument('<tenantId>', 'The Tenant Id')
|
|
@@ -64,14 +101,7 @@ function cmdAdmin() {
|
|
|
64
101
|
try {
|
|
65
102
|
const globalOpts = command.optsWithGlobals();
|
|
66
103
|
const environment = globalOpts?.env || 'prod';
|
|
67
|
-
const
|
|
68
|
-
const instancesToRemove = [];
|
|
69
|
-
for (const serviceId of services) {
|
|
70
|
-
const instances = await (0, instance_1.listInstancesForTenant)(tenantId, serviceId, environment);
|
|
71
|
-
instances.forEach((instance) => {
|
|
72
|
-
instancesToRemove.push({ serviceId, instance });
|
|
73
|
-
});
|
|
74
|
-
}
|
|
104
|
+
const instancesToRemove = await (0, instance_1.getInstancesToRemove)(tenantId, environment);
|
|
75
105
|
if (instancesToRemove.length === 0) {
|
|
76
106
|
(0, client_core_1.Log)().info(`No instances found for tenant ${tenantId} in ${environment}`);
|
|
77
107
|
console.log('Tenant has no instances');
|
package/dist/admin/cmd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cmd.js","sourceRoot":"","sources":["../../src/admin/cmd.ts"],"names":[],"mappings":";;AAAA,yCAAoC;AACpC,mCAAsC;AACtC,oDAM4B;AAC5B,
|
|
1
|
+
{"version":3,"file":"cmd.js","sourceRoot":"","sources":["../../src/admin/cmd.ts"],"names":[],"mappings":"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"}
|
package/dist/admin/instance.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
export declare function listInstancesForTenant(tenantId: string, serviceId: string, environment: string): Promise<string[]>;
|
|
2
2
|
export declare function removeInstanceForTenant(tenantId: string, serviceId: string, name: string, environment: string): Promise<void>;
|
|
3
|
+
export declare function getInstancesToRemove(tenantId: string, environment: string): Promise<{
|
|
4
|
+
serviceId: string;
|
|
5
|
+
instance: string;
|
|
6
|
+
}[]>;
|
|
3
7
|
//# sourceMappingURL=instance.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../../src/admin/instance.ts"],"names":[],"mappings":"AAIA,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnB;AAED,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,iBAQpB"}
|
|
1
|
+
{"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../../src/admin/instance.ts"],"names":[],"mappings":"AAIA,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnB;AAED,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,iBAQpB;AAED,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM;eAGmB,MAAM;cAAY,MAAM;KAY/D"}
|
package/dist/admin/instance.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.removeInstanceForTenant = exports.listInstancesForTenant = void 0;
|
|
3
|
+
exports.getInstancesToRemove = exports.removeInstanceForTenant = exports.listInstancesForTenant = void 0;
|
|
4
4
|
const client_core_1 = require("@osaas/client-core");
|
|
5
5
|
const token_1 = require("./token");
|
|
6
|
+
const subscription_1 = require("./subscription");
|
|
6
7
|
async function listInstancesForTenant(tenantId, serviceId, environment) {
|
|
7
8
|
const pat = (0, token_1.generatePat)(tenantId, 'osc-admin');
|
|
8
9
|
const ctx = new client_core_1.Context({ personalAccessToken: pat, environment });
|
|
@@ -18,4 +19,16 @@ async function removeInstanceForTenant(tenantId, serviceId, name, environment) {
|
|
|
18
19
|
await (0, client_core_1.removeInstance)(ctx, serviceId, name, serviceAccessToken);
|
|
19
20
|
}
|
|
20
21
|
exports.removeInstanceForTenant = removeInstanceForTenant;
|
|
22
|
+
async function getInstancesToRemove(tenantId, environment) {
|
|
23
|
+
const services = await (0, subscription_1.listSubscriptionsForTenant)(tenantId, environment);
|
|
24
|
+
const instancesToRemove = [];
|
|
25
|
+
for (const serviceId of services) {
|
|
26
|
+
const instances = await listInstancesForTenant(tenantId, serviceId, environment);
|
|
27
|
+
instances.forEach((instance) => {
|
|
28
|
+
instancesToRemove.push({ serviceId, instance });
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return instancesToRemove;
|
|
32
|
+
}
|
|
33
|
+
exports.getInstancesToRemove = getInstancesToRemove;
|
|
21
34
|
//# sourceMappingURL=instance.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instance.js","sourceRoot":"","sources":["../../src/admin/instance.ts"],"names":[],"mappings":";;;AAAA,oDAA4E;AAC5E,mCAAsC;
|
|
1
|
+
{"version":3,"file":"instance.js","sourceRoot":"","sources":["../../src/admin/instance.ts"],"names":[],"mappings":";;;AAAA,oDAA4E;AAC5E,mCAAsC;AACtC,iDAA4D;AAErD,KAAK,UAAU,sBAAsB,CAC1C,QAAgB,EAChB,SAAiB,EACjB,WAAmB;IAEnB,MAAM,GAAG,GAAG,IAAA,mBAAW,EAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAE/C,MAAM,GAAG,GAAG,IAAI,qBAAO,CAAC,EAAE,mBAAmB,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;IACnE,MAAM,kBAAkB,GAAG,MAAM,GAAG,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAEtE,MAAM,SAAS,GAAG,MAAM,IAAA,2BAAa,EAAC,GAAG,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAC;IAC1E,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,QAA0B,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACtE,CAAC;AAZD,wDAYC;AAEM,KAAK,UAAU,uBAAuB,CAC3C,QAAgB,EAChB,SAAiB,EACjB,IAAY,EACZ,WAAmB;IAEnB,MAAM,GAAG,GAAG,IAAA,mBAAW,EAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAE/C,MAAM,GAAG,GAAG,IAAI,qBAAO,CAAC,EAAE,mBAAmB,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;IACnE,MAAM,kBAAkB,GAAG,MAAM,GAAG,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAEtE,MAAM,IAAA,4BAAc,EAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,kBAAkB,CAAC,CAAC;AACjE,CAAC;AAZD,0DAYC;AAEM,KAAK,UAAU,oBAAoB,CACxC,QAAgB,EAChB,WAAmB;IAEnB,MAAM,QAAQ,GAAG,MAAM,IAAA,yCAA0B,EAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACzE,MAAM,iBAAiB,GAA8C,EAAE,CAAC;IACxE,KAAK,MAAM,SAAS,IAAI,QAAQ,EAAE;QAChC,MAAM,SAAS,GAAG,MAAM,sBAAsB,CAC5C,QAAQ,EACR,SAAS,EACT,WAAW,CACZ,CAAC;QACF,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC7B,iBAAiB,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;KACJ;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAjBD,oDAiBC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type TenantTokenCount = {
|
|
2
|
+
tenantId: string;
|
|
3
|
+
tokenCount: number;
|
|
4
|
+
availableTokens: number;
|
|
5
|
+
remainingTokens: number;
|
|
6
|
+
};
|
|
7
|
+
export type TenantPlan = {
|
|
8
|
+
tenantId: string;
|
|
9
|
+
planType: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function getTenantTokenCounts(environment: string): Promise<TenantTokenCount[]>;
|
|
12
|
+
export declare function getTenantPlanMap(environment: string): Promise<Record<string, TenantPlan>>;
|
|
13
|
+
//# sourceMappingURL=money.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"money.d.ts","sourceRoot":"","sources":["../../src/admin/money.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAsB,oBAAoB,CAAC,WAAW,EAAE,MAAM,+BAc7D;AAED,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,uCAkBzD"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTenantPlanMap = exports.getTenantTokenCounts = void 0;
|
|
4
|
+
const client_core_1 = require("@osaas/client-core");
|
|
5
|
+
const token_1 = require("./token");
|
|
6
|
+
async function getTenantTokenCounts(environment) {
|
|
7
|
+
const moneyManagerUrl = `https://money.svc.${environment}.osaas.io`;
|
|
8
|
+
const tokenCounts = await (0, client_core_1.createFetch)(new URL('/tokencount', moneyManagerUrl), {
|
|
9
|
+
method: 'GET',
|
|
10
|
+
headers: {
|
|
11
|
+
accept: 'application/json',
|
|
12
|
+
Authorization: `Bearer ${(0, token_1.apiKey)()}`
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
return tokenCounts;
|
|
16
|
+
}
|
|
17
|
+
exports.getTenantTokenCounts = getTenantTokenCounts;
|
|
18
|
+
async function getTenantPlanMap(environment) {
|
|
19
|
+
const moneyManagerUrl = `https://money.svc.${environment}.osaas.io`;
|
|
20
|
+
const tenantPlans = await (0, client_core_1.createFetch)(new URL('/tenantplan', moneyManagerUrl), {
|
|
21
|
+
method: 'GET',
|
|
22
|
+
headers: {
|
|
23
|
+
accept: 'application/json',
|
|
24
|
+
Authorization: `Bearer ${(0, token_1.apiKey)()}`
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
const tenantPlanMap = {};
|
|
28
|
+
for (const plan of tenantPlans) {
|
|
29
|
+
tenantPlanMap[plan.tenantId] = plan;
|
|
30
|
+
}
|
|
31
|
+
return tenantPlanMap;
|
|
32
|
+
}
|
|
33
|
+
exports.getTenantPlanMap = getTenantPlanMap;
|
|
34
|
+
//# sourceMappingURL=money.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"money.js","sourceRoot":"","sources":["../../src/admin/money.ts"],"names":[],"mappings":";;;AAAA,oDAAiD;AACjD,mCAAiC;AAc1B,KAAK,UAAU,oBAAoB,CAAC,WAAmB;IAC5D,MAAM,eAAe,GAAG,qBAAqB,WAAW,WAAW,CAAC;IAEpE,MAAM,WAAW,GAAG,MAAM,IAAA,yBAAW,EACnC,IAAI,GAAG,CAAC,aAAa,EAAE,eAAe,CAAC,EACvC;QACE,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACP,MAAM,EAAE,kBAAkB;YAC1B,aAAa,EAAE,UAAU,IAAA,cAAM,GAAE,EAAE;SACpC;KACF,CACF,CAAC;IACF,OAAO,WAAW,CAAC;AACrB,CAAC;AAdD,oDAcC;AAEM,KAAK,UAAU,gBAAgB,CAAC,WAAmB;IACxD,MAAM,eAAe,GAAG,qBAAqB,WAAW,WAAW,CAAC;IAEpE,MAAM,WAAW,GAAG,MAAM,IAAA,yBAAW,EACnC,IAAI,GAAG,CAAC,aAAa,EAAE,eAAe,CAAC,EACvC;QACE,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACP,MAAM,EAAE,kBAAkB;YAC1B,aAAa,EAAE,UAAU,IAAA,cAAM,GAAE,EAAE;SACpC;KACF,CACF,CAAC;IACF,MAAM,aAAa,GAA+B,EAAE,CAAC;IACrD,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE;QAC9B,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;KACrC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAlBD,4CAkBC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@osaas/cli",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.17.1",
|
|
4
4
|
"description": "Open Source Cloud CLI",
|
|
5
5
|
"author": "Eyevinn Open Source Cloud <osc@eyevinn.se>",
|
|
6
6
|
"homepage": "https://www.osaas.io",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@osaas/client-core": "^0.18.0",
|
|
26
26
|
"@osaas/client-db": "^0.6.3",
|
|
27
27
|
"@osaas/client-intercom": "^0.3.3",
|
|
28
|
-
"@osaas/client-transcode": "^0.
|
|
28
|
+
"@osaas/client-transcode": "^0.21.0",
|
|
29
29
|
"@osaas/client-web": "^0.5.7",
|
|
30
30
|
"@types/promptly": "^3.0.5",
|
|
31
31
|
"chalk": "4.1.2",
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
"publishConfig": {
|
|
38
38
|
"access": "public"
|
|
39
39
|
},
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "a44d9a399a3adc7fa452defcc60305c43aecfb84"
|
|
41
41
|
}
|
package/src/admin/cmd.ts
CHANGED
|
@@ -7,12 +7,17 @@ import {
|
|
|
7
7
|
remakeOrder,
|
|
8
8
|
waitForOrder
|
|
9
9
|
} from '@osaas/client-core';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
getInstancesToRemove,
|
|
12
|
+
listInstancesForTenant,
|
|
13
|
+
removeInstanceForTenant
|
|
14
|
+
} from './instance';
|
|
11
15
|
import { confirm } from '../user/util';
|
|
12
16
|
import {
|
|
13
17
|
listSubscriptionsForTenant,
|
|
14
18
|
removeSubscriptionForTenant
|
|
15
19
|
} from './subscription';
|
|
20
|
+
import { getTenantPlanMap, getTenantTokenCounts } from './money';
|
|
16
21
|
|
|
17
22
|
export default function cmdAdmin() {
|
|
18
23
|
const admin = new Command('admin');
|
|
@@ -72,6 +77,59 @@ export default function cmdAdmin() {
|
|
|
72
77
|
console.log((err as Error).message);
|
|
73
78
|
}
|
|
74
79
|
});
|
|
80
|
+
admin
|
|
81
|
+
.command('remove-exceeding-tenant-instances')
|
|
82
|
+
.description(
|
|
83
|
+
'Remove all instances for all tenants with a negative usage token balance'
|
|
84
|
+
)
|
|
85
|
+
.option('--apply', 'Actually remove instances, otherwise just a dry run')
|
|
86
|
+
.action(async (options, command) => {
|
|
87
|
+
try {
|
|
88
|
+
const globalOpts = command.optsWithGlobals();
|
|
89
|
+
const environment = globalOpts?.env || 'prod';
|
|
90
|
+
const tenantPlanMap = await getTenantPlanMap(environment);
|
|
91
|
+
const tokenCounts = await getTenantTokenCounts(environment);
|
|
92
|
+
const tenantsExceeding = tokenCounts.filter(
|
|
93
|
+
(tenant) => tenant.remainingTokens < -200
|
|
94
|
+
);
|
|
95
|
+
let instancesRemoved = 0;
|
|
96
|
+
const tenantsExceedingCount = tenantsExceeding.length;
|
|
97
|
+
for (const tenant of tenantsExceeding) {
|
|
98
|
+
if (tenantPlanMap[tenant.tenantId]?.planType === 'FREE') {
|
|
99
|
+
const instancesToRemove = await getInstancesToRemove(
|
|
100
|
+
tenant.tenantId,
|
|
101
|
+
environment
|
|
102
|
+
);
|
|
103
|
+
if (instancesToRemove.length > 0) {
|
|
104
|
+
console.log(
|
|
105
|
+
`Tenant ${tenant.tenantId} has a negative or low token balance of ${tenant.remainingTokens} tokens and is on the 'FREE' plan`
|
|
106
|
+
);
|
|
107
|
+
console.log('Removing all instances for this tenant...');
|
|
108
|
+
for (const item of instancesToRemove) {
|
|
109
|
+
console.log(` - ${item.serviceId}: ${item.instance}`);
|
|
110
|
+
if (options.apply) {
|
|
111
|
+
await removeInstanceForTenant(
|
|
112
|
+
tenant.tenantId,
|
|
113
|
+
item.serviceId,
|
|
114
|
+
item.instance,
|
|
115
|
+
environment
|
|
116
|
+
);
|
|
117
|
+
instancesRemoved++;
|
|
118
|
+
console.log('Removed');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
console.log(
|
|
125
|
+
`${tenantsExceedingCount} / ${
|
|
126
|
+
Object.keys(tenantPlanMap).length
|
|
127
|
+
} tenants below threshold, removed ${instancesRemoved} instances`
|
|
128
|
+
);
|
|
129
|
+
} catch (err) {
|
|
130
|
+
console.log((err as Error).message);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
75
133
|
admin
|
|
76
134
|
.command('remove-all-instances')
|
|
77
135
|
.argument('<tenantId>', 'The Tenant Id')
|
|
@@ -79,21 +137,10 @@ export default function cmdAdmin() {
|
|
|
79
137
|
try {
|
|
80
138
|
const globalOpts = command.optsWithGlobals();
|
|
81
139
|
const environment = globalOpts?.env || 'prod';
|
|
82
|
-
const
|
|
140
|
+
const instancesToRemove = await getInstancesToRemove(
|
|
83
141
|
tenantId,
|
|
84
142
|
environment
|
|
85
143
|
);
|
|
86
|
-
const instancesToRemove: { serviceId: string; instance: string }[] = [];
|
|
87
|
-
for (const serviceId of services) {
|
|
88
|
-
const instances = await listInstancesForTenant(
|
|
89
|
-
tenantId,
|
|
90
|
-
serviceId,
|
|
91
|
-
environment
|
|
92
|
-
);
|
|
93
|
-
instances.forEach((instance) => {
|
|
94
|
-
instancesToRemove.push({ serviceId, instance });
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
144
|
if (instancesToRemove.length === 0) {
|
|
98
145
|
Log().info(
|
|
99
146
|
`No instances found for tenant ${tenantId} in ${environment}`
|
package/src/admin/instance.ts
CHANGED
|
@@ -29,3 +29,22 @@ export async function removeInstanceForTenant(
|
|
|
29
29
|
|
|
30
30
|
await removeInstance(ctx, serviceId, name, serviceAccessToken);
|
|
31
31
|
}
|
|
32
|
+
|
|
33
|
+
export async function getInstancesToRemove(
|
|
34
|
+
tenantId: string,
|
|
35
|
+
environment: string
|
|
36
|
+
) {
|
|
37
|
+
const services = await listSubscriptionsForTenant(tenantId, environment);
|
|
38
|
+
const instancesToRemove: { serviceId: string; instance: string }[] = [];
|
|
39
|
+
for (const serviceId of services) {
|
|
40
|
+
const instances = await listInstancesForTenant(
|
|
41
|
+
tenantId,
|
|
42
|
+
serviceId,
|
|
43
|
+
environment
|
|
44
|
+
);
|
|
45
|
+
instances.forEach((instance) => {
|
|
46
|
+
instancesToRemove.push({ serviceId, instance });
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return instancesToRemove;
|
|
50
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createFetch } from '@osaas/client-core';
|
|
2
|
+
import { apiKey } from './token';
|
|
3
|
+
|
|
4
|
+
export type TenantTokenCount = {
|
|
5
|
+
tenantId: string;
|
|
6
|
+
tokenCount: number;
|
|
7
|
+
availableTokens: number;
|
|
8
|
+
remainingTokens: number;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type TenantPlan = {
|
|
12
|
+
tenantId: string;
|
|
13
|
+
planType: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export async function getTenantTokenCounts(environment: string) {
|
|
17
|
+
const moneyManagerUrl = `https://money.svc.${environment}.osaas.io`;
|
|
18
|
+
|
|
19
|
+
const tokenCounts = await createFetch<TenantTokenCount[]>(
|
|
20
|
+
new URL('/tokencount', moneyManagerUrl),
|
|
21
|
+
{
|
|
22
|
+
method: 'GET',
|
|
23
|
+
headers: {
|
|
24
|
+
accept: 'application/json',
|
|
25
|
+
Authorization: `Bearer ${apiKey()}`
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
return tokenCounts;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function getTenantPlanMap(environment: string) {
|
|
33
|
+
const moneyManagerUrl = `https://money.svc.${environment}.osaas.io`;
|
|
34
|
+
|
|
35
|
+
const tenantPlans = await createFetch<TenantPlan[]>(
|
|
36
|
+
new URL('/tenantplan', moneyManagerUrl),
|
|
37
|
+
{
|
|
38
|
+
method: 'GET',
|
|
39
|
+
headers: {
|
|
40
|
+
accept: 'application/json',
|
|
41
|
+
Authorization: `Bearer ${apiKey()}`
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
const tenantPlanMap: Record<string, TenantPlan> = {};
|
|
46
|
+
for (const plan of tenantPlans) {
|
|
47
|
+
tenantPlanMap[plan.tenantId] = plan;
|
|
48
|
+
}
|
|
49
|
+
return tenantPlanMap;
|
|
50
|
+
}
|