@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,216 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deleteResource = exports.updateResource = exports.readResource = exports.createResource = void 0;
4
+ const tencentClient_1 = require("../../common/tencentClient");
5
+ const fileUtils_1 = require("../../common/fileUtils");
6
+ const scfTypes_1 = require("./scfTypes");
7
+ const stateManager_1 = require("../../common/stateManager");
8
+ const hashUtils_1 = require("../../common/hashUtils");
9
+ const buildScfInstanceFromProvider = (info, arn) => {
10
+ const envMap = info.Environment?.Variables?.reduce((acc, v) => ({ ...acc, [v.Key]: v.Value }), {}) ?? {};
11
+ const triggersArray = info.Triggers?.map((t) => ({
12
+ modTime: t.ModTime,
13
+ type: t.Type,
14
+ triggerDesc: t.TriggerDesc,
15
+ triggerName: t.TriggerName,
16
+ addTime: t.AddTime,
17
+ enable: t.Enable,
18
+ customArgument: t.CustomArgument ?? null,
19
+ availableStatus: t.AvailableStatus ?? null,
20
+ resourceId: t.ResourceId ?? null,
21
+ bindStatus: t.BindStatus ?? null,
22
+ triggerAttribute: t.TriggerAttribute ?? null,
23
+ qualifier: t.Qualifier ?? null,
24
+ description: t.Description ?? null,
25
+ }));
26
+ const tagsArray = info.Tags?.map((t) => ({
27
+ key: t.Key,
28
+ value: t.Value,
29
+ }));
30
+ const layersArray = info.Layers?.map((l) => ({
31
+ layerName: l.LayerName ?? null,
32
+ layerVersion: l.LayerVersion ?? null,
33
+ compatibleRuntimes: l.CompatibleRuntimes ?? [],
34
+ }));
35
+ return {
36
+ arn,
37
+ id: info.FunctionName,
38
+ functionName: info.FunctionName,
39
+ runtime: info.Runtime,
40
+ handler: info.Handler,
41
+ memorySize: info.MemorySize,
42
+ timeout: info.Timeout,
43
+ environment: envMap,
44
+ modTime: info.ModTime ?? null,
45
+ codeSha256: info.CodeSha256 ?? null,
46
+ codeInfo: info.CodeInfo ?? null,
47
+ description: info.Description ?? null,
48
+ triggers: triggersArray ?? [],
49
+ codeSize: info.CodeSize ?? null,
50
+ functionVersion: info.FunctionVersion ?? null,
51
+ vpcConfig: info.VpcConfig
52
+ ? {
53
+ vpcId: info.VpcConfig.VpcId ?? null,
54
+ subnetId: info.VpcConfig.SubnetId ?? null,
55
+ }
56
+ : {},
57
+ useGpu: info.UseGpu ?? null,
58
+ codeResult: info.CodeResult ?? null,
59
+ codeError: info.CodeError ?? null,
60
+ errNo: info.ErrNo ?? null,
61
+ namespace: info.Namespace ?? null,
62
+ role: info.Role ?? null,
63
+ installDependency: info.InstallDependency ?? null,
64
+ status: info.Status ?? null,
65
+ statusDesc: info.StatusDesc ?? null,
66
+ clsLogsetId: info.ClsLogsetId ?? null,
67
+ clsTopicId: info.ClsTopicId ?? null,
68
+ functionId: info.FunctionId ?? null,
69
+ tags: tagsArray ?? [],
70
+ eipConfig: info.EipConfig
71
+ ? {
72
+ eipFixed: info.EipConfig.EipFixed ?? null,
73
+ eips: info.EipConfig.Eips ?? [],
74
+ }
75
+ : {},
76
+ accessInfo: info.AccessInfo
77
+ ? {
78
+ host: info.AccessInfo.Host ?? null,
79
+ vip: info.AccessInfo.Vip ?? null,
80
+ }
81
+ : {},
82
+ type: info.Type ?? null,
83
+ l5Enable: info.L5Enable ?? null,
84
+ layers: layersArray ?? [],
85
+ deadLetterConfig: info.DeadLetterConfig
86
+ ? {
87
+ type: info.DeadLetterConfig.Type ?? null,
88
+ name: info.DeadLetterConfig.Name ?? null,
89
+ filterType: info.DeadLetterConfig.FilterType ?? null,
90
+ }
91
+ : {},
92
+ addTime: info.AddTime ?? null,
93
+ publicNetConfig: info.PublicNetConfig
94
+ ? {
95
+ publicNetStatus: info.PublicNetConfig.PublicNetStatus ?? null,
96
+ eipConfig: info.PublicNetConfig.EipConfig
97
+ ? {
98
+ eipStatus: info.PublicNetConfig.EipConfig.EipStatus ?? null,
99
+ eipAddress: info.PublicNetConfig.EipConfig.EipAddress ?? [],
100
+ }
101
+ : {},
102
+ }
103
+ : {},
104
+ onsEnable: info.OnsEnable ?? null,
105
+ cfsConfig: info.CfsConfig
106
+ ? {
107
+ cfsInsList: info.CfsConfig.CfsInsList?.map((c) => ({
108
+ userId: c.UserId ?? null,
109
+ userGroupId: c.UserGroupId ?? null,
110
+ cfsId: c.CfsId ?? null,
111
+ mountInsId: c.MountInsId ?? null,
112
+ localMountDir: c.LocalMountDir ?? null,
113
+ remoteMountDir: c.RemoteMountDir ?? null,
114
+ ipAddress: c.IpAddress ?? null,
115
+ mountVpcId: c.MountVpcId ?? null,
116
+ mountSubnetId: c.MountSubnetId ?? null,
117
+ })) ?? [],
118
+ }
119
+ : {},
120
+ availableStatus: info.AvailableStatus ?? null,
121
+ qualifier: info.Qualifier ?? null,
122
+ initTimeout: info.InitTimeout ?? null,
123
+ statusReasons: info.StatusReasons?.map((s) => ({
124
+ errorCode: s.ErrorCode ?? null,
125
+ errorMessage: s.ErrorMessage ?? null,
126
+ })) ?? [],
127
+ asyncRunEnable: info.AsyncRunEnable ?? null,
128
+ traceEnable: info.TraceEnable ?? null,
129
+ imageConfig: info.ImageConfig
130
+ ? {
131
+ imageType: info.ImageConfig.ImageType ?? null,
132
+ imageUri: info.ImageConfig.ImageUri ?? null,
133
+ }
134
+ : {},
135
+ protocolType: info.ProtocolType ?? null,
136
+ protocolParams: info.ProtocolParams
137
+ ? {
138
+ wsParams: info.ProtocolParams.WSParams
139
+ ? {
140
+ idleTimeOut: info.ProtocolParams.WSParams.IdleTimeOut ?? null,
141
+ }
142
+ : {},
143
+ }
144
+ : {},
145
+ dnsCache: info.DnsCache ?? null,
146
+ intranetConfig: info.IntranetConfig
147
+ ? {
148
+ ipFixed: info.IntranetConfig.IpFixed ?? null,
149
+ }
150
+ : {},
151
+ };
152
+ };
153
+ const createResource = async (context, fn, state) => {
154
+ const config = (0, scfTypes_1.functionToScfConfig)(fn);
155
+ const codePath = fn.code.path;
156
+ const codeBase64 = (0, fileUtils_1.readFileAsBase64)(codePath);
157
+ const client = (0, tencentClient_1.createTencentClient)(context);
158
+ await client.scf.createFunction(config, codeBase64);
159
+ // Refresh state from provider to get all attributes
160
+ const functionInfo = await client.scf.getFunction(fn.name);
161
+ if (!functionInfo) {
162
+ throw new Error(`Failed to refresh state for function: ${fn.name}`);
163
+ }
164
+ const codeHash = (0, hashUtils_1.computeFileHash)(codePath);
165
+ const definition = (0, scfTypes_1.extractScfDefinition)(config, codeHash);
166
+ const arn = `arn:tencent:scf:${context.region}::function:${fn.name}`;
167
+ const resourceState = {
168
+ mode: 'managed',
169
+ region: context.region,
170
+ definition,
171
+ instances: [buildScfInstanceFromProvider(functionInfo, arn)],
172
+ lastUpdated: new Date().toISOString(),
173
+ };
174
+ const logicalId = `functions.${fn.key}`;
175
+ return (0, stateManager_1.setResource)(state, logicalId, resourceState);
176
+ };
177
+ exports.createResource = createResource;
178
+ const readResource = async (context, functionName) => {
179
+ const client = (0, tencentClient_1.createTencentClient)(context);
180
+ return await client.scf.getFunction(functionName);
181
+ };
182
+ exports.readResource = readResource;
183
+ const updateResource = async (context, fn, state) => {
184
+ const config = (0, scfTypes_1.functionToScfConfig)(fn);
185
+ const codePath = fn.code.path;
186
+ const client = (0, tencentClient_1.createTencentClient)(context);
187
+ // Update configuration
188
+ await client.scf.updateFunctionConfiguration(config);
189
+ // Update code
190
+ const codeBase64 = (0, fileUtils_1.readFileAsBase64)(codePath);
191
+ await client.scf.updateFunctionCode(fn.name, codeBase64);
192
+ // Refresh state from provider to get all attributes
193
+ const functionInfo = await client.scf.getFunction(fn.name);
194
+ if (!functionInfo) {
195
+ throw new Error(`Failed to refresh state for function: ${fn.name}`);
196
+ }
197
+ const codeHash = (0, hashUtils_1.computeFileHash)(codePath);
198
+ const definition = (0, scfTypes_1.extractScfDefinition)(config, codeHash);
199
+ const arn = `arn:tencent:scf:${context.region}::function:${fn.name}`;
200
+ const resourceState = {
201
+ mode: 'managed',
202
+ region: context.region,
203
+ definition,
204
+ instances: [buildScfInstanceFromProvider(functionInfo, arn)],
205
+ lastUpdated: new Date().toISOString(),
206
+ };
207
+ const logicalId = `functions.${fn.key}`;
208
+ return (0, stateManager_1.setResource)(state, logicalId, resourceState);
209
+ };
210
+ exports.updateResource = updateResource;
211
+ const deleteResource = async (context, functionName, logicalId, state) => {
212
+ const client = (0, tencentClient_1.createTencentClient)(context);
213
+ await client.scf.deleteFunction(functionName);
214
+ return (0, stateManager_1.removeResource)(state, logicalId);
215
+ };
216
+ exports.deleteResource = deleteResource;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractFunctionDomainDefinition = exports.extractScfDefinition = exports.functionToScfConfig = void 0;
4
+ const common_1 = require("../../common");
5
+ const functionToScfConfig = (fn) => {
6
+ const config = {
7
+ FunctionName: fn.name,
8
+ Runtime: (0, common_1.mapRuntime)(fn.code.runtime, common_1.ProviderEnum.TENCENT),
9
+ Handler: fn.code.handler,
10
+ MemorySize: fn.memory ?? 128,
11
+ Timeout: fn.timeout ?? 3,
12
+ };
13
+ if (fn.environment && Object.keys(fn.environment).length > 0) {
14
+ config.Environment = {
15
+ Variables: Object.entries(fn.environment).map(([key, value]) => ({
16
+ Key: key,
17
+ Value: value,
18
+ })),
19
+ };
20
+ }
21
+ return config;
22
+ };
23
+ exports.functionToScfConfig = functionToScfConfig;
24
+ const extractScfDefinition = (config, codeHash) => {
25
+ const envMap = config.Environment?.Variables?.reduce((acc, v) => ({ ...acc, [v.Key]: v.Value }), {}) ?? {};
26
+ return {
27
+ functionName: config.FunctionName,
28
+ runtime: config.Runtime,
29
+ handler: config.Handler,
30
+ memorySize: config.MemorySize,
31
+ timeout: config.Timeout,
32
+ environment: envMap,
33
+ codeHash,
34
+ };
35
+ };
36
+ exports.extractScfDefinition = extractScfDefinition;
37
+ const extractFunctionDomainDefinition = (fn, codeHash) => {
38
+ const config = (0, exports.functionToScfConfig)(fn);
39
+ return (0, exports.extractScfDefinition)(config, codeHash);
40
+ };
41
+ exports.extractFunctionDomainDefinition = extractFunctionDomainDefinition;
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeDatabasePlan = void 0;
4
+ const tdsqlcResource_1 = require("./tdsqlcResource");
5
+ const common_1 = require("../../common");
6
+ const stateManager_1 = require("../../common/stateManager");
7
+ const lang_1 = require("../../lang");
8
+ const executeCreateAction = async (context, database, currentState) => {
9
+ common_1.logger.info(`Creating TDSQL-C database: ${database.name}`);
10
+ const newState = await (0, tdsqlcResource_1.createDatabaseResource)(context, database, currentState);
11
+ common_1.logger.info(`Successfully created TDSQL-C database: ${database.name}`);
12
+ return newState;
13
+ };
14
+ const executeUpdateAction = async (context, database, clusterId, currentState) => {
15
+ common_1.logger.info(`Updating TDSQL-C database: ${database.name}`);
16
+ const newState = await (0, tdsqlcResource_1.updateDatabaseResource)(context, database, clusterId, currentState);
17
+ common_1.logger.info(`Successfully updated TDSQL-C database: ${database.name}`);
18
+ return newState;
19
+ };
20
+ const executeDeleteAction = async (context, clusterId, logicalId, currentState) => {
21
+ common_1.logger.info(`Deleting TDSQL-C database: ${clusterId}`);
22
+ const newState = await (0, tdsqlcResource_1.deleteDatabaseResource)(context, clusterId, logicalId, currentState);
23
+ common_1.logger.info(`Successfully deleted TDSQL-C database: ${clusterId}`);
24
+ return newState;
25
+ };
26
+ const executeSingleItem = async (context, item, databasesMap, currentState) => {
27
+ if (item.resourceType !== 'TDSQL_C_SERVERLESS') {
28
+ return null;
29
+ }
30
+ switch (item.action) {
31
+ case 'noop':
32
+ common_1.logger.info(`No changes for ${item.logicalId}`);
33
+ return null;
34
+ case 'create': {
35
+ const database = databasesMap.get(item.logicalId);
36
+ if (!database) {
37
+ throw new Error(`Database not found for logical ID: ${item.logicalId}`);
38
+ }
39
+ return executeCreateAction(context, database, currentState);
40
+ }
41
+ case 'update': {
42
+ const database = databasesMap.get(item.logicalId);
43
+ if (!database) {
44
+ throw new Error(`Database not found for logical ID: ${item.logicalId}`);
45
+ }
46
+ const state = (0, stateManager_1.getResource)(currentState, item.logicalId);
47
+ if (!state) {
48
+ throw new Error(`State not found for ${item.logicalId}`);
49
+ }
50
+ const clusterId = state.metadata?.clusterId || state.instances?.[0]?.id;
51
+ if (!clusterId) {
52
+ throw new Error(`Cluster ID not found in state for ${item.logicalId}`);
53
+ }
54
+ return executeUpdateAction(context, database, clusterId, currentState);
55
+ }
56
+ case 'delete': {
57
+ const state = (0, stateManager_1.getResource)(currentState, item.logicalId);
58
+ if (!state) {
59
+ common_1.logger.warn(`State not found for ${item.logicalId}, skipping deletion`);
60
+ return null;
61
+ }
62
+ const clusterId = state.metadata?.clusterId || state.instances?.[0]?.id;
63
+ if (!clusterId) {
64
+ throw new Error(`Cluster ID not found in state for ${item.logicalId}`);
65
+ }
66
+ return executeDeleteAction(context, clusterId, item.logicalId, currentState);
67
+ }
68
+ default:
69
+ common_1.logger.warn(`Unknown action: ${item.action} for ${item.logicalId}`);
70
+ return null;
71
+ }
72
+ };
73
+ const executeDatabasePlan = async (context, plan, databases, initialState, onStateChange) => {
74
+ const databasesMap = new Map(databases?.map((database) => [`databases.${database.key}`, database]) ?? []);
75
+ const successfulItems = [];
76
+ let currentState = initialState;
77
+ for (const item of plan.items) {
78
+ try {
79
+ const newState = await executeSingleItem(context, item, databasesMap, currentState);
80
+ if (newState !== null) {
81
+ currentState = newState;
82
+ successfulItems.push(item);
83
+ if (onStateChange) {
84
+ onStateChange(currentState);
85
+ common_1.logger.debug(lang_1.lang.__('STATE_PERSISTED_AFTER_OPERATION', {
86
+ action: item.action,
87
+ resourceId: item.logicalId,
88
+ }));
89
+ }
90
+ }
91
+ }
92
+ catch (error) {
93
+ return {
94
+ state: currentState,
95
+ partialFailure: {
96
+ failedItem: item,
97
+ error: error instanceof Error ? error : new Error(String(error)),
98
+ successfulItems,
99
+ },
100
+ };
101
+ }
102
+ }
103
+ return { state: currentState };
104
+ };
105
+ exports.executeDatabasePlan = executeDatabasePlan;
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateDatabasePlan = void 0;
4
+ const tencentClient_1 = require("../../common/tencentClient");
5
+ const tdsqlcTypes_1 = require("./tdsqlcTypes");
6
+ const stateManager_1 = require("../../common/stateManager");
7
+ const hashUtils_1 = require("../../common/hashUtils");
8
+ const planDatabaseDeletion = (logicalId, definition) => ({
9
+ logicalId,
10
+ action: 'delete',
11
+ resourceType: 'TDSQL_C_SERVERLESS',
12
+ changes: { before: definition },
13
+ });
14
+ const generateDatabasePlan = async (context, state, databases) => {
15
+ const tdsqlcDatabases = databases?.filter((db) => db.type === "TDSQL_C_SERVERLESS" /* DatabaseEnum.TDSQL_C_SERVERLESS */);
16
+ if (!tdsqlcDatabases || tdsqlcDatabases.length === 0) {
17
+ const allStates = (0, stateManager_1.getAllResources)(state);
18
+ const items = Object.entries(allStates)
19
+ .filter(([logicalId, resourceState]) => {
20
+ if (!logicalId.startsWith('databases.'))
21
+ return false;
22
+ const resourceType = resourceState.metadata?.resourceType;
23
+ // Only plan deletion for TDSQL-C resources (or legacy resources without resourceType
24
+ // that have clusterId metadata, indicating they are TDSQL-C)
25
+ return !resourceType || resourceType === 'TDSQL_C_SERVERLESS';
26
+ })
27
+ .map(([logicalId, resourceState]) => planDatabaseDeletion(logicalId, resourceState.definition));
28
+ return { items };
29
+ }
30
+ const desiredLogicalIds = new Set(tdsqlcDatabases.map((db) => `databases.${db.key}`));
31
+ const databaseItems = await Promise.all(tdsqlcDatabases.map(async (database) => {
32
+ const logicalId = `databases.${database.key}`;
33
+ const currentState = (0, stateManager_1.getResource)(state, logicalId);
34
+ const config = (0, tdsqlcTypes_1.databaseToTdsqlcConfig)(database);
35
+ const desiredDefinition = (0, tdsqlcTypes_1.extractTdsqlcDefinition)(config);
36
+ if (!currentState) {
37
+ return {
38
+ logicalId,
39
+ action: 'create',
40
+ resourceType: 'TDSQL_C_SERVERLESS',
41
+ changes: { after: desiredDefinition },
42
+ };
43
+ }
44
+ const clusterId = currentState.metadata?.clusterId || currentState.instances?.[0]?.id;
45
+ try {
46
+ const client = (0, tencentClient_1.createTencentClient)(context);
47
+ const remoteCluster = clusterId ? await client.tdsqlc.getCluster(clusterId) : null;
48
+ if (!remoteCluster) {
49
+ return {
50
+ logicalId,
51
+ action: 'create',
52
+ resourceType: 'TDSQL_C_SERVERLESS',
53
+ changes: { before: currentState.definition, after: desiredDefinition },
54
+ drifted: true,
55
+ };
56
+ }
57
+ const currentDefinition = currentState.definition || {};
58
+ const definitionChanged = !(0, hashUtils_1.attributesEqual)(currentDefinition, desiredDefinition);
59
+ if (definitionChanged) {
60
+ return {
61
+ logicalId,
62
+ action: 'update',
63
+ resourceType: 'TDSQL_C_SERVERLESS',
64
+ changes: { before: currentDefinition, after: desiredDefinition },
65
+ drifted: true,
66
+ };
67
+ }
68
+ return { logicalId, action: 'noop', resourceType: 'TDSQL_C_SERVERLESS' };
69
+ }
70
+ catch {
71
+ return {
72
+ logicalId,
73
+ action: 'create',
74
+ resourceType: 'TDSQL_C_SERVERLESS',
75
+ changes: { before: currentState.definition, after: desiredDefinition },
76
+ };
77
+ }
78
+ }));
79
+ const allStates = (0, stateManager_1.getAllResources)(state);
80
+ const deletionItems = Object.entries(allStates)
81
+ .filter(([logicalId, resourceState]) => {
82
+ if (!logicalId.startsWith('databases.') || desiredLogicalIds.has(logicalId))
83
+ return false;
84
+ const resourceType = resourceState.metadata?.resourceType;
85
+ return !resourceType || resourceType === 'TDSQL_C_SERVERLESS';
86
+ })
87
+ .map(([logicalId, resourceState]) => planDatabaseDeletion(logicalId, resourceState.definition));
88
+ return { items: [...databaseItems, ...deletionItems] };
89
+ };
90
+ exports.generateDatabasePlan = generateDatabasePlan;
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deleteDatabaseResource = exports.updateDatabaseResource = exports.readDatabaseResource = exports.createDatabaseResource = void 0;
4
+ const tencentClient_1 = require("../../common/tencentClient");
5
+ const tdsqlcTypes_1 = require("./tdsqlcTypes");
6
+ const stateManager_1 = require("../../common/stateManager");
7
+ const buildTdsqlcInstanceFromProvider = (info, arn) => {
8
+ return {
9
+ arn,
10
+ id: info.ClusterId,
11
+ clusterId: info.ClusterId,
12
+ clusterName: info.ClusterName,
13
+ region: info.Region,
14
+ zone: info.Zone ?? null,
15
+ physicalZone: info.PhysicalZone ?? null,
16
+ dbType: info.DbType,
17
+ dbVersion: info.DbVersion,
18
+ dbMode: info.DbMode ?? null,
19
+ status: info.Status,
20
+ statusDesc: info.StatusDesc ?? null,
21
+ serverlessStatus: info.ServerlessStatus ?? null,
22
+ vpcId: info.VpcId ?? null,
23
+ vpcName: info.VpcName ?? null,
24
+ subnetId: info.SubnetId ?? null,
25
+ subnetName: info.SubnetName ?? null,
26
+ charset: info.Charset ?? null,
27
+ vip: info.Vip ?? null,
28
+ vport: info.Vport ?? null,
29
+ wanDomain: info.WanDomain ?? null,
30
+ wanIP: info.WanIP ?? null,
31
+ wanPort: info.WanPort ?? null,
32
+ wanStatus: info.WanStatus ?? null,
33
+ minCpu: info.MinCpu ?? null,
34
+ maxCpu: info.MaxCpu ?? null,
35
+ minStorageSize: info.MinStorageSize ?? null,
36
+ maxStorageSize: info.MaxStorageSize ?? null,
37
+ storageId: info.StorageId ?? null,
38
+ storage: info.Storage ?? null,
39
+ storageLimit: info.StorageLimit ?? null,
40
+ storagePayMode: info.StoragePayMode ?? null,
41
+ autoPause: info.AutoPause ?? null,
42
+ autoPauseDelay: info.AutoPauseDelay ?? null,
43
+ createTime: info.CreateTime ?? null,
44
+ updateTime: info.UpdateTime ?? null,
45
+ projectId: info.ProjectId ?? null,
46
+ payMode: info.PayMode ?? null,
47
+ periodEndTime: info.PeriodEndTime ?? null,
48
+ autoRenewFlag: info.AutoRenewFlag ?? null,
49
+ instanceCount: info.InstanceCount ?? null,
50
+ processingTask: info.ProcessingTask ?? null,
51
+ supportedFeatures: info.SupportedFeatures ?? [],
52
+ rollbackSupport: info.RollbackSupport ?? null,
53
+ networkType: info.NetworkType ?? null,
54
+ resourcePackageId: info.ResourcePackageId ?? null,
55
+ resourcePackageType: info.ResourcePackageType ?? null,
56
+ resourcePackageState: info.ResourcePackageState ?? null,
57
+ physicalRegion: info.PhysicalRegion ?? null,
58
+ proxyStatus: info.ProxyStatus ?? null,
59
+ rwGroupId: info.RwGroupId ?? null,
60
+ masterZone: info.MasterZone ?? null,
61
+ slaveZones: info.SlaveZones ?? [],
62
+ businessType: info.BusinessType ?? null,
63
+ isFreeze: info.IsFreeze ?? null,
64
+ orderSource: info.OrderSource ?? null,
65
+ ability: info.Ability
66
+ ? {
67
+ isSupportSlaveZone: info.Ability.IsSupportSlaveZone ?? null,
68
+ nonsupportSlaveZoneReason: info.Ability.NonsupportSlaveZoneReason ?? null,
69
+ isSupportRo: info.Ability.IsSupportRo ?? null,
70
+ nonsupportRoReason: info.Ability.NonsupportRoReason ?? null,
71
+ }
72
+ : {},
73
+ resourceTags: info.ResourceTags?.map((t) => ({
74
+ tagKey: t.TagKey ?? null,
75
+ tagValue: t.TagValue ?? null,
76
+ })) ?? [],
77
+ cynosVersion: info.CynosVersion ?? null,
78
+ cynosVersionStatus: info.CynosVersionStatus ?? null,
79
+ isLatestVersion: info.IsLatestVersion ?? null,
80
+ };
81
+ };
82
+ const createDatabaseResource = async (context, database, state) => {
83
+ const config = (0, tdsqlcTypes_1.databaseToTdsqlcConfig)(database);
84
+ const client = (0, tencentClient_1.createTencentClient)(context);
85
+ const clusterId = await client.tdsqlc.createCluster(config);
86
+ // Refresh state from provider to get all attributes
87
+ const clusterInfo = await client.tdsqlc.getCluster(clusterId);
88
+ if (!clusterInfo) {
89
+ throw new Error(`Failed to refresh state for cluster: ${clusterId}`);
90
+ }
91
+ const definition = (0, tdsqlcTypes_1.extractTdsqlcDefinition)(config);
92
+ const arn = `arn:tencent:cynosdb:${context.region}::cluster:${clusterId}`;
93
+ const resourceState = {
94
+ mode: 'managed',
95
+ region: context.region,
96
+ definition,
97
+ instances: [buildTdsqlcInstanceFromProvider(clusterInfo, arn)],
98
+ lastUpdated: new Date().toISOString(),
99
+ metadata: {
100
+ clusterName: database.name,
101
+ clusterId,
102
+ resourceType: 'TDSQL_C_SERVERLESS',
103
+ },
104
+ };
105
+ const logicalId = `databases.${database.key}`;
106
+ return (0, stateManager_1.setResource)(state, logicalId, resourceState);
107
+ };
108
+ exports.createDatabaseResource = createDatabaseResource;
109
+ const readDatabaseResource = async (context, clusterId) => {
110
+ const client = (0, tencentClient_1.createTencentClient)(context);
111
+ return await client.tdsqlc.getCluster(clusterId);
112
+ };
113
+ exports.readDatabaseResource = readDatabaseResource;
114
+ const updateDatabaseResource = async (context, database, clusterId, state) => {
115
+ const config = (0, tdsqlcTypes_1.databaseToTdsqlcConfig)(database);
116
+ const client = (0, tencentClient_1.createTencentClient)(context);
117
+ await client.tdsqlc.updateCluster(clusterId, config);
118
+ // Refresh state from provider to get all attributes
119
+ const clusterInfo = await client.tdsqlc.getCluster(clusterId);
120
+ if (!clusterInfo) {
121
+ throw new Error(`Failed to refresh state for cluster: ${clusterId}`);
122
+ }
123
+ const definition = (0, tdsqlcTypes_1.extractTdsqlcDefinition)(config);
124
+ const arn = `arn:tencent:cynosdb:${context.region}::cluster:${clusterId}`;
125
+ const resourceState = {
126
+ mode: 'managed',
127
+ region: context.region,
128
+ definition,
129
+ instances: [buildTdsqlcInstanceFromProvider(clusterInfo, arn)],
130
+ lastUpdated: new Date().toISOString(),
131
+ metadata: {
132
+ clusterName: database.name,
133
+ clusterId,
134
+ resourceType: 'TDSQL_C_SERVERLESS',
135
+ },
136
+ };
137
+ const logicalId = `databases.${database.key}`;
138
+ return (0, stateManager_1.setResource)(state, logicalId, resourceState);
139
+ };
140
+ exports.updateDatabaseResource = updateDatabaseResource;
141
+ const deleteDatabaseResource = async (context, clusterId, logicalId, state) => {
142
+ const client = (0, tencentClient_1.createTencentClient)(context);
143
+ await client.tdsqlc.deleteCluster(clusterId);
144
+ return (0, stateManager_1.removeResource)(state, logicalId);
145
+ };
146
+ exports.deleteDatabaseResource = deleteDatabaseResource;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractTdsqlcDefinition = exports.databaseToTdsqlcConfig = void 0;
4
+ const databaseToTdsqlcConfig = (database) => {
5
+ // Map version from enum to Tencent Cloud version format
6
+ const versionMap = {
7
+ 'MYSQL_5.7': '5.7',
8
+ 'MYSQL_8.0': '8.0',
9
+ };
10
+ const dbVersion = versionMap[database.version] || '8.0';
11
+ const config = {
12
+ ClusterName: database.name,
13
+ DbType: 'MYSQL',
14
+ DbVersion: dbVersion,
15
+ DbMode: 'SERVERLESS',
16
+ MinCpu: database.cu.min,
17
+ MaxCpu: database.cu.max,
18
+ AutoPause: database.cu.min === 0,
19
+ AutoPauseDelay: 600, // Default 10 minutes
20
+ StoragePayMode: 0, // Pay-per-use
21
+ AdminPassword: database.security.basicAuth.password,
22
+ };
23
+ // Add VPC configuration if provided
24
+ if (database.network.vpcId) {
25
+ config.VpcId = database.network.vpcId;
26
+ }
27
+ if (database.network.subnetId) {
28
+ config.SubnetId = database.network.subnetId;
29
+ }
30
+ // Add storage configuration if provided
31
+ if (database.storage.min !== undefined) {
32
+ config.MinStorageSize = database.storage.min;
33
+ }
34
+ if (database.storage.max !== undefined) {
35
+ config.MaxStorageSize = database.storage.max;
36
+ }
37
+ return config;
38
+ };
39
+ exports.databaseToTdsqlcConfig = databaseToTdsqlcConfig;
40
+ const extractTdsqlcDefinition = (config) => {
41
+ return {
42
+ clusterName: config.ClusterName,
43
+ dbType: config.DbType,
44
+ dbVersion: config.DbVersion,
45
+ dbMode: config.DbMode,
46
+ minCpu: config.MinCpu,
47
+ maxCpu: config.MaxCpu,
48
+ autoPause: config.AutoPause ?? null,
49
+ autoPauseDelay: config.AutoPauseDelay ?? null,
50
+ storagePayMode: config.StoragePayMode ?? null,
51
+ vpcId: config.VpcId ?? null,
52
+ subnetId: config.SubnetId ?? null,
53
+ port: config.Port ?? null,
54
+ projectId: config.ProjectId ?? null,
55
+ minStorageSize: config.MinStorageSize ?? null,
56
+ maxStorageSize: config.MaxStorageSize ?? null,
57
+ };
58
+ };
59
+ exports.extractTdsqlcDefinition = extractTdsqlcDefinition;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });