@geek-fun/serverlessinsight 0.4.0 → 0.5.0

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.
Files changed (160) hide show
  1. package/.gitattributes +1 -0
  2. package/README.md +108 -8
  3. package/README.zh-CN.md +52 -8
  4. package/dist/package.json +37 -35
  5. package/dist/src/commands/deploy.js +17 -7
  6. package/dist/src/commands/destroy.js +27 -4
  7. package/dist/src/commands/forceUnlock.js +61 -0
  8. package/dist/src/commands/index.js +86 -14
  9. package/dist/src/commands/local.js +10 -1
  10. package/dist/src/commands/plan.js +33 -0
  11. package/dist/src/commands/template.js +3 -1
  12. package/dist/src/commands/validate.js +2 -1
  13. package/dist/src/common/aliyunClient/apigwOperations.js +652 -0
  14. package/dist/src/common/aliyunClient/dnsOperations.js +90 -0
  15. package/dist/src/common/aliyunClient/ecsOperations.js +141 -0
  16. package/dist/src/common/aliyunClient/esOperations.js +219 -0
  17. package/dist/src/common/aliyunClient/fc3Operations.js +270 -0
  18. package/dist/src/common/aliyunClient/index.js +141 -0
  19. package/dist/src/common/aliyunClient/nasOperations.js +233 -0
  20. package/dist/src/common/aliyunClient/ossOperations.js +237 -0
  21. package/dist/src/common/aliyunClient/ramOperations.js +205 -0
  22. package/dist/src/common/aliyunClient/rdsOperations.js +206 -0
  23. package/dist/src/common/aliyunClient/slsOperations.js +218 -0
  24. package/dist/src/common/aliyunClient/tablestoreOperations.js +199 -0
  25. package/dist/src/common/aliyunClient/types.js +2 -0
  26. package/dist/src/common/constants.js +7 -1
  27. package/dist/src/common/context.js +32 -14
  28. package/dist/src/common/credentials.js +39 -0
  29. package/dist/src/common/dependencyGraph/graph.js +280 -0
  30. package/dist/src/common/dependencyGraph/index.js +18 -0
  31. package/dist/src/common/dependencyGraph/types.js +2 -0
  32. package/dist/src/common/fileUtils.js +16 -0
  33. package/dist/src/common/hashUtils.js +121 -0
  34. package/dist/src/common/iacHelper.js +25 -97
  35. package/dist/src/common/imsClient.js +4 -0
  36. package/dist/src/common/index.js +7 -2
  37. package/dist/src/common/lockManager.js +212 -0
  38. package/dist/src/common/logger.js +89 -6
  39. package/dist/src/common/providerEnum.js +2 -3
  40. package/dist/src/common/runtimeMapper.js +160 -0
  41. package/dist/src/common/scfClient.js +84 -0
  42. package/dist/src/common/stateManager.js +107 -0
  43. package/dist/src/common/tencentClient/cosOperations.js +287 -0
  44. package/dist/src/common/tencentClient/esOperations.js +156 -0
  45. package/dist/src/common/tencentClient/index.js +116 -0
  46. package/dist/src/common/tencentClient/scfOperations.js +141 -0
  47. package/dist/src/common/tencentClient/tdsqlcOperations.js +211 -0
  48. package/dist/src/common/tencentClient/types.js +17 -0
  49. package/dist/src/lang/en.js +254 -0
  50. package/dist/src/lang/index.js +28 -8
  51. package/dist/src/lang/zh-CN.js +229 -0
  52. package/dist/src/parser/bucketParser.js +25 -12
  53. package/dist/src/parser/databaseParser.js +14 -10
  54. package/dist/src/parser/functionParser.js +19 -6
  55. package/dist/src/parser/parseUtils.js +74 -0
  56. package/dist/src/parser/tableParser.js +19 -17
  57. package/dist/src/stack/aliyunStack/apigwExecutor.js +84 -0
  58. package/dist/src/stack/aliyunStack/apigwPlanner.js +118 -0
  59. package/dist/src/stack/aliyunStack/apigwResource.js +339 -0
  60. package/dist/src/stack/aliyunStack/apigwTypes.js +125 -0
  61. package/dist/src/stack/aliyunStack/databaseExecutor.js +112 -0
  62. package/dist/src/stack/aliyunStack/databasePlanner.js +128 -0
  63. package/dist/src/stack/aliyunStack/databaseResource.js +228 -0
  64. package/dist/src/stack/aliyunStack/deployer.js +133 -0
  65. package/dist/src/stack/aliyunStack/destroyer.js +114 -0
  66. package/dist/src/stack/aliyunStack/esServerlessTypes.js +141 -0
  67. package/dist/src/stack/aliyunStack/fc3Executor.js +91 -0
  68. package/dist/src/stack/aliyunStack/fc3Planner.js +77 -0
  69. package/dist/src/stack/aliyunStack/fc3Resource.js +511 -0
  70. package/dist/src/stack/aliyunStack/fc3Types.js +76 -0
  71. package/dist/src/stack/aliyunStack/index.js +40 -0
  72. package/dist/src/stack/aliyunStack/ossExecutor.js +91 -0
  73. package/dist/src/stack/aliyunStack/ossPlanner.js +76 -0
  74. package/dist/src/stack/aliyunStack/ossResource.js +196 -0
  75. package/dist/src/stack/aliyunStack/ossTypes.js +50 -0
  76. package/dist/src/stack/aliyunStack/planner.js +37 -0
  77. package/dist/src/stack/aliyunStack/rdsTypes.js +217 -0
  78. package/dist/src/stack/aliyunStack/tablestoreExecutor.js +92 -0
  79. package/dist/src/stack/aliyunStack/tablestorePlanner.js +94 -0
  80. package/dist/src/stack/aliyunStack/tablestoreResource.js +120 -0
  81. package/dist/src/stack/aliyunStack/tablestoreTypes.js +77 -0
  82. package/dist/src/stack/bucketTypes.js +17 -0
  83. package/dist/src/stack/deploy.js +24 -77
  84. package/dist/src/stack/localStack/bucket.js +11 -6
  85. package/dist/src/stack/localStack/event.js +10 -5
  86. package/dist/src/stack/localStack/function.js +13 -7
  87. package/dist/src/stack/localStack/functionRunner.js +1 -1
  88. package/dist/src/stack/localStack/localServer.js +7 -6
  89. package/dist/src/stack/scfStack/cosExecutor.js +91 -0
  90. package/dist/src/stack/scfStack/cosPlanner.js +76 -0
  91. package/dist/src/stack/scfStack/cosResource.js +126 -0
  92. package/dist/src/stack/scfStack/cosTypes.js +46 -0
  93. package/dist/src/stack/scfStack/deployer.js +91 -0
  94. package/dist/src/stack/scfStack/destroyer.js +88 -0
  95. package/dist/src/stack/scfStack/esServerlessExecutor.js +105 -0
  96. package/dist/src/stack/scfStack/esServerlessPlanner.js +86 -0
  97. package/dist/src/stack/scfStack/esServerlessResource.js +94 -0
  98. package/dist/src/stack/scfStack/esServerlessTypes.js +48 -0
  99. package/dist/src/stack/scfStack/index.js +35 -0
  100. package/dist/src/stack/scfStack/planner.js +91 -0
  101. package/dist/src/stack/scfStack/scfExecutor.js +91 -0
  102. package/dist/src/stack/scfStack/scfPlanner.js +78 -0
  103. package/dist/src/stack/scfStack/scfResource.js +216 -0
  104. package/dist/src/stack/scfStack/scfTypes.js +41 -0
  105. package/dist/src/stack/scfStack/tdsqlcExecutor.js +105 -0
  106. package/dist/src/stack/scfStack/tdsqlcPlanner.js +90 -0
  107. package/dist/src/stack/scfStack/tdsqlcResource.js +146 -0
  108. package/dist/src/stack/scfStack/tdsqlcTypes.js +59 -0
  109. package/dist/src/types/domains/lock.js +2 -0
  110. package/dist/src/types/domains/resolvable.js +2 -0
  111. package/dist/src/types/domains/state.js +19 -0
  112. package/dist/src/types/index.js +4 -0
  113. package/dist/src/validator/bucketSchema.js +4 -10
  114. package/dist/src/validator/databaseSchema.js +36 -36
  115. package/dist/src/validator/eventSchema.js +3 -2
  116. package/dist/src/validator/functionSchema.js +51 -46
  117. package/dist/src/validator/iacSchema.js +52 -3
  118. package/dist/src/validator/rootSchema.js +47 -1
  119. package/dist/src/validator/tableschema.js +9 -8
  120. package/dist/src/validator/templateRefSchema.js +23 -0
  121. package/dist/tsconfig.tsbuildinfo +1 -1
  122. package/package.json +37 -35
  123. package/samples/README_TENCENT_COS.md +486 -0
  124. package/samples/README_TENCENT_SCF.md +272 -0
  125. package/samples/aliyun-poc-api.yml +1 -1
  126. package/samples/aliyun-poc-bucket.yml +0 -1
  127. package/samples/aliyun-poc-domain.yml +0 -1
  128. package/samples/aliyun-poc-es.yml +14 -13
  129. package/samples/aliyun-poc-rds.yml +0 -2
  130. package/samples/aliyun-poc-table.yml +1 -3
  131. package/samples/tencent-poc-cos.yml +20 -0
  132. package/samples/tencent-poc-scf.yml +36 -0
  133. package/dist/src/commands/index.d.ts +0 -2
  134. package/dist/src/common/index.d.ts +0 -11
  135. package/dist/src/common/rosAssets.js +0 -178
  136. package/dist/src/common/rosClient.js +0 -198
  137. package/dist/src/index.d.ts +0 -1
  138. package/dist/src/lang/index.d.ts +0 -3
  139. package/dist/src/parser/index.d.ts +0 -3
  140. package/dist/src/stack/index.d.ts +0 -1
  141. package/dist/src/stack/localStack/index.d.ts +0 -5
  142. package/dist/src/stack/rfsStack/index.d.ts +0 -9
  143. package/dist/src/stack/rosStack/bootstrap.js +0 -187
  144. package/dist/src/stack/rosStack/bucket.js +0 -127
  145. package/dist/src/stack/rosStack/database.js +0 -313
  146. package/dist/src/stack/rosStack/event.js +0 -143
  147. package/dist/src/stack/rosStack/function.js +0 -259
  148. package/dist/src/stack/rosStack/index.d.ts +0 -7
  149. package/dist/src/stack/rosStack/index.js +0 -75
  150. package/dist/src/stack/rosStack/stage.js +0 -46
  151. package/dist/src/stack/rosStack/table.js +0 -95
  152. package/dist/src/stack/rosStack/tag.js +0 -11
  153. package/dist/src/stack/rosStack/vars.js +0 -49
  154. package/dist/src/types/index.d.ts +0 -55
  155. package/dist/src/types/localStack/index.d.ts +0 -81
  156. package/dist/src/validator/index.d.ts +0 -1
  157. package/layers/si-bootstrap-sdk/Dockerfile-aliyuncli +0 -12
  158. package/layers/si-bootstrap-sdk/README.md +0 -1
  159. package/layers/si-bootstrap-sdk/package-lock.json +0 -875
  160. package/layers/si-bootstrap-sdk/package.json +0 -33
@@ -0,0 +1,511 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deleteResource = exports.updateResource = exports.readResource = exports.createResource = void 0;
4
+ const aliyunClient_1 = require("../../common/aliyunClient");
5
+ const common_1 = require("../../common");
6
+ const fc3Types_1 = require("./fc3Types");
7
+ const logger_1 = require("../../common/logger");
8
+ const lang_1 = require("../../lang");
9
+ const buildFc3InstanceFromProvider = (info, arn) => {
10
+ return {
11
+ type: 'ALIYUN_FC3_FUNCTION',
12
+ arn,
13
+ id: info.functionName ?? '',
14
+ functionName: info.functionName ?? null,
15
+ functionId: info.functionId ?? null,
16
+ runtime: info.runtime ?? null,
17
+ handler: info.handler ?? null,
18
+ memorySize: info.memorySize ?? null,
19
+ timeout: info.timeout ?? null,
20
+ diskSize: info.diskSize ?? null,
21
+ cpu: info.cpu ?? null,
22
+ environment: info.environmentVariables ?? {},
23
+ vpcConfig: info.vpcConfig
24
+ ? {
25
+ vpcId: info.vpcConfig.vpcId ?? null,
26
+ vSwitchIds: info.vpcConfig.vSwitchIds ?? [],
27
+ securityGroupId: info.vpcConfig.securityGroupId ?? null,
28
+ }
29
+ : {},
30
+ gpuConfig: info.gpuConfig
31
+ ? {
32
+ gpuMemorySize: info.gpuConfig.gpuMemorySize ?? null,
33
+ gpuType: info.gpuConfig.gpuType ?? null,
34
+ }
35
+ : {},
36
+ nasConfig: info.nasConfig
37
+ ? {
38
+ userId: info.nasConfig.userId ?? null,
39
+ groupId: info.nasConfig.groupId ?? null,
40
+ mountPoints: info.nasConfig.mountPoints?.map((mp) => ({
41
+ serverAddr: mp.serverAddr ?? null,
42
+ mountDir: mp.mountDir ?? null,
43
+ enableTls: mp.enableTls ?? null,
44
+ })) ?? [],
45
+ }
46
+ : {},
47
+ logConfig: info.logConfig
48
+ ? {
49
+ project: info.logConfig.project ?? null,
50
+ logstore: info.logConfig.logstore ?? null,
51
+ enableRequestMetrics: info.logConfig.enableRequestMetrics ?? null,
52
+ enableInstanceMetrics: info.logConfig.enableInstanceMetrics ?? null,
53
+ logBeginRule: info.logConfig.logBeginRule ?? null,
54
+ }
55
+ : {},
56
+ customContainerConfig: info.customContainerConfig
57
+ ? {
58
+ image: info.customContainerConfig.image ?? null,
59
+ entrypoint: info.customContainerConfig.entrypoint ?? [],
60
+ command: info.customContainerConfig.command ?? [],
61
+ port: info.customContainerConfig.port ?? null,
62
+ accelerationType: info.customContainerConfig.accelerationType ?? null,
63
+ }
64
+ : {},
65
+ description: info.description ?? null,
66
+ internetAccess: info.internetAccess ?? null,
67
+ role: info.role ?? null,
68
+ codeChecksum: info.codeChecksum ?? null,
69
+ codeSize: info.codeSize ?? null,
70
+ createdTime: info.createdTime ?? null,
71
+ lastModifiedTime: info.lastModifiedTime ?? null,
72
+ state: info.state ?? null,
73
+ stateReason: info.stateReason ?? null,
74
+ stateReasonCode: info.stateReasonCode ?? null,
75
+ lastUpdateStatus: info.lastUpdateStatus ?? null,
76
+ lastUpdateStatusReason: info.lastUpdateStatusReason ?? null,
77
+ lastUpdateStatusReasonCode: info.lastUpdateStatusReasonCode ?? null,
78
+ };
79
+ };
80
+ // Helper function to create dependent resources directly using the client
81
+ const createDependentResources = async (context, fn, serviceName) => {
82
+ const client = (0, aliyunClient_1.createAliyunClient)(context);
83
+ const instances = [];
84
+ let logConfig;
85
+ let securityGroup;
86
+ let nasConfig;
87
+ // Create SLS resources if logging is enabled
88
+ if (fn.log) {
89
+ const projectName = `${serviceName}-sls`;
90
+ const logstoreName = `${serviceName}-sls-logstore`;
91
+ logger_1.logger.info(`Creating SLS project: ${projectName}`);
92
+ const project = await client.sls.createProject(projectName);
93
+ instances.push({
94
+ type: 'ALIYUN_SLS_PROJECT',
95
+ id: projectName,
96
+ attributes: { ...project },
97
+ });
98
+ logger_1.logger.info(`Creating SLS logstore: ${logstoreName}`);
99
+ const logstore = await client.sls.createLogstore(projectName, logstoreName);
100
+ instances.push({
101
+ type: 'ALIYUN_SLS_LOGSTORE',
102
+ id: `${projectName}/${logstoreName}`,
103
+ attributes: { ...logstore },
104
+ });
105
+ logger_1.logger.info(`Creating SLS index for: ${logstoreName}`);
106
+ const index = await client.sls.createIndex(projectName, logstoreName);
107
+ instances.push({
108
+ type: 'ALIYUN_SLS_INDEX',
109
+ id: `${projectName}/${logstoreName}/index`,
110
+ attributes: { ...index },
111
+ });
112
+ logger_1.logger.info(`Waiting for SLS project and logstore to be ready: ${projectName}/${logstoreName}`);
113
+ await client.sls.waitForProject(projectName);
114
+ await client.sls.waitForLogstore(projectName, logstoreName);
115
+ logConfig = { project: projectName, logstore: logstoreName };
116
+ }
117
+ // Create RAM role
118
+ const roleName = `${serviceName}-fc-role`;
119
+ logger_1.logger.info(`Creating RAM role: ${roleName}`);
120
+ const ramRole = await client.ram.createRole(roleName);
121
+ instances.push({
122
+ type: 'ALIYUN_RAM_ROLE',
123
+ id: roleName,
124
+ arn: ramRole.arn,
125
+ attributes: { ...ramRole },
126
+ });
127
+ const role = { roleName, arn: ramRole.arn ?? `acs:ram::${context.accountId}:role/${roleName}` };
128
+ // Create security group if network is configured
129
+ if (fn.network) {
130
+ const sgName = fn.network.security_group.name;
131
+ logger_1.logger.info(`Creating security group: ${sgName}`);
132
+ const sg = await client.ecs.createSecurityGroup(sgName, fn.network.vpc_id, fn.network.security_group.ingress, fn.network.security_group.egress);
133
+ instances.push({
134
+ type: 'ALIYUN_ECS_SECURITY_GROUP',
135
+ id: sg.securityGroupId,
136
+ attributes: { ...sg },
137
+ });
138
+ securityGroup = { securityGroupId: sg.securityGroupId };
139
+ }
140
+ // Create NAS resources if configured
141
+ if (fn.storage?.nas && fn.storage.nas.length > 0 && fn.network) {
142
+ const mountPoints = [];
143
+ for (const nasItem of fn.storage.nas) {
144
+ const mountPath = nasItem.mount_path.replace(/\//g, '-').replace(/^-/, '');
145
+ const accessGroupName = `${fn.name}-nas-access-${mountPath}`;
146
+ logger_1.logger.info(`Creating NAS access group: ${accessGroupName}`);
147
+ const accessGroup = await client.nas.createAccessGroup(accessGroupName);
148
+ instances.push({
149
+ type: 'ALIYUN_NAS_ACCESS_GROUP',
150
+ id: accessGroupName,
151
+ attributes: { ...accessGroup },
152
+ });
153
+ logger_1.logger.info(`Creating NAS access rule for: ${accessGroupName}`);
154
+ await client.nas.createAccessRule(accessGroupName, '10.0.0.0/8');
155
+ logger_1.logger.info(`Creating NAS file system for: ${fn.name}`);
156
+ const fileSystem = await client.nas.createFileSystem(nasItem.storage_class, fn.name);
157
+ instances.push({
158
+ type: 'ALIYUN_NAS_FILE_SYSTEM',
159
+ id: fileSystem.fileSystemId,
160
+ attributes: { ...fileSystem },
161
+ });
162
+ logger_1.logger.info(`Creating NAS mount target for: ${fileSystem.fileSystemId}`);
163
+ const mountTarget = await client.nas.createMountTarget(fileSystem.fileSystemId, accessGroupName, fn.network.vpc_id, fn.network.subnet_ids[0]);
164
+ instances.push({
165
+ type: 'ALIYUN_NAS_MOUNT_TARGET',
166
+ id: `${fileSystem.fileSystemId}/${mountTarget.mountTargetDomain}`,
167
+ attributes: { ...mountTarget },
168
+ });
169
+ mountPoints.push({
170
+ serverAddr: `${mountTarget.mountTargetDomain}:/`,
171
+ mountDir: nasItem.mount_path,
172
+ fileSystemId: fileSystem.fileSystemId,
173
+ mountTargetDomain: mountTarget.mountTargetDomain,
174
+ accessGroupName,
175
+ });
176
+ }
177
+ nasConfig = { mountPoints };
178
+ }
179
+ return {
180
+ logConfig,
181
+ role,
182
+ securityGroup,
183
+ nasConfig,
184
+ instances,
185
+ };
186
+ };
187
+ // Helper function to delete dependent resources directly using the client
188
+ const deleteDependentResources = async (context, instances) => {
189
+ const client = (0, aliyunClient_1.createAliyunClient)(context);
190
+ // Delete in reverse order of creation
191
+ for (const instance of [...instances].reverse()) {
192
+ try {
193
+ switch (instance.type) {
194
+ case 'ALIYUN_NAS_MOUNT_TARGET': {
195
+ const [fileSystemId, mountTargetDomain] = instance.id.split('/');
196
+ logger_1.logger.info(`Deleting NAS mount target: ${instance.id}`);
197
+ await client.nas.deleteMountTarget(fileSystemId, mountTargetDomain);
198
+ break;
199
+ }
200
+ case 'ALIYUN_NAS_FILE_SYSTEM':
201
+ logger_1.logger.info(`Deleting NAS file system: ${instance.id}`);
202
+ await client.nas.deleteFileSystem(instance.id);
203
+ break;
204
+ case 'ALIYUN_NAS_ACCESS_GROUP':
205
+ logger_1.logger.info(`Deleting NAS access group: ${instance.id}`);
206
+ await client.nas.deleteAccessGroup(instance.id);
207
+ break;
208
+ case 'ALIYUN_ECS_SECURITY_GROUP':
209
+ logger_1.logger.info(`Deleting security group: ${instance.id}`);
210
+ await client.ecs.deleteSecurityGroup(instance.id);
211
+ break;
212
+ case 'ALIYUN_RAM_ROLE':
213
+ logger_1.logger.info(`Deleting RAM role: ${instance.id}`);
214
+ await client.ram.deleteRole(instance.id);
215
+ break;
216
+ case 'ALIYUN_SLS_INDEX': {
217
+ const [projectName, logstoreName] = instance.id.split('/');
218
+ logger_1.logger.info(`Deleting SLS index: ${instance.id}`);
219
+ await client.sls.deleteIndex(projectName, logstoreName);
220
+ break;
221
+ }
222
+ case 'ALIYUN_SLS_LOGSTORE': {
223
+ const [projectName, logstoreName] = instance.id.split('/');
224
+ logger_1.logger.info(`Deleting SLS logstore: ${instance.id}`);
225
+ await client.sls.deleteLogstore(projectName, logstoreName);
226
+ break;
227
+ }
228
+ case 'ALIYUN_SLS_PROJECT':
229
+ logger_1.logger.info(`Deleting SLS project: ${instance.id}`);
230
+ await client.sls.deleteProject(instance.id);
231
+ break;
232
+ default:
233
+ logger_1.logger.warn(`Unknown resource type: ${instance.type}`);
234
+ }
235
+ }
236
+ catch (err) {
237
+ logger_1.logger.error(`Failed to delete resource ${instance.type}:${instance.id}: ${err}`);
238
+ }
239
+ }
240
+ };
241
+ const createResource = async (context, fn, state) => {
242
+ const ctx = (0, common_1.getContext)();
243
+ const serviceName = ctx.stackName ?? fn.name;
244
+ // Create dependent resources (SLS, RAM, ECS SecurityGroup, NAS)
245
+ const dependentResources = await createDependentResources(context, fn, serviceName);
246
+ // Build FC3 config with dependent resources
247
+ let config = (0, fc3Types_1.functionToFc3Config)(fn);
248
+ // Update config with dependent resources
249
+ if (dependentResources.logConfig) {
250
+ config = {
251
+ ...config,
252
+ logConfig: {
253
+ project: dependentResources.logConfig.project,
254
+ logstore: dependentResources.logConfig.logstore,
255
+ enableRequestMetrics: true,
256
+ },
257
+ };
258
+ }
259
+ if (dependentResources.role) {
260
+ config = {
261
+ ...config,
262
+ role: dependentResources.role.arn,
263
+ };
264
+ }
265
+ if (dependentResources.securityGroup && fn.network) {
266
+ config = {
267
+ ...config,
268
+ vpcConfig: {
269
+ vpcId: fn.network.vpc_id,
270
+ vSwitchIds: fn.network.subnet_ids,
271
+ securityGroupId: dependentResources.securityGroup.securityGroupId,
272
+ },
273
+ };
274
+ }
275
+ if (dependentResources.nasConfig) {
276
+ config = {
277
+ ...config,
278
+ nasConfig: {
279
+ userId: -1,
280
+ groupId: -1,
281
+ mountPoints: dependentResources.nasConfig.mountPoints.map((mp) => ({
282
+ serverAddr: mp.serverAddr,
283
+ mountDir: mp.mountDir,
284
+ })),
285
+ },
286
+ };
287
+ }
288
+ const codePath = fn.code.path;
289
+ const codeHash = (0, common_1.computeFileHash)(codePath);
290
+ const definition = (0, fc3Types_1.extractFc3Definition)(config, codeHash);
291
+ const logicalId = `functions.${fn.key}`;
292
+ // Save state with dependent resources BEFORE attempting function creation
293
+ const dependentInstances = dependentResources.instances.map((dep) => ({
294
+ arn: dep.arn ??
295
+ `arn:acs:${dep.type.toLowerCase()}:${context.region}:${context.accountId}:${dep.id}`,
296
+ id: dep.id,
297
+ type: dep.type,
298
+ ...dep.attributes,
299
+ }));
300
+ // Create partial state with just dependent resources
301
+ const partialResourceState = {
302
+ mode: 'managed',
303
+ region: context.region,
304
+ definition,
305
+ instances: dependentInstances,
306
+ lastUpdated: new Date().toISOString(),
307
+ };
308
+ state = (0, common_1.setResource)(state, logicalId, partialResourceState);
309
+ // Now attempt to create the function
310
+ const client = (0, aliyunClient_1.createAliyunClient)(context);
311
+ try {
312
+ await client.fc3.createFunction(config, codePath);
313
+ }
314
+ catch (error) {
315
+ logger_1.logger.error(`Failed to create function, but dependent resources were created and saved to state: ${error}`);
316
+ logger_1.logger.info(lang_1.lang.__('FC3_DEPENDENT_RESOURCES_TRACKED'));
317
+ logger_1.logger.info(lang_1.lang.__('FC3_CAN_RETRY_DEPLOYMENT'));
318
+ return state;
319
+ }
320
+ // Refresh state from provider to get all attributes
321
+ const functionInfo = await client.fc3.getFunction(fn.name);
322
+ if (!functionInfo) {
323
+ throw new Error(`Failed to refresh state for function: ${fn.name}`);
324
+ }
325
+ const arn = functionInfo.functionArn ??
326
+ `arn:acs:fc:${context.region}:${context.accountId}:function/${fn.name}`;
327
+ // Build instances array with FC function as first item, followed by dependent resources
328
+ const fcInstance = buildFc3InstanceFromProvider(functionInfo, arn);
329
+ const resourceState = {
330
+ mode: 'managed',
331
+ region: context.region,
332
+ definition,
333
+ instances: [fcInstance, ...dependentInstances],
334
+ lastUpdated: new Date().toISOString(),
335
+ };
336
+ return (0, common_1.setResource)(state, logicalId, resourceState);
337
+ };
338
+ exports.createResource = createResource;
339
+ const readResource = async (context, functionName) => {
340
+ const client = (0, aliyunClient_1.createAliyunClient)(context);
341
+ return await client.fc3.getFunction(functionName);
342
+ };
343
+ exports.readResource = readResource;
344
+ const updateResource = async (context, fn, state) => {
345
+ const ctx = (0, common_1.getContext)();
346
+ const serviceName = ctx.stackName ?? fn.name;
347
+ const logicalId = `functions.${fn.key}`;
348
+ // Get existing resource state to check if dependent resources exist
349
+ const existingState = (0, common_1.getResource)(state, logicalId);
350
+ const existingInstances = (existingState?.instances ?? []);
351
+ // Check if we need to create new dependent resources
352
+ const hasSlsResources = existingInstances.some((i) => i.type === 'ALIYUN_SLS_PROJECT');
353
+ const hasRamRole = existingInstances.some((i) => i.type === 'ALIYUN_RAM_ROLE');
354
+ const hasSecurityGroup = existingInstances.some((i) => i.type === 'ALIYUN_ECS_SECURITY_GROUP');
355
+ const hasNasResources = existingInstances.some((i) => i.type === 'ALIYUN_NAS_FILE_SYSTEM');
356
+ const newDependentInstances = [];
357
+ let logConfig;
358
+ let role;
359
+ let securityGroup;
360
+ let nasConfig;
361
+ // Create new dependent resources if they don't exist
362
+ if (fn.log && !hasSlsResources) {
363
+ const deps = await createDependentResources(context, { ...fn, network: undefined, storage: { ...fn.storage, nas: undefined } }, serviceName);
364
+ logConfig = deps.logConfig;
365
+ newDependentInstances.push(...deps.instances.filter((i) => i.type.startsWith('ALIYUN_SLS_')));
366
+ }
367
+ else if (hasSlsResources) {
368
+ const slsProjectInstance = existingInstances.find((i) => i.type === 'ALIYUN_SLS_PROJECT');
369
+ const slsLogstoreInstance = existingInstances.find((i) => i.type === 'ALIYUN_SLS_LOGSTORE');
370
+ if (slsProjectInstance && slsLogstoreInstance) {
371
+ const [projectName, logstoreName] = slsLogstoreInstance.id.split('/');
372
+ logConfig = { project: projectName, logstore: logstoreName };
373
+ }
374
+ }
375
+ if (!hasRamRole) {
376
+ const deps = await createDependentResources(context, { ...fn, log: false, network: undefined, storage: { ...fn.storage, nas: undefined } }, serviceName);
377
+ role = deps.role;
378
+ newDependentInstances.push(...deps.instances.filter((i) => i.type === 'ALIYUN_RAM_ROLE'));
379
+ }
380
+ else {
381
+ const ramRoleInstance = existingInstances.find((i) => i.type === 'ALIYUN_RAM_ROLE');
382
+ if (ramRoleInstance) {
383
+ role = {
384
+ roleName: ramRoleInstance.id,
385
+ arn: ramRoleInstance.arn ?? `acs:ram::${context.accountId}:role/${ramRoleInstance.id}`,
386
+ };
387
+ }
388
+ }
389
+ if (fn.network && !hasSecurityGroup) {
390
+ const deps = await createDependentResources(context, { ...fn, log: false, storage: { ...fn.storage, nas: undefined } }, serviceName);
391
+ securityGroup = deps.securityGroup;
392
+ newDependentInstances.push(...deps.instances.filter((i) => i.type === 'ALIYUN_ECS_SECURITY_GROUP'));
393
+ }
394
+ else if (hasSecurityGroup) {
395
+ const sgInstance = existingInstances.find((i) => i.type === 'ALIYUN_ECS_SECURITY_GROUP');
396
+ if (sgInstance) {
397
+ securityGroup = { securityGroupId: sgInstance.id };
398
+ }
399
+ }
400
+ if (fn.storage?.nas && fn.storage.nas.length > 0 && fn.network && !hasNasResources) {
401
+ const deps = await createDependentResources(context, { ...fn, log: false }, serviceName);
402
+ nasConfig = deps.nasConfig;
403
+ newDependentInstances.push(...deps.instances.filter((i) => i.type.startsWith('ALIYUN_NAS_')));
404
+ }
405
+ else if (hasNasResources) {
406
+ const mountTargetInstances = existingInstances.filter((i) => i.type === 'ALIYUN_NAS_MOUNT_TARGET');
407
+ const nasStorageItems = fn.storage?.nas ?? [];
408
+ if (mountTargetInstances.length > 0 && nasStorageItems.length > 0) {
409
+ nasConfig = {
410
+ mountPoints: mountTargetInstances.map((mt, idx) => ({
411
+ serverAddr: `${mt.id.split('/')[1]}:/`,
412
+ mountDir: nasStorageItems[idx]?.mount_path ?? '/mnt/nas',
413
+ })),
414
+ };
415
+ }
416
+ }
417
+ // Build FC3 config with dependent resources
418
+ let config = (0, fc3Types_1.functionToFc3Config)(fn);
419
+ if (logConfig) {
420
+ config = {
421
+ ...config,
422
+ logConfig: {
423
+ project: logConfig.project,
424
+ logstore: logConfig.logstore,
425
+ enableRequestMetrics: true,
426
+ },
427
+ };
428
+ }
429
+ if (role) {
430
+ config = {
431
+ ...config,
432
+ role: role.arn,
433
+ };
434
+ }
435
+ if (securityGroup && fn.network) {
436
+ config = {
437
+ ...config,
438
+ vpcConfig: {
439
+ vpcId: fn.network.vpc_id,
440
+ vSwitchIds: fn.network.subnet_ids,
441
+ securityGroupId: securityGroup.securityGroupId,
442
+ },
443
+ };
444
+ }
445
+ if (nasConfig) {
446
+ config = {
447
+ ...config,
448
+ nasConfig: {
449
+ userId: -1,
450
+ groupId: -1,
451
+ mountPoints: nasConfig.mountPoints,
452
+ },
453
+ };
454
+ }
455
+ const codePath = fn.code.path;
456
+ const client = (0, aliyunClient_1.createAliyunClient)(context);
457
+ await client.fc3.updateFunctionConfiguration(config);
458
+ await client.fc3.updateFunctionCode(fn.name, codePath);
459
+ const functionInfo = await client.fc3.getFunction(fn.name);
460
+ if (!functionInfo) {
461
+ throw new Error(`Failed to refresh state for function: ${fn.name}`);
462
+ }
463
+ const codeHash = (0, common_1.computeFileHash)(codePath);
464
+ const definition = (0, fc3Types_1.extractFc3Definition)(config, codeHash);
465
+ const arn = functionInfo.functionArn ??
466
+ `arn:acs:fc:${context.region}:${context.accountId}:function/${fn.name}`;
467
+ // Build instances array: FC function + existing dependent resources + new dependent resources
468
+ const fcInstance = buildFc3InstanceFromProvider(functionInfo, arn);
469
+ const existingDependentInstances = existingInstances
470
+ .filter((i) => i.type !== 'ALIYUN_FC3_FUNCTION')
471
+ .map((i) => {
472
+ const { arn: existingArn, id: existingId, ...rest } = i;
473
+ return {
474
+ arn: existingArn ??
475
+ `arn:acs:${i.type?.toString().toLowerCase()}:${context.region}:${context.accountId}:${existingId}`,
476
+ id: existingId?.toString() ?? '',
477
+ ...rest,
478
+ };
479
+ });
480
+ const newDependentInstancesMapped = newDependentInstances.map((dep) => ({
481
+ arn: dep.arn ??
482
+ `arn:acs:${dep.type.toLowerCase()}:${context.region}:${context.accountId}:${dep.id}`,
483
+ id: dep.id,
484
+ type: dep.type,
485
+ ...dep.attributes,
486
+ }));
487
+ const resourceState = {
488
+ mode: 'managed',
489
+ region: context.region,
490
+ definition,
491
+ instances: [fcInstance, ...existingDependentInstances, ...newDependentInstancesMapped],
492
+ lastUpdated: new Date().toISOString(),
493
+ };
494
+ return (0, common_1.setResource)(state, logicalId, resourceState);
495
+ };
496
+ exports.updateResource = updateResource;
497
+ const deleteResource = async (context, functionName, logicalId, state) => {
498
+ // Get existing resource state to find dependent resources
499
+ const existingState = (0, common_1.getResource)(state, logicalId);
500
+ const existingInstances = (existingState?.instances ?? []);
501
+ // Delete FC function first
502
+ const client = (0, aliyunClient_1.createAliyunClient)(context);
503
+ await client.fc3.deleteFunction(functionName);
504
+ // Delete dependent resources
505
+ const dependentInstances = existingInstances.filter((i) => i.type !== 'ALIYUN_FC3_FUNCTION' && !i.type.includes('undefined'));
506
+ if (dependentInstances.length > 0) {
507
+ await deleteDependentResources(context, dependentInstances);
508
+ }
509
+ return (0, common_1.removeResource)(state, logicalId);
510
+ };
511
+ exports.deleteResource = deleteResource;
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractFunctionDomainDefinition = exports.extractFc3Definition = exports.functionToFc3Config = void 0;
4
+ const types_1 = require("../../types");
5
+ const common_1 = require("../../common");
6
+ const gpuConfigMap = {
7
+ [types_1.FunctionGpuEnum.TESLA_8]: { gpuMemorySize: 8192, gpuType: 'fc.gpu.tesla.1' },
8
+ [types_1.FunctionGpuEnum.TESLA_12]: { gpuMemorySize: 12288, gpuType: 'fc.gpu.tesla.1' },
9
+ [types_1.FunctionGpuEnum.TESLA_16]: { gpuMemorySize: 16384, gpuType: 'fc.gpu.tesla.1' },
10
+ [types_1.FunctionGpuEnum.AMPERE_8]: { gpuMemorySize: 8192, gpuType: 'fc.gpu.ampere.1' },
11
+ [types_1.FunctionGpuEnum.AMPERE_12]: { gpuMemorySize: 12288, gpuType: 'fc.gpu.ampere.1' },
12
+ [types_1.FunctionGpuEnum.AMPERE_16]: { gpuMemorySize: 16384, gpuType: 'fc.gpu.ampere.1' },
13
+ [types_1.FunctionGpuEnum.AMPERE_24]: { gpuMemorySize: 24576, gpuType: 'fc.gpu.ampere.1' },
14
+ [types_1.FunctionGpuEnum.ADA_48]: { gpuMemorySize: 49152, gpuType: 'fc.gpu.ada.1' },
15
+ };
16
+ const transformGpuConfig = (gpu) => {
17
+ if (!gpu) {
18
+ return undefined;
19
+ }
20
+ return gpuConfigMap[gpu];
21
+ };
22
+ const functionToFc3Config = (fn) => {
23
+ const config = {
24
+ functionName: fn.name,
25
+ runtime: fn.container ? 'custom-container' : (0, common_1.mapRuntime)(fn.code.runtime, common_1.ProviderEnum.ALIYUN),
26
+ handler: fn.container ? 'index.handler' : fn.code.handler,
27
+ memorySize: fn.memory ?? 128,
28
+ timeout: fn.timeout ?? 60,
29
+ };
30
+ if (fn.storage?.disk) {
31
+ config.diskSize = fn.storage.disk;
32
+ }
33
+ if (fn.environment && Object.keys(fn.environment).length > 0) {
34
+ config.environmentVariables = fn.environment;
35
+ }
36
+ if (fn.gpu) {
37
+ config.gpuConfig = transformGpuConfig(fn.gpu);
38
+ }
39
+ if (fn.container) {
40
+ config.customContainerConfig = {
41
+ image: fn.container.image,
42
+ port: fn.container.port,
43
+ ...(fn.container.cmd && { command: fn.container.cmd.split(' ') }),
44
+ };
45
+ }
46
+ if (fn.network) {
47
+ config.vpcConfig = {
48
+ vpcId: fn.network.vpc_id,
49
+ vSwitchIds: fn.network.subnet_ids,
50
+ securityGroupId: fn.network.security_group.name,
51
+ };
52
+ }
53
+ return config;
54
+ };
55
+ exports.functionToFc3Config = functionToFc3Config;
56
+ const extractFc3Definition = (config, codeHash) => {
57
+ return {
58
+ functionName: config.functionName,
59
+ runtime: config.runtime,
60
+ handler: config.handler,
61
+ memorySize: config.memorySize,
62
+ timeout: config.timeout,
63
+ diskSize: config.diskSize ?? null,
64
+ environment: config.environmentVariables ?? {},
65
+ vpcConfig: config.vpcConfig ?? null,
66
+ gpuConfig: config.gpuConfig ?? null,
67
+ customContainerConfig: config.customContainerConfig ?? null,
68
+ codeHash,
69
+ };
70
+ };
71
+ exports.extractFc3Definition = extractFc3Definition;
72
+ const extractFunctionDomainDefinition = (fn, codeHash) => {
73
+ const config = (0, exports.functionToFc3Config)(fn);
74
+ return (0, exports.extractFc3Definition)(config, codeHash);
75
+ };
76
+ exports.extractFunctionDomainDefinition = extractFunctionDomainDefinition;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./fc3Types"), exports);
18
+ __exportStar(require("./fc3Resource"), exports);
19
+ __exportStar(require("./fc3Planner"), exports);
20
+ __exportStar(require("./fc3Executor"), exports);
21
+ __exportStar(require("./apigwTypes"), exports);
22
+ __exportStar(require("./apigwResource"), exports);
23
+ __exportStar(require("./apigwPlanner"), exports);
24
+ __exportStar(require("./apigwExecutor"), exports);
25
+ __exportStar(require("./ossTypes"), exports);
26
+ __exportStar(require("./ossResource"), exports);
27
+ __exportStar(require("./ossPlanner"), exports);
28
+ __exportStar(require("./ossExecutor"), exports);
29
+ __exportStar(require("./rdsTypes"), exports);
30
+ __exportStar(require("./esServerlessTypes"), exports);
31
+ __exportStar(require("./databaseResource"), exports);
32
+ __exportStar(require("./databasePlanner"), exports);
33
+ __exportStar(require("./databaseExecutor"), exports);
34
+ __exportStar(require("./tablestoreTypes"), exports);
35
+ __exportStar(require("./tablestoreResource"), exports);
36
+ __exportStar(require("./tablestorePlanner"), exports);
37
+ __exportStar(require("./tablestoreExecutor"), exports);
38
+ __exportStar(require("./deployer"), exports);
39
+ __exportStar(require("./destroyer"), exports);
40
+ __exportStar(require("./planner"), exports);