@geek-fun/serverlessinsight 0.6.7 → 0.6.9
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 +1 -1
- package/dist/src/commands/plan.js +4 -1
- package/dist/src/common/aliyunClient/ecsOperations.js +189 -93
- package/dist/src/common/aliyunClient/nasOperations.js +12 -0
- package/dist/src/common/aliyunClient/ramOperations.js +19 -3
- package/dist/src/common/domainUtils.js +19 -1
- package/dist/src/common/imsClient.js +6 -2
- package/dist/src/lang/en.js +6 -0
- package/dist/src/lang/zh-CN.js +8 -2
- package/dist/src/parser/bucketParser.js +5 -2
- package/dist/src/parser/eventParser.js +7 -1
- package/dist/src/stack/aliyunStack/apigwPlanner.js +1 -7
- package/dist/src/stack/aliyunStack/apigwResource.js +100 -28
- package/dist/src/stack/aliyunStack/apigwTypes.js +15 -1
- package/dist/src/stack/aliyunStack/fc3Planner.js +28 -1
- package/dist/src/stack/aliyunStack/fc3Resource.js +3 -3
- package/dist/src/stack/aliyunStack/fc3Types.js +19 -0
- package/dist/src/stack/aliyunStack/ossResource.js +86 -27
- package/dist/src/stack/aliyunStack/ossTypes.js +32 -0
- package/dist/src/stack/aliyunStack/tablestoreTypes.js +14 -0
- package/dist/src/stack/scfStack/cosResource.js +91 -29
- package/dist/src/stack/scfStack/cosTypes.js +36 -0
- package/dist/src/stack/scfStack/scfTypes.js +30 -0
- package/dist/src/validator/bucketSchema.js +2 -0
- package/dist/src/validator/eventSchema.js +1 -0
- package/package.json +1 -1
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geek-fun/serverlessinsight",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.9",
|
|
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",
|
|
@@ -23,7 +23,10 @@ const plan = async (options) => {
|
|
|
23
23
|
const iac = (0, parser_1.revalYaml)(iacLocation, context);
|
|
24
24
|
// Store IAC in context for access by all functions
|
|
25
25
|
(0, common_1.setIac)(iac);
|
|
26
|
-
|
|
26
|
+
const providerDisplayName = iac.provider.name === common_1.ProviderEnum.ALIYUN
|
|
27
|
+
? lang_1.lang.__('PROVIDER_ALIYUN')
|
|
28
|
+
: lang_1.lang.__('PROVIDER_TENCENT');
|
|
29
|
+
common_1.logger.info(lang_1.lang.__('GENERATING_PLAN_FOR_PROVIDER', { provider: providerDisplayName }));
|
|
27
30
|
const backend = (0, stateBackend_1.createStateBackend)(iac.backend, context);
|
|
28
31
|
let planResult;
|
|
29
32
|
if (iac.provider.name === common_1.ProviderEnum.TENCENT) {
|
|
@@ -78,115 +78,211 @@ const isDuplicateSecurityGroupRuleError = (error) => {
|
|
|
78
78
|
]);
|
|
79
79
|
return duplicateCodes.has(error.code);
|
|
80
80
|
};
|
|
81
|
-
const createEcsOperations = (ecsClient, context) =>
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
securityGroupName,
|
|
86
|
-
vpcId,
|
|
87
|
-
description: description ?? `ServerlessInsight security group for ${securityGroupName}`,
|
|
88
|
-
});
|
|
89
|
-
const response = await ecsClient.createSecurityGroup(createRequest);
|
|
90
|
-
const securityGroupId = response.body?.securityGroupId;
|
|
91
|
-
if (!securityGroupId) {
|
|
92
|
-
throw new Error('Failed to create security group');
|
|
93
|
-
}
|
|
94
|
-
// Add ingress rules
|
|
95
|
-
for (const rule of ingressRules) {
|
|
96
|
-
let parsedRule;
|
|
97
|
-
try {
|
|
98
|
-
parsedRule = (0, exports.parseSecurityGroupRule)(rule);
|
|
99
|
-
}
|
|
100
|
-
catch (error) {
|
|
101
|
-
logger_1.logger.warn(`Skipping invalid ingress rule: ${rule}. ${String(error)}`);
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
const ingressRequest = new ecs.AuthorizeSecurityGroupRequest({
|
|
81
|
+
const createEcsOperations = (ecsClient, context) => {
|
|
82
|
+
const operations = {
|
|
83
|
+
createSecurityGroup: async (securityGroupName, vpcId, ingressRules, egressRules, description) => {
|
|
84
|
+
const createRequest = new ecs.CreateSecurityGroupRequest({
|
|
105
85
|
regionId: context.region,
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
portRange: transformPortRange(parsedRule.protocol, parsedRule.portRange),
|
|
86
|
+
securityGroupName,
|
|
87
|
+
vpcId,
|
|
88
|
+
description: description ?? `ServerlessInsight security group for ${securityGroupName}`,
|
|
110
89
|
});
|
|
111
|
-
|
|
112
|
-
|
|
90
|
+
const response = await ecsClient.createSecurityGroup(createRequest);
|
|
91
|
+
const securityGroupId = response.body?.securityGroupId;
|
|
92
|
+
if (!securityGroupId) {
|
|
93
|
+
throw new Error('Failed to create security group');
|
|
113
94
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
95
|
+
// Add ingress rules
|
|
96
|
+
for (const rule of ingressRules) {
|
|
97
|
+
let parsedRule;
|
|
98
|
+
try {
|
|
99
|
+
parsedRule = (0, exports.parseSecurityGroupRule)(rule);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
logger_1.logger.warn(`Skipping invalid ingress rule: ${rule}. ${String(error)}`);
|
|
117
103
|
continue;
|
|
118
104
|
}
|
|
119
|
-
|
|
105
|
+
const ingressRequest = new ecs.AuthorizeSecurityGroupRequest({
|
|
106
|
+
regionId: context.region,
|
|
107
|
+
securityGroupId,
|
|
108
|
+
ipProtocol: parsedRule.protocol.toLowerCase(),
|
|
109
|
+
sourceCidrIp: parsedRule.cidr,
|
|
110
|
+
portRange: transformPortRange(parsedRule.protocol, parsedRule.portRange),
|
|
111
|
+
});
|
|
112
|
+
try {
|
|
113
|
+
await ecsClient.authorizeSecurityGroup(ingressRequest);
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
if (isDuplicateSecurityGroupRuleError(error)) {
|
|
117
|
+
logger_1.logger.debug(`Ingress rule already exists, skipping: ${rule}`);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
logger_1.logger.warn(`Failed to add ingress rule: ${rule}. ${String(error)}`);
|
|
121
|
+
}
|
|
120
122
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
// Add egress rules
|
|
124
|
+
for (const rule of egressRules) {
|
|
125
|
+
let parsedRule;
|
|
126
|
+
try {
|
|
127
|
+
parsedRule = (0, exports.parseSecurityGroupRule)(rule);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
logger_1.logger.warn(`Skipping invalid egress rule: ${rule}. ${String(error)}`);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
const egressRequest = new ecs.AuthorizeSecurityGroupEgressRequest({
|
|
134
|
+
regionId: context.region,
|
|
135
|
+
securityGroupId,
|
|
136
|
+
ipProtocol: parsedRule.protocol.toLowerCase(),
|
|
137
|
+
destCidrIp: parsedRule.cidr,
|
|
138
|
+
portRange: transformPortRange(parsedRule.protocol, parsedRule.portRange),
|
|
139
|
+
});
|
|
140
|
+
try {
|
|
141
|
+
await ecsClient.authorizeSecurityGroupEgress(egressRequest);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
if (isDuplicateSecurityGroupRuleError(error)) {
|
|
145
|
+
logger_1.logger.debug(`Egress rule already exists, skipping: ${rule}`);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
logger_1.logger.warn(`Failed to add egress rule: ${rule}. ${String(error)}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const sg = await operations.getSecurityGroup(securityGroupId);
|
|
152
|
+
if (!sg) {
|
|
153
|
+
return {
|
|
154
|
+
securityGroupId,
|
|
155
|
+
securityGroupName,
|
|
156
|
+
vpcId,
|
|
157
|
+
description,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
return sg;
|
|
161
|
+
},
|
|
162
|
+
getSecurityGroupRules: async (securityGroupId) => {
|
|
163
|
+
const ingressRules = [];
|
|
164
|
+
const egressRules = [];
|
|
125
165
|
try {
|
|
126
|
-
|
|
166
|
+
const request = new ecs.DescribeSecurityGroupAttributeRequest({
|
|
167
|
+
regionId: context.region,
|
|
168
|
+
securityGroupId,
|
|
169
|
+
direction: 'ingress',
|
|
170
|
+
});
|
|
171
|
+
const response = await ecsClient.describeSecurityGroupAttribute(request);
|
|
172
|
+
if (response?.body?.permissions?.permission) {
|
|
173
|
+
for (const perm of response.body.permissions.permission) {
|
|
174
|
+
ingressRules.push({
|
|
175
|
+
direction: 'ingress',
|
|
176
|
+
ipProtocol: perm.ipProtocol ?? '',
|
|
177
|
+
portRange: perm.portRange ?? '',
|
|
178
|
+
sourceCidrIp: perm.sourceCidrIp,
|
|
179
|
+
priority: perm.priority,
|
|
180
|
+
policy: perm.policy,
|
|
181
|
+
description: perm.description,
|
|
182
|
+
ruleId: perm.ruleId,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
127
186
|
}
|
|
128
187
|
catch (error) {
|
|
129
|
-
logger_1.logger.
|
|
130
|
-
continue;
|
|
188
|
+
logger_1.logger.debug(`Failed to get ingress rules: ${String(error)}`);
|
|
131
189
|
}
|
|
132
|
-
const egressRequest = new ecs.AuthorizeSecurityGroupEgressRequest({
|
|
133
|
-
regionId: context.region,
|
|
134
|
-
securityGroupId,
|
|
135
|
-
ipProtocol: parsedRule.protocol.toLowerCase(),
|
|
136
|
-
destCidrIp: parsedRule.cidr,
|
|
137
|
-
portRange: transformPortRange(parsedRule.protocol, parsedRule.portRange),
|
|
138
|
-
});
|
|
139
190
|
try {
|
|
140
|
-
|
|
191
|
+
const request = new ecs.DescribeSecurityGroupAttributeRequest({
|
|
192
|
+
regionId: context.region,
|
|
193
|
+
securityGroupId,
|
|
194
|
+
direction: 'egress',
|
|
195
|
+
});
|
|
196
|
+
const response = await ecsClient.describeSecurityGroupAttribute(request);
|
|
197
|
+
if (response?.body?.permissions?.permission) {
|
|
198
|
+
for (const perm of response.body.permissions.permission) {
|
|
199
|
+
egressRules.push({
|
|
200
|
+
direction: 'egress',
|
|
201
|
+
ipProtocol: perm.ipProtocol ?? '',
|
|
202
|
+
portRange: perm.portRange ?? '',
|
|
203
|
+
destCidrIp: perm.destCidrIp,
|
|
204
|
+
priority: perm.priority,
|
|
205
|
+
policy: perm.policy,
|
|
206
|
+
description: perm.description,
|
|
207
|
+
ruleId: perm.ruleId,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
141
211
|
}
|
|
142
212
|
catch (error) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
213
|
+
logger_1.logger.debug(`Failed to get egress rules: ${String(error)}`);
|
|
214
|
+
}
|
|
215
|
+
return { ingressRules, egressRules };
|
|
216
|
+
},
|
|
217
|
+
getSecurityGroup: async (securityGroupId) => {
|
|
218
|
+
try {
|
|
219
|
+
const request = new ecs.DescribeSecurityGroupsRequest({
|
|
220
|
+
regionId: context.region,
|
|
221
|
+
securityGroupId,
|
|
222
|
+
});
|
|
223
|
+
const response = await ecsClient.describeSecurityGroups(request);
|
|
224
|
+
if (!response ||
|
|
225
|
+
!response.body ||
|
|
226
|
+
!response.body.securityGroups ||
|
|
227
|
+
!response.body.securityGroups.securityGroup ||
|
|
228
|
+
response.body.securityGroups.securityGroup.length === 0) {
|
|
229
|
+
return null;
|
|
146
230
|
}
|
|
147
|
-
|
|
231
|
+
const sg = response.body.securityGroups.securityGroup[0];
|
|
232
|
+
const rules = await operations.getSecurityGroupRules(securityGroupId);
|
|
233
|
+
return {
|
|
234
|
+
securityGroupId: sg.securityGroupId ?? securityGroupId,
|
|
235
|
+
securityGroupName: sg.securityGroupName,
|
|
236
|
+
vpcId: sg.vpcId,
|
|
237
|
+
description: sg.description,
|
|
238
|
+
createTime: sg.creationTime,
|
|
239
|
+
ingressRules: rules.ingressRules,
|
|
240
|
+
egressRules: rules.egressRules,
|
|
241
|
+
};
|
|
148
242
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
243
|
+
catch {
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
getSecurityGroupByName: async (securityGroupName, vpcId) => {
|
|
248
|
+
try {
|
|
249
|
+
const request = new ecs.DescribeSecurityGroupsRequest({
|
|
250
|
+
regionId: context.region,
|
|
251
|
+
securityGroupName,
|
|
252
|
+
vpcId,
|
|
253
|
+
});
|
|
254
|
+
const response = await ecsClient.describeSecurityGroups(request);
|
|
255
|
+
if (!response ||
|
|
256
|
+
!response.body ||
|
|
257
|
+
!response.body.securityGroups ||
|
|
258
|
+
!response.body.securityGroups.securityGroup ||
|
|
259
|
+
response.body.securityGroups.securityGroup.length === 0) {
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
const sg = response.body.securityGroups.securityGroup[0];
|
|
263
|
+
const rules = await operations.getSecurityGroupRules(sg.securityGroupId);
|
|
264
|
+
return {
|
|
265
|
+
securityGroupId: sg.securityGroupId,
|
|
266
|
+
securityGroupName: sg.securityGroupName,
|
|
267
|
+
vpcId: sg.vpcId,
|
|
268
|
+
description: sg.description,
|
|
269
|
+
createTime: sg.creationTime,
|
|
270
|
+
ingressRules: rules.ingressRules,
|
|
271
|
+
egressRules: rules.egressRules,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
deleteSecurityGroup: async (securityGroupId) => {
|
|
279
|
+
const request = new ecs.DeleteSecurityGroupRequest({
|
|
160
280
|
regionId: context.region,
|
|
161
281
|
securityGroupId,
|
|
162
282
|
});
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
response.body.securityGroups.securityGroup.length === 0) {
|
|
169
|
-
return null;
|
|
170
|
-
}
|
|
171
|
-
const sg = response.body.securityGroups.securityGroup[0];
|
|
172
|
-
return {
|
|
173
|
-
securityGroupId: sg.securityGroupId ?? securityGroupId,
|
|
174
|
-
securityGroupName: sg.securityGroupName,
|
|
175
|
-
vpcId: sg.vpcId,
|
|
176
|
-
description: sg.description,
|
|
177
|
-
createTime: sg.creationTime,
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
catch {
|
|
181
|
-
return null;
|
|
182
|
-
}
|
|
183
|
-
},
|
|
184
|
-
deleteSecurityGroup: async (securityGroupId) => {
|
|
185
|
-
const request = new ecs.DeleteSecurityGroupRequest({
|
|
186
|
-
regionId: context.region,
|
|
187
|
-
securityGroupId,
|
|
188
|
-
});
|
|
189
|
-
await ecsClient.deleteSecurityGroup(request);
|
|
190
|
-
},
|
|
191
|
-
});
|
|
283
|
+
await ecsClient.deleteSecurityGroup(request);
|
|
284
|
+
},
|
|
285
|
+
};
|
|
286
|
+
return operations;
|
|
287
|
+
};
|
|
192
288
|
exports.createEcsOperations = createEcsOperations;
|
|
@@ -97,6 +97,13 @@ const createNasOperations = (nasClient) => {
|
|
|
97
97
|
priority: 1,
|
|
98
98
|
});
|
|
99
99
|
await nasClient.createAccessRule(request);
|
|
100
|
+
return {
|
|
101
|
+
accessGroupName,
|
|
102
|
+
sourceCidrIp,
|
|
103
|
+
rwAccessType: 'RDWR',
|
|
104
|
+
userAccessType: 'no_squash',
|
|
105
|
+
priority: 1,
|
|
106
|
+
};
|
|
100
107
|
},
|
|
101
108
|
createFileSystem: async (storageClass, functionName) => {
|
|
102
109
|
const { fileSystemType, storageType } = storageClassMap[storageClass];
|
|
@@ -149,6 +156,11 @@ const createNasOperations = (nasClient) => {
|
|
|
149
156
|
protocolType: fs.protocolType,
|
|
150
157
|
status: fs.status,
|
|
151
158
|
createTime: fs.createTime,
|
|
159
|
+
description: fs.description,
|
|
160
|
+
zoneId: fs.zoneId,
|
|
161
|
+
capacity: fs.capacity,
|
|
162
|
+
encrypted: fs.encrypted,
|
|
163
|
+
mountTargetCount: fs.mountTargetCount,
|
|
152
164
|
};
|
|
153
165
|
}
|
|
154
166
|
catch {
|
|
@@ -131,6 +131,7 @@ const createRamOperations = (ramClient) => {
|
|
|
131
131
|
throw error;
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
+
return policyName;
|
|
134
135
|
};
|
|
135
136
|
return {
|
|
136
137
|
createRole: async (roleName, trustedServices, description) => {
|
|
@@ -148,9 +149,12 @@ const createRamOperations = (ramClient) => {
|
|
|
148
149
|
arn: response.body?.role?.arn,
|
|
149
150
|
description: response.body?.role?.description,
|
|
150
151
|
createDate: response.body?.role?.createDate,
|
|
152
|
+
updateDate: response.body?.role?.updateDate,
|
|
153
|
+
maxSessionDuration: response.body?.role?.maxSessionDuration,
|
|
154
|
+
assumeRolePolicyDocument: assumeRolePolicy,
|
|
151
155
|
};
|
|
152
|
-
await attachRolePolicyForFc(roleName);
|
|
153
|
-
return roleInfo;
|
|
156
|
+
const policyName = await attachRolePolicyForFc(roleName);
|
|
157
|
+
return { ...roleInfo, policyName };
|
|
154
158
|
}
|
|
155
159
|
catch (error) {
|
|
156
160
|
if (error &&
|
|
@@ -166,13 +170,17 @@ const createRamOperations = (ramClient) => {
|
|
|
166
170
|
newAssumeRolePolicyDocument: assumeRolePolicy,
|
|
167
171
|
});
|
|
168
172
|
await ramClient.updateRole(updateRequest);
|
|
169
|
-
await attachRolePolicyForFc(roleName);
|
|
173
|
+
const policyName = await attachRolePolicyForFc(roleName);
|
|
170
174
|
return {
|
|
171
175
|
roleName,
|
|
172
176
|
roleId: getResponse.body?.role?.roleId,
|
|
173
177
|
arn: getResponse.body?.role?.arn,
|
|
174
178
|
description: getResponse.body?.role?.description,
|
|
175
179
|
createDate: getResponse.body?.role?.createDate,
|
|
180
|
+
updateDate: getResponse.body?.role?.updateDate,
|
|
181
|
+
maxSessionDuration: getResponse.body?.role?.maxSessionDuration,
|
|
182
|
+
assumeRolePolicyDocument: assumeRolePolicy,
|
|
183
|
+
policyName,
|
|
176
184
|
};
|
|
177
185
|
}
|
|
178
186
|
catch (recoveryError) {
|
|
@@ -197,6 +205,10 @@ const createRamOperations = (ramClient) => {
|
|
|
197
205
|
arn: getResponse.body?.role?.arn,
|
|
198
206
|
description: getResponse.body?.role?.description,
|
|
199
207
|
createDate: getResponse.body?.role?.createDate,
|
|
208
|
+
updateDate: getResponse.body?.role?.updateDate,
|
|
209
|
+
maxSessionDuration: getResponse.body?.role?.maxSessionDuration,
|
|
210
|
+
assumeRolePolicyDocument: assumeRolePolicy,
|
|
211
|
+
policyName: `${roleName}-policy`,
|
|
200
212
|
};
|
|
201
213
|
const updateRequest = new ram.UpdateRoleRequest({
|
|
202
214
|
roleName,
|
|
@@ -231,6 +243,10 @@ const createRamOperations = (ramClient) => {
|
|
|
231
243
|
arn: response.body.role.arn,
|
|
232
244
|
description: response.body.role.description,
|
|
233
245
|
createDate: response.body.role.createDate,
|
|
246
|
+
updateDate: response.body.role.updateDate,
|
|
247
|
+
maxSessionDuration: response.body.role.maxSessionDuration,
|
|
248
|
+
assumeRolePolicyDocument: response.body.role.assumeRolePolicyDocument,
|
|
249
|
+
policyName: `${roleName}-policy`,
|
|
234
250
|
};
|
|
235
251
|
}
|
|
236
252
|
catch (error) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.extractHostRecord = exports.extractMainDomain = void 0;
|
|
3
|
+
exports.deriveWwwDomain = exports.extractHostRecord = exports.extractMainDomain = void 0;
|
|
4
4
|
const MULTI_LEVEL_TLDS = new Set([
|
|
5
5
|
// United Kingdom
|
|
6
6
|
'co.uk',
|
|
@@ -119,3 +119,21 @@ const extractHostRecord = (fullDomain, mainDomain) => {
|
|
|
119
119
|
return fullDomain;
|
|
120
120
|
};
|
|
121
121
|
exports.extractHostRecord = extractHostRecord;
|
|
122
|
+
/**
|
|
123
|
+
* Derive the www variant of a domain by prepending "www."
|
|
124
|
+
*
|
|
125
|
+
* @example deriveWwwDomain("example.com") // "www.example.com"
|
|
126
|
+
* @example deriveWwwDomain("www.example.com") // null (already has www prefix)
|
|
127
|
+
* @example deriveWwwDomain("api.example.com") // "www.api.example.com" (subdomains also get www prepended)
|
|
128
|
+
*
|
|
129
|
+
* Note: This function prepends "www." to any domain that doesn't already start with "www.",
|
|
130
|
+
* including subdomains. For example, "api.example.com" becomes "www.api.example.com".
|
|
131
|
+
* Users should ensure the domain is appropriate for www binding before calling this function.
|
|
132
|
+
*/
|
|
133
|
+
const deriveWwwDomain = (domain) => {
|
|
134
|
+
if (domain.startsWith('www.')) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
return `www.${domain}`;
|
|
138
|
+
};
|
|
139
|
+
exports.deriveWwwDomain = deriveWwwDomain;
|
|
@@ -37,14 +37,18 @@ exports.getIamInfo = void 0;
|
|
|
37
37
|
const ims20190815_1 = __importStar(require("@alicloud/ims20190815")), ims20190815 = ims20190815_1;
|
|
38
38
|
const openApi = __importStar(require("@alicloud/openapi-client"));
|
|
39
39
|
const providerEnum_1 = require("./providerEnum");
|
|
40
|
+
const constants_1 = require("./constants");
|
|
40
41
|
const getIamInfo = async (context) => {
|
|
41
42
|
if (context.provider !== providerEnum_1.ProviderEnum.ALIYUN) {
|
|
42
43
|
return undefined;
|
|
43
44
|
}
|
|
44
|
-
const
|
|
45
|
+
const imsConfig = new openApi.Config({
|
|
45
46
|
accessKeyId: context.accessKeyId,
|
|
46
47
|
accessKeySecret: context.accessKeySecret,
|
|
47
|
-
})
|
|
48
|
+
});
|
|
49
|
+
imsConfig.connectTimeout = constants_1.ALIYUN_FC3_CONNECT_TIMEOUT_MS;
|
|
50
|
+
imsConfig.readTimeout = constants_1.ALIYUN_FC3_READ_TIMEOUT_MS;
|
|
51
|
+
const imsClient = new ims20190815_1.default(imsConfig);
|
|
48
52
|
const { body } = await imsClient.getUser(new ims20190815.GetUserRequest({ userAccessKeyId: context.accessKeyId }));
|
|
49
53
|
return body?.user
|
|
50
54
|
? {
|
package/dist/src/lang/en.js
CHANGED
|
@@ -79,6 +79,9 @@ exports.en = {
|
|
|
79
79
|
// Plan command messages
|
|
80
80
|
PLAN_COMMAND_TENCENT_ONLY: 'Plan command is currently only supported for Tencent provider',
|
|
81
81
|
GENERATING_PLAN_FOR_SCF: 'Generating plan for Tencent SCF resources...',
|
|
82
|
+
GENERATING_PLAN_FOR_PROVIDER: 'Generating plan for {{provider}} resources...',
|
|
83
|
+
PROVIDER_ALIYUN: 'Alibaba Cloud',
|
|
84
|
+
PROVIDER_TENCENT: 'Tencent Cloud',
|
|
82
85
|
DEPLOYMENT_PLAN: 'DEPLOYMENT PLAN',
|
|
83
86
|
NO_CHANGES_INFRASTRUCTURE_UP_TO_DATE: 'No changes. Infrastructure is up to date.',
|
|
84
87
|
CREATE: 'CREATE',
|
|
@@ -220,6 +223,8 @@ exports.en = {
|
|
|
220
223
|
// API Gateway messages
|
|
221
224
|
APIGW_GROUP_FOUND_REUSING: 'Found existing API Group: {{groupName}}, will reuse it',
|
|
222
225
|
APIGW_DOMAIN_BINDING_FAILED: 'Failed to bind custom domain: {{error}}',
|
|
226
|
+
APIGW_DOMAIN_UNBIND_FAILED: 'Failed to unbind domain {{domain}}: {{error}}',
|
|
227
|
+
APIGW_WWW_DOMAIN_UNBIND_FAILED: 'Failed to unbind www domain {{domain}}: {{error}}',
|
|
223
228
|
APIGW_GROUP_APIS_CREATED_DOMAIN_FAILED: 'API Gateway group and APIs created successfully, but domain binding failed',
|
|
224
229
|
APIGW_STATE_SAVED_RETRY: 'State has been saved. You can fix domain verification and retry deployment',
|
|
225
230
|
APIGW_DOMAIN_VERIFICATION_REQUIRED: 'Domain {{domainName}} requires ownership verification. Add DNS records as instructed above.',
|
|
@@ -365,6 +370,7 @@ exports.en = {
|
|
|
365
370
|
CREATING_SLS_INDEX: 'Creating SLS index for: {{logstoreName}}',
|
|
366
371
|
CREATING_RAM_ROLE: 'Creating RAM role: {{roleName}}',
|
|
367
372
|
CREATING_SECURITY_GROUP: 'Creating security group: {{sgName}}',
|
|
373
|
+
SECURITY_GROUP_NOT_FOUND: 'Security group "{{sgName}}" not found in VPC "{{vpcId}}"',
|
|
368
374
|
CREATING_NAS_ACCESS_GROUP: 'Creating NAS access group: {{accessGroupName}}',
|
|
369
375
|
CREATING_NAS_ACCESS_RULE: 'Creating NAS access rule for: {{accessGroupName}}',
|
|
370
376
|
CREATING_NAS_FILE_SYSTEM: 'Creating NAS file system for: {{name}}',
|
package/dist/src/lang/zh-CN.js
CHANGED
|
@@ -79,6 +79,9 @@ exports.zhCN = {
|
|
|
79
79
|
// Plan command messages
|
|
80
80
|
PLAN_COMMAND_TENCENT_ONLY: 'Plan 命令目前仅支持腾讯云提供商',
|
|
81
81
|
GENERATING_PLAN_FOR_SCF: '正在为腾讯云 SCF 资源生成计划...',
|
|
82
|
+
GENERATING_PLAN_FOR_PROVIDER: '正在为{{provider}}资源生成计划...',
|
|
83
|
+
PROVIDER_ALIYUN: '阿里云',
|
|
84
|
+
PROVIDER_TENCENT: '腾讯云',
|
|
82
85
|
DEPLOYMENT_PLAN: '部署计划',
|
|
83
86
|
NO_CHANGES_INFRASTRUCTURE_UP_TO_DATE: '无变更。基础设施已是最新状态。',
|
|
84
87
|
CREATE: '创建',
|
|
@@ -218,8 +221,10 @@ exports.zhCN = {
|
|
|
218
221
|
LOCK_TIME_AGO_ONE_HOUR: '1 小时前',
|
|
219
222
|
LOCK_TIME_AGO_HOURS: '{{hours}} 小时前',
|
|
220
223
|
// API Gateway messages
|
|
221
|
-
APIGW_GROUP_FOUND_REUSING: '找到现有 API
|
|
222
|
-
APIGW_DOMAIN_BINDING_FAILED: '
|
|
224
|
+
APIGW_GROUP_FOUND_REUSING: '找到现有 API 分组:{{groupName}},将复用它',
|
|
225
|
+
APIGW_DOMAIN_BINDING_FAILED: '绑定自定义域名失败:{{error}}',
|
|
226
|
+
APIGW_DOMAIN_UNBIND_FAILED: '解绑域名 {{domain}} 失败:{{error}}',
|
|
227
|
+
APIGW_WWW_DOMAIN_UNBIND_FAILED: '解绑 www 域名 {{domain}} 失败:{{error}}',
|
|
223
228
|
APIGW_GROUP_APIS_CREATED_DOMAIN_FAILED: 'API 网关分组和 API 创建成功,但域名绑定失败',
|
|
224
229
|
APIGW_STATE_SAVED_RETRY: '状态已保存。您可以修复域名验证问题后重新部署',
|
|
225
230
|
APIGW_DOMAIN_VERIFICATION_REQUIRED: '域名 {{domainName}} 需要所有权验证。请按照上面的说明添加 DNS 记录。',
|
|
@@ -362,6 +367,7 @@ exports.zhCN = {
|
|
|
362
367
|
CREATING_SLS_INDEX: '正在为 SLS 日志库创建索引: {{logstoreName}}',
|
|
363
368
|
CREATING_RAM_ROLE: '正在创建 RAM 角色: {{roleName}}',
|
|
364
369
|
CREATING_SECURITY_GROUP: '正在创建安全组: {{sgName}}',
|
|
370
|
+
SECURITY_GROUP_NOT_FOUND: '在 VPC "{{vpcId}}" 中未找到安全组 "{{sgName}}"',
|
|
365
371
|
CREATING_NAS_ACCESS_GROUP: '正在创建 NAS 权限组: {{accessGroupName}}',
|
|
366
372
|
CREATING_NAS_ACCESS_RULE: '正在为 NAS 权限组创建访问规则: {{accessGroupName}}',
|
|
367
373
|
CREATING_NAS_FILE_SYSTEM: '正在为 {{name}} 创建 NAS 文件系统',
|
|
@@ -4,10 +4,11 @@ exports.parseBucket = void 0;
|
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const parseUtils_1 = require("./parseUtils");
|
|
6
6
|
const isStructuredDomain = (domain) => typeof domain === 'object' && domain !== null && 'domain_name' in domain;
|
|
7
|
-
const parseWebsiteDomain = (domain) => {
|
|
7
|
+
const parseWebsiteDomain = (domain, www_bind_apex) => {
|
|
8
8
|
if (domain == null) {
|
|
9
9
|
return {
|
|
10
10
|
domain: undefined,
|
|
11
|
+
www_bind_apex: (0, parseUtils_1.parseBooleanWithDefault)(www_bind_apex, false),
|
|
11
12
|
domain_certificate_id: undefined,
|
|
12
13
|
domain_certificate_body: undefined,
|
|
13
14
|
domain_certificate_private_key: undefined,
|
|
@@ -17,6 +18,7 @@ const parseWebsiteDomain = (domain) => {
|
|
|
17
18
|
if (!isStructuredDomain(domain)) {
|
|
18
19
|
return {
|
|
19
20
|
domain: String(domain),
|
|
21
|
+
www_bind_apex: (0, parseUtils_1.parseBooleanWithDefault)(www_bind_apex, false),
|
|
20
22
|
domain_certificate_id: undefined,
|
|
21
23
|
domain_certificate_body: undefined,
|
|
22
24
|
domain_certificate_private_key: undefined,
|
|
@@ -25,6 +27,7 @@ const parseWebsiteDomain = (domain) => {
|
|
|
25
27
|
}
|
|
26
28
|
return {
|
|
27
29
|
domain: String(domain.domain_name),
|
|
30
|
+
www_bind_apex: (0, parseUtils_1.parseBooleanWithDefault)(www_bind_apex, false),
|
|
28
31
|
domain_certificate_id: domain.certificate_id != null ? String(domain.certificate_id) : undefined,
|
|
29
32
|
domain_certificate_body: domain.certificate_body != null ? String(domain.certificate_body) : undefined,
|
|
30
33
|
domain_certificate_private_key: domain.certificate_private_key != null ? String(domain.certificate_private_key) : undefined,
|
|
@@ -69,7 +72,7 @@ const parseBucket = (buckets) => {
|
|
|
69
72
|
website: bucket.website
|
|
70
73
|
? {
|
|
71
74
|
code: String(bucket.website.code),
|
|
72
|
-
...parseWebsiteDomain(bucket.website.domain),
|
|
75
|
+
...parseWebsiteDomain(bucket.website.domain, bucket.website.www_bind_apex),
|
|
73
76
|
index: (0, parseUtils_1.parseStringWithDefault)(bucket.website.index, 'index.html'),
|
|
74
77
|
error_page: (0, parseUtils_1.parseStringWithDefault)(bucket.website.error_page, '404.html'),
|
|
75
78
|
error_code: (0, parseUtils_1.parseNumberWithDefault)(bucket.website.error_code, 404),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseEvent = void 0;
|
|
4
|
+
const parseUtils_1 = require("./parseUtils");
|
|
4
5
|
const parseEvent = (events) => {
|
|
5
6
|
if (!events) {
|
|
6
7
|
return undefined;
|
|
@@ -10,7 +11,12 @@ const parseEvent = (events) => {
|
|
|
10
11
|
name: event.name,
|
|
11
12
|
type: event.type,
|
|
12
13
|
triggers: event.triggers?.map((trigger) => ({ ...trigger, method: trigger.method ?? 'GET' })),
|
|
13
|
-
domain: event.domain
|
|
14
|
+
domain: event.domain
|
|
15
|
+
? {
|
|
16
|
+
...event.domain,
|
|
17
|
+
www_bind_apex: (0, parseUtils_1.parseBooleanWithDefault)(event.domain.www_bind_apex, false),
|
|
18
|
+
}
|
|
19
|
+
: undefined,
|
|
14
20
|
}));
|
|
15
21
|
};
|
|
16
22
|
exports.parseEvent = parseEvent;
|
|
@@ -40,13 +40,7 @@ const generateApigwPlan = async (context, state, events, serviceName) => {
|
|
|
40
40
|
path: t.path,
|
|
41
41
|
backend: t.backend,
|
|
42
42
|
})),
|
|
43
|
-
domain: event.domain
|
|
44
|
-
? {
|
|
45
|
-
domainName: event.domain.domain_name,
|
|
46
|
-
hasCertificate: !!(event.domain.certificate_body || event.domain.certificate_id),
|
|
47
|
-
protocol: event.domain.protocol ?? null,
|
|
48
|
-
}
|
|
49
|
-
: null,
|
|
43
|
+
domain: (0, apigwTypes_1.extractEventDomainDefinition)(event.domain),
|
|
50
44
|
};
|
|
51
45
|
if (!currentState) {
|
|
52
46
|
// No state exists, check if resource exists remotely
|