@geek-fun/serverlessinsight 0.3.0 → 0.3.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/package.json +32 -31
- package/dist/src/commands/deploy.js +2 -2
- package/dist/src/commands/destroy.js +2 -1
- package/dist/src/commands/index.js +11 -10
- package/dist/src/commands/template.js +2 -2
- package/dist/src/commands/validate.js +2 -1
- package/dist/src/common/constants.js +2 -1
- package/dist/src/common/{actionContext.js → context.js} +19 -4
- package/dist/src/common/iacHelper.js +54 -27
- package/dist/src/common/index.d.ts +1 -1
- package/dist/src/common/index.js +1 -1
- package/dist/src/common/rosAssets.js +33 -8
- package/dist/src/common/rosClient.js +5 -3
- package/dist/src/stack/deploy.js +30 -13
- package/dist/src/stack/rfsStack/index.d.ts +2 -2
- package/dist/src/stack/rfsStack/index.js +2 -1
- package/dist/src/stack/rosStack/bootstrap.js +5 -4
- package/dist/src/stack/rosStack/bucket.js +12 -12
- package/dist/src/stack/rosStack/database.js +10 -10
- package/dist/src/stack/rosStack/event.js +21 -21
- package/dist/src/stack/rosStack/function.js +65 -44
- package/dist/src/stack/rosStack/index.d.ts +2 -2
- package/dist/src/stack/rosStack/index.js +3 -3
- package/dist/src/stack/rosStack/stage.js +1 -1
- package/dist/src/stack/rosStack/tag.js +1 -1
- package/dist/src/stack/rosStack/vars.js +3 -3
- package/dist/src/validator/functionSchema.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +32 -31
- package/samples/aliyun-poc-fc-gpu.yml +23 -22
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geek-fun/serverlessinsight",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Full life cycle cross providers serverless application management for your fast-growing business.",
|
|
5
5
|
"homepage": "https://serverlessinsight.geekfun.club",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -49,51 +49,52 @@
|
|
|
49
49
|
"function"
|
|
50
50
|
],
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@alicloud/ims20190815": "^2.
|
|
53
|
-
"@alicloud/openapi-client": "^0.4.
|
|
54
|
-
"@alicloud/ros-cdk-apigateway": "^1.
|
|
55
|
-
"@alicloud/ros-cdk-core": "^1.
|
|
56
|
-
"@alicloud/ros-cdk-dns": "^1.
|
|
57
|
-
"@alicloud/ros-cdk-ecs": "^1.
|
|
58
|
-
"@alicloud/ros-cdk-elasticsearchserverless": "^1.
|
|
59
|
-
"@alicloud/ros-cdk-fc3": "^1.
|
|
60
|
-
"@alicloud/ros-cdk-nas": "^1.
|
|
61
|
-
"@alicloud/ros-cdk-oss": "^1.
|
|
62
|
-
"@alicloud/ros-cdk-ossdeployment": "^1.
|
|
63
|
-
"@alicloud/ros-cdk-ram": "^1.
|
|
64
|
-
"@alicloud/ros-cdk-rds": "^1.
|
|
65
|
-
"@alicloud/ros-cdk-sls": "^1.
|
|
66
|
-
"@alicloud/
|
|
52
|
+
"@alicloud/ims20190815": "^2.2.0",
|
|
53
|
+
"@alicloud/openapi-client": "^0.4.14",
|
|
54
|
+
"@alicloud/ros-cdk-apigateway": "^1.8.0",
|
|
55
|
+
"@alicloud/ros-cdk-core": "^1.8.0",
|
|
56
|
+
"@alicloud/ros-cdk-dns": "^1.8.0",
|
|
57
|
+
"@alicloud/ros-cdk-ecs": "^1.8.0",
|
|
58
|
+
"@alicloud/ros-cdk-elasticsearchserverless": "^1.8.0",
|
|
59
|
+
"@alicloud/ros-cdk-fc3": "^1.8.0",
|
|
60
|
+
"@alicloud/ros-cdk-nas": "^1.8.0",
|
|
61
|
+
"@alicloud/ros-cdk-oss": "^1.8.0",
|
|
62
|
+
"@alicloud/ros-cdk-ossdeployment": "^1.8.0",
|
|
63
|
+
"@alicloud/ros-cdk-ram": "^1.8.0",
|
|
64
|
+
"@alicloud/ros-cdk-rds": "^1.8.0",
|
|
65
|
+
"@alicloud/ros-cdk-sls": "^1.8.0",
|
|
66
|
+
"@alicloud/ros-cdk-vpc": "^1.8.0",
|
|
67
|
+
"@alicloud/ros20190910": "^3.5.6",
|
|
67
68
|
"ajv": "^8.17.1",
|
|
68
69
|
"ali-oss": "^6.22.0",
|
|
69
70
|
"chalk": "^5.4.1",
|
|
70
|
-
"commander": "^
|
|
71
|
+
"commander": "^13.1.0",
|
|
71
72
|
"i": "^0.3.7",
|
|
72
73
|
"i18n": "^0.15.1",
|
|
73
74
|
"jszip": "^3.10.1",
|
|
74
75
|
"lodash": "^4.17.21",
|
|
75
|
-
"npm": "^11.
|
|
76
|
-
"pino": "^9.
|
|
76
|
+
"npm": "^11.2.0",
|
|
77
|
+
"pino": "^9.6.0",
|
|
77
78
|
"pino-pretty": "^13.0.0",
|
|
78
|
-
"yaml": "^2.7.
|
|
79
|
+
"yaml": "^2.7.1"
|
|
79
80
|
},
|
|
80
81
|
"devDependencies": {
|
|
81
82
|
"@types/ali-oss": "^6.16.11",
|
|
82
83
|
"@types/i18n": "^0.13.12",
|
|
83
84
|
"@types/jest": "^29.5.14",
|
|
84
|
-
"@types/lodash": "^4.17.
|
|
85
|
-
"@types/node": "^22.
|
|
86
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
87
|
-
"@typescript-eslint/parser": "^8.
|
|
88
|
-
"eslint": "^9.
|
|
89
|
-
"eslint-config-prettier": "^
|
|
90
|
-
"eslint-plugin-prettier": "^5.2.
|
|
91
|
-
"globals": "^
|
|
85
|
+
"@types/lodash": "^4.17.16",
|
|
86
|
+
"@types/node": "^22.14.0",
|
|
87
|
+
"@typescript-eslint/eslint-plugin": "^8.29.0",
|
|
88
|
+
"@typescript-eslint/parser": "^8.29.0",
|
|
89
|
+
"eslint": "^9.24.0",
|
|
90
|
+
"eslint-config-prettier": "^10.1.1",
|
|
91
|
+
"eslint-plugin-prettier": "^5.2.6",
|
|
92
|
+
"globals": "^16.0.0",
|
|
92
93
|
"husky": "^9.1.7",
|
|
93
94
|
"jest": "^29.7.0",
|
|
94
|
-
"prettier": "^3.
|
|
95
|
-
"ts-jest": "^29.
|
|
95
|
+
"prettier": "^3.5.3",
|
|
96
|
+
"ts-jest": "^29.3.1",
|
|
96
97
|
"ts-node": "^10.9.2",
|
|
97
|
-
"typescript": "^5.
|
|
98
|
+
"typescript": "^5.8.3"
|
|
98
99
|
}
|
|
99
100
|
}
|
|
@@ -8,9 +8,9 @@ const deploy = async (stackName, options) => {
|
|
|
8
8
|
common_1.logger.info('Validating yaml...');
|
|
9
9
|
const iac = (0, parser_1.parseYaml)((0, common_1.getIacLocation)(options.location));
|
|
10
10
|
common_1.logger.info('Yaml is valid! 🎉');
|
|
11
|
-
|
|
11
|
+
(0, common_1.setContext)({ ...options, stackName, iacProvider: iac.provider });
|
|
12
12
|
common_1.logger.info('Deploying stack...');
|
|
13
|
-
await (0, stack_1.deployStack)(stackName, iac
|
|
13
|
+
await (0, stack_1.deployStack)(stackName, iac);
|
|
14
14
|
common_1.logger.info('Stack deployed! 🎉');
|
|
15
15
|
};
|
|
16
16
|
exports.deploy = deploy;
|
|
@@ -5,7 +5,8 @@ const common_1 = require("../common");
|
|
|
5
5
|
const parser_1 = require("../parser");
|
|
6
6
|
const destroyStack = async (stackName, options) => {
|
|
7
7
|
const iac = (0, parser_1.parseYaml)((0, common_1.getIacLocation)(options.location));
|
|
8
|
-
|
|
8
|
+
(0, common_1.setContext)({ stackName, ...options, iacProvider: iac.provider });
|
|
9
|
+
const context = (0, common_1.getContext)();
|
|
9
10
|
common_1.logger.info(`Destroying stack: ${stackName}, provider: ${context.provider}, region: ${context.region}...`);
|
|
10
11
|
await (0, common_1.rosStackDelete)(context);
|
|
11
12
|
};
|
|
@@ -14,7 +14,8 @@ program
|
|
|
14
14
|
.command('show')
|
|
15
15
|
.description('show string')
|
|
16
16
|
.action(async (options) => {
|
|
17
|
-
|
|
17
|
+
(0, common_1.setContext)({ ...options });
|
|
18
|
+
const context = (0, common_1.getContext)();
|
|
18
19
|
const result = await (0, common_2.getIamInfo)(context);
|
|
19
20
|
console.log('result:', JSON.stringify(result));
|
|
20
21
|
});
|
|
@@ -33,10 +34,10 @@ program
|
|
|
33
34
|
.option('-f, --file <path>', 'specify the yaml file')
|
|
34
35
|
.option('-s, --stage <stage>', 'specify the stage')
|
|
35
36
|
.option('-r, --region <region>', 'specify the region')
|
|
36
|
-
.option('-
|
|
37
|
-
.option('-
|
|
38
|
-
.option('-
|
|
39
|
-
.option('-
|
|
37
|
+
.option('-v, --provider <provider>', 'specify the provider')
|
|
38
|
+
.option('-k, --accessKeyId <accessKeyId>', 'specify the AccessKeyId')
|
|
39
|
+
.option('-x, --accessKeySecret <accessKeySecret>', 'specify the AccessKeySecret')
|
|
40
|
+
.option('-n, --securityToken <securityToken>', 'specify the SecurityToken')
|
|
40
41
|
.option('-p, --parameter <key=value>', 'override parameters', (value, previous) => {
|
|
41
42
|
const [key, val] = value.split('=');
|
|
42
43
|
previous[key] = val;
|
|
@@ -56,7 +57,7 @@ program
|
|
|
56
57
|
});
|
|
57
58
|
program
|
|
58
59
|
.command('template <stackName>')
|
|
59
|
-
.description('print
|
|
60
|
+
.description('print platform specific infrastructure as code template')
|
|
60
61
|
.option('-f, --file <path>', 'specify the yaml file')
|
|
61
62
|
.option('-s, --stage <stage>', 'specify the stage')
|
|
62
63
|
.option('-t, --format <type>', 'output content type (JSON or YAML)', 'JSON')
|
|
@@ -67,10 +68,10 @@ program
|
|
|
67
68
|
.command('destroy <stackName>')
|
|
68
69
|
.option('-f, --file <path>', 'specify the yaml file')
|
|
69
70
|
.option('-r, --region <region>', 'specify the region')
|
|
70
|
-
.option('-
|
|
71
|
-
.option('-
|
|
72
|
-
.option('-
|
|
73
|
-
.option('-
|
|
71
|
+
.option('-v, --provider <provider>', 'specify the provider')
|
|
72
|
+
.option('-k, --accessKeyId <accessKeyId>', 'specify the AccessKeyId')
|
|
73
|
+
.option('-x, --accessKeySecret <accessKeySecret>', 'specify the AccessKeySecret')
|
|
74
|
+
.option('-n, --securityToken <securityToken>', 'specify the SecurityToken')
|
|
74
75
|
.description('destroy serverless stack')
|
|
75
76
|
.action(async (stackName, { file, region, provider, accessKeyId, accessKeySecret, securityToken }) => {
|
|
76
77
|
await (0, destroy_1.destroyStack)(stackName, {
|
|
@@ -11,8 +11,8 @@ const common_1 = require("../common");
|
|
|
11
11
|
const parser_1 = require("../parser");
|
|
12
12
|
const template = (stackName, options) => {
|
|
13
13
|
const iac = (0, parser_1.parseYaml)((0, common_1.getIacLocation)(options.location));
|
|
14
|
-
|
|
15
|
-
const { template } = (0, deploy_1.generateStackTemplate)(stackName, iac
|
|
14
|
+
(0, common_1.setContext)({ ...options, stackName, provider: iac.provider.name });
|
|
15
|
+
const { template } = (0, deploy_1.generateStackTemplate)(stackName, iac);
|
|
16
16
|
if (typeof template === 'string') {
|
|
17
17
|
common_1.logger.info(`\n${template}`);
|
|
18
18
|
}
|
|
@@ -4,7 +4,8 @@ exports.validate = void 0;
|
|
|
4
4
|
const common_1 = require("../common");
|
|
5
5
|
const parser_1 = require("../parser");
|
|
6
6
|
const validate = (stackName, options) => {
|
|
7
|
-
|
|
7
|
+
(0, common_1.setContext)({ stackName, ...options });
|
|
8
|
+
const context = (0, common_1.getContext)();
|
|
8
9
|
(0, parser_1.parseYaml)(context.iacLocation);
|
|
9
10
|
common_1.logger.info('Yaml is valid! 🎉');
|
|
10
11
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CODE_ZIP_SIZE_LIMIT = void 0;
|
|
3
|
+
exports.OSS_DEPLOYMENT_TIMEOUT = exports.CODE_ZIP_SIZE_LIMIT = void 0;
|
|
4
4
|
exports.CODE_ZIP_SIZE_LIMIT = 15 * 1000 * 1000;
|
|
5
|
+
exports.OSS_DEPLOYMENT_TIMEOUT = 3000; // in seconds
|
|
@@ -3,9 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.getContext = exports.setContext = exports.getIacLocation = void 0;
|
|
7
7
|
const node_path_1 = __importDefault(require("node:path"));
|
|
8
8
|
const providerEnum_1 = require("./providerEnum");
|
|
9
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
10
|
+
const asyncLocalStorage = new node_async_hooks_1.AsyncLocalStorage();
|
|
9
11
|
const getIacLocation = (location) => {
|
|
10
12
|
const projectRoot = node_path_1.default.resolve(process.cwd());
|
|
11
13
|
return location
|
|
@@ -16,8 +18,8 @@ const getIacLocation = (location) => {
|
|
|
16
18
|
node_path_1.default.resolve(projectRoot, 'serverless-insight.yml');
|
|
17
19
|
};
|
|
18
20
|
exports.getIacLocation = getIacLocation;
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
+
const setContext = (config) => {
|
|
22
|
+
const context = {
|
|
21
23
|
stage: config.stage ?? 'default',
|
|
22
24
|
stackName: config.stackName ?? '',
|
|
23
25
|
provider: (config.provider ?? config.iacProvider?.name ?? providerEnum_1.ProviderEnum.ALIYUN),
|
|
@@ -31,6 +33,19 @@ const constructActionContext = (config) => {
|
|
|
31
33
|
securityToken: config.securityToken ?? process.env.ALIYUN_SECURITY_TOKEN,
|
|
32
34
|
iacLocation: (0, exports.getIacLocation)(config.location),
|
|
33
35
|
parameters: Object.entries(config.parameters ?? {}).map(([key, value]) => ({ key, value })),
|
|
36
|
+
stages: Object.entries(config.stages ?? {}).reduce((acc, [stage, parameters]) => ({
|
|
37
|
+
...acc,
|
|
38
|
+
[stage]: Object.entries(parameters).map(([key, value]) => ({ key, value })),
|
|
39
|
+
}), {}),
|
|
34
40
|
};
|
|
41
|
+
asyncLocalStorage.enterWith(context);
|
|
35
42
|
};
|
|
36
|
-
exports.
|
|
43
|
+
exports.setContext = setContext;
|
|
44
|
+
const getContext = () => {
|
|
45
|
+
const context = asyncLocalStorage.getStore();
|
|
46
|
+
if (!context) {
|
|
47
|
+
throw new Error('No context found');
|
|
48
|
+
}
|
|
49
|
+
return context;
|
|
50
|
+
};
|
|
51
|
+
exports.getContext = getContext;
|
|
@@ -36,12 +36,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.
|
|
39
|
+
exports.formatRosId = exports.calcValue = exports.calcRefs = exports.getFileSource = exports.readCodeSize = exports.resolveCode = void 0;
|
|
40
40
|
const node_path_1 = __importDefault(require("node:path"));
|
|
41
41
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
42
42
|
const ros = __importStar(require("@alicloud/ros-cdk-core"));
|
|
43
43
|
const ossDeployment = __importStar(require("@alicloud/ros-cdk-ossdeployment"));
|
|
44
44
|
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
45
|
+
const lodash_1 = require("lodash");
|
|
45
46
|
const resolveCode = (location) => {
|
|
46
47
|
const filePath = node_path_1.default.resolve(process.cwd(), location);
|
|
47
48
|
const fileContent = node_fs_1.default.readFileSync(filePath);
|
|
@@ -65,19 +66,17 @@ const getFileSource = (fcName, location) => {
|
|
|
65
66
|
return { source, objectKey };
|
|
66
67
|
};
|
|
67
68
|
exports.getFileSource = getFileSource;
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
};
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (value.match(/\$\{ctx.\w+}/)) {
|
|
80
|
-
return evalCtx(value, ctx);
|
|
69
|
+
const calcRefs = (rawValue, ctx) => {
|
|
70
|
+
if (typeof rawValue === 'string') {
|
|
71
|
+
const containsStage = rawValue.match(/\$\{ctx.\w+}/);
|
|
72
|
+
const matchVar = rawValue.match(/^\$\{vars\.(\w+)}$/);
|
|
73
|
+
const containsVar = rawValue.match(/\$\{vars\.(\w+)}/);
|
|
74
|
+
const matchMap = rawValue.match(/^\$\{stages\.(\w+)}$/);
|
|
75
|
+
const containsMap = rawValue.match(/\$\{stages\.(\w+)}/);
|
|
76
|
+
const matchFn = rawValue.match(/^\$\{functions\.(\w+(\.\w+)?)}$/);
|
|
77
|
+
let value = rawValue;
|
|
78
|
+
if (containsStage) {
|
|
79
|
+
value = value.replace(/\$\{ctx.stage}/g, ctx.stage);
|
|
81
80
|
}
|
|
82
81
|
if (matchVar?.length) {
|
|
83
82
|
return ros.Fn.ref(matchVar[1]);
|
|
@@ -88,23 +87,51 @@ const replaceReference = (value, ctx) => {
|
|
|
88
87
|
if (matchFn?.length) {
|
|
89
88
|
return ros.Fn.getAtt(matchFn[1], 'FunctionName');
|
|
90
89
|
}
|
|
91
|
-
if (containsMap?.length
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
if (containsVar?.length) {
|
|
95
|
-
return ros.Fn.sub(value.replace(/\$\{vars\.(\w+)}/g, '${$1}'));
|
|
96
|
-
}
|
|
97
|
-
if (containsMap?.length) {
|
|
98
|
-
return ros.Fn.sub(value.replace(/\$\{stages\.(\w+)}/g, '${$1}'));
|
|
90
|
+
if (containsMap?.length || containsVar?.length) {
|
|
91
|
+
value = ros.Fn.sub(rawValue.replace(/\$\{stages\.(\w+)}/g, '${$1}').replace(/\$\{vars\.(\w+)}/g, '${$1}'));
|
|
99
92
|
}
|
|
100
93
|
return value;
|
|
101
94
|
}
|
|
102
|
-
if (Array.isArray(
|
|
103
|
-
return
|
|
95
|
+
if (Array.isArray(rawValue)) {
|
|
96
|
+
return rawValue.map((item) => (0, exports.calcRefs)(item, ctx));
|
|
104
97
|
}
|
|
105
|
-
if (typeof
|
|
106
|
-
return Object.fromEntries(Object.entries(
|
|
98
|
+
if (typeof rawValue === 'object' && rawValue !== null) {
|
|
99
|
+
return Object.fromEntries(Object.entries(rawValue).map(([key, val]) => [key, (0, exports.calcRefs)(val, ctx)]));
|
|
100
|
+
}
|
|
101
|
+
return rawValue;
|
|
102
|
+
};
|
|
103
|
+
exports.calcRefs = calcRefs;
|
|
104
|
+
const getParam = (key, records) => {
|
|
105
|
+
return records?.find((param) => param.key === key)?.value;
|
|
106
|
+
};
|
|
107
|
+
const calcValue = (rawValue, ctx) => {
|
|
108
|
+
const containsStage = rawValue.match(/\$\{ctx.stage}/);
|
|
109
|
+
const containsVar = rawValue.match(/\$\{vars.\w+}/);
|
|
110
|
+
const containsMap = rawValue.match(/\$\{stages\.(\w+)}/);
|
|
111
|
+
let value = rawValue;
|
|
112
|
+
if (containsStage?.length) {
|
|
113
|
+
value = rawValue.replace(/\$\{ctx.stage}/g, ctx.stage);
|
|
114
|
+
}
|
|
115
|
+
if (containsVar?.length) {
|
|
116
|
+
value = value.replace(/\$\{vars\.(\w+)}/g, (_, key) => getParam(key, ctx.parameters));
|
|
117
|
+
}
|
|
118
|
+
if (containsMap?.length) {
|
|
119
|
+
value = value.replace(/\$\{stages\.(\w+)}/g, (_, key) => getParam(key, (0, lodash_1.get)(ctx.stages, `${ctx.stage}`)));
|
|
107
120
|
}
|
|
108
121
|
return value;
|
|
109
122
|
};
|
|
110
|
-
exports.
|
|
123
|
+
exports.calcValue = calcValue;
|
|
124
|
+
const formatRosId = (id) => {
|
|
125
|
+
// Insert underscore before uppercase letters, but only when they follow a lowercase letter
|
|
126
|
+
let result = id.replace(/([a-z])([A-Z])/g, '$1_$2');
|
|
127
|
+
// Convert to lowercase
|
|
128
|
+
result = result.toLowerCase();
|
|
129
|
+
// Replace special characters with underscores
|
|
130
|
+
result = result.replace(/[/#,-]/g, '_');
|
|
131
|
+
// Remove any number of underscores to single one
|
|
132
|
+
result = result.replace(/_+/g, '_');
|
|
133
|
+
// Remove leading underscores
|
|
134
|
+
result = result.replace(/^_/, '');
|
|
135
|
+
return result;
|
|
136
|
+
};
|
|
137
|
+
exports.formatRosId = formatRosId;
|
|
@@ -2,7 +2,7 @@ export * from './providerEnum';
|
|
|
2
2
|
export * from './logger';
|
|
3
3
|
export * from './getVersion';
|
|
4
4
|
export * from './rosClient';
|
|
5
|
-
export * from './
|
|
5
|
+
export * from './context';
|
|
6
6
|
export * from './iacHelper';
|
|
7
7
|
export * from './constants';
|
|
8
8
|
export * from './imsClient';
|
package/dist/src/common/index.js
CHANGED
|
@@ -18,7 +18,7 @@ __exportStar(require("./providerEnum"), exports);
|
|
|
18
18
|
__exportStar(require("./logger"), exports);
|
|
19
19
|
__exportStar(require("./getVersion"), exports);
|
|
20
20
|
__exportStar(require("./rosClient"), exports);
|
|
21
|
-
__exportStar(require("./
|
|
21
|
+
__exportStar(require("./context"), exports);
|
|
22
22
|
__exportStar(require("./iacHelper"), exports);
|
|
23
23
|
__exportStar(require("./constants"), exports);
|
|
24
24
|
__exportStar(require("./imsClient"), exports);
|
|
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.publishAssets = exports.getAssets = void 0;
|
|
39
|
+
exports.cleanupAssets = exports.publishAssets = exports.constructAssets = exports.getAssets = void 0;
|
|
40
40
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
41
41
|
const ossDeployment = __importStar(require("@alicloud/ros-cdk-ossdeployment"));
|
|
42
42
|
const node_path_1 = __importDefault(require("node:path"));
|
|
@@ -44,6 +44,7 @@ const jszip_1 = __importDefault(require("jszip"));
|
|
|
44
44
|
const logger_1 = require("./logger");
|
|
45
45
|
const lodash_1 = require("lodash");
|
|
46
46
|
const ali_oss_1 = __importDefault(require("ali-oss"));
|
|
47
|
+
const context_1 = require("./context");
|
|
47
48
|
const buildAssets = (rootPath, relativePath) => {
|
|
48
49
|
const location = node_path_1.default.resolve(rootPath, relativePath);
|
|
49
50
|
if (!node_fs_1.default.existsSync(location)) {
|
|
@@ -95,7 +96,8 @@ const zipAssets = async (assetsPath) => {
|
|
|
95
96
|
});
|
|
96
97
|
return zipPath;
|
|
97
98
|
};
|
|
98
|
-
const constructAssets = async ({ files, rootPath }
|
|
99
|
+
const constructAssets = async ({ files, rootPath, }) => {
|
|
100
|
+
const { region } = (0, context_1.getContext)();
|
|
99
101
|
const assets = await Promise.all(Object.entries(files)
|
|
100
102
|
.filter(([, fileItem]) => !fileItem.source.path.endsWith('.template.json'))
|
|
101
103
|
.map(async ([, fileItem]) => {
|
|
@@ -111,6 +113,7 @@ const constructAssets = async ({ files, rootPath }, region) => {
|
|
|
111
113
|
}));
|
|
112
114
|
return !(0, lodash_1.isEmpty)(assets) ? assets : undefined;
|
|
113
115
|
};
|
|
116
|
+
exports.constructAssets = constructAssets;
|
|
114
117
|
const ensureBucketExits = async (bucketName, ossClient) => await ossClient.getBucketInfo(bucketName).catch((err) => {
|
|
115
118
|
if (err.code === 'NoSuchBucket') {
|
|
116
119
|
logger_1.logger.info(`Bucket: ${bucketName} not exists, creating...`);
|
|
@@ -124,13 +127,13 @@ const ensureBucketExits = async (bucketName, ossClient) => await ossClient.getBu
|
|
|
124
127
|
throw err;
|
|
125
128
|
}
|
|
126
129
|
});
|
|
127
|
-
const publishAssets = async (assets
|
|
128
|
-
|
|
129
|
-
if (!constructedAssets?.length) {
|
|
130
|
+
const publishAssets = async (assets) => {
|
|
131
|
+
if (!assets?.length) {
|
|
130
132
|
logger_1.logger.info('No assets to publish, skipped!');
|
|
131
133
|
return;
|
|
132
134
|
}
|
|
133
|
-
const
|
|
135
|
+
const context = (0, context_1.getContext)();
|
|
136
|
+
const bucketName = assets[0].bucketName;
|
|
134
137
|
const client = new ali_oss_1.default({
|
|
135
138
|
region: `oss-${context.region}`,
|
|
136
139
|
accessKeyId: context.accessKeyId,
|
|
@@ -143,10 +146,32 @@ const publishAssets = async (assets, context) => {
|
|
|
143
146
|
'x-oss-object-acl': 'default',
|
|
144
147
|
'x-oss-forbid-overwrite': 'false',
|
|
145
148
|
};
|
|
146
|
-
await Promise.all(
|
|
149
|
+
await Promise.all(assets.map(async ({ source, objectKey }) => {
|
|
147
150
|
await client.put(objectKey, node_path_1.default.normalize(source), { headers });
|
|
148
|
-
logger_1.logger.
|
|
151
|
+
logger_1.logger.debug(`Upload file: ${source} to bucket: ${bucketName} successfully!`);
|
|
149
152
|
}));
|
|
150
153
|
return bucketName;
|
|
151
154
|
};
|
|
152
155
|
exports.publishAssets = publishAssets;
|
|
156
|
+
const cleanupAssets = async (assets) => {
|
|
157
|
+
if (!assets?.length) {
|
|
158
|
+
logger_1.logger.info('No assets to cleanup, skipped!');
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const context = (0, context_1.getContext)();
|
|
162
|
+
const bucketName = assets[0].bucketName;
|
|
163
|
+
const client = new ali_oss_1.default({
|
|
164
|
+
region: `oss-${context.region}`,
|
|
165
|
+
accessKeyId: context.accessKeyId,
|
|
166
|
+
accessKeySecret: context.accessKeySecret,
|
|
167
|
+
bucket: bucketName,
|
|
168
|
+
});
|
|
169
|
+
await Promise.all(assets.map(async ({ objectKey }) => {
|
|
170
|
+
await client.delete(objectKey);
|
|
171
|
+
logger_1.logger.debug(`Cleanup file: ${objectKey} from bucket: ${bucketName} successfully!`);
|
|
172
|
+
}));
|
|
173
|
+
// delete the bucket
|
|
174
|
+
await client.deleteBucket(bucketName);
|
|
175
|
+
logger_1.logger.debug(`Cleanup bucket: ${bucketName} successfully!`);
|
|
176
|
+
};
|
|
177
|
+
exports.cleanupAssets = cleanupAssets;
|
|
@@ -42,6 +42,7 @@ const ros20190910_1 = __importStar(require("@alicloud/ros20190910"));
|
|
|
42
42
|
const openapi_client_1 = require("@alicloud/openapi-client");
|
|
43
43
|
const logger_1 = require("./logger");
|
|
44
44
|
const lang_1 = require("../lang");
|
|
45
|
+
const context_1 = require("./context");
|
|
45
46
|
const client = new ros20190910_1.default(new openapi_client_1.Config({
|
|
46
47
|
accessKeyId: process.env.ALIYUN_ACCESS_KEY_ID,
|
|
47
48
|
accessKeySecret: process.env.ALIYUN_ACCESS_KEY_SECRET,
|
|
@@ -85,7 +86,7 @@ const updateStack = async (stackId, templateBody, context) => {
|
|
|
85
86
|
return await getStackActionResult(response.body?.stackId || '', context.region);
|
|
86
87
|
}
|
|
87
88
|
catch (err) {
|
|
88
|
-
const {
|
|
89
|
+
const { message, statusCode } = err || {};
|
|
89
90
|
if (statusCode === 400 && message.includes('Update the completely same stack')) {
|
|
90
91
|
logger_1.logger.warn(`${lang_1.lang.__('UPDATE_COMPLETELY_SAME_STACK')}`);
|
|
91
92
|
return null;
|
|
@@ -154,7 +155,8 @@ const getStackActionResult = async (stackId, region) => {
|
|
|
154
155
|
}, 5000); // 5 seconds interval
|
|
155
156
|
});
|
|
156
157
|
};
|
|
157
|
-
const rosStackDeploy = async (stackName, templateBody
|
|
158
|
+
const rosStackDeploy = async (stackName, templateBody) => {
|
|
159
|
+
const context = (0, context_1.getContext)();
|
|
158
160
|
const stackInfo = await getStackByName(stackName, context.region);
|
|
159
161
|
if (stackInfo) {
|
|
160
162
|
const { Status: stackStatus } = stackInfo;
|
|
@@ -186,7 +188,7 @@ const rosStackDelete = async ({ stackName, region, }) => {
|
|
|
186
188
|
});
|
|
187
189
|
await client.deleteStack(deleteStackRequest);
|
|
188
190
|
await getStackActionResult(stackInfo.stackId, region);
|
|
189
|
-
logger_1.logger.info(`Stack: ${stackName} deleted
|
|
191
|
+
logger_1.logger.info(`Stack: ${stackName} deleted!🗑 `);
|
|
190
192
|
}
|
|
191
193
|
catch (err) {
|
|
192
194
|
logger_1.logger.error(`Stack: ${stackName} delete failed! ❌, error: ${JSON.stringify(err)}`);
|
package/dist/src/stack/deploy.js
CHANGED
|
@@ -43,7 +43,8 @@ const common_1 = require("../common");
|
|
|
43
43
|
const rosStack_1 = require("./rosStack");
|
|
44
44
|
const rfsStack_1 = require("./rfsStack");
|
|
45
45
|
const lodash_1 = require("lodash");
|
|
46
|
-
const generateRosStackTemplate = (stackName, iac
|
|
46
|
+
const generateRosStackTemplate = (stackName, iac) => {
|
|
47
|
+
const context = (0, common_1.getContext)();
|
|
47
48
|
const app = new ros.App();
|
|
48
49
|
new rosStack_1.RosStack(app, iac, context);
|
|
49
50
|
const assembly = app.synth();
|
|
@@ -57,29 +58,45 @@ const generateRosStackTemplate = (stackName, iac, context) => {
|
|
|
57
58
|
return { template, assets };
|
|
58
59
|
};
|
|
59
60
|
exports.generateRosStackTemplate = generateRosStackTemplate;
|
|
60
|
-
const generateRfsStackTemplate = (stackName, iac
|
|
61
|
-
const stack = new rfsStack_1.RfsStack(iac
|
|
61
|
+
const generateRfsStackTemplate = (stackName, iac) => {
|
|
62
|
+
const stack = new rfsStack_1.RfsStack(iac);
|
|
62
63
|
const hcl = stack.toHclTerraform();
|
|
63
64
|
console.log('HCL:', hcl);
|
|
64
65
|
return { template: hcl };
|
|
65
66
|
};
|
|
66
67
|
exports.generateRfsStackTemplate = generateRfsStackTemplate;
|
|
67
|
-
const deployStack = async (stackName, iac
|
|
68
|
-
const { template, assets } = (0, exports.generateRosStackTemplate)(stackName, iac
|
|
69
|
-
await (0, rosStack_1.prepareBootstrapStack)(
|
|
68
|
+
const deployStack = async (stackName, iac) => {
|
|
69
|
+
const { template, assets } = (0, exports.generateRosStackTemplate)(stackName, iac);
|
|
70
|
+
await (0, rosStack_1.prepareBootstrapStack)();
|
|
70
71
|
common_1.logger.info(`Deploying stack, publishing assets...`);
|
|
71
|
-
await (0, common_1.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
const constructedAssets = await (0, common_1.constructAssets)(assets);
|
|
73
|
+
try {
|
|
74
|
+
await (0, common_1.publishAssets)(constructedAssets);
|
|
75
|
+
common_1.logger.info(`Assets published! 🎉`);
|
|
76
|
+
await (0, common_1.rosStackDeploy)(stackName, template);
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
common_1.logger.error(`Failed to deploy stack: ${e}`);
|
|
80
|
+
throw e;
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
try {
|
|
84
|
+
common_1.logger.info(`Cleaning up temporary Assets...`);
|
|
85
|
+
await (0, common_1.cleanupAssets)(constructedAssets);
|
|
86
|
+
common_1.logger.info(`Assets cleaned up!♻️`);
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
common_1.logger.error(`Failed to cleanup assets, it wont affect the deployment result, but to avoid potential cost, you can delete the temporary bucket : ${constructedAssets?.[0].bucketName}, error details:${e}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
75
92
|
};
|
|
76
93
|
exports.deployStack = deployStack;
|
|
77
|
-
const generateStackTemplate = (stackName, iac
|
|
94
|
+
const generateStackTemplate = (stackName, iac) => {
|
|
78
95
|
if (iac.provider.name === common_1.ProviderEnum.ALIYUN) {
|
|
79
|
-
return (0, exports.generateRosStackTemplate)(stackName, iac
|
|
96
|
+
return (0, exports.generateRosStackTemplate)(stackName, iac);
|
|
80
97
|
}
|
|
81
98
|
else if (iac.provider.name === common_1.ProviderEnum.HUAWEI) {
|
|
82
|
-
return (0, exports.generateRfsStackTemplate)(stackName, iac
|
|
99
|
+
return (0, exports.generateRfsStackTemplate)(stackName, iac);
|
|
83
100
|
}
|
|
84
101
|
return { template: '' };
|
|
85
102
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Context, ServerlessIac } from '../../types';
|
|
2
2
|
export declare class RfsStack {
|
|
3
3
|
private readonly iac;
|
|
4
4
|
private readonly context;
|
|
5
5
|
private hcl;
|
|
6
|
-
constructor(iac: ServerlessIac, context
|
|
6
|
+
constructor(iac: ServerlessIac, context?: Context);
|
|
7
7
|
toHclTerraform(): string;
|
|
8
8
|
appendHcl(hcl: string): void;
|
|
9
9
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RfsStack = void 0;
|
|
4
4
|
const function_1 = require("./function");
|
|
5
|
+
const common_1 = require("../../common");
|
|
5
6
|
const provider = (stack, context) => {
|
|
6
7
|
const hcl = `
|
|
7
8
|
terraform {
|
|
@@ -22,7 +23,7 @@ provider "huaweicloud" {
|
|
|
22
23
|
stack.appendHcl(hcl);
|
|
23
24
|
};
|
|
24
25
|
class RfsStack {
|
|
25
|
-
constructor(iac, context) {
|
|
26
|
+
constructor(iac, context = (0, common_1.getContext)()) {
|
|
26
27
|
this.iac = iac;
|
|
27
28
|
this.context = context;
|
|
28
29
|
this.hcl = '';
|
|
@@ -4,7 +4,7 @@ exports.prepareBootstrapStack = void 0;
|
|
|
4
4
|
const common_1 = require("../../common");
|
|
5
5
|
const getBootstrapTemplate = async (context) => {
|
|
6
6
|
const iamInfo = await (0, common_1.getIamInfo)(context);
|
|
7
|
-
const stackName = `
|
|
7
|
+
const stackName = `si-bootstrap-${iamInfo?.accountId}-${context.region}`;
|
|
8
8
|
const template = {
|
|
9
9
|
Description: 'ServerlessInsight Bootstrap Stack',
|
|
10
10
|
Metadata: {
|
|
@@ -14,7 +14,7 @@ const getBootstrapTemplate = async (context) => {
|
|
|
14
14
|
},
|
|
15
15
|
ROSTemplateFormatVersion: '2015-09-01',
|
|
16
16
|
Resources: {
|
|
17
|
-
|
|
17
|
+
si_auto_artifacts_bucket: {
|
|
18
18
|
Type: 'ALIYUN::OSS::Bucket',
|
|
19
19
|
Properties: {
|
|
20
20
|
BucketName: {
|
|
@@ -33,8 +33,9 @@ const getBootstrapTemplate = async (context) => {
|
|
|
33
33
|
};
|
|
34
34
|
return { stackName, template };
|
|
35
35
|
};
|
|
36
|
-
const prepareBootstrapStack = async (
|
|
36
|
+
const prepareBootstrapStack = async () => {
|
|
37
|
+
const context = (0, common_1.getContext)();
|
|
37
38
|
const { stackName, template } = await getBootstrapTemplate(context);
|
|
38
|
-
await (0, common_1.rosStackDeploy)(stackName, template
|
|
39
|
+
await (0, common_1.rosStackDeploy)(stackName, template);
|
|
39
40
|
};
|
|
40
41
|
exports.prepareBootstrapStack = prepareBootstrapStack;
|