Skip to content

Commit

Permalink
refactor: serverlessInsight provider format refactor (#23)
Browse files Browse the repository at this point in the history
refactor: serverlessInsight provider format refactor

refactor the provider format,to support specify the region:
```yaml
provider: aliyun
```
to
```yaml
provider
    name: alialiyun
    region: cn-hangzhou

```

Refs: #5

Signed-off-by: seven <zilisheng1996@gmail.com>
  • Loading branch information
Blankll authored Dec 15, 2024
1 parent d4cf33e commit bba9248
Show file tree
Hide file tree
Showing 18 changed files with 90 additions and 64 deletions.
2 changes: 1 addition & 1 deletion src/commands/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const deploy = async (
) => {
const context = constructActionContext({ ...options, stackName });
logger.info('Validating yaml...');
const iac = parseYaml(context);
const iac = parseYaml(context.iacLocation);
logger.info('Yaml is valid! 🎉');

logger.info('Deploying stack...');
Expand Down
7 changes: 4 additions & 3 deletions src/commands/template.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { TemplateFormat } from '../types';
import yaml from 'yaml';
import { generateStackTemplate } from '../stack/deploy';
import { constructActionContext, logger } from '../common';
import { constructActionContext, getIacLocation, logger } from '../common';
import { parseYaml } from '../parser';

export const template = (
stackName: string,
options: { format: TemplateFormat; location: string; stage: string | undefined },
) => {
const context = constructActionContext({ ...options, stackName });
const iac = parseYaml(context);
const iac = parseYaml(getIacLocation(options.location));

const context = constructActionContext({ ...options, stackName, provider: iac.provider.name });

const { template } = generateStackTemplate(stackName, iac, context);
if (typeof template === 'string') {
Expand Down
3 changes: 1 addition & 2 deletions src/commands/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { parseYaml } from '../parser';

export const validate = (location: string | undefined, stage: string | undefined) => {
const context = constructActionContext({ location, stage });
parseYaml(context);
parseYaml(context.iacLocation);
logger.info('Yaml is valid! 🎉');
logger.debug('Yaml is valid! debug🎉');
};
23 changes: 14 additions & 9 deletions src/common/actionContext.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
import { ActionContext } from '../types';
import path from 'node:path';
import { ProviderEnum } from './providerEnum';

export const getIacLocation = (location?: string): string => {
const projectRoot = path.resolve(process.cwd());
return location
? path.resolve(projectRoot, location)
: path.resolve(projectRoot, 'serverlessinsight.yml') ||
path.resolve(projectRoot, 'serverlessInsight.yml') ||
path.resolve(projectRoot, 'ServerlessInsight.yml') ||
path.resolve(projectRoot, 'serverless-insight.yml');
};

export const constructActionContext = (config?: {
region?: string;
provider?: string;
account?: string;
accessKeyId?: string;
accessKeySecret?: string;
Expand All @@ -20,15 +32,8 @@ export const constructActionContext = (config?: {
accessKeyId: config?.accessKeyId ?? (process.env.ALIYUN_ACCESS_KEY_ID as string),
accessKeySecret: config?.accessKeySecret ?? (process.env.ALIYUN_ACCESS_KEY_SECRET as string),
securityToken: config?.securityToken ?? process.env.ALIYUN_SECURITY_TOKEN,
iacLocation: (() => {
const projectRoot = path.resolve(process.cwd());
return config?.location
? path.resolve(projectRoot, config.location)
: path.resolve(projectRoot, 'serverlessinsight.yml') ||
path.resolve(projectRoot, 'serverlessInsight.yml') ||
path.resolve(projectRoot, 'ServerlessInsight.yml') ||
path.resolve(projectRoot, 'serverless-insight.yml');
})(),
iacLocation: getIacLocation(config?.location),
parameters: Object.entries(config?.parameters ?? {}).map(([key, value]) => ({ key, value })),
provider: config?.provider as ProviderEnum,
};
};
2 changes: 1 addition & 1 deletion src/common/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from './provider';
export * from './providerEnum';
export * from './logger';
export * from './getVersion';
export * from './rosClient';
Expand Down
2 changes: 1 addition & 1 deletion src/common/provider.ts → src/common/providerEnum.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export enum Provider {
export enum ProviderEnum {
HUAWEI = 'huawei',
ALIYUN = 'aliyun',
// TENCENT = 'TENCENT',
Expand Down
11 changes: 5 additions & 6 deletions src/parser/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { existsSync, readFileSync } from 'node:fs';
import { ActionContext, ServerlessIac, ServerlessIacRaw } from '../types';
import { ServerlessIac, ServerlessIacRaw } from '../types';
import { parseFunction } from './functionParser';
import { parseEvent } from './eventParser';
import { parseDatabase } from './databaseParser';
import { parseTag } from './tagParser';
import { parse } from 'yaml';
import { validateYaml } from '../validator';
import { Provider } from '../common';

const validateExistence = (path: string) => {
if (!existsSync(path)) {
Expand All @@ -18,7 +17,7 @@ const transformYaml = (iacJson: ServerlessIacRaw): ServerlessIac => {
return {
service: iacJson.service,
version: iacJson.version,
provider: iacJson.provider as Provider,
provider: iacJson.provider,
vars: iacJson.vars,
stages: iacJson.stages,
functions: parseFunction(iacJson.functions),
Expand All @@ -28,10 +27,10 @@ const transformYaml = (iacJson: ServerlessIacRaw): ServerlessIac => {
};
};

export const parseYaml = (context: ActionContext): ServerlessIac => {
validateExistence(context.iacLocation);
export const parseYaml = (iacLocation: string): ServerlessIac => {
validateExistence(iacLocation);

const yamlContent = readFileSync(context.iacLocation, 'utf8');
const yamlContent = readFileSync(iacLocation, 'utf8');
const iacJson = parse(yamlContent) as ServerlessIacRaw;

validateYaml(iacJson);
Expand Down
6 changes: 3 additions & 3 deletions src/stack/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as ros from '@alicloud/ros-cdk-core';

import { ActionContext, ServerlessIac } from '../types';
import { logger, Provider, rosStackDeploy } from '../common';
import { logger, ProviderEnum, rosStackDeploy } from '../common';
import { RosStack } from './rosStack';
import { RfsStack } from './rfsStack';

Expand Down Expand Up @@ -48,9 +48,9 @@ export const generateStackTemplate = (
iac: ServerlessIac,
context: ActionContext,
): { template: unknown } => {
if (iac.provider === Provider.ALIYUN) {
if (iac.provider.name === ProviderEnum.ALIYUN) {
return generateRosStackTemplate(stackName, iac, context);
} else if (iac.provider === Provider.HUAWEI) {
} else if (iac.provider.name === ProviderEnum.HUAWEI) {
return generateRfsStackTemplate(stackName, iac, context);
}
return { template: '' };
Expand Down
7 changes: 5 additions & 2 deletions src/types/domains/context.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { ProviderEnum } from '../../common';

export type ActionContext = {
stage: string;
stackName: string;
region: string;
provider: ProviderEnum;
stackName: string;
stage: string;
accessKeyId: string;
accessKeySecret: string;
securityToken?: string;
Expand Down
6 changes: 6 additions & 0 deletions src/types/domains/provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ProviderEnum } from '../../common';

export type Provider = {
name: ProviderEnum;
region: string;
};
2 changes: 1 addition & 1 deletion src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Tags } from './domains/tag';
import { EventDomain, EventRaw } from './domains/event';
import { DatabaseDomain, DatabaseRaw } from './domains/database';
import { FunctionDomain, FunctionRaw } from './domains/function';
import { Provider } from '../common';
import { Provider } from './domains/provider';

export * from './domains/database';
export * from './domains/event';
Expand Down
8 changes: 7 additions & 1 deletion src/validator/rootSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ export const rootSchema = {
type: 'object',
properties: {
version: { type: 'string', enum: ['0.0.0', '0.0.1'] },
provider: { type: 'string', enum: ['aliyun', 'huawei'] },
provider: {
type: 'object',
properties: {
name: { type: 'string', enum: ['huawei', 'aliyun'] },
region: { type: 'string' },
},
},
service: { type: 'string' },
vars: {
type: 'object',
Expand Down
2 changes: 2 additions & 0 deletions tests/fixtures/contextFixture.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { ActionContext } from '../../src/types';
import { ProviderEnum } from '../../src/common';

export const context: ActionContext = {
stage: 'test',
stackName: 'testStack',
provider: ProviderEnum.ALIYUN,
region: 'cn-hangzhou',
accessKeyId: 'testAccessKeyId',
accessKeySecret: 'testAccessKeySecret',
Expand Down
38 changes: 21 additions & 17 deletions tests/fixtures/deployFixture.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { DatabaseEnum, ServerlessIac } from '../../src/types';
import { cloneDeep, set } from 'lodash';
import { Provider } from '../../src/common';
import { ProviderEnum } from '../../src/common';

export const oneFcOneGatewayIac = {
service: 'my-demo-service',
version: '0.0.1',
provider: 'aliyun' as Provider,
provider: {
name: 'aliyun' as ProviderEnum,
region: "cn-hangzhou'",
},
vars: {
region: 'cn-hangzhou',
account_id: 1234567890,
},
stages: {
Expand Down Expand Up @@ -65,7 +67,6 @@ export const oneFcOneGatewayRos = {
Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } },
Parameters: {
account_id: { Default: 1234567890, Type: 'String' },
region: { Default: 'cn-hangzhou', Type: 'String' },
},
ROSTemplateFormatVersion: '2015-09-01',
Resources: {
Expand Down Expand Up @@ -160,7 +161,6 @@ export const referredServiceRos = {
Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } },
Parameters: {
account_id: { Default: 1234567890, Type: 'String' },
region: { Default: 'cn-hangzhou', Type: 'String' },
},
ROSTemplateFormatVersion: '2015-09-01',
Resources: {
Expand Down Expand Up @@ -240,7 +240,10 @@ export const referredServiceRos = {
export const minimumIac = {
service: 'my-demo-minimum-service',
version: '0.0.1',
provider: 'aliyun' as Provider,
provider: {
name: 'aliyun' as ProviderEnum,
region: 'cn-hangzhou',
},

functions: [
{
Expand Down Expand Up @@ -273,9 +276,11 @@ export const minimumRos = {
export const oneFcIac = {
service: 'my-demo-service',
version: '0.0.1',
provider: 'aliyun' as Provider,
vars: {
provider: {
name: 'aliyun' as ProviderEnum,
region: 'cn-hangzhou',
},
vars: {
account_id: 1234567890,
},
stages: {
Expand Down Expand Up @@ -319,7 +324,6 @@ export const oneFcRos = {
Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } },
Parameters: {
account_id: { Default: 1234567890, Type: 'String' },
region: { Default: 'cn-hangzhou', Type: 'String' },
},
ROSTemplateFormatVersion: '2015-09-01',
Resources: {
Expand All @@ -341,9 +345,11 @@ export const oneFcRos = {
export const oneFcIacWithStage = {
service: 'my-demo-service',
version: '0.0.1',
provider: 'aliyun' as Provider,
vars: {
provider: {
name: 'aliyun',
region: 'cn-hangzhou',
},
vars: {
account_id: 1234567890,
},
stages: {
Expand Down Expand Up @@ -395,7 +401,6 @@ export const oneFcWithStageRos = {
Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } },
Parameters: {
account_id: { Default: 1234567890, Type: 'String' },
region: { Default: 'cn-hangzhou', Type: 'String' },
},
ROSTemplateFormatVersion: '2015-09-01',
Resources: {
Expand Down Expand Up @@ -437,10 +442,6 @@ export const largeCodeRos = {
Default: 1234567890,
Type: 'String',
},
region: {
Default: 'cn-hangzhou',
Type: 'String',
},
},
ROSTemplateFormatVersion: '2015-09-01',
Resources: {
Expand Down Expand Up @@ -752,7 +753,10 @@ export const defaultContext = {
export const esServerlessMinimumIac: ServerlessIac = {
service: 'my-demo-es-serverless-service',
version: '0.0.1',
provider: 'aliyun' as Provider as Provider,
provider: {
name: 'aliyun' as ProviderEnum,
region: 'cn-hangzhou',
},
databases: [
{
key: 'insight_es_db_test',
Expand Down
5 changes: 4 additions & 1 deletion tests/fixtures/serverless-insight-es.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
version: 0.0.1
provider: aliyun

provider:
name: aliyun
region: cn-chengdu


service: insight-es-poc
Expand Down
9 changes: 4 additions & 5 deletions tests/fixtures/serverless-insight-huawei.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
version: 0.0.1
provider: huawei
provider:
name: huawei
region: cn-north-4

vars:
region: cn-hangzhou
testv: testVarValue
handler: index.handler

stages:
default:
region: ${vars.region}
node_env: default
dev:
region: ${vars.region}
node_env: development
prod:
region: cn-shanghai

node_env: prod
service: insight-poc

tags:
Expand Down
4 changes: 3 additions & 1 deletion tests/fixtures/serverless-insight.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
version: 0.0.1
provider: aliyun
provider:
name: aliyun
region: cn-chengdu

vars:
region: cn-hangzhou
Expand Down
17 changes: 7 additions & 10 deletions tests/parser/parse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,17 @@ import { parseYaml } from '../../src/parser';

describe('unit test for parse', () => {
describe('domain - databases', () => {
const defaultContext = {
iacLocation: path.resolve(__dirname, '../fixtures/serverless-insight-es.yml'),
accessKeyId: 'xxx',
accessKeySecret: 'xxx',
region: 'cn-chengdu',
stackName: 'insight-es-poc-test',
stage: 'test',
};
const iacLocation = path.resolve(__dirname, '../fixtures/serverless-insight-es.yml');

it('should pass databases from yaml to domain instance when the yaml is valid', () => {
const databaseDomain = parseYaml(defaultContext);
const databaseDomain = parseYaml(iacLocation);
expect(databaseDomain).toEqual({
service: 'insight-es-poc',
version: '0.0.1',
provider: 'aliyun',
provider: {
name: 'aliyun',
region: 'cn-chengdu',
},
tags: [
{ key: 'iac-provider', value: 'ServerlessInsight' },
{ key: 'owner', value: 'geek-fun' },
Expand Down

0 comments on commit bba9248

Please sign in to comment.