Skip to content

Commit

Permalink
feat: deploy action create apigateway OK
Browse files Browse the repository at this point in the history
Signed-off-by: seven <[email protected]>
  • Loading branch information
Blankll committed Sep 21, 2024
1 parent 533f1c0 commit 42c6125
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 20 deletions.
46 changes: 46 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@
],
"dependencies": {
"@alicloud/openapi-client": "^0.4.11",
"@alicloud/ros-cdk-apigateway": "^1.2.0",
"@alicloud/ros-cdk-core": "^1.2.0",
"@alicloud/ros-cdk-fc": "^1.2.0",
"@alicloud/ros-cdk-ram": "^1.2.0",
"@alicloud/ros20190910": "^3.4.3",
"ajv": "^8.17.1",
"chalk": "^4.1.2",
Expand Down
13 changes: 8 additions & 5 deletions src/common/rosClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ROS20190910, {
CreateStackRequestParameters,
CreateStackRequestTags,
ListStacksRequest,
UpdateStackRequest,
} from '@alicloud/ros20190910';
import { Config } from '@alicloud/openapi-client';
import { ActionContext } from '../types';
Expand Down Expand Up @@ -42,7 +43,7 @@ const createStack = async (stackName: string, templateBody: unknown, context: Ac
return response.body?.stackId;
};

const updateStack = async (stackName: string, templateBody: unknown, context: ActionContext) => {
const updateStack = async (stackId: string, templateBody: unknown, context: ActionContext) => {
const parameters = context.parameters?.map(
(parameter) =>
new CreateStackRequestParameters({
Expand All @@ -51,10 +52,12 @@ const updateStack = async (stackName: string, templateBody: unknown, context: Ac
}),
);

const createStackRequest = new CreateStackRequest({
stackName,
templateBody,
const createStackRequest = new UpdateStackRequest({
regionId: context.region,
stackId,
templateBody: JSON.stringify(templateBody),
parameters,
tags: context.tags?.map((tag) => new CreateStackRequestTags(tag)),
});

const response = await client.updateStack(createStackRequest);
Expand Down Expand Up @@ -93,7 +96,7 @@ export const rosStackDeploy = async (
}

printer.info(`Update stack: ${stackName} deploying... `);
return await updateStack(stackName, templateBody, context);
return await updateStack(stackInfo.stackId as string, templateBody, context);
} else {
// create stack
printer.info(`Create stack: ${stackName} deploying... `);
Expand Down
3 changes: 2 additions & 1 deletion src/iac/iacSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ const schema = {
'.*': {
type: 'object',
properties: {
name: { type: 'string' },
type: { type: 'string', enum: ['API_GATEWAY'] },
triggers: {
type: 'array',
Expand All @@ -90,7 +91,7 @@ const schema = {
},
},
},
required: ['type', 'triggers'],
required: ['name', 'type', 'triggers'],
},
},
},
Expand Down
104 changes: 97 additions & 7 deletions src/stack/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import * as ros from '@alicloud/ros-cdk-core';
import * as fc from '@alicloud/ros-cdk-fc';
import { ActionContext, ServerlessIac } from '../types';
import * as agw from '@alicloud/ros-cdk-apigateway';
import * as ram from '@alicloud/ros-cdk-ram';

import { ActionContext, EventTypes, ServerlessIac } from '../types';
import { printer, rosStackDeploy } from '../common';
import path from 'node:path';
import * as fs from 'node:fs';
Expand All @@ -13,9 +16,10 @@ const resolveCode = (location: string): string => {
};

export class IacStack extends ros.Stack {
constructor(scope: ros.Construct, iac: ServerlessIac, props?: ros.StackProps) {
super(scope, iac.service, props);
new ros.RosInfo(this, ros.RosInfo.description, 'This is the simple ros cdk app example.');
constructor(scope: ros.Construct, iac: ServerlessIac, context: ActionContext) {
super(scope, iac.service);
new ros.RosInfo(this, ros.RosInfo.description, `${iac.service} stack`);

const service = new fc.RosService(
this,
`${iac.service}-service`,
Expand Down Expand Up @@ -45,12 +49,98 @@ export class IacStack extends ros.Stack {
);
func.addDependsOn(service);
});

const apiGateway = iac.events.find((event) => event.type === EventTypes.API_GATEWAY);
if (apiGateway) {
const gatewayAccessRole = new ram.RosRole(
this,
`${iac.service}_role`,
{
roleName: `${iac.service}-gateway-access-role`,
description: `${iac.service} role`,
assumeRolePolicyDocument: {
version: '1',
statement: [
{
action: 'sts:AssumeRole',
effect: 'Allow',
principal: {
service: ['apigateway.aliyuncs.com'],
},
},
],
},
policies: [
{
policyName: `${iac.service}-policy`,
policyDocument: {
version: '1',
statement: [
{
action: ['fc:InvokeFunction'],
effect: 'Allow',
// @TODO implement at least permission granting
resource: ['*'],
},
],
},
},
],
},
true,
);

const apiGatewayGroup = new agw.RosGroup(
this,
`${iac.service}_apigroup`,
{
groupName: `${iac.service}_apigroup`,
},
true,
);

iac.events
.filter((event) => event.type === EventTypes.API_GATEWAY)
.forEach((event) => {
event.triggers.forEach((trigger) => {
const key = `${trigger.method}_${trigger.path}`.toLowerCase().replace(/\//g, '_');
const api = new agw.RosApi(
this,
`${event.key}_api_${key}`,
{
apiName: `${event.name}_api_${key}`,
groupId: apiGatewayGroup.attrGroupId,
visibility: 'PRIVATE',
requestConfig: {
requestProtocol: 'HTTP',
requestHttpMethod: trigger.method,
requestPath: trigger.path,
requestMode: 'PASSTHROUGH',
},
serviceConfig: {
serviceProtocol: 'FunctionCompute',
functionComputeConfig: {
fcRegionId: context.region,
serviceName: service.serviceName,
functionName: trigger.backend,
roleArn: gatewayAccessRole.attrArn,
},
},
resultSample: 'ServerlessInsight resultSample',
resultType: 'JSON',
},
true,
);
api.addDependsOn(apiGatewayGroup);
});
});
}
}
}

const generateStackTemplate = (stackName: string, iac: ServerlessIac) => {
const generateStackTemplate = (stackName: string, iac: ServerlessIac, context: ActionContext) => {
const app = new ros.App();
new IacStack(app, iac);
new IacStack(app, iac, context);

const assembly = app.synth();
const stackArtifact = assembly.getStackByName(stackName);
Expand All @@ -69,7 +159,7 @@ export const deployStack = async (
) => {
printer.info(`Deploying stack... ${JSON.stringify(iac)}`);

const { template, parameters } = generateStackTemplate(stackName, iac);
const { template, parameters } = generateStackTemplate(stackName, iac, context);
console.log('Generated ROS YAML:', JSON.stringify({ template, parameters }));
await rosStackDeploy(stackName, template, { ...context, parameters });
printer.info(`Stack deployed! 🎉`);
Expand Down
18 changes: 12 additions & 6 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ type Stages = {
[key: string]: Stage;
};

export enum EventTypes {
API_GATEWAY = 'API_GATEWAY',
}

export type IacFunction = {
name: string;
key: string;
Expand All @@ -24,12 +28,14 @@ export type IacFunction = {
};

export type Event = {
type: string;
source: string;
function: string;
batch_size?: number;
enabled?: boolean;
target: string;
key: string;
name: string;
type: EventTypes;
triggers: Array<{
method: string;
path: string;
backend: string;
}>;
};

type Events = {
Expand Down
3 changes: 2 additions & 1 deletion tests/fixtures/serverless-insignt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ tags:
functions:
insight_poc_fn:
name: insight-poc-fn
runtime: nodejs14
runtime: nodejs18
handler: index.handler
code: artifacts/artifact.zip
memory: 512
Expand All @@ -30,6 +30,7 @@ functions:
events:
gateway_event:
type: API_GATEWAY
name: insight-poc-gateway
triggers:
- method: GET
path: /api/hello
Expand Down

0 comments on commit 42c6125

Please sign in to comment.