Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: serverlessInsight provider format refactor #23

Merged
merged 1 commit into from
Dec 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading