Skip to content

Commit 93de6e2

Browse files
authored
feat: support to specify custom domain to apigateway (#53)
feat: support to specify custom domain to apigateway . Refs: #49 --------- Signed-off-by: seven <[email protected]>
1 parent 8b7ffc9 commit 93de6e2

File tree

11 files changed

+276
-188
lines changed

11 files changed

+276
-188
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version: 0.0.1
22
provider:
33
name: aliyun
4-
region: cn-chengdu
4+
region: cn-hongkong
55

66
vars:
77
region: cn-hangzhou
@@ -18,33 +18,25 @@ stages:
1818
prod:
1919
region: cn-shanghai
2020

21-
service: insight-poc
21+
service: insight-poc-api
2222

2323
tags:
2424
owner: geek-fun
2525

2626
functions:
2727
insight_poc_fn:
28-
name: insight-poc-fn
29-
runtime: nodejs18
30-
handler: ${vars.handler}
31-
code: tests/fixtures/artifacts/artifact.zip
28+
name: insight-poc-api-fn
29+
code:
30+
runtime: nodejs18
31+
handler: ${vars.handler}
32+
path: tests/fixtures/artifacts/artifact.zip
3233
memory: 512
3334
timeout: 10
3435
environment:
3536
NODE_ENV: ${stages.node_env}
3637
TEST_VAR: ${vars.testv}
3738
TEST_VAR_EXTRA: abcds-${vars.testv}-andyou
3839

39-
databases:
40-
insight_poc_db:
41-
name: insight-poc-db
42-
type: RDS_POSTGRESQL_SERVERLESS
43-
version: '17.0'
44-
security:
45-
basic_auth:
46-
password: 'U34I6InQ8elseTgqTWT2t2oFXpoqFg'
47-
4840
events:
4941
gateway_event:
5042
type: API_GATEWAY
@@ -53,8 +45,5 @@ events:
5345
- method: GET
5446
path: /api/hello
5547
backend: ${functions.insight_poc_fn}
56-
# custom_domain:
57-
# domain_name: test.com
58-
# certificate_name: test
59-
# certificate_private_key: test
60-
# certificate_body: test
48+
domain:
49+
domain_name: insight-api.serverlessinsight.com

samples/huawei-poc-fc.yml

+4-3
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ tags:
2323
functions:
2424
insight_poc_fn:
2525
name: insight-poc-fn
26-
runtime: nodejs18
27-
handler: ${vars.handler}
28-
code: tests/fixtures/artifacts/artifact.zip
26+
code:
27+
runtime: nodejs18
28+
handler: ${vars.handler}
29+
path: tests/fixtures/artifacts/artifact.zip
2930
memory: 512
3031
timeout: 10
3132
environment:

src/common/iacHelper.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export const getFileSource = (
2929
const hash = crypto.createHash('md5').update(fs.readFileSync(filePath)).digest('hex');
3030

3131
const objectKey = `${fcName}/${hash}-${filePath.split('/').pop()}`;
32-
const source = ossDeployment.Source.asset(filePath, {}, `${fcName}/${hash}-`);
32+
const source = ossDeployment.Source.asset(filePath, { deployTime: true }, `${fcName}/${hash}-`);
3333

3434
return { source, objectKey };
3535
};

src/parser/eventParser.ts

+1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ export const parseEvent = (events: { [key: string]: EventRaw }): Array<EventDoma
99
name: event.name,
1010
type: event.type,
1111
triggers: event.triggers,
12+
domain: event.domain,
1213
}));
1314
};

src/stack/rosStack/event.ts

+72-58
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import * as ros from '@alicloud/ros-cdk-core';
22
import { ActionContext, EventDomain, EventTypes, ServerlessIac } from '../../types';
33
import * as ram from '@alicloud/ros-cdk-ram';
4-
import { encodeBase64ForRosId, replaceReference } from '../../common';
4+
import { encodeBase64ForRosId, replaceReference, splitDomain } from '../../common';
55
import * as agw from '@alicloud/ros-cdk-apigateway';
66
import { isEmpty } from 'lodash';
7+
import * as dns from '@alicloud/ros-cdk-dns';
78

89
export const resolveEvents = (
910
scope: ros.Construct,
@@ -16,12 +17,14 @@ export const resolveEvents = (
1617
return undefined;
1718
}
1819
const apiGateway = events!.filter((event) => event.type === EventTypes.API_GATEWAY);
19-
if (apiGateway?.length) {
20+
if (!apiGateway?.length) return;
21+
22+
apiGateway.forEach((event) => {
2023
const gatewayAccessRole = new ram.RosRole(
2124
scope,
22-
replaceReference(`${service}_role`, context),
25+
replaceReference(`${event.key}_role`, context),
2326
{
24-
roleName: replaceReference(`${service}-gateway-access-role`, context),
27+
roleName: replaceReference(`${service}-${event.name}-agw-access-role`, context),
2528
description: replaceReference(`${service} role`, context),
2629
assumeRolePolicyDocument: {
2730
version: '1',
@@ -37,7 +40,7 @@ export const resolveEvents = (
3740
},
3841
policies: [
3942
{
40-
policyName: replaceReference(`${service}-policy`, context),
43+
policyName: replaceReference(`${service}-${event.name}-policy`, context),
4144
policyDocument: {
4245
version: '1',
4346
statement: [
@@ -66,64 +69,75 @@ export const resolveEvents = (
6669
true,
6770
);
6871

69-
// new agw.RosCustomDomain(
70-
// this,
71-
// 'customDomain',
72-
// {
73-
// domainName: 'example.com',
74-
// certificateName: 'example.com',
75-
// certificateBody: 'example.com',
76-
// certificatePrivateKey: 'example.com',
77-
// groupId: apiGatewayGroup.attrGroupId,
78-
// },
79-
// true,
80-
// );
72+
if (event.domain) {
73+
const dnsRecordRosId = `${event.key}_custom_domain_record_${encodeBase64ForRosId(event.domain.domain_name)}`;
74+
const { domainName, rr } = splitDomain(event.domain?.domain_name);
8175

82-
apiGateway.forEach((event) => {
83-
event.triggers.forEach((trigger) => {
84-
const key = encodeBase64ForRosId(
85-
replaceReference(`${trigger.method}_${trigger.path}`, context),
86-
);
76+
new dns.DomainRecord(scope, dnsRecordRosId, {
77+
domainName,
78+
rr,
79+
type: 'CNAME',
80+
value: apiGatewayGroup.attrSubDomain,
81+
});
8782

88-
const api = new agw.RosApi(
89-
scope,
90-
`${event.key}_api_${key}`,
91-
{
92-
apiName: replaceReference(`${event.name}_api_${key}`, context),
93-
groupId: apiGatewayGroup.attrGroupId,
94-
visibility: 'PRIVATE',
95-
authType: 'ANONYMOUS',
96-
requestConfig: {
97-
requestProtocol: 'HTTP',
98-
requestHttpMethod: replaceReference(trigger.method, context),
99-
requestPath: replaceReference(trigger.path, context),
100-
requestMode: 'PASSTHROUGH',
101-
},
102-
serviceConfig: {
103-
serviceProtocol: 'FunctionCompute',
104-
functionComputeConfig: {
105-
fcRegionId: context.region,
106-
functionName: replaceReference(trigger.backend, context),
107-
roleArn: gatewayAccessRole.attrArn,
108-
fcVersion: '3.0',
109-
method: replaceReference(trigger.method, context),
110-
},
83+
const agwCustomDomain = new agw.RosCustomDomain(
84+
scope,
85+
`${event.key}_custom_domain_${encodeBase64ForRosId(event.domain.domain_name)}`,
86+
{
87+
groupId: apiGatewayGroup.attrGroupId,
88+
domainName: event.domain.domain_name,
89+
certificateName: event.domain.certificate_name,
90+
certificateBody: event.domain.certificate_body,
91+
certificatePrivateKey: event.domain.certificate_private_key,
92+
},
93+
true,
94+
);
95+
agwCustomDomain.addRosDependency(dnsRecordRosId);
96+
}
97+
98+
event.triggers.forEach((trigger) => {
99+
const key = encodeBase64ForRosId(
100+
replaceReference(`${trigger.method}_${trigger.path}`, context),
101+
);
102+
103+
const api = new agw.RosApi(
104+
scope,
105+
`${event.key}_api_${key}`,
106+
{
107+
apiName: replaceReference(`${event.name}_api_${key}`, context),
108+
groupId: apiGatewayGroup.attrGroupId,
109+
visibility: 'PRIVATE',
110+
authType: 'ANONYMOUS',
111+
requestConfig: {
112+
requestProtocol: 'HTTP',
113+
requestHttpMethod: replaceReference(trigger.method, context),
114+
requestPath: replaceReference(trigger.path, context),
115+
requestMode: 'PASSTHROUGH',
116+
},
117+
serviceConfig: {
118+
serviceProtocol: 'FunctionCompute',
119+
functionComputeConfig: {
120+
fcRegionId: context.region,
121+
functionName: replaceReference(trigger.backend, context),
122+
roleArn: gatewayAccessRole.attrArn,
123+
fcVersion: '3.0',
124+
method: replaceReference(trigger.method, context),
111125
},
112-
resultSample: 'ServerlessInsight resultSample',
113-
resultType: 'PASSTHROUGH',
114-
tags: replaceReference(tags, context),
115126
},
116-
true,
117-
);
118-
api.addDependsOn(apiGatewayGroup);
127+
resultSample: 'ServerlessInsight resultSample',
128+
resultType: 'PASSTHROUGH',
129+
tags: replaceReference(tags, context),
130+
},
131+
true,
132+
);
133+
api.addDependsOn(apiGatewayGroup);
119134

120-
new agw.Deployment(scope, `${service}_deployment`, {
121-
apiId: api.attrApiId,
122-
groupId: apiGatewayGroup.attrGroupId,
123-
stageName: 'RELEASE',
124-
description: `${service} Api Gateway deployment`,
125-
});
135+
new agw.Deployment(scope, `${service}_deployment`, {
136+
apiId: api.attrApiId,
137+
groupId: apiGatewayGroup.attrGroupId,
138+
stageName: 'RELEASE',
139+
description: `${service} Api Gateway deployment`,
126140
});
127141
});
128-
}
142+
});
129143
};

src/types/domains/event.ts

+6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ export type EventRaw = {
1010
path: string;
1111
backend: string;
1212
}>;
13+
domain?: {
14+
domain_name: string;
15+
certificate_name?: string;
16+
certificate_body?: string;
17+
certificate_private_key?: string;
18+
};
1319
};
1420

1521
export type EventDomain = {

src/validator/eventSchema.ts

+3-7
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,16 @@ export const eventSchema = {
1616
required: ['method', 'path', 'backend'],
1717
},
1818
},
19-
custom_domain: {
19+
domain: {
2020
type: 'object',
21+
additionalProperties: false,
22+
required: ['domain_name'],
2123
properties: {
2224
domain_name: { type: 'string' },
2325
certificate_name: { type: 'string' },
2426
certificate_body: { type: 'string' },
2527
certificate_private_key: { type: 'string' },
2628
},
27-
required: [
28-
'domain_name',
29-
'certificate_name',
30-
'certificate_body',
31-
'certificate_private_key',
32-
],
3329
},
3430
},
3531
required: ['name', 'type', 'triggers'],

tests/common/iacHelper.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe('Unit test for iacHelper', () => {
1818
getFileSource(fcName, location);
1919
expect(ossDeployment.Source.asset).toHaveBeenCalledWith(
2020
`${process.cwd()}/${location}`,
21-
{},
21+
{ deployTime: true },
2222
`${fcName}/50861cd99a3a678356030f5f189300af-`,
2323
);
2424
});

0 commit comments

Comments
 (0)