diff --git a/src/commands/index.ts b/src/commands/index.ts index b8e605d..875175e 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -38,10 +38,10 @@ program .option('-f, --file ', 'specify the yaml file') .option('-s, --stage ', 'specify the stage') .option('-r, --region ', 'specify the region') - .option('-pr, --provider ', 'specify the provider') - .option('-ak, --accessKeyId ', 'specify the AccessKeyId') - .option('-as, --accessKeySecret ', 'specify the AccessKeySecret') - .option('-at, --securityToken ', 'specify the SecurityToken') + .option('-v, --provider ', 'specify the provider') + .option('-k, --accessKeyId ', 'specify the AccessKeyId') + .option('-x, --accessKeySecret ', 'specify the AccessKeySecret') + .option('-n, --securityToken ', 'specify the SecurityToken') .option( '-p, --parameter ', 'override parameters', @@ -72,7 +72,7 @@ program program .command('template ') - .description('print ROS template') + .description('print platform specific infrastructure as code template') .option('-f, --file ', 'specify the yaml file') .option('-s, --stage ', 'specify the stage') .option('-t, --format ', 'output content type (JSON or YAML)', 'JSON') @@ -84,10 +84,10 @@ program .command('destroy ') .option('-f, --file ', 'specify the yaml file') .option('-r, --region ', 'specify the region') - .option('-pr, --provider ', 'specify the provider') - .option('-ak, --accessKeyId ', 'specify the AccessKeyId') - .option('-as, --accessKeySecret ', 'specify the AccessKeySecret') - .option('-at, --securityToken ', 'specify the SecurityToken') + .option('-v, --provider ', 'specify the provider') + .option('-k, --accessKeyId ', 'specify the AccessKeyId') + .option('-x, --accessKeySecret ', 'specify the AccessKeySecret') + .option('-n, --securityToken ', 'specify the SecurityToken') .description('destroy serverless stack') .action( async (stackName, { file, region, provider, accessKeyId, accessKeySecret, securityToken }) => { diff --git a/src/common/iacHelper.ts b/src/common/iacHelper.ts index 294f865..355504f 100644 --- a/src/common/iacHelper.ts +++ b/src/common/iacHelper.ts @@ -84,7 +84,7 @@ const getParam = (key: string, records?: Array<{ key: string; value: string }>) return records?.find((param) => param.key === key)?.value as string; }; -export const realValue = (rawValue: string, ctx: Context): T => { +export const calcValue = (rawValue: string, ctx: Context): T => { const containsStage = rawValue.match(/\$\{ctx.stage}/); const containsVar = rawValue.match(/\$\{vars.\w+}/); const containsMap = rawValue.match(/\$\{stages\.(\w+)}/); @@ -107,3 +107,21 @@ export const realValue = (rawValue: string, ctx: Context): T => { return value as T; }; +export const formatRosId = (id: string): string => { + // Insert underscore before uppercase letters, but only when they follow a lowercase letter + let result = id.replace(/([a-z])([A-Z])/g, '$1_$2'); + + // Convert to lowercase + result = result.toLowerCase(); + + // Replace special characters with underscores + result = result.replace(/[/#,-]/g, '_'); + + // Remove any number of underscores to single one + result = result.replace(/_+/g, '_'); + + // Remove leading underscores + result = result.replace(/^_/, ''); + + return result; +}; diff --git a/src/stack/rosStack/bootstrap.ts b/src/stack/rosStack/bootstrap.ts index 33e5811..3236cff 100644 --- a/src/stack/rosStack/bootstrap.ts +++ b/src/stack/rosStack/bootstrap.ts @@ -3,7 +3,7 @@ import { Context } from '../../types'; const getBootstrapTemplate = async (context: Context) => { const iamInfo = await getIamInfo(context); - const stackName = `serverlessInsight-bootstrap-${iamInfo?.accountId}-${context.region}`; + const stackName = `si-bootstrap-${iamInfo?.accountId}-${context.region}`; const template = { Description: 'ServerlessInsight Bootstrap Stack', @@ -14,7 +14,7 @@ const getBootstrapTemplate = async (context: Context) => { }, ROSTemplateFormatVersion: '2015-09-01', Resources: { - ServerlessInsight_artifacts_bucket: { + si_artifacts_bucket: { Type: 'ALIYUN::OSS::Bucket', Properties: { BucketName: { diff --git a/src/stack/rosStack/bucket.ts b/src/stack/rosStack/bucket.ts index 99451ea..ecffc19 100644 --- a/src/stack/rosStack/bucket.ts +++ b/src/stack/rosStack/bucket.ts @@ -2,10 +2,11 @@ import { BucketAccessEnum, BucketDomain, Context } from '../../types'; import * as oss from '@alicloud/ros-cdk-oss'; import * as ros from '@alicloud/ros-cdk-core'; import { - encodeBase64ForRosId, + calcRefs, + calcValue, + formatRosId, getAssets, OSS_DEPLOYMENT_TIMEOUT, - calcRefs, splitDomain, } from '../../common'; import * as ossDeployment from '@alicloud/ros-cdk-ossdeployment'; @@ -58,7 +59,7 @@ export const resolveBuckets = ( } buckets.forEach((bucket) => { - const ossBucket = new oss.Bucket(scope, calcRefs(bucket.key, context), { + const ossBucket = new oss.Bucket(scope, bucket.key, { bucketName: calcRefs(bucket.name, context), accessControl: aclMap.get( calcRefs(bucket.security?.acl, context) ?? ('' as BucketAccessEnum), @@ -78,10 +79,10 @@ export const resolveBuckets = ( : undefined, }); if (bucket.website?.code) { - const filePath = path.resolve(process.cwd(), calcRefs(bucket.website.code, context)); + const filePath = path.resolve(process.cwd(), calcValue(bucket.website.code, context)); new ossDeployment.BucketDeployment( scope, - `si_auto_${bucket.key}_bucket_code_deployment`, + formatRosId(`si_auto_${bucket.key}_bucket_code_deployment`), { sources: getAssets(filePath), destinationBucket: ossBucket.attrName, @@ -95,29 +96,21 @@ export const resolveBuckets = ( } if (bucket.website?.domain) { const { rr, domainName } = splitDomain(bucket.website.domain); - new oss.Domain( - scope, - `${bucket.key}_custom_domain_${encodeBase64ForRosId(bucket.website.domain)}`, - { - bucketName: ossBucket.attrName, - domainName: calcRefs(bucket.website.domain, context), - }, - ); + new oss.Domain(scope, formatRosId(`${bucket.key}_custom_domain`), { + bucketName: ossBucket.attrName, + domainName: calcRefs(bucket.website.domain, context), + }); - new dns.DomainRecord( - scope, - `${bucket.key}_custom_domain_record_${encodeBase64ForRosId(bucket.website.domain)}`, - { - domainName: domainName, - rr, - type: 'CNAME', - value: [BucketAccessEnum.PUBLIC_READ, BucketAccessEnum.PUBLIC_READ_WRITE].includes( - bucket.security?.acl ?? ('' as BucketAccessEnum), - ) - ? ossBucket.attrDomainName - : ossBucket.attrInternalDomainName, - }, - ); + new dns.DomainRecord(scope, formatRosId(`${bucket.key}_custom_domain_record`), { + domainName: domainName, + rr, + type: 'CNAME', + value: [BucketAccessEnum.PUBLIC_READ, BucketAccessEnum.PUBLIC_READ_WRITE].includes( + bucket.security?.acl ?? ('' as BucketAccessEnum), + ) + ? ossBucket.attrDomainName + : ossBucket.attrInternalDomainName, + }); } }); }; diff --git a/src/stack/rosStack/database.ts b/src/stack/rosStack/database.ts index 227ddd8..eb77154 100644 --- a/src/stack/rosStack/database.ts +++ b/src/stack/rosStack/database.ts @@ -208,7 +208,7 @@ export const resolveDatabases = ( if ([DatabaseEnum.ELASTICSEARCH_SERVERLESS].includes(db.type)) { new esServerless.App( scope, - calcRefs(db.key, context), + db.key, { appName: calcRefs(db.name, context), appVersion: version, @@ -249,7 +249,7 @@ export const resolveDatabases = ( ) { new rds.DBInstance( scope, - calcRefs(db.key, context), + db.key, { engine: engine as string, /** diff --git a/src/stack/rosStack/event.ts b/src/stack/rosStack/event.ts index 0f05b0a..258fc0b 100644 --- a/src/stack/rosStack/event.ts +++ b/src/stack/rosStack/event.ts @@ -1,7 +1,7 @@ import * as ros from '@alicloud/ros-cdk-core'; import { Context, EventDomain, EventTypes, ServerlessIac } from '../../types'; import * as ram from '@alicloud/ros-cdk-ram'; -import { encodeBase64ForRosId, calcRefs, splitDomain } from '../../common'; +import { calcRefs, calcValue, formatRosId, splitDomain } from '../../common'; import * as agw from '@alicloud/ros-cdk-apigateway'; import { isEmpty } from 'lodash'; import * as dns from '@alicloud/ros-cdk-dns'; @@ -22,9 +22,9 @@ export const resolveEvents = ( apiGateway.forEach((event) => { const gatewayAccessRole = new ram.RosRole( scope, - calcRefs(`${event.key}_role`, context), + formatRosId(`${event.key}_agw_role`), { - roleName: calcRefs(`${service}-${event.name}-agw-access-role`, context), + roleName: calcRefs(`${event.name}-agw-access-role`, context), description: calcRefs(`${service} role`, context), assumeRolePolicyDocument: { version: '1', @@ -60,9 +60,9 @@ export const resolveEvents = ( const apiGatewayGroup = new agw.RosGroup( scope, - calcRefs(`${service}_apigroup`, context), + formatRosId(`${event.key}_agw_group`), { - groupName: calcRefs(`${service}_apigroup`, context), + groupName: calcRefs(`${service}-agw-group`, context), tags: calcRefs(tags, context), passthroughHeaders: 'host', }, @@ -70,10 +70,10 @@ export const resolveEvents = ( ); if (event.domain) { - const dnsRecordRosId = `${event.key}_custom_domain_record_${encodeBase64ForRosId(event.domain.domain_name)}`; + const dnsRecordId = formatRosId(`${event.key}_agw_custom_domain_record`); const { domainName, rr } = splitDomain(event.domain?.domain_name); - new dns.DomainRecord(scope, dnsRecordRosId, { + new dns.DomainRecord(scope, dnsRecordId, { domainName, rr, type: 'CNAME', @@ -82,7 +82,7 @@ export const resolveEvents = ( const agwCustomDomain = new agw.RosCustomDomain( scope, - `${event.key}_custom_domain_${encodeBase64ForRosId(event.domain.domain_name)}`, + formatRosId(`${event.key}_agw_custom_domain`), { groupId: apiGatewayGroup.attrGroupId, domainName: event.domain.domain_name, @@ -92,17 +92,16 @@ export const resolveEvents = ( }, true, ); - agwCustomDomain.addRosDependency(dnsRecordRosId); + agwCustomDomain.addRosDependency(dnsRecordId); } event.triggers.forEach((trigger) => { - const key = encodeBase64ForRosId(calcRefs(`${trigger.method}_${trigger.path}`, context)); - + const key = formatRosId(calcValue(`${trigger.method}_${trigger.path}`, context)); const api = new agw.RosApi( scope, - `${event.key}_api_${key}`, + formatRosId(`${event.key}_agw_api_${key}`), { - apiName: calcRefs(`${event.name}_api_${key}`, context), + apiName: calcRefs(`${event.name}-agw-api-${key.replace(/_/g, '-')}`, context), groupId: apiGatewayGroup.attrGroupId, visibility: 'PRIVATE', authType: 'ANONYMOUS', @@ -130,11 +129,14 @@ export const resolveEvents = ( ); api.addDependsOn(apiGatewayGroup); - new agw.Deployment(scope, `${service}_deployment`, { + new agw.Deployment(scope, formatRosId(`${event.key}_agw_api_deployment_${key}`), { apiId: api.attrApiId, groupId: apiGatewayGroup.attrGroupId, stageName: 'RELEASE', - description: `${service} Api Gateway deployment`, + description: calcRefs( + `${service} Api Gateway deployment for api: ${trigger.method} ${trigger.path}`, + context, + ), }); }); }); diff --git a/src/stack/rosStack/function.ts b/src/stack/rosStack/function.ts index d7fc4a9..be0355e 100644 --- a/src/stack/rosStack/function.ts +++ b/src/stack/rosStack/function.ts @@ -6,12 +6,13 @@ import { ServerlessIac, } from '../../types'; import { + calcRefs, + calcValue, CODE_ZIP_SIZE_LIMIT, - encodeBase64ForRosId, + formatRosId, getFileSource, OSS_DEPLOYMENT_TIMEOUT, readCodeSize, - calcRefs, resolveCode, } from '../../common'; import * as fc from '@alicloud/ros-cdk-fc3'; @@ -76,6 +77,7 @@ const transformGpuConfig = (gpu: FunctionDomain['gpu']) => { return gpuConfigMap[gpu]; }; + export const resolveFunctions = ( scope: ros.Construct, functions: Array | undefined, @@ -89,19 +91,23 @@ export const resolveFunctions = ( let logConfig: RosFunction.LogConfigProperty | undefined = undefined; const enableLog = functions?.some(({ log }) => log); - const slsService = new sls.Project( + const slsProjectId = 'sls_project'; + const slsLogstoreId = 'sls_logstore'; + const slsIndexId = 'sls_index'; + + const slsProject = new sls.Project( scope, - `${service}_sls`, - { name: `${service}-sls`, tags: calcRefs(tags, context) }, + slsProjectId, + { name: calcRefs(`${service}-sls`, context), tags: calcRefs(tags, context) }, true, ); const slsLogstore = new sls.Logstore( scope, - `${service}_sls_logstore`, + slsLogstoreId, { - logstoreName: `${service}-sls-logstore`, - projectName: slsService.attrName, + logstoreName: calcRefs(`${service}-sls-logstore`, context), + projectName: slsProject.attrName, ttl: 7, }, true, @@ -109,9 +115,9 @@ export const resolveFunctions = ( new sls.Index( scope, - `${service}_sls_index`, + slsIndexId, { - projectName: slsService.attrName, + projectName: slsProject.attrName, logstoreName: slsLogstore.attrLogstoreName, fullTextIndex: { enable: true }, }, @@ -136,7 +142,7 @@ export const resolveFunctions = ( const destinationBucketName = ros.Fn.sub( 'si-bootstrap-artifacts-${ALIYUN::AccountId}-${ALIYUN::Region}', ); - const ossDeploymentId = `${service}_artifacts_code_deployment`; + const ossDeploymentId = 'si_auto_artifacts_code_deployment'; if (!isEmpty(fileSources)) { new ossDeployment.BucketDeployment( @@ -166,21 +172,22 @@ export const resolveFunctions = ( handler: RosFunctionProps['handler']; }; - const storeInBucket = !!fnc.code?.path && readCodeSize(fnc.code.path) > CODE_ZIP_SIZE_LIMIT; + const storeInBucket = + !!fnc.code?.path && readCodeSize(calcValue(fnc.code.path, context)) > CODE_ZIP_SIZE_LIMIT; if (fnc.container) { runtimeConfig = { runtime: 'custom-container', handler: 'index.handler', customContainerConfig: { - image: fnc.container.image, - command: fnc.container.cmd?.split(' '), - port: fnc.container.port, + image: calcRefs(fnc.container.image, context), + command: calcRefs(fnc.container.cmd, context)?.split(' '), + port: calcRefs(fnc.container.port, context), }, }; } else { let code: fc.RosFunction.CodeProperty = { - zipFile: resolveCode(fnc.code!.path), + zipFile: resolveCode(calcValue(fnc.code!.path, context)), }; if (storeInBucket) { code = { @@ -200,7 +207,7 @@ export const resolveFunctions = ( if (fnc.network) { const securityGroup = new ecs.SecurityGroup( scope, - `${fnc.key}_security_group`, + formatRosId(`${fnc.key}_security_group`), { securityGroupName: fnc.network.security_group.name, vpcId: calcRefs(fnc.network.vpc_id, context), @@ -222,16 +229,28 @@ export const resolveFunctions = ( } let fcNas: - | Array<{ nas: nas.FileSystem; nasMount: nas.MountTarget; mountDir: string }> + | Array<{ + nas: nas.FileSystem; + nasMount: nas.MountTarget; + mountDir: string; + nasMountTargetId: string; + }> | undefined; if (fnc.storage?.nas) { fcNas = fnc.storage.nas.map((nasItem) => { - const { fileSystemType, storageType } = storageClassMap[nasItem.storage_class]; + const storageClass = calcValue(nasItem.storage_class, context) as NasStorageClassEnum; + const { fileSystemType, storageType } = storageClassMap[storageClass]; + const mountPathValue = formatRosId(calcValue(nasItem.mount_path, context)); + const nasMountTargetId = formatRosId(`${fnc.key}_nas_mount_${mountPathValue}`); + const accessGroup = new nas.AccessGroup( scope, - `${fnc.key}_nas_access_${encodeBase64ForRosId(nasItem.mount_path)}`, + formatRosId(`${fnc.key}_nas_access_${mountPathValue}`), { - accessGroupName: `${fnc.name}-nas-access-${encodeBase64ForRosId(nasItem.mount_path)}`, + accessGroupName: calcRefs( + `${fnc.name}-nas-access-${mountPathValue.replace(/_/g, '-')}`, + context, + ), accessGroupType: 'Vpc', }, true, @@ -241,7 +260,7 @@ export const resolveFunctions = ( (subnet) => new vpc.datasource.VSwitch( scope, - `${fnc.key}_datasource_subnet_${encodeBase64ForRosId(subnet)}`, + formatRosId(calcValue(`${fnc.key}_datasource_subnet_${subnet}`, context)), { vSwitchId: subnet, refreshOptions: 'Always', @@ -252,7 +271,9 @@ export const resolveFunctions = ( fcVpcSubnets?.forEach((subnetDatasource, index) => { new nas.AccessRule( scope, - `${fnc.key}_nas_rule_${encodeBase64ForRosId(fnc.network!.subnet_ids[index])}`, + formatRosId( + calcValue(`${fnc.key}_nas_rule_${fnc.network!.subnet_ids[index]}`, context), + ), { accessGroupName: accessGroup.attrAccessGroupName, sourceCidrIp: subnetDatasource.attrCidrBlock, @@ -263,29 +284,37 @@ export const resolveFunctions = ( const nasResource = new nas.FileSystem( scope, - `${fnc.key}_nas_${encodeBase64ForRosId(nasItem.mount_path)}`, + formatRosId(`${fnc.key}_nas_${mountPathValue}`), { fileSystemType, storageType, protocolType: 'NFS', - tags: [...(calcRefs(tags, context) ?? []), { key: 'function-name', value: fnc.name }], + tags: [ + ...(calcRefs(tags, context) ?? []), + { key: 'function-name', value: calcRefs(fnc.name, context) }, + ], }, true, ); const nasMountTarget = new nas.MountTarget( scope, - `${fnc.key}_nas_mount_${encodeBase64ForRosId(nasItem.mount_path)}`, + nasMountTargetId, { fileSystemId: nasResource.attrFileSystemId, networkType: 'Vpc', accessGroupName: accessGroup.attrAccessGroupName, - vpcId: fnc.network!.vpc_id, - vSwitchId: fnc.network!.subnet_ids[0], + vpcId: calcRefs(fnc.network!.vpc_id, context), + vSwitchId: calcRefs(fnc.network!.subnet_ids[0], context), }, true, ); - return { nas: nasResource, nasMount: nasMountTarget, mountDir: nasItem.mount_path }; + return { + nas: nasResource, + nasMount: nasMountTarget, + mountDir: calcRefs(nasItem.mount_path, context), + nasMountTargetId, + }; }); } @@ -295,7 +324,7 @@ export const resolveFunctions = ( { functionName: calcRefs(fnc.name, context), memorySize: calcRefs(fnc.memory, context), - diskSize: fnc.storage?.disk, + diskSize: calcRefs(fnc.storage?.disk, context), gpuConfig: transformGpuConfig(fnc.gpu), timeout: calcRefs(fnc.timeout, context), environmentVariables: calcRefs(fnc.environment, context), @@ -314,18 +343,16 @@ export const resolveFunctions = ( true, ); if (enableLog) { - fcn.addRosDependency(`${service}_sls`); - fcn.addRosDependency(`${service}_sls_logstore`); - fcn.addRosDependency(`${service}_sls_index`); + fcn.addRosDependency(slsProjectId); + fcn.addRosDependency(slsLogstoreId); + fcn.addRosDependency(slsIndexId); } if (storeInBucket) { - fcn.addRosDependency(`${service}_artifacts_code_deployment`); + fcn.addRosDependency(ossDeploymentId); } if (fcNas?.length) { - fcNas.forEach((nasItem) => { - fcn.addRosDependency(`${fnc.key}_nas_mount_${encodeBase64ForRosId(nasItem.mountDir)}`); - }); + fcNas.forEach(({ nasMountTargetId }) => fcn.addRosDependency(nasMountTargetId)); } }); }; diff --git a/src/stack/rosStack/index.ts b/src/stack/rosStack/index.ts index 538b104..b832e6a 100644 --- a/src/stack/rosStack/index.ts +++ b/src/stack/rosStack/index.ts @@ -4,7 +4,7 @@ import { calcRefs } from '../../common'; import { resolveTags } from './tag'; import { resolveFunctions } from './function'; import { resolveStages } from './stage'; -import { resloveVars } from './vars'; +import { resolveVars } from './vars'; import { resolveDatabases } from './database'; import { resolveEvents } from './event'; import { resolveBuckets } from './bucket'; @@ -24,7 +24,7 @@ export class RosStack extends ros.Stack { new ros.RosInfo(this, ros.RosInfo.description, `${this.service} stack`); // Define Parameters - resloveVars(this, iac.vars); + resolveVars(this, iac.vars); // Define Mappings resolveStages(this, iac.stages, context); // Define functions diff --git a/src/stack/rosStack/vars.ts b/src/stack/rosStack/vars.ts index 39be434..e957c02 100644 --- a/src/stack/rosStack/vars.ts +++ b/src/stack/rosStack/vars.ts @@ -3,7 +3,7 @@ import { RosParameterType } from '@alicloud/ros-cdk-core'; import { Vars } from '../../types'; import { isEmpty } from 'lodash'; -export const resloveVars = (scope: ros.Construct, vars: Vars | undefined) => { +export const resolveVars = (scope: ros.Construct, vars: Vars | undefined) => { if (isEmpty(vars)) { return undefined; } diff --git a/tests/common/iacHelper.test.ts b/tests/common/iacHelper.test.ts index 7cd4370..2487a08 100644 --- a/tests/common/iacHelper.test.ts +++ b/tests/common/iacHelper.test.ts @@ -1,6 +1,6 @@ import * as ros from '@alicloud/ros-cdk-core'; import * as ossDeployment from '@alicloud/ros-cdk-ossdeployment'; -import { getFileSource, calcRefs, realValue } from '../../src/common'; +import { getFileSource, calcRefs, calcValue, formatRosId } from '../../src/common'; import fs from 'node:fs'; import { context } from '../fixtures/contextFixture'; @@ -79,43 +79,43 @@ describe('Unit test for iacHelper', () => { describe('Unit test for calcValue', () => { it('should return the value when raw string match vars', () => { - const value = realValue('${vars.handler}', context); + const value = calcValue('${vars.handler}', context); expect(value).toEqual('index.handler'); }); it('should return the value when raw string contains vars', () => { - const value = realValue('test-${vars.testVar}-value', context); + const value = calcValue('test-${vars.testVar}-value', context); expect(value).toEqual('test-testVarValue-value'); }); it('should return the value when raw string match stage', () => { - const value = realValue('${ctx.stage}', context); + const value = calcValue('${ctx.stage}', context); expect(value).toEqual('test'); }); it('should return the value when raw string contains stage', () => { - const value = realValue('test${ctx.stage}-value', context); + const value = calcValue('test${ctx.stage}-value', context); expect(value).toEqual('testtest-value'); }); it('should return the value when raw string match stages', () => { - const value = realValue('${stages.testStage}', context); + const value = calcValue('${stages.testStage}', context); expect(value).toEqual('testStageValue'); }); it('should return the value when raw string contains stages', () => { - const value = realValue('test-${stages.testStage}-value', context); + const value = calcValue('test-${stages.testStage}-value', context); expect(value).toEqual('test-testStageValue-value'); }); it('should return the value when raw string contains stage, vars and stages', () => { - const value = realValue( + const value = calcValue( `wearedongyiIASJ#test$\{stages.testStage}SUPERE$\{ctx.stage}ROR-AHID_#YOUD$\{vars.testVar}-value`, context, ); @@ -125,4 +125,31 @@ describe('Unit test for iacHelper', () => { ); }); }); + + describe('Unit test for formatRosId', () => { + it('should convert camelCase to snake_case', () => { + const result = formatRosId('helloWorld'); + expect(result).toEqual('hello_world'); + }); + + it('should remove leading underscore when first letter is capitalized', () => { + const result = formatRosId('HElloWORld'); + expect(result).toEqual('hello_world'); + }); + + it('should replace special characters with underscores', () => { + const result = formatRosId('hello/world#test,example-case'); + expect(result).toEqual('hello_world_test_example_case'); + }); + + it('should convert camelCase and replace special characters', () => { + const result = formatRosId('helloWorld/withSpecial#Chars'); + expect(result).toEqual('hello_world_with_special_chars'); + }); + + it('should not modify already snake_case strings without special chars', () => { + const result = formatRosId('hello_world'); + expect(result).toEqual('hello_world'); + }); + }); }); diff --git a/tests/fixtures/contextFixture.ts b/tests/fixtures/contextFixture.ts index 5139694..16941d7 100644 --- a/tests/fixtures/contextFixture.ts +++ b/tests/fixtures/contextFixture.ts @@ -23,3 +23,15 @@ export const context: Context = { }, tags: [{ key: 'owner', value: 'geekfun' }], }; + +export const defaultContext = { + accessKeyId: 'access key id', + accessKeySecret: 'access key secret', + iacLocation: expect.stringContaining('tests/fixtures/serverless-insight.yml'), + parameters: [], + region: 'cn-hangzhou', + provider: ProviderEnum.ALIYUN, + securityToken: 'account id', + stackName: 'my-demo-stack', + stage: 'default', +}; diff --git a/tests/fixtures/deploy-fixtures/bucketMinimum.ts b/tests/fixtures/deploy-fixtures/bucketMinimum.ts new file mode 100644 index 0000000..4615d93 --- /dev/null +++ b/tests/fixtures/deploy-fixtures/bucketMinimum.ts @@ -0,0 +1,34 @@ +import { ServerlessIac } from '../../../src/types'; + +export const bucketMinimumIac = { + version: '0.0.1', + provider: { + name: 'aliyun', + region: 'cn-hangzhou', + }, + service: 'my-bucket-service', + buckets: [ + { + key: 'my_bucket', + name: 'my-bucket', + }, + ], +} as unknown as ServerlessIac; + +export const bucketMinimumRos = { + Description: 'my-bucket-service stack', + Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } }, + ROSTemplateFormatVersion: '2015-09-01', + Resources: { + my_bucket: { + Properties: { + BucketName: 'my-bucket', + AccessControl: 'private', + DeletionForce: false, + EnableOssHdfsService: false, + RedundancyType: 'LRS', + }, + Type: 'ALIYUN::OSS::Bucket', + }, + }, +}; diff --git a/tests/fixtures/deploy-fixtures/bucketWithWebsite.ts b/tests/fixtures/deploy-fixtures/bucketWithWebsite.ts new file mode 100644 index 0000000..84784c9 --- /dev/null +++ b/tests/fixtures/deploy-fixtures/bucketWithWebsite.ts @@ -0,0 +1,199 @@ +import { ServerlessIac } from '../../../src/types'; + +export const bucketWithWebsiteIac = { + version: '0.0.1', + provider: { + name: 'aliyun', + region: 'cn-hangzhou', + }, + service: 'my-bucket-service', + buckets: [ + { + key: 'my_bucket', + name: 'my-bucket', + website: { + code: 'tests/fixtures/artifacts/large-artifact.zip', + domain: 'my-bucket.com', + index: 'index.html', + error_page: '404.html', + error_code: 404, + }, + }, + ], +} as ServerlessIac; + +export const bucketWithWebsiteRos = { + Description: 'my-bucket-service stack', + Metadata: { + 'ALIYUN::ROS::Interface': { + TemplateTags: ['Create by ROS CDK'], + }, + }, + ROSTemplateFormatVersion: '2015-09-01', + Resources: { + FCFunctionForsi_auto_my_bucket_bucket_code_deployment: { + Properties: { + CAPort: 9000, + Code: { + OssBucketName: { + 'Fn::Sub': expect.any(String), + }, + OssObjectName: 'c6a72ed7e7e83f01a000b75885758088fa050298a31a1e95d37ac88f08e42315.zip', + }, + FunctionName: { + 'Fn::Join': [ + '-', + [ + 'ros-cdk', + { + 'Fn::Select': [ + 0, + { + 'Fn::Split': [ + '-', + { + Ref: 'ALIYUN::StackId', + }, + ], + }, + ], + }, + ], + ], + }, + Handler: 'index.handler', + MemorySize: 128, + Runtime: 'python3.10', + ServiceName: { + 'Fn::GetAtt': ['FCServiceForsi_auto_my_bucket_bucket_code_deployment', 'ServiceName'], + }, + Timeout: 3000, + }, + Type: 'ALIYUN::FC::Function', + }, + FCServiceForsi_auto_my_bucket_bucket_code_deployment: { + Properties: { + DeletionForce: false, + Description: 'FC service for oss deployment by CDK', + Role: { + 'Fn::GetAtt': ['si_auto_od_bucket_role', 'Arn'], + }, + ServiceName: { + 'Fn::Join': [ + '-', + [ + 'ros-cdk', + { + 'Fn::Select': [ + 0, + { + 'Fn::Split': [ + '-', + { + Ref: 'ALIYUN::StackId', + }, + ], + }, + ], + }, + ], + ], + }, + }, + Type: 'ALIYUN::FC::Service', + }, + my_bucket: { + Properties: { + AccessControl: 'private', + BucketName: 'my-bucket', + DeletionForce: false, + EnableOssHdfsService: false, + RedundancyType: 'LRS', + WebsiteConfigurationV2: { + ErrorDocument: { + HttpStatus: '404', + Key: '404.html', + }, + IndexDocument: { + Suffix: 'index.html', + SupportSubDir: 'true', + Type: '0', + }, + }, + }, + Type: 'ALIYUN::OSS::Bucket', + }, + my_bucket_custom_domain: { + Properties: { + BucketName: { + 'Fn::GetAtt': ['my_bucket', 'Name'], + }, + DomainName: 'my-bucket.com', + }, + Type: 'ALIYUN::OSS::Domain', + }, + my_bucket_custom_domain_record: { + Properties: { + DomainName: 'my-bucket.com', + RR: '@', + TTL: 600, + Type: 'CNAME', + Value: { + 'Fn::GetAtt': ['my_bucket', 'InternalDomainName'], + }, + }, + Type: 'ALIYUN::DNS::DomainRecord', + }, + si_auto_my_bucket_bucket_code_deployment: { + Properties: { + Parameters: { + destinationBucket: { + 'Fn::GetAtt': ['my_bucket', 'Name'], + }, + retainOnCreate: false, + sources: [ + { + bucket: { + 'Fn::Sub': expect.any(String), + }, + fileName: 'large-artifact.zip', + objectKey: '2bfeafed8d3df0d44c235271cdf2aa7d908a3c2757af14a67d33d102847f46fd.zip', + }, + ], + }, + ServiceToken: { + 'Fn::GetAtt': ['FCFunctionForsi_auto_my_bucket_bucket_code_deployment', 'ARN'], + }, + Timeout: 3000, + }, + Type: 'ALIYUN::ROS::CustomResource', + }, + si_auto_od_bucket_role: { + Properties: { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: ['fc.aliyuncs.com'], + }, + }, + ], + Version: '1', + }, + DeletionForce: false, + Description: + 'roles created by ServerlessInsight for oss deployment to put files to oss bucket during deployment', + IgnoreExisting: false, + PolicyAttachments: { + System: ['AliyunOSSFullAccess', 'AliyunLogFullAccess'], + }, + RoleName: { + 'Fn::Sub': 'si-auto-od-bucket-role-${ALIYUN::StackId}', + }, + }, + Type: 'ALIYUN::RAM::Role', + }, + }, +}; diff --git a/tests/fixtures/deploy-fixtures/esMinimum.ts b/tests/fixtures/deploy-fixtures/esMinimum.ts new file mode 100644 index 0000000..90a93fd --- /dev/null +++ b/tests/fixtures/deploy-fixtures/esMinimum.ts @@ -0,0 +1,64 @@ +import { ProviderEnum } from '../../../src/common'; +import { DatabaseEnum, DatabaseVersionEnum, ServerlessIac } from '../../../src/types'; + +export const esServerlessMinimumIac = { + service: 'my-demo-es-serverless-service', + version: '0.0.1', + provider: { + name: 'aliyun' as ProviderEnum, + region: 'cn-hangzhou', + }, + databases: [ + { + key: 'insight_es_db_test', + name: 'insight-poc-es-test', + type: DatabaseEnum.ELASTICSEARCH_SERVERLESS, + version: DatabaseVersionEnum['ES_SEARCH_7.10'], + security: { + basicAuth: { + username: 'test-username', + password: 'test-password', + }, + }, + cu: { min: 1, max: 8 }, + storage: { min: 20 }, + }, + ], +} as unknown as ServerlessIac; + +export const esServerlessMinimumRos = { + Description: 'my-demo-es-serverless-service stack', + Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } }, + ROSTemplateFormatVersion: '2015-09-01', + Resources: { + insight_es_db_test: { + Properties: { + AppName: 'insight-poc-es-test', + AppVersion: '7.10', + Authentication: { + BasicAuth: [ + { + Password: 'test-password', + }, + ], + }, + QuotaInfo: { + AppType: 'STANDARD', + Cu: 1, + Storage: 20, + }, + // Network: [ + // { + // Enabled: true, + // Type: 'PUBLIC_KIBANA', + // }, + // { + // Enabled: true, + // Type: 'PUBLIC_ES', + // }, + // ], + }, + Type: 'ALIYUN::ElasticSearchServerless::App', + }, + }, +}; diff --git a/tests/fixtures/deploy-fixtures/index.ts b/tests/fixtures/deploy-fixtures/index.ts new file mode 100644 index 0000000..0f13837 --- /dev/null +++ b/tests/fixtures/deploy-fixtures/index.ts @@ -0,0 +1,12 @@ +export * from './bucketMinimum'; +export * from './bucketWithWebsite'; +export * from './esMinimum'; +export * from './minimum'; +export * from './oneFc'; +export * from './oneFcLargeCode'; +export * from './oneFcOneGateway'; +export * from './oneFcWithContainer'; +export * from './oneFcWithGpu'; +export * from './oneFcWithNas'; +export * from './oneFcWithStage'; +export * from './referredService'; diff --git a/tests/fixtures/deploy-fixtures/minimum.ts b/tests/fixtures/deploy-fixtures/minimum.ts new file mode 100644 index 0000000..dbcbfca --- /dev/null +++ b/tests/fixtures/deploy-fixtures/minimum.ts @@ -0,0 +1,78 @@ +import { ProviderEnum } from '../../../src/common'; +import { ServerlessIac } from '../../../src/types'; + +export const minimumIac = { + service: 'my-demo-minimum-service', + version: '0.0.1', + provider: { + name: 'aliyun' as ProviderEnum, + region: 'cn-hangzhou', + }, + + functions: [ + { + key: 'hello_fn', + name: 'hello-fn', + code: { + runtime: 'nodejs18', + handler: 'index.handler', + path: 'tests/fixtures/artifacts/artifact.zip', + }, + }, + ], +} as ServerlessIac; + +export const minimumRos = { + Description: 'my-demo-minimum-service stack', + Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } }, + ROSTemplateFormatVersion: '2015-09-01', + Resources: { + sls_project: { + Properties: { + Name: 'my-demo-minimum-service-sls', + }, + Type: 'ALIYUN::SLS::Project', + }, + sls_index: { + Properties: { + FullTextIndex: { + Enable: true, + }, + LogReduce: false, + LogstoreName: { + 'Fn::GetAtt': ['sls_logstore', 'LogstoreName'], + }, + ProjectName: { + 'Fn::GetAtt': ['sls_project', 'Name'], + }, + }, + Type: 'ALIYUN::SLS::Index', + }, + sls_logstore: { + Properties: { + AppendMeta: false, + AutoSplit: false, + EnableTracking: false, + LogstoreName: 'my-demo-minimum-service-sls-logstore', + PreserveStorage: false, + ProjectName: { + 'Fn::GetAtt': ['sls_project', 'Name'], + }, + ShardCount: 2, + TTL: 7, + }, + Type: 'ALIYUN::SLS::Logstore', + }, + hello_fn: { + Properties: { + Code: { + ZipFile: 'resolved-code', + }, + FunctionName: 'hello-fn', + Handler: 'index.handler', + Runtime: 'nodejs18', + }, + Type: 'ALIYUN::FC3::Function', + }, + }, +}; diff --git a/tests/fixtures/deploy-fixtures/oneFc.ts b/tests/fixtures/deploy-fixtures/oneFc.ts new file mode 100644 index 0000000..194c467 --- /dev/null +++ b/tests/fixtures/deploy-fixtures/oneFc.ts @@ -0,0 +1,134 @@ +import { ServerlessIac } from '../../../src/types'; +import { ProviderEnum } from '../../../src/common'; + +export const oneFcIac = { + service: 'my-demo-service', + version: '0.0.1', + provider: { + name: 'aliyun' as ProviderEnum, + region: 'cn-hangzhou', + }, + vars: { + account_id: 1234567890, + }, + stages: { + dev: { + region: '${vars.region}', + account_id: '${vars.account_id}', + }, + }, + functions: [ + { + key: 'hello_fn', + name: 'hello-fn', + code: { + runtime: 'nodejs18', + handler: 'index.handler', + path: 'tests/fixtures/artifacts/artifact.zip', + }, + memory: 128, + timeout: 10, + log: true, + environment: { + NODE_ENV: 'production', + }, + storage: {}, + }, + ], + tags: [ + { + key: 'owner', + value: 'geek-fun', + }, + ], +} as ServerlessIac; + +export const oneFcRos = { + Description: 'my-demo-service stack', + Mappings: { + stages: { + dev: { + account_id: { Ref: 'account_id' }, + region: { Ref: 'region' }, + }, + }, + }, + Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } }, + Parameters: { + account_id: { + Default: 1234567890, + Type: 'String', + }, + }, + ROSTemplateFormatVersion: '2015-09-01', + Resources: { + hello_fn: { + DependsOn: ['sls_project', 'sls_logstore', 'sls_index'], + Properties: { + Code: { + ZipFile: 'resolved-code', + }, + EnvironmentVariables: { + NODE_ENV: 'production', + }, + FunctionName: 'hello-fn', + Handler: 'index.handler', + LogConfig: { + EnableRequestMetrics: true, + Logstore: { + 'Fn::GetAtt': ['sls_logstore', 'LogstoreName'], + }, + Project: { + 'Fn::GetAtt': ['sls_logstore', 'ProjectName'], + }, + }, + MemorySize: 128, + Runtime: 'nodejs18', + Timeout: 10, + }, + Type: 'ALIYUN::FC3::Function', + }, + sls_project: { + Properties: { + Name: 'my-demo-service-sls', + Tags: [ + { + Key: 'owner', + Value: 'geek-fun', + }, + ], + }, + Type: 'ALIYUN::SLS::Project', + }, + sls_index: { + Properties: { + FullTextIndex: { + Enable: true, + }, + LogReduce: false, + LogstoreName: { + 'Fn::GetAtt': ['sls_logstore', 'LogstoreName'], + }, + ProjectName: { + 'Fn::GetAtt': ['sls_project', 'Name'], + }, + }, + Type: 'ALIYUN::SLS::Index', + }, + sls_logstore: { + Properties: { + AppendMeta: false, + AutoSplit: false, + EnableTracking: false, + LogstoreName: 'my-demo-service-sls-logstore', + PreserveStorage: false, + ProjectName: { + 'Fn::GetAtt': ['sls_project', 'Name'], + }, + ShardCount: 2, + TTL: 7, + }, + Type: 'ALIYUN::SLS::Logstore', + }, + }, +}; diff --git a/tests/fixtures/deploy-fixtures/oneFcLargeCode.ts b/tests/fixtures/deploy-fixtures/oneFcLargeCode.ts new file mode 100644 index 0000000..b1003e9 --- /dev/null +++ b/tests/fixtures/deploy-fixtures/oneFcLargeCode.ts @@ -0,0 +1,396 @@ +export const largeCodeRos = { + Description: 'my-demo-service stack', + Mappings: { + stages: { + dev: { + account_id: { + Ref: 'account_id', + }, + region: { + Ref: 'region', + }, + }, + }, + }, + Metadata: { + 'ALIYUN::ROS::Interface': { + TemplateTags: ['Create by ROS CDK'], + }, + }, + Parameters: { + account_id: { + Default: 1234567890, + Type: 'String', + }, + }, + ROSTemplateFormatVersion: '2015-09-01', + Resources: { + FCFunctionForsi_auto_artifacts_code_deployment: { + Properties: { + CAPort: 9000, + Code: { + OssBucketName: { 'Fn::Sub': expect.stringContaining('assets-${ALIYUN::Region}') }, + OssObjectName: 'c6a72ed7e7e83f01a000b75885758088fa050298a31a1e95d37ac88f08e42315.zip', + }, + FunctionName: { + 'Fn::Join': [ + '-', + [ + 'ros-cdk', + { + 'Fn::Select': [ + 0, + { + 'Fn::Split': [ + '-', + { + Ref: 'ALIYUN::StackId', + }, + ], + }, + ], + }, + ], + ], + }, + Handler: 'index.handler', + MemorySize: 128, + Runtime: 'python3.10', + ServiceName: { + 'Fn::GetAtt': ['FCServiceForsi_auto_artifacts_code_deployment', 'ServiceName'], + }, + Timeout: 3000, + }, + Type: 'ALIYUN::FC::Function', + }, + FCRoleForsi_auto_artifacts_code_deployment: { + Properties: { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: ['fc.aliyuncs.com'], + }, + }, + ], + Version: '1', + }, + DeletionForce: false, + IgnoreExisting: false, + Policies: [ + { + PolicyDocument: { + Statement: [ + { + Action: ['oss:*'], + Effect: 'Allow', + Resource: ['*'], + }, + ], + Version: '1', + }, + PolicyName: 'AliyunOSSFullAccess', + }, + { + PolicyDocument: { + Statement: [ + { + Action: ['log:*'], + Effect: 'Allow', + Resource: ['*'], + }, + { + Action: ['ram:CreateServiceLinkedRole'], + Condition: { + StringEquals: { + 'ram:ServiceName': [ + 'audit.log.aliyuncs.com', + 'alert.log.aliyuncs.com', + 'middlewarelens.log.aliyuncs.com', + 'storagelens.log.aliyuncs.com', + 'ai-lens.log.aliyuncs.com', + 'securitylens.log.aliyuncs.com', + ], + }, + }, + Effect: 'Allow', + Resource: ['*'], + }, + ], + Version: '1', + }, + PolicyName: 'AliyunLogFullAccess', + }, + ], + RoleName: { + 'Fn::Join': [ + '-', + [ + 'ros-cdk', + { + 'Fn::Select': [ + 0, + { + 'Fn::Split': [ + '-', + { + Ref: 'ALIYUN::StackId', + }, + ], + }, + ], + }, + ], + ], + }, + }, + Type: 'ALIYUN::RAM::Role', + }, + FCServiceForsi_auto_artifacts_code_deployment: { + Properties: { + DeletionForce: false, + Description: 'FC service for oss deployment by CDK', + Role: { + 'Fn::GetAtt': ['FCRoleForsi_auto_artifacts_code_deployment', 'Arn'], + }, + ServiceName: { + 'Fn::Join': [ + '-', + [ + 'ros-cdk', + { + 'Fn::Select': [ + 0, + { + 'Fn::Split': [ + '-', + { + Ref: 'ALIYUN::StackId', + }, + ], + }, + ], + }, + ], + ], + }, + }, + Type: 'ALIYUN::FC::Service', + }, + gateway_event_agw_api_deployment_get_api_hello: { + Properties: { + ApiId: { + 'Fn::GetAtt': ['gateway_event_agw_api_get_api_hello', 'ApiId'], + }, + Description: 'my-demo-service Api Gateway deployment for api: GET /api/hello', + GroupId: { + 'Fn::GetAtt': ['gateway_event_agw_group', 'GroupId'], + }, + StageName: 'RELEASE', + }, + Type: 'ALIYUN::ApiGateway::Deployment', + }, + gateway_event_agw_api_get_api_hello: { + Properties: { + ApiName: 'gateway-event-agw-api-get-api-hello', + AuthType: 'ANONYMOUS', + GroupId: { + 'Fn::GetAtt': ['gateway_event_agw_group', 'GroupId'], + }, + RequestConfig: { + RequestHttpMethod: 'GET', + RequestMode: 'PASSTHROUGH', + RequestPath: '/api/hello', + RequestProtocol: 'HTTP', + }, + ResultSample: 'ServerlessInsight resultSample', + ResultType: 'PASSTHROUGH', + ServiceConfig: { + FunctionComputeConfig: { + FcVersion: '3.0', + FunctionName: { + 'Fn::GetAtt': ['hello_fn', 'FunctionName'], + }, + Method: 'GET', + RoleArn: { + 'Fn::GetAtt': ['gateway_event_agw_role', 'Arn'], + }, + }, + ServiceProtocol: 'FunctionCompute', + }, + Tags: [ + { + Key: 'owner', + Value: 'geek-fun', + }, + ], + Visibility: 'PRIVATE', + }, + Type: 'ALIYUN::ApiGateway::Api', + }, + hello_fn: { + DependsOn: ['sls_project', 'sls_logstore', 'sls_index', 'si_auto_artifacts_code_deployment'], + Properties: { + Code: { + OssBucketName: { + 'Fn::Sub': 'si-bootstrap-artifacts-${ALIYUN::AccountId}-${ALIYUN::Region}', + }, + OssObjectName: 'hello-fn/43cb4c356149762dbe507fc1baede172-large-artifact.zip', + }, + EnvironmentVariables: { + NODE_ENV: 'production', + }, + FunctionName: 'hello-fn', + Handler: 'index.handler', + LogConfig: { + EnableRequestMetrics: true, + Logstore: { + 'Fn::GetAtt': ['sls_logstore', 'LogstoreName'], + }, + Project: { + 'Fn::GetAtt': ['sls_logstore', 'ProjectName'], + }, + }, + MemorySize: 128, + Runtime: 'nodejs18', + Timeout: 10, + }, + Type: 'ALIYUN::FC3::Function', + }, + si_auto_artifacts_code_deployment: { + Properties: { + Parameters: { + destinationBucket: { + 'Fn::Sub': 'si-bootstrap-artifacts-${ALIYUN::AccountId}-${ALIYUN::Region}', + }, + retainOnCreate: false, + sources: [ + { + bucket: { 'Fn::Sub': expect.any(String) }, + fileName: 'hello-fn/43cb4c356149762dbe507fc1baede172-large-artifact.zip', + objectKey: '2bfeafed8d3df0d44c235271cdf2aa7d908a3c2757af14a67d33d102847f46fd.zip', + }, + ], + }, + ServiceToken: { + 'Fn::GetAtt': ['FCFunctionForsi_auto_artifacts_code_deployment', 'ARN'], + }, + Timeout: 3000, + }, + Type: 'ALIYUN::ROS::CustomResource', + }, + gateway_event_agw_custom_domain: { + DependsOn: ['gateway_event_agw_custom_domain_record'], + Properties: { + DomainName: 'api.my-demo-service.com', + GroupId: { + 'Fn::GetAtt': ['gateway_event_agw_group', 'GroupId'], + }, + }, + Type: 'ALIYUN::ApiGateway::CustomDomain', + }, + gateway_event_agw_custom_domain_record: { + Properties: { + DomainName: 'my-demo-service.com', + RR: 'api', + TTL: 600, + Type: 'CNAME', + Value: { + 'Fn::GetAtt': ['gateway_event_agw_group', 'SubDomain'], + }, + }, + Type: 'ALIYUN::DNS::DomainRecord', + }, + gateway_event_agw_group: { + Properties: { + GroupName: 'my-demo-service-agw-group', + PassthroughHeaders: 'host', + Tags: [ + { + Key: 'owner', + Value: 'geek-fun', + }, + ], + }, + Type: 'ALIYUN::ApiGateway::Group', + }, + gateway_event_agw_role: { + Properties: { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: ['apigateway.aliyuncs.com'], + }, + }, + ], + Version: '1', + }, + Description: 'my-demo-service role', + Policies: [ + { + PolicyDocument: { + Statement: [ + { + Action: ['fc:InvokeFunction'], + Effect: 'Allow', + Resource: ['*'], + }, + ], + Version: '1', + }, + PolicyName: 'my-demo-service-gateway-event-policy', + }, + ], + RoleName: 'gateway-event-agw-access-role', + }, + Type: 'ALIYUN::RAM::Role', + }, + sls_project: { + Properties: { + Name: 'my-demo-service-sls', + Tags: [ + { + Key: 'owner', + Value: 'geek-fun', + }, + ], + }, + Type: 'ALIYUN::SLS::Project', + }, + sls_index: { + Properties: { + FullTextIndex: { + Enable: true, + }, + LogReduce: false, + LogstoreName: { + 'Fn::GetAtt': ['sls_logstore', 'LogstoreName'], + }, + ProjectName: { + 'Fn::GetAtt': ['sls_project', 'Name'], + }, + }, + Type: 'ALIYUN::SLS::Index', + }, + sls_logstore: { + Properties: { + AppendMeta: false, + AutoSplit: false, + EnableTracking: false, + LogstoreName: 'my-demo-service-sls-logstore', + PreserveStorage: false, + ProjectName: { + 'Fn::GetAtt': ['sls_project', 'Name'], + }, + ShardCount: 2, + TTL: 7, + }, + Type: 'ALIYUN::SLS::Logstore', + }, + }, +}; diff --git a/tests/fixtures/deploy-fixtures/oneFcOneGateway.ts b/tests/fixtures/deploy-fixtures/oneFcOneGateway.ts new file mode 100644 index 0000000..9336c57 --- /dev/null +++ b/tests/fixtures/deploy-fixtures/oneFcOneGateway.ts @@ -0,0 +1,279 @@ +import { ProviderEnum } from '../../../src/common'; +import { ServerlessIac } from '../../../src/types'; + +export const oneFcOneGatewayIac = { + service: 'my-demo-service', + version: '0.0.1', + provider: { + name: 'aliyun' as ProviderEnum, + region: 'cn-hangzhou', + }, + vars: { + account_id: 1234567890, + }, + stages: { + dev: { + region: '${vars.region}', + account_id: '${vars.account_id}', + }, + }, + functions: [ + { + key: 'hello_fn', + name: 'hello-fn', + code: { + runtime: 'nodejs18', + handler: 'index.handler', + path: 'tests/fixtures/artifacts/artifact.zip', + }, + memory: 128, + timeout: 10, + log: true, + environment: { + NODE_ENV: 'production', + }, + storage: {}, + }, + ], + events: [ + { + type: 'API_GATEWAY', + key: 'gateway_event', + name: 'gateway-event', + domain: { + domain_name: 'api.my-demo-service.com', + }, + triggers: [ + { + method: 'GET', + path: '/api/hello', + backend: '${functions.hello_fn}', + }, + ], + }, + ], + tags: [ + { + key: 'owner', + value: 'geek-fun', + }, + ], +} as ServerlessIac; + +export const oneFcOneGatewayRos = { + Description: 'my-demo-service stack', + Mappings: { + stages: { + dev: { + account_id: { + Ref: 'account_id', + }, + region: { + Ref: 'region', + }, + }, + }, + }, + Metadata: { + 'ALIYUN::ROS::Interface': { + TemplateTags: ['Create by ROS CDK'], + }, + }, + Parameters: { + account_id: { + Default: 1234567890, + Type: 'String', + }, + }, + ROSTemplateFormatVersion: '2015-09-01', + Resources: { + gateway_event_agw_api_deployment_get_api_hello: { + Properties: { + ApiId: { + 'Fn::GetAtt': ['gateway_event_agw_api_get_api_hello', 'ApiId'], + }, + Description: 'my-demo-service Api Gateway deployment for api: GET /api/hello', + GroupId: { + 'Fn::GetAtt': ['gateway_event_agw_group', 'GroupId'], + }, + StageName: 'RELEASE', + }, + Type: 'ALIYUN::ApiGateway::Deployment', + }, + gateway_event_agw_api_get_api_hello: { + Properties: { + ApiName: 'gateway-event-agw-api-get-api-hello', + AuthType: 'ANONYMOUS', + GroupId: { + 'Fn::GetAtt': ['gateway_event_agw_group', 'GroupId'], + }, + RequestConfig: { + RequestHttpMethod: 'GET', + RequestMode: 'PASSTHROUGH', + RequestPath: '/api/hello', + RequestProtocol: 'HTTP', + }, + ResultSample: 'ServerlessInsight resultSample', + ResultType: 'PASSTHROUGH', + ServiceConfig: { + FunctionComputeConfig: { + FcVersion: '3.0', + FunctionName: { + 'Fn::GetAtt': ['hello_fn', 'FunctionName'], + }, + Method: 'GET', + RoleArn: { + 'Fn::GetAtt': ['gateway_event_agw_role', 'Arn'], + }, + }, + ServiceProtocol: 'FunctionCompute', + }, + Tags: [ + { + Key: 'owner', + Value: 'geek-fun', + }, + ], + Visibility: 'PRIVATE', + }, + Type: 'ALIYUN::ApiGateway::Api', + }, + gateway_event_agw_custom_domain: { + DependsOn: ['gateway_event_agw_custom_domain_record'], + Properties: { + DomainName: 'api.my-demo-service.com', + GroupId: { + 'Fn::GetAtt': ['gateway_event_agw_group', 'GroupId'], + }, + }, + Type: 'ALIYUN::ApiGateway::CustomDomain', + }, + gateway_event_agw_custom_domain_record: { + Properties: { + DomainName: 'my-demo-service.com', + RR: 'api', + TTL: 600, + Type: 'CNAME', + Value: { + 'Fn::GetAtt': ['gateway_event_agw_group', 'SubDomain'], + }, + }, + Type: 'ALIYUN::DNS::DomainRecord', + }, + gateway_event_agw_group: { + Properties: { + GroupName: 'my-demo-service-agw-group', + PassthroughHeaders: 'host', + Tags: [ + { + Key: 'owner', + Value: 'geek-fun', + }, + ], + }, + Type: 'ALIYUN::ApiGateway::Group', + }, + gateway_event_agw_role: { + Properties: { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: ['apigateway.aliyuncs.com'], + }, + }, + ], + Version: '1', + }, + Description: 'my-demo-service role', + Policies: [ + { + PolicyDocument: { + Statement: [ + { + Action: ['fc:InvokeFunction'], + Effect: 'Allow', + Resource: ['*'], + }, + ], + Version: '1', + }, + PolicyName: 'my-demo-service-gateway-event-policy', + }, + ], + RoleName: 'gateway-event-agw-access-role', + }, + Type: 'ALIYUN::RAM::Role', + }, + hello_fn: { + DependsOn: ['sls_project', 'sls_logstore', 'sls_index'], + Properties: { + Code: { + ZipFile: 'resolved-code', + }, + EnvironmentVariables: { + NODE_ENV: 'production', + }, + FunctionName: 'hello-fn', + Handler: 'index.handler', + LogConfig: { + EnableRequestMetrics: true, + Logstore: { + 'Fn::GetAtt': ['sls_logstore', 'LogstoreName'], + }, + Project: { + 'Fn::GetAtt': ['sls_logstore', 'ProjectName'], + }, + }, + MemorySize: 128, + Runtime: 'nodejs18', + Timeout: 10, + }, + Type: 'ALIYUN::FC3::Function', + }, + sls_project: { + Properties: { + Name: 'my-demo-service-sls', + Tags: [ + { + Key: 'owner', + Value: 'geek-fun', + }, + ], + }, + Type: 'ALIYUN::SLS::Project', + }, + sls_index: { + Properties: { + FullTextIndex: { + Enable: true, + }, + LogReduce: false, + LogstoreName: { + 'Fn::GetAtt': ['sls_logstore', 'LogstoreName'], + }, + ProjectName: { + 'Fn::GetAtt': ['sls_project', 'Name'], + }, + }, + Type: 'ALIYUN::SLS::Index', + }, + sls_logstore: { + Properties: { + AppendMeta: false, + AutoSplit: false, + EnableTracking: false, + LogstoreName: 'my-demo-service-sls-logstore', + PreserveStorage: false, + ProjectName: { + 'Fn::GetAtt': ['sls_project', 'Name'], + }, + ShardCount: 2, + TTL: 7, + }, + Type: 'ALIYUN::SLS::Logstore', + }, + }, +}; diff --git a/tests/fixtures/deploy-fixtures/oneFcWithContainer.ts b/tests/fixtures/deploy-fixtures/oneFcWithContainer.ts new file mode 100644 index 0000000..2bd848a --- /dev/null +++ b/tests/fixtures/deploy-fixtures/oneFcWithContainer.ts @@ -0,0 +1,37 @@ +import { ServerlessIac } from '../../../src/types'; +import { oneFcIac, oneFcRos } from './oneFc'; + +export const oneFcWithContainerIac = { + ...oneFcIac, + functions: [ + { + ...((oneFcIac.functions && oneFcIac.functions[0]) ?? {}), + code: undefined, + container: { + image: 'registry.cn-hangzhou.aliyuncs.com/aliyunfc/abcd:1.6.0', + cmd: 'npm start', + port: 9200, + }, + }, + ], +} as ServerlessIac; + +export const oneFcWithContainerRos = { + ...oneFcRos, + Resources: { + ...oneFcRos.Resources, + hello_fn: { + ...oneFcRos.Resources.hello_fn, + Properties: { + ...oneFcRos.Resources.hello_fn.Properties, + Code: undefined, + Runtime: 'custom-container', + CustomContainerConfig: { + Command: ['npm', 'start'], + Image: 'registry.cn-hangzhou.aliyuncs.com/aliyunfc/abcd:1.6.0', + Port: 9200, + }, + }, + }, + }, +}; diff --git a/tests/fixtures/deploy-fixtures/oneFcWithGpu.ts b/tests/fixtures/deploy-fixtures/oneFcWithGpu.ts new file mode 100644 index 0000000..16fd38c --- /dev/null +++ b/tests/fixtures/deploy-fixtures/oneFcWithGpu.ts @@ -0,0 +1,28 @@ +import { ServerlessIac } from '../../../src/types'; +import { oneFcIac, oneFcRos } from './oneFc'; + +export const oneFcWithGpuIac = { + ...oneFcIac, + functions: [ + { + ...((oneFcIac.functions && oneFcIac.functions[0]) ?? {}), + gpu: 'TESLA_8', + }, + ], +} as ServerlessIac; +export const oneFcWithGpuRos = { + ...oneFcRos, + Resources: { + ...oneFcRos.Resources, + hello_fn: { + ...oneFcRos.Resources.hello_fn, + Properties: { + ...oneFcRos.Resources.hello_fn.Properties, + GpuConfig: { + GpuMemorySize: 8192, + GpuType: 'fc.gpu.tesla.1', + }, + }, + }, + }, +}; diff --git a/tests/fixtures/deploy-fixtures/oneFcWithNas.ts b/tests/fixtures/deploy-fixtures/oneFcWithNas.ts new file mode 100644 index 0000000..04e5bd9 --- /dev/null +++ b/tests/fixtures/deploy-fixtures/oneFcWithNas.ts @@ -0,0 +1,222 @@ +import { ServerlessIac } from '../../../src/types'; +import { oneFcIac, oneFcRos } from './oneFc'; + +export const oneFcIacWithNas = { + ...oneFcIac, + functions: [ + { + ...((oneFcIac.functions && oneFcIac.functions[0]) ?? {}), + network: { + vpc_id: 'vpc-123456', + subnet_ids: ['subnet-123456', 'subnet-67890', 'subnet-98765'], + security_group: { + name: 'my-security-group', + ingress: [ + 'TCP:0.0.0.0/0:80', + 'TCP:0.0.0.0/0:443', + 'TCP:0.0.0.0/0:22/22', + 'ICMP:0.0.0.0/0:ALL', + ], + egress: ['ALL:0.0.0.0/0:ALL'], + }, + }, + storage: { + nas: [ + { + mount_path: '/mnt/nas', + storage_class: 'STANDARD_CAPACITY', + }, + ], + }, + }, + ], +} as ServerlessIac; + +export const oneFcIacWithNasRos = { + ...oneFcRos, + Resources: { + ...oneFcRos.Resources, + hello_fn: { + Type: 'ALIYUN::FC3::Function', + Properties: { + ...oneFcRos.Resources.hello_fn.Properties, + NasConfig: { + MountPoints: [ + { + MountDir: '/mnt/nas', + ServerAddr: { + 'Fn::Join': [ + '', + [ + { + 'Fn::GetAtt': ['hello_fn_nas_mount_mnt_nas', 'MountTargetDomain'], + }, + ':/', + ], + ], + }, + }, + ], + }, + VpcConfig: { + SecurityGroupId: { + 'Fn::GetAtt': ['hello_fn_security_group', 'SecurityGroupId'], + }, + VSwitchIds: ['subnet-123456', 'subnet-67890', 'subnet-98765'], + VpcId: 'vpc-123456', + }, + }, + DependsOn: ['sls_project', 'sls_logstore', 'sls_index', 'hello_fn_nas_mount_mnt_nas'], + }, + hello_fn_datasource_subnet_subnet_123456: { + Properties: { + RefreshOptions: 'Always', + VSwitchId: 'subnet-123456', + }, + Type: 'DATASOURCE::VPC::VSwitch', + }, + hello_fn_datasource_subnet_subnet_67890: { + Properties: { + RefreshOptions: 'Always', + VSwitchId: 'subnet-67890', + }, + Type: 'DATASOURCE::VPC::VSwitch', + }, + hello_fn_datasource_subnet_subnet_98765: { + Properties: { + RefreshOptions: 'Always', + VSwitchId: 'subnet-98765', + }, + Type: 'DATASOURCE::VPC::VSwitch', + }, + + hello_fn_nas_mnt_nas: { + Properties: { + DeletionForce: false, + FileSystemType: 'standard', + ProtocolType: 'NFS', + StorageType: 'Capacity', + Tags: [ + { + Key: 'owner', + Value: 'geek-fun', + }, + { + Key: 'function-name', + Value: 'hello-fn', + }, + ], + }, + Type: 'ALIYUN::NAS::FileSystem', + }, + hello_fn_nas_access_mnt_nas: { + Properties: { + AccessGroupName: 'hello-fn-nas-access-mnt-nas', + AccessGroupType: 'Vpc', + FileSystemType: 'standard', + }, + Type: 'ALIYUN::NAS::AccessGroup', + }, + hello_fn_nas_mount_mnt_nas: { + Properties: { + AccessGroupName: { + 'Fn::GetAtt': ['hello_fn_nas_access_mnt_nas', 'AccessGroupName'], + }, + FileSystemId: { + 'Fn::GetAtt': ['hello_fn_nas_mnt_nas', 'FileSystemId'], + }, + NetworkType: 'Vpc', + VSwitchId: 'subnet-123456', + VpcId: 'vpc-123456', + }, + Type: 'ALIYUN::NAS::MountTarget', + }, + hello_fn_nas_rule_subnet_123456: { + Properties: { + AccessGroupName: { + 'Fn::GetAtt': ['hello_fn_nas_access_mnt_nas', 'AccessGroupName'], + }, + FileSystemType: 'standard', + Priority: 1, + RWAccessType: 'RDWR', + SourceCidrIp: { + 'Fn::GetAtt': ['hello_fn_datasource_subnet_subnet_123456', 'CidrBlock'], + }, + UserAccessType: 'no_squash', + }, + Type: 'ALIYUN::NAS::AccessRule', + }, + hello_fn_nas_rule_subnet_67890: { + Properties: { + AccessGroupName: { + 'Fn::GetAtt': ['hello_fn_nas_access_mnt_nas', 'AccessGroupName'], + }, + FileSystemType: 'standard', + Priority: 1, + RWAccessType: 'RDWR', + SourceCidrIp: { + 'Fn::GetAtt': ['hello_fn_datasource_subnet_subnet_67890', 'CidrBlock'], + }, + UserAccessType: 'no_squash', + }, + Type: 'ALIYUN::NAS::AccessRule', + }, + hello_fn_nas_rule_subnet_98765: { + Properties: { + AccessGroupName: { + 'Fn::GetAtt': ['hello_fn_nas_access_mnt_nas', 'AccessGroupName'], + }, + FileSystemType: 'standard', + Priority: 1, + RWAccessType: 'RDWR', + SourceCidrIp: { + 'Fn::GetAtt': ['hello_fn_datasource_subnet_subnet_98765', 'CidrBlock'], + }, + UserAccessType: 'no_squash', + }, + Type: 'ALIYUN::NAS::AccessRule', + }, + hello_fn_security_group: { + Properties: { + SecurityGroupEgress: [ + { + DestCidrIp: '0.0.0.0/0', + IpProtocol: 'all', + PortRange: '-1/-1', + }, + ], + SecurityGroupIngress: [ + { + IpProtocol: 'tcp', + PortRange: '80/80', + SourceCidrIp: '0.0.0.0/0', + }, + { + IpProtocol: 'tcp', + PortRange: '443/443', + SourceCidrIp: '0.0.0.0/0', + }, + { + IpProtocol: 'tcp', + PortRange: '22/22', + SourceCidrIp: '0.0.0.0/0', + }, + { + IpProtocol: 'icmp', + PortRange: '-1/-1', + SourceCidrIp: '0.0.0.0/0', + }, + ], + SecurityGroupName: 'my-security-group', + Tags: [ + { + Key: 'owner', + Value: 'geek-fun', + }, + ], + VpcId: 'vpc-123456', + }, + Type: 'ALIYUN::ECS::SecurityGroup', + }, + }, +}; diff --git a/tests/fixtures/deploy-fixtures/oneFcWithStage.ts b/tests/fixtures/deploy-fixtures/oneFcWithStage.ts new file mode 100644 index 0000000..6b1ba89 --- /dev/null +++ b/tests/fixtures/deploy-fixtures/oneFcWithStage.ts @@ -0,0 +1,134 @@ +import { ServerlessIac } from '../../../src/types'; + +export const oneFcIacWithStage = { + service: 'my-demo-service', + version: '0.0.1', + provider: { + name: 'aliyun', + region: 'cn-hangzhou', + }, + vars: { + account_id: 1234567890, + }, + stages: { + default: { + node_env: 'default', + }, + dev: { + region: '${vars.region}', + account_id: '${vars.account_id}', + node_env: 'develop', + }, + }, + functions: [ + { + key: 'hello_fn', + name: 'hello-fn', + code: { + runtime: 'nodejs18', + handler: 'index.handler', + path: 'tests/fixtures/artifacts/artifact.zip', + }, + memory: 128, + timeout: 10, + log: true, + environment: { + NODE_ENV: '${stages.node_env}', + }, + storage: {}, + }, + ], + tags: [ + { + key: 'owner', + value: 'geek-fun', + }, + ], +} as ServerlessIac; + +export const oneFcWithStageRos = { + Description: 'my-demo-service stack', + Mappings: { + stages: { + default: { + node_env: 'default', + }, + dev: { + account_id: { Ref: 'account_id' }, + region: { Ref: 'region' }, + node_env: 'develop', + }, + }, + }, + Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } }, + Parameters: { + account_id: { Default: 1234567890, Type: 'String' }, + }, + ROSTemplateFormatVersion: '2015-09-01', + Resources: { + hello_fn: { + DependsOn: ['sls_project', 'sls_logstore', 'sls_index'], + Properties: { + Code: { ZipFile: 'resolved-code' }, + EnvironmentVariables: { NODE_ENV: { 'Fn::FindInMap': ['stages', 'default', 'node_env'] } }, + FunctionName: 'hello-fn', + Handler: 'index.handler', + LogConfig: { + EnableRequestMetrics: true, + Logstore: { + 'Fn::GetAtt': ['sls_logstore', 'LogstoreName'], + }, + Project: { + 'Fn::GetAtt': ['sls_logstore', 'ProjectName'], + }, + }, + MemorySize: 128, + Runtime: 'nodejs18', + Timeout: 10, + }, + Type: 'ALIYUN::FC3::Function', + }, + sls_project: { + Properties: { + Name: 'my-demo-service-sls', + Tags: [ + { + Key: 'owner', + Value: 'geek-fun', + }, + ], + }, + Type: 'ALIYUN::SLS::Project', + }, + sls_index: { + Properties: { + FullTextIndex: { + Enable: true, + }, + LogReduce: false, + LogstoreName: { + 'Fn::GetAtt': ['sls_logstore', 'LogstoreName'], + }, + ProjectName: { + 'Fn::GetAtt': ['sls_project', 'Name'], + }, + }, + Type: 'ALIYUN::SLS::Index', + }, + sls_logstore: { + Properties: { + AppendMeta: false, + AutoSplit: false, + EnableTracking: false, + LogstoreName: 'my-demo-service-sls-logstore', + PreserveStorage: false, + ProjectName: { + 'Fn::GetAtt': ['sls_project', 'Name'], + }, + ShardCount: 2, + TTL: 7, + }, + Type: 'ALIYUN::SLS::Logstore', + }, + }, +}; diff --git a/tests/fixtures/deploy-fixtures/referredService.ts b/tests/fixtures/deploy-fixtures/referredService.ts new file mode 100644 index 0000000..87320ac --- /dev/null +++ b/tests/fixtures/deploy-fixtures/referredService.ts @@ -0,0 +1,226 @@ +import { cloneDeep, set } from 'lodash'; +import { oneFcOneGatewayIac } from './oneFcOneGateway'; + +export const referredServiceIac = set( + cloneDeep(oneFcOneGatewayIac), + 'service', + 'my-demo-service-${ctx.stage}', +); + +export const referredServiceRos = { + Description: 'my-demo-service-dev stack', + Mappings: { + stages: { + dev: { + account_id: { + Ref: 'account_id', + }, + region: { + Ref: 'region', + }, + }, + }, + }, + Metadata: { + 'ALIYUN::ROS::Interface': { + TemplateTags: ['Create by ROS CDK'], + }, + }, + Parameters: { + account_id: { + Default: 1234567890, + Type: 'String', + }, + }, + ROSTemplateFormatVersion: '2015-09-01', + Resources: { + gateway_event_agw_api_deployment_get_api_hello: { + Properties: { + ApiId: { + 'Fn::GetAtt': ['gateway_event_agw_api_get_api_hello', 'ApiId'], + }, + Description: 'my-demo-service-dev Api Gateway deployment for api: GET /api/hello', + GroupId: { + 'Fn::GetAtt': ['gateway_event_agw_group', 'GroupId'], + }, + StageName: 'RELEASE', + }, + Type: 'ALIYUN::ApiGateway::Deployment', + }, + gateway_event_agw_api_get_api_hello: { + Properties: { + ApiName: 'gateway-event-agw-api-get-api-hello', + AuthType: 'ANONYMOUS', + GroupId: { + 'Fn::GetAtt': ['gateway_event_agw_group', 'GroupId'], + }, + RequestConfig: { + RequestHttpMethod: 'GET', + RequestMode: 'PASSTHROUGH', + RequestPath: '/api/hello', + RequestProtocol: 'HTTP', + }, + ResultSample: 'ServerlessInsight resultSample', + ResultType: 'PASSTHROUGH', + ServiceConfig: { + FunctionComputeConfig: { + FcVersion: '3.0', + FunctionName: { + 'Fn::GetAtt': ['hello_fn', 'FunctionName'], + }, + Method: 'GET', + RoleArn: { + 'Fn::GetAtt': ['gateway_event_agw_role', 'Arn'], + }, + }, + ServiceProtocol: 'FunctionCompute', + }, + Tags: [ + { + Key: 'owner', + Value: 'geek-fun', + }, + ], + Visibility: 'PRIVATE', + }, + Type: 'ALIYUN::ApiGateway::Api', + }, + gateway_event_agw_custom_domain: { + DependsOn: ['gateway_event_agw_custom_domain_record'], + Properties: { + DomainName: 'api.my-demo-service.com', + GroupId: { + 'Fn::GetAtt': ['gateway_event_agw_group', 'GroupId'], + }, + }, + Type: 'ALIYUN::ApiGateway::CustomDomain', + }, + gateway_event_agw_custom_domain_record: { + Properties: { + DomainName: 'my-demo-service.com', + RR: 'api', + TTL: 600, + Type: 'CNAME', + Value: { + 'Fn::GetAtt': ['gateway_event_agw_group', 'SubDomain'], + }, + }, + Type: 'ALIYUN::DNS::DomainRecord', + }, + gateway_event_agw_group: { + Properties: { + GroupName: 'my-demo-service-dev-agw-group', + PassthroughHeaders: 'host', + Tags: [ + { + Key: 'owner', + Value: 'geek-fun', + }, + ], + }, + Type: 'ALIYUN::ApiGateway::Group', + }, + gateway_event_agw_role: { + Properties: { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: ['apigateway.aliyuncs.com'], + }, + }, + ], + Version: '1', + }, + Description: 'my-demo-service-dev role', + Policies: [ + { + PolicyDocument: { + Statement: [ + { + Action: ['fc:InvokeFunction'], + Effect: 'Allow', + Resource: ['*'], + }, + ], + Version: '1', + }, + PolicyName: 'my-demo-service-dev-gateway-event-policy', + }, + ], + RoleName: 'gateway-event-agw-access-role', + }, + Type: 'ALIYUN::RAM::Role', + }, + hello_fn: { + DependsOn: ['sls_project', 'sls_logstore', 'sls_index'], + Properties: { + Code: { + ZipFile: 'resolved-code', + }, + EnvironmentVariables: { + NODE_ENV: 'production', + }, + FunctionName: 'hello-fn', + Handler: 'index.handler', + LogConfig: { + EnableRequestMetrics: true, + Logstore: { + 'Fn::GetAtt': ['sls_logstore', 'LogstoreName'], + }, + Project: { + 'Fn::GetAtt': ['sls_logstore', 'ProjectName'], + }, + }, + MemorySize: 128, + Runtime: 'nodejs18', + Timeout: 10, + }, + Type: 'ALIYUN::FC3::Function', + }, + sls_project: { + Properties: { + Name: 'my-demo-service-dev-sls', + Tags: [ + { + Key: 'owner', + Value: 'geek-fun', + }, + ], + }, + Type: 'ALIYUN::SLS::Project', + }, + sls_index: { + Properties: { + FullTextIndex: { + Enable: true, + }, + LogReduce: false, + LogstoreName: { + 'Fn::GetAtt': ['sls_logstore', 'LogstoreName'], + }, + ProjectName: { + 'Fn::GetAtt': ['sls_project', 'Name'], + }, + }, + Type: 'ALIYUN::SLS::Index', + }, + sls_logstore: { + Properties: { + AppendMeta: false, + AutoSplit: false, + EnableTracking: false, + LogstoreName: 'my-demo-service-dev-sls-logstore', + PreserveStorage: false, + ProjectName: { + 'Fn::GetAtt': ['sls_project', 'Name'], + }, + ShardCount: 2, + TTL: 7, + }, + Type: 'ALIYUN::SLS::Logstore', + }, + }, +}; diff --git a/tests/fixtures/deployFixture.ts b/tests/fixtures/deployFixture.ts deleted file mode 100644 index 10e917e..0000000 --- a/tests/fixtures/deployFixture.ts +++ /dev/null @@ -1,1843 +0,0 @@ -import { DatabaseEnum, DatabaseVersionEnum, ServerlessIac } from '../../src/types'; -import { cloneDeep, set } from 'lodash'; -import { ProviderEnum } from '../../src/common'; - -export const oneFcOneGatewayIac = { - service: 'my-demo-service', - version: '0.0.1', - provider: { - name: 'aliyun' as ProviderEnum, - region: 'cn-hangzhou', - }, - vars: { - account_id: 1234567890, - }, - stages: { - dev: { - region: '${vars.region}', - account_id: '${vars.account_id}', - }, - }, - functions: [ - { - key: 'hello_fn', - name: 'hello_fn', - code: { - runtime: 'nodejs18', - handler: 'index.handler', - path: 'tests/fixtures/artifacts/artifact.zip', - }, - memory: 128, - timeout: 10, - log: true, - environment: { - NODE_ENV: 'production', - }, - storage: {}, - }, - ], - events: [ - { - type: 'API_GATEWAY', - key: 'gateway_event', - name: 'gateway_event', - domain: { - domain_name: 'api.my-demo-service.com', - }, - triggers: [ - { - method: 'GET', - path: '/api/hello', - backend: '${functions.hello_fn}', - }, - ], - }, - ], - tags: [ - { - key: 'owner', - value: 'geek-fun', - }, - ], -} as ServerlessIac; - -export const oneFcOneGatewayRos = { - Description: 'my-demo-service stack', - Mappings: { - stages: { - dev: { - account_id: { - Ref: 'account_id', - }, - region: { - Ref: 'region', - }, - }, - }, - }, - Metadata: { - 'ALIYUN::ROS::Interface': { - TemplateTags: ['Create by ROS CDK'], - }, - }, - Parameters: { - account_id: { - Default: 1234567890, - Type: 'String', - }, - }, - ROSTemplateFormatVersion: '2015-09-01', - Resources: { - gateway_event_api_R0VUXy9hcGkvaGVsbG8: { - Properties: { - ApiName: 'gateway_event_api_R0VUXy9hcGkvaGVsbG8', - AuthType: 'ANONYMOUS', - GroupId: { - 'Fn::GetAtt': ['my-demo-service_apigroup', 'GroupId'], - }, - RequestConfig: { - RequestHttpMethod: 'GET', - RequestMode: 'PASSTHROUGH', - RequestPath: '/api/hello', - RequestProtocol: 'HTTP', - }, - ResultSample: 'ServerlessInsight resultSample', - ResultType: 'PASSTHROUGH', - ServiceConfig: { - FunctionComputeConfig: { - FcVersion: '3.0', - FunctionName: { - 'Fn::GetAtt': ['hello_fn', 'FunctionName'], - }, - Method: 'GET', - RoleArn: { - 'Fn::GetAtt': ['gateway_event_role', 'Arn'], - }, - }, - ServiceProtocol: 'FunctionCompute', - }, - Tags: [ - { - Key: 'owner', - Value: 'geek-fun', - }, - ], - Visibility: 'PRIVATE', - }, - Type: 'ALIYUN::ApiGateway::Api', - }, - gateway_event_custom_domain_YXBpLm15LWRlbW8tc2VydmljZS5jb20: { - DependsOn: ['gateway_event_custom_domain_record_YXBpLm15LWRlbW8tc2VydmljZS5jb20'], - Properties: { - DomainName: 'api.my-demo-service.com', - GroupId: { - 'Fn::GetAtt': ['my-demo-service_apigroup', 'GroupId'], - }, - }, - Type: 'ALIYUN::ApiGateway::CustomDomain', - }, - gateway_event_custom_domain_record_YXBpLm15LWRlbW8tc2VydmljZS5jb20: { - Properties: { - DomainName: 'my-demo-service.com', - RR: 'api', - TTL: 600, - Type: 'CNAME', - Value: { - 'Fn::GetAtt': ['my-demo-service_apigroup', 'SubDomain'], - }, - }, - Type: 'ALIYUN::DNS::DomainRecord', - }, - gateway_event_role: { - Properties: { - AssumeRolePolicyDocument: { - Statement: [ - { - Action: 'sts:AssumeRole', - Effect: 'Allow', - Principal: { - Service: ['apigateway.aliyuncs.com'], - }, - }, - ], - Version: '1', - }, - Description: 'my-demo-service role', - Policies: [ - { - PolicyDocument: { - Statement: [ - { - Action: ['fc:InvokeFunction'], - Effect: 'Allow', - Resource: ['*'], - }, - ], - Version: '1', - }, - PolicyName: 'my-demo-service-gateway_event-policy', - }, - ], - RoleName: 'my-demo-service-gateway_event-agw-access-role', - }, - Type: 'ALIYUN::RAM::Role', - }, - hello_fn: { - DependsOn: [ - 'my-demo-service_sls', - 'my-demo-service_sls_logstore', - 'my-demo-service_sls_index', - ], - Properties: { - Code: { - ZipFile: 'resolved-code', - }, - EnvironmentVariables: { - NODE_ENV: 'production', - }, - FunctionName: 'hello_fn', - Handler: 'index.handler', - LogConfig: { - EnableRequestMetrics: true, - Logstore: { - 'Fn::GetAtt': ['my-demo-service_sls_logstore', 'LogstoreName'], - }, - Project: { - 'Fn::GetAtt': ['my-demo-service_sls_logstore', 'ProjectName'], - }, - }, - MemorySize: 128, - Runtime: 'nodejs18', - Timeout: 10, - }, - Type: 'ALIYUN::FC3::Function', - }, - 'my-demo-service_apigroup': { - Properties: { - GroupName: 'my-demo-service_apigroup', - PassthroughHeaders: 'host', - Tags: [ - { - Key: 'owner', - Value: 'geek-fun', - }, - ], - }, - Type: 'ALIYUN::ApiGateway::Group', - }, - 'my-demo-service_deployment': { - Properties: { - ApiId: { - 'Fn::GetAtt': ['gateway_event_api_R0VUXy9hcGkvaGVsbG8', 'ApiId'], - }, - Description: 'my-demo-service Api Gateway deployment', - GroupId: { - 'Fn::GetAtt': ['my-demo-service_apigroup', 'GroupId'], - }, - StageName: 'RELEASE', - }, - Type: 'ALIYUN::ApiGateway::Deployment', - }, - 'my-demo-service_sls': { - Properties: { - Name: 'my-demo-service-sls', - Tags: [ - { - Key: 'owner', - Value: 'geek-fun', - }, - ], - }, - Type: 'ALIYUN::SLS::Project', - }, - 'my-demo-service_sls_index': { - Properties: { - FullTextIndex: { - Enable: true, - }, - LogReduce: false, - LogstoreName: { - 'Fn::GetAtt': ['my-demo-service_sls_logstore', 'LogstoreName'], - }, - ProjectName: { - 'Fn::GetAtt': ['my-demo-service_sls', 'Name'], - }, - }, - Type: 'ALIYUN::SLS::Index', - }, - 'my-demo-service_sls_logstore': { - Properties: { - AppendMeta: false, - AutoSplit: false, - EnableTracking: false, - LogstoreName: 'my-demo-service-sls-logstore', - PreserveStorage: false, - ProjectName: { - 'Fn::GetAtt': ['my-demo-service_sls', 'Name'], - }, - ShardCount: 2, - TTL: 7, - }, - Type: 'ALIYUN::SLS::Logstore', - }, - }, -}; - -export const referredServiceIac = set( - cloneDeep(oneFcOneGatewayIac), - 'service', - 'my-demo-service-${ctx.stage}', -); - -export const referredServiceRos = { - Description: 'my-demo-service-dev stack', - Mappings: { - stages: { - dev: { - account_id: { Ref: 'account_id' }, - region: { Ref: 'region' }, - }, - }, - }, - Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } }, - Parameters: { - account_id: { Default: 1234567890, Type: 'String' }, - }, - ROSTemplateFormatVersion: '2015-09-01', - Resources: { - gateway_event_api_R0VUXy9hcGkvaGVsbG8: { - Properties: { - ApiName: 'gateway_event_api_R0VUXy9hcGkvaGVsbG8', - AuthType: 'ANONYMOUS', - GroupId: { - 'Fn::GetAtt': ['my-demo-service-dev_apigroup', 'GroupId'], - }, - RequestConfig: { - RequestHttpMethod: 'GET', - RequestMode: 'PASSTHROUGH', - RequestPath: '/api/hello', - RequestProtocol: 'HTTP', - }, - ResultSample: 'ServerlessInsight resultSample', - ResultType: 'PASSTHROUGH', - ServiceConfig: { - FunctionComputeConfig: { - FcVersion: '3.0', - FunctionName: { - 'Fn::GetAtt': ['hello_fn', 'FunctionName'], - }, - Method: 'GET', - RoleArn: { - 'Fn::GetAtt': ['gateway_event_role', 'Arn'], - }, - }, - ServiceProtocol: 'FunctionCompute', - }, - Tags: [ - { - Key: 'owner', - Value: 'geek-fun', - }, - ], - Visibility: 'PRIVATE', - }, - Type: 'ALIYUN::ApiGateway::Api', - }, - gateway_event_custom_domain_YXBpLm15LWRlbW8tc2VydmljZS5jb20: { - DependsOn: ['gateway_event_custom_domain_record_YXBpLm15LWRlbW8tc2VydmljZS5jb20'], - Properties: { - DomainName: 'api.my-demo-service.com', - GroupId: { - 'Fn::GetAtt': ['my-demo-service-dev_apigroup', 'GroupId'], - }, - }, - Type: 'ALIYUN::ApiGateway::CustomDomain', - }, - gateway_event_custom_domain_record_YXBpLm15LWRlbW8tc2VydmljZS5jb20: { - Properties: { - DomainName: 'my-demo-service.com', - RR: 'api', - TTL: 600, - Type: 'CNAME', - Value: { - 'Fn::GetAtt': ['my-demo-service-dev_apigroup', 'SubDomain'], - }, - }, - Type: 'ALIYUN::DNS::DomainRecord', - }, - gateway_event_role: { - Properties: { - AssumeRolePolicyDocument: { - Statement: [ - { - Action: 'sts:AssumeRole', - Effect: 'Allow', - Principal: { - Service: ['apigateway.aliyuncs.com'], - }, - }, - ], - Version: '1', - }, - Description: 'my-demo-service-dev role', - Policies: [ - { - PolicyDocument: { - Statement: [ - { - Action: ['fc:InvokeFunction'], - Effect: 'Allow', - Resource: ['*'], - }, - ], - Version: '1', - }, - PolicyName: 'my-demo-service-dev-gateway_event-policy', - }, - ], - RoleName: 'my-demo-service-dev-gateway_event-agw-access-role', - }, - Type: 'ALIYUN::RAM::Role', - }, - hello_fn: { - DependsOn: [ - 'my-demo-service-dev_sls', - 'my-demo-service-dev_sls_logstore', - 'my-demo-service-dev_sls_index', - ], - Properties: { - Code: { - ZipFile: 'resolved-code', - }, - EnvironmentVariables: { - NODE_ENV: 'production', - }, - FunctionName: 'hello_fn', - Handler: 'index.handler', - LogConfig: { - EnableRequestMetrics: true, - Logstore: { - 'Fn::GetAtt': ['my-demo-service-dev_sls_logstore', 'LogstoreName'], - }, - Project: { - 'Fn::GetAtt': ['my-demo-service-dev_sls_logstore', 'ProjectName'], - }, - }, - MemorySize: 128, - Runtime: 'nodejs18', - Timeout: 10, - }, - Type: 'ALIYUN::FC3::Function', - }, - 'my-demo-service-dev_apigroup': { - Properties: { - GroupName: 'my-demo-service-dev_apigroup', - PassthroughHeaders: 'host', - Tags: [ - { - Key: 'owner', - Value: 'geek-fun', - }, - ], - }, - Type: 'ALIYUN::ApiGateway::Group', - }, - 'my-demo-service-dev_deployment': { - Properties: { - ApiId: { - 'Fn::GetAtt': ['gateway_event_api_R0VUXy9hcGkvaGVsbG8', 'ApiId'], - }, - Description: 'my-demo-service-dev Api Gateway deployment', - GroupId: { - 'Fn::GetAtt': ['my-demo-service-dev_apigroup', 'GroupId'], - }, - StageName: 'RELEASE', - }, - Type: 'ALIYUN::ApiGateway::Deployment', - }, - 'my-demo-service-dev_sls': { - Properties: { - Name: 'my-demo-service-dev-sls', - Tags: [ - { - Key: 'owner', - Value: 'geek-fun', - }, - ], - }, - Type: 'ALIYUN::SLS::Project', - }, - 'my-demo-service-dev_sls_index': { - Properties: { - FullTextIndex: { - Enable: true, - }, - LogReduce: false, - LogstoreName: { - 'Fn::GetAtt': ['my-demo-service-dev_sls_logstore', 'LogstoreName'], - }, - ProjectName: { - 'Fn::GetAtt': ['my-demo-service-dev_sls', 'Name'], - }, - }, - Type: 'ALIYUN::SLS::Index', - }, - 'my-demo-service-dev_sls_logstore': { - Properties: { - AppendMeta: false, - AutoSplit: false, - EnableTracking: false, - LogstoreName: 'my-demo-service-dev-sls-logstore', - PreserveStorage: false, - ProjectName: { - 'Fn::GetAtt': ['my-demo-service-dev_sls', 'Name'], - }, - ShardCount: 2, - TTL: 7, - }, - Type: 'ALIYUN::SLS::Logstore', - }, - }, -}; - -export const minimumIac = { - service: 'my-demo-minimum-service', - version: '0.0.1', - provider: { - name: 'aliyun' as ProviderEnum, - region: 'cn-hangzhou', - }, - - functions: [ - { - key: 'hello_fn', - name: 'hello_fn', - code: { - runtime: 'nodejs18', - handler: 'index.handler', - path: 'tests/fixtures/artifacts/artifact.zip', - }, - }, - ], -} as ServerlessIac; - -export const minimumRos = { - Description: 'my-demo-minimum-service stack', - Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } }, - ROSTemplateFormatVersion: '2015-09-01', - Resources: { - 'my-demo-minimum-service_sls': { - Properties: { - Name: 'my-demo-minimum-service-sls', - }, - Type: 'ALIYUN::SLS::Project', - }, - 'my-demo-minimum-service_sls_index': { - Properties: { - FullTextIndex: { - Enable: true, - }, - LogReduce: false, - LogstoreName: { - 'Fn::GetAtt': ['my-demo-minimum-service_sls_logstore', 'LogstoreName'], - }, - ProjectName: { - 'Fn::GetAtt': ['my-demo-minimum-service_sls', 'Name'], - }, - }, - Type: 'ALIYUN::SLS::Index', - }, - 'my-demo-minimum-service_sls_logstore': { - Properties: { - AppendMeta: false, - AutoSplit: false, - EnableTracking: false, - LogstoreName: 'my-demo-minimum-service-sls-logstore', - PreserveStorage: false, - ProjectName: { - 'Fn::GetAtt': ['my-demo-minimum-service_sls', 'Name'], - }, - ShardCount: 2, - TTL: 7, - }, - Type: 'ALIYUN::SLS::Logstore', - }, - hello_fn: { - Properties: { - Code: { - ZipFile: 'resolved-code', - }, - FunctionName: 'hello_fn', - Handler: 'index.handler', - Runtime: 'nodejs18', - }, - Type: 'ALIYUN::FC3::Function', - }, - }, -}; - -export const oneFcIac = { - service: 'my-demo-service', - version: '0.0.1', - provider: { - name: 'aliyun' as ProviderEnum, - region: 'cn-hangzhou', - }, - vars: { - account_id: 1234567890, - }, - stages: { - dev: { - region: '${vars.region}', - account_id: '${vars.account_id}', - }, - }, - functions: [ - { - key: 'hello_fn', - name: 'hello_fn', - code: { - runtime: 'nodejs18', - handler: 'index.handler', - path: 'tests/fixtures/artifacts/artifact.zip', - }, - memory: 128, - timeout: 10, - log: true, - environment: { - NODE_ENV: 'production', - }, - storage: {}, - }, - ], - tags: [ - { - key: 'owner', - value: 'geek-fun', - }, - ], -} as ServerlessIac; - -export const oneFcRos = { - Description: 'my-demo-service stack', - Mappings: { - stages: { - dev: { - account_id: { Ref: 'account_id' }, - region: { Ref: 'region' }, - }, - }, - }, - Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } }, - Parameters: { - account_id: { - Default: 1234567890, - Type: 'String', - }, - }, - ROSTemplateFormatVersion: '2015-09-01', - Resources: { - hello_fn: { - DependsOn: [ - 'my-demo-service_sls', - 'my-demo-service_sls_logstore', - 'my-demo-service_sls_index', - ], - Properties: { - Code: { - ZipFile: 'resolved-code', - }, - EnvironmentVariables: { - NODE_ENV: 'production', - }, - FunctionName: 'hello_fn', - Handler: 'index.handler', - LogConfig: { - EnableRequestMetrics: true, - Logstore: { - 'Fn::GetAtt': ['my-demo-service_sls_logstore', 'LogstoreName'], - }, - Project: { - 'Fn::GetAtt': ['my-demo-service_sls_logstore', 'ProjectName'], - }, - }, - MemorySize: 128, - Runtime: 'nodejs18', - Timeout: 10, - }, - Type: 'ALIYUN::FC3::Function', - }, - 'my-demo-service_sls': { - Properties: { - Name: 'my-demo-service-sls', - Tags: [ - { - Key: 'owner', - Value: 'geek-fun', - }, - ], - }, - Type: 'ALIYUN::SLS::Project', - }, - 'my-demo-service_sls_index': { - Properties: { - FullTextIndex: { - Enable: true, - }, - LogReduce: false, - LogstoreName: { - 'Fn::GetAtt': ['my-demo-service_sls_logstore', 'LogstoreName'], - }, - ProjectName: { - 'Fn::GetAtt': ['my-demo-service_sls', 'Name'], - }, - }, - Type: 'ALIYUN::SLS::Index', - }, - 'my-demo-service_sls_logstore': { - Properties: { - AppendMeta: false, - AutoSplit: false, - EnableTracking: false, - LogstoreName: 'my-demo-service-sls-logstore', - PreserveStorage: false, - ProjectName: { - 'Fn::GetAtt': ['my-demo-service_sls', 'Name'], - }, - ShardCount: 2, - TTL: 7, - }, - Type: 'ALIYUN::SLS::Logstore', - }, - }, -}; - -export const oneFcIacWithNas = { - ...oneFcIac, - functions: [ - { - ...((oneFcIac.functions && oneFcIac.functions[0]) ?? {}), - network: { - vpc_id: 'vpc-123456', - subnet_ids: ['subnet-123456', 'subnet-67890', 'subnet-98765'], - security_group: { - name: 'my-security-group', - ingress: [ - 'TCP:0.0.0.0/0:80', - 'TCP:0.0.0.0/0:443', - 'TCP:0.0.0.0/0:22/22', - 'ICMP:0.0.0.0/0:ALL', - ], - egress: ['ALL:0.0.0.0/0:ALL'], - }, - }, - storage: { - nas: [ - { - mount_path: '/mnt/nas', - storage_class: 'STANDARD_CAPACITY', - }, - ], - }, - }, - ], -} as ServerlessIac; - -export const oneFcIacWithNasRos = { - ...oneFcRos, - Resources: { - ...oneFcRos.Resources, - hello_fn: { - Type: 'ALIYUN::FC3::Function', - Properties: { - ...oneFcRos.Resources.hello_fn.Properties, - NasConfig: { - MountPoints: [ - { - MountDir: '/mnt/nas', - ServerAddr: { - 'Fn::Join': [ - '', - [ - { - 'Fn::GetAtt': ['hello_fn_nas_mount_L21udC9uYXM', 'MountTargetDomain'], - }, - ':/', - ], - ], - }, - }, - ], - }, - VpcConfig: { - SecurityGroupId: { - 'Fn::GetAtt': ['hello_fn_security_group', 'SecurityGroupId'], - }, - VSwitchIds: ['subnet-123456', 'subnet-67890', 'subnet-98765'], - VpcId: 'vpc-123456', - }, - }, - DependsOn: [ - 'my-demo-service_sls', - 'my-demo-service_sls_logstore', - 'my-demo-service_sls_index', - 'hello_fn_nas_mount_L21udC9uYXM', - ], - }, - hello_fn_datasource_subnet_c3VibmV0LTEyMzQ1Ng: { - Properties: { - RefreshOptions: 'Always', - VSwitchId: 'subnet-123456', - }, - Type: 'DATASOURCE::VPC::VSwitch', - }, - hello_fn_datasource_subnet_c3VibmV0LTY3ODkw: { - Properties: { - RefreshOptions: 'Always', - VSwitchId: 'subnet-67890', - }, - Type: 'DATASOURCE::VPC::VSwitch', - }, - hello_fn_datasource_subnet_c3VibmV0LTk4NzY1: { - Properties: { - RefreshOptions: 'Always', - VSwitchId: 'subnet-98765', - }, - Type: 'DATASOURCE::VPC::VSwitch', - }, - - hello_fn_nas_L21udC9uYXM: { - Properties: { - DeletionForce: false, - FileSystemType: 'standard', - ProtocolType: 'NFS', - StorageType: 'Capacity', - Tags: [ - { - Key: 'owner', - Value: 'geek-fun', - }, - { - Key: 'function-name', - Value: 'hello_fn', - }, - ], - }, - Type: 'ALIYUN::NAS::FileSystem', - }, - hello_fn_nas_access_L21udC9uYXM: { - Properties: { - AccessGroupName: 'hello_fn-nas-access-L21udC9uYXM', - AccessGroupType: 'Vpc', - FileSystemType: 'standard', - }, - Type: 'ALIYUN::NAS::AccessGroup', - }, - hello_fn_nas_mount_L21udC9uYXM: { - Properties: { - AccessGroupName: { - 'Fn::GetAtt': ['hello_fn_nas_access_L21udC9uYXM', 'AccessGroupName'], - }, - FileSystemId: { - 'Fn::GetAtt': ['hello_fn_nas_L21udC9uYXM', 'FileSystemId'], - }, - NetworkType: 'Vpc', - VSwitchId: 'subnet-123456', - VpcId: 'vpc-123456', - }, - Type: 'ALIYUN::NAS::MountTarget', - }, - hello_fn_nas_rule_c3VibmV0LTEyMzQ1Ng: { - Properties: { - AccessGroupName: { - 'Fn::GetAtt': ['hello_fn_nas_access_L21udC9uYXM', 'AccessGroupName'], - }, - FileSystemType: 'standard', - Priority: 1, - RWAccessType: 'RDWR', - SourceCidrIp: { - 'Fn::GetAtt': ['hello_fn_datasource_subnet_c3VibmV0LTEyMzQ1Ng', 'CidrBlock'], - }, - UserAccessType: 'no_squash', - }, - Type: 'ALIYUN::NAS::AccessRule', - }, - hello_fn_nas_rule_c3VibmV0LTY3ODkw: { - Properties: { - AccessGroupName: { - 'Fn::GetAtt': ['hello_fn_nas_access_L21udC9uYXM', 'AccessGroupName'], - }, - FileSystemType: 'standard', - Priority: 1, - RWAccessType: 'RDWR', - SourceCidrIp: { - 'Fn::GetAtt': ['hello_fn_datasource_subnet_c3VibmV0LTY3ODkw', 'CidrBlock'], - }, - UserAccessType: 'no_squash', - }, - Type: 'ALIYUN::NAS::AccessRule', - }, - hello_fn_nas_rule_c3VibmV0LTk4NzY1: { - Properties: { - AccessGroupName: { - 'Fn::GetAtt': ['hello_fn_nas_access_L21udC9uYXM', 'AccessGroupName'], - }, - FileSystemType: 'standard', - Priority: 1, - RWAccessType: 'RDWR', - SourceCidrIp: { - 'Fn::GetAtt': ['hello_fn_datasource_subnet_c3VibmV0LTk4NzY1', 'CidrBlock'], - }, - UserAccessType: 'no_squash', - }, - Type: 'ALIYUN::NAS::AccessRule', - }, - hello_fn_security_group: { - Properties: { - SecurityGroupEgress: [ - { - DestCidrIp: '0.0.0.0/0', - IpProtocol: 'all', - PortRange: '-1/-1', - }, - ], - SecurityGroupIngress: [ - { - IpProtocol: 'tcp', - PortRange: '80/80', - SourceCidrIp: '0.0.0.0/0', - }, - { - IpProtocol: 'tcp', - PortRange: '443/443', - SourceCidrIp: '0.0.0.0/0', - }, - { - IpProtocol: 'tcp', - PortRange: '22/22', - SourceCidrIp: '0.0.0.0/0', - }, - { - IpProtocol: 'icmp', - PortRange: '-1/-1', - SourceCidrIp: '0.0.0.0/0', - }, - ], - SecurityGroupName: 'my-security-group', - Tags: [ - { - Key: 'owner', - Value: 'geek-fun', - }, - ], - VpcId: 'vpc-123456', - }, - Type: 'ALIYUN::ECS::SecurityGroup', - }, - }, -}; -export const oneFcIacWithStage = { - service: 'my-demo-service', - version: '0.0.1', - provider: { - name: 'aliyun', - region: 'cn-hangzhou', - }, - vars: { - account_id: 1234567890, - }, - stages: { - default: { - node_env: 'default', - }, - dev: { - region: '${vars.region}', - account_id: '${vars.account_id}', - node_env: 'develop', - }, - }, - functions: [ - { - key: 'hello_fn', - name: 'hello_fn', - code: { - runtime: 'nodejs18', - handler: 'index.handler', - path: 'tests/fixtures/artifacts/artifact.zip', - }, - memory: 128, - timeout: 10, - log: true, - environment: { - NODE_ENV: '${stages.node_env}', - }, - storage: {}, - }, - ], - tags: [ - { - key: 'owner', - value: 'geek-fun', - }, - ], -} as ServerlessIac; - -export const oneFcWithStageRos = { - Description: 'my-demo-service stack', - Mappings: { - stages: { - default: { - node_env: 'default', - }, - dev: { - account_id: { Ref: 'account_id' }, - region: { Ref: 'region' }, - node_env: 'develop', - }, - }, - }, - Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } }, - Parameters: { - account_id: { Default: 1234567890, Type: 'String' }, - }, - ROSTemplateFormatVersion: '2015-09-01', - Resources: { - hello_fn: { - DependsOn: [ - 'my-demo-service_sls', - 'my-demo-service_sls_logstore', - 'my-demo-service_sls_index', - ], - Properties: { - Code: { ZipFile: 'resolved-code' }, - EnvironmentVariables: { NODE_ENV: { 'Fn::FindInMap': ['stages', 'default', 'node_env'] } }, - FunctionName: 'hello_fn', - Handler: 'index.handler', - LogConfig: { - EnableRequestMetrics: true, - Logstore: { - 'Fn::GetAtt': ['my-demo-service_sls_logstore', 'LogstoreName'], - }, - Project: { - 'Fn::GetAtt': ['my-demo-service_sls_logstore', 'ProjectName'], - }, - }, - MemorySize: 128, - Runtime: 'nodejs18', - Timeout: 10, - }, - Type: 'ALIYUN::FC3::Function', - }, - 'my-demo-service_sls': { - Properties: { - Name: 'my-demo-service-sls', - Tags: [ - { - Key: 'owner', - Value: 'geek-fun', - }, - ], - }, - Type: 'ALIYUN::SLS::Project', - }, - 'my-demo-service_sls_index': { - Properties: { - FullTextIndex: { - Enable: true, - }, - LogReduce: false, - LogstoreName: { - 'Fn::GetAtt': ['my-demo-service_sls_logstore', 'LogstoreName'], - }, - ProjectName: { - 'Fn::GetAtt': ['my-demo-service_sls', 'Name'], - }, - }, - Type: 'ALIYUN::SLS::Index', - }, - 'my-demo-service_sls_logstore': { - Properties: { - AppendMeta: false, - AutoSplit: false, - EnableTracking: false, - LogstoreName: 'my-demo-service-sls-logstore', - PreserveStorage: false, - ProjectName: { - 'Fn::GetAtt': ['my-demo-service_sls', 'Name'], - }, - ShardCount: 2, - TTL: 7, - }, - Type: 'ALIYUN::SLS::Logstore', - }, - }, -}; - -export const oneFcWithContainerIac = { - ...oneFcIac, - functions: [ - { - ...((oneFcIac.functions && oneFcIac.functions[0]) ?? {}), - code: undefined, - container: { - image: 'registry.cn-hangzhou.aliyuncs.com/aliyunfc/abcd:1.6.0', - cmd: 'npm start', - port: 9200, - }, - }, - ], -} as ServerlessIac; - -export const oneFcWithContainerRos = { - ...oneFcRos, - Resources: { - ...oneFcRos.Resources, - hello_fn: { - ...oneFcRos.Resources.hello_fn, - Properties: { - ...oneFcRos.Resources.hello_fn.Properties, - Code: undefined, - Runtime: 'custom-container', - CustomContainerConfig: { - Command: ['npm', 'start'], - Image: 'registry.cn-hangzhou.aliyuncs.com/aliyunfc/abcd:1.6.0', - Port: 9200, - }, - }, - }, - }, -}; - -export const oneFcWithGpuIac = { - ...oneFcIac, - functions: [ - { - ...((oneFcIac.functions && oneFcIac.functions[0]) ?? {}), - gpu: 'TESLA_8', - }, - ], -} as ServerlessIac; -export const oneFcWithGpuRos = { - ...oneFcRos, - Resources: { - ...oneFcRos.Resources, - hello_fn: { - ...oneFcRos.Resources.hello_fn, - Properties: { - ...oneFcRos.Resources.hello_fn.Properties, - GpuConfig: { - GpuMemorySize: 8192, - GpuType: 'fc.gpu.tesla.1', - }, - }, - }, - }, -}; - -export const largeCodeRos = { - Description: 'my-demo-service stack', - Mappings: { - stages: { - dev: { - account_id: { - Ref: 'account_id', - }, - region: { - Ref: 'region', - }, - }, - }, - }, - Metadata: { - 'ALIYUN::ROS::Interface': { - TemplateTags: ['Create by ROS CDK'], - }, - }, - Parameters: { - account_id: { - Default: 1234567890, - Type: 'String', - }, - }, - ROSTemplateFormatVersion: '2015-09-01', - Resources: { - 'FCFunctionFormy-demo-service_artifacts_code_deployment': { - Properties: { - CAPort: 9000, - Code: { - OssBucketName: { - 'Fn::Sub': expect.stringContaining('assets-${ALIYUN::Region}'), - }, - OssObjectName: 'c6a72ed7e7e83f01a000b75885758088fa050298a31a1e95d37ac88f08e42315.zip', - }, - FunctionName: { - 'Fn::Join': [ - '-', - [ - 'ros-cdk', - { - 'Fn::Select': [ - 0, - { - 'Fn::Split': [ - '-', - { - Ref: 'ALIYUN::StackId', - }, - ], - }, - ], - }, - ], - ], - }, - Handler: 'index.handler', - MemorySize: 128, - Runtime: 'python3.10', - ServiceName: { - 'Fn::GetAtt': ['FCServiceFormy-demo-service_artifacts_code_deployment', 'ServiceName'], - }, - Timeout: 3000, - }, - Type: 'ALIYUN::FC::Function', - }, - 'FCRoleFormy-demo-service_artifacts_code_deployment': { - Properties: { - AssumeRolePolicyDocument: { - Statement: [ - { - Action: 'sts:AssumeRole', - Effect: 'Allow', - Principal: { - Service: ['fc.aliyuncs.com'], - }, - }, - ], - Version: '1', - }, - DeletionForce: false, - IgnoreExisting: false, - Policies: [ - { - PolicyDocument: { - Statement: [ - { - Action: ['oss:*'], - Effect: 'Allow', - Resource: ['*'], - }, - ], - Version: '1', - }, - PolicyName: 'AliyunOSSFullAccess', - }, - { - PolicyDocument: { - Statement: [ - { - Action: ['log:*'], - Effect: 'Allow', - Resource: ['*'], - }, - { - Action: ['ram:CreateServiceLinkedRole'], - Condition: { - StringEquals: { - 'ram:ServiceName': [ - 'audit.log.aliyuncs.com', - 'alert.log.aliyuncs.com', - 'middlewarelens.log.aliyuncs.com', - 'storagelens.log.aliyuncs.com', - 'ai-lens.log.aliyuncs.com', - 'securitylens.log.aliyuncs.com', - ], - }, - }, - Effect: 'Allow', - Resource: ['*'], - }, - ], - Version: '1', - }, - PolicyName: 'AliyunLogFullAccess', - }, - ], - RoleName: { - 'Fn::Join': [ - '-', - [ - 'ros-cdk', - { - 'Fn::Select': [ - 0, - { - 'Fn::Split': [ - '-', - { - Ref: 'ALIYUN::StackId', - }, - ], - }, - ], - }, - ], - ], - }, - }, - Type: 'ALIYUN::RAM::Role', - }, - 'FCServiceFormy-demo-service_artifacts_code_deployment': { - Properties: { - DeletionForce: false, - Description: 'FC service for oss deployment by CDK', - Role: { - 'Fn::GetAtt': ['FCRoleFormy-demo-service_artifacts_code_deployment', 'Arn'], - }, - ServiceName: { - 'Fn::Join': [ - '-', - [ - 'ros-cdk', - { - 'Fn::Select': [ - 0, - { - 'Fn::Split': [ - '-', - { - Ref: 'ALIYUN::StackId', - }, - ], - }, - ], - }, - ], - ], - }, - }, - Type: 'ALIYUN::FC::Service', - }, - gateway_event_api_R0VUXy9hcGkvaGVsbG8: { - Properties: { - ApiName: 'gateway_event_api_R0VUXy9hcGkvaGVsbG8', - AuthType: 'ANONYMOUS', - GroupId: { - 'Fn::GetAtt': ['my-demo-service_apigroup', 'GroupId'], - }, - RequestConfig: { - RequestHttpMethod: 'GET', - RequestMode: 'PASSTHROUGH', - RequestPath: '/api/hello', - RequestProtocol: 'HTTP', - }, - ResultSample: 'ServerlessInsight resultSample', - ResultType: 'PASSTHROUGH', - ServiceConfig: { - FunctionComputeConfig: { - FcVersion: '3.0', - FunctionName: { - 'Fn::GetAtt': ['hello_fn', 'FunctionName'], - }, - Method: 'GET', - RoleArn: { - 'Fn::GetAtt': ['gateway_event_role', 'Arn'], - }, - }, - ServiceProtocol: 'FunctionCompute', - }, - Tags: [ - { - Key: 'owner', - Value: 'geek-fun', - }, - ], - Visibility: 'PRIVATE', - }, - Type: 'ALIYUN::ApiGateway::Api', - }, - hello_fn: { - DependsOn: [ - 'my-demo-service_sls', - 'my-demo-service_sls_logstore', - 'my-demo-service_sls_index', - 'my-demo-service_artifacts_code_deployment', - ], - Properties: { - Code: { - OssBucketName: { - 'Fn::Sub': 'si-bootstrap-artifacts-${ALIYUN::AccountId}-${ALIYUN::Region}', - }, - OssObjectName: 'hello_fn/43cb4c356149762dbe507fc1baede172-large-artifact.zip', - }, - EnvironmentVariables: { - NODE_ENV: 'production', - }, - FunctionName: 'hello_fn', - Handler: 'index.handler', - LogConfig: { - EnableRequestMetrics: true, - Logstore: { - 'Fn::GetAtt': ['my-demo-service_sls_logstore', 'LogstoreName'], - }, - Project: { - 'Fn::GetAtt': ['my-demo-service_sls_logstore', 'ProjectName'], - }, - }, - MemorySize: 128, - Runtime: 'nodejs18', - Timeout: 10, - }, - Type: 'ALIYUN::FC3::Function', - }, - 'my-demo-service_apigroup': { - Properties: { - GroupName: 'my-demo-service_apigroup', - PassthroughHeaders: 'host', - Tags: [ - { - Key: 'owner', - Value: 'geek-fun', - }, - ], - }, - Type: 'ALIYUN::ApiGateway::Group', - }, - 'my-demo-service_artifacts_code_deployment': { - Properties: { - Parameters: { - destinationBucket: { - 'Fn::Sub': 'si-bootstrap-artifacts-${ALIYUN::AccountId}-${ALIYUN::Region}', - }, - retainOnCreate: false, - sources: [ - { - bucket: { 'Fn::Sub': expect.any(String) }, - fileName: 'hello_fn/43cb4c356149762dbe507fc1baede172-large-artifact.zip', - objectKey: '2bfeafed8d3df0d44c235271cdf2aa7d908a3c2757af14a67d33d102847f46fd.zip', - }, - ], - }, - ServiceToken: { - 'Fn::GetAtt': ['FCFunctionFormy-demo-service_artifacts_code_deployment', 'ARN'], - }, - Timeout: 3000, - }, - Type: 'ALIYUN::ROS::CustomResource', - }, - 'my-demo-service_deployment': { - Properties: { - ApiId: { - 'Fn::GetAtt': ['gateway_event_api_R0VUXy9hcGkvaGVsbG8', 'ApiId'], - }, - Description: 'my-demo-service Api Gateway deployment', - GroupId: { - 'Fn::GetAtt': ['my-demo-service_apigroup', 'GroupId'], - }, - StageName: 'RELEASE', - }, - Type: 'ALIYUN::ApiGateway::Deployment', - }, - gateway_event_custom_domain_YXBpLm15LWRlbW8tc2VydmljZS5jb20: { - DependsOn: ['gateway_event_custom_domain_record_YXBpLm15LWRlbW8tc2VydmljZS5jb20'], - Properties: { - DomainName: 'api.my-demo-service.com', - GroupId: { - 'Fn::GetAtt': ['my-demo-service_apigroup', 'GroupId'], - }, - }, - Type: 'ALIYUN::ApiGateway::CustomDomain', - }, - gateway_event_custom_domain_record_YXBpLm15LWRlbW8tc2VydmljZS5jb20: { - Properties: { - DomainName: 'my-demo-service.com', - RR: 'api', - TTL: 600, - Type: 'CNAME', - Value: { - 'Fn::GetAtt': ['my-demo-service_apigroup', 'SubDomain'], - }, - }, - Type: 'ALIYUN::DNS::DomainRecord', - }, - gateway_event_role: { - Properties: { - AssumeRolePolicyDocument: { - Statement: [ - { - Action: 'sts:AssumeRole', - Effect: 'Allow', - Principal: { - Service: ['apigateway.aliyuncs.com'], - }, - }, - ], - Version: '1', - }, - Description: 'my-demo-service role', - Policies: [ - { - PolicyDocument: { - Statement: [ - { - Action: ['fc:InvokeFunction'], - Effect: 'Allow', - Resource: ['*'], - }, - ], - Version: '1', - }, - PolicyName: 'my-demo-service-gateway_event-policy', - }, - ], - RoleName: 'my-demo-service-gateway_event-agw-access-role', - }, - Type: 'ALIYUN::RAM::Role', - }, - 'my-demo-service_sls': { - Properties: { - Name: 'my-demo-service-sls', - Tags: [ - { - Key: 'owner', - Value: 'geek-fun', - }, - ], - }, - Type: 'ALIYUN::SLS::Project', - }, - 'my-demo-service_sls_index': { - Properties: { - FullTextIndex: { - Enable: true, - }, - LogReduce: false, - LogstoreName: { - 'Fn::GetAtt': ['my-demo-service_sls_logstore', 'LogstoreName'], - }, - ProjectName: { - 'Fn::GetAtt': ['my-demo-service_sls', 'Name'], - }, - }, - Type: 'ALIYUN::SLS::Index', - }, - 'my-demo-service_sls_logstore': { - Properties: { - AppendMeta: false, - AutoSplit: false, - EnableTracking: false, - LogstoreName: 'my-demo-service-sls-logstore', - PreserveStorage: false, - ProjectName: { - 'Fn::GetAtt': ['my-demo-service_sls', 'Name'], - }, - ShardCount: 2, - TTL: 7, - }, - Type: 'ALIYUN::SLS::Logstore', - }, - }, -}; -export const defaultContext = { - accessKeyId: 'access key id', - accessKeySecret: 'access key secret', - iacLocation: expect.stringContaining('tests/fixtures/serverless-insight.yml'), - parameters: [], - region: 'cn-hangzhou', - provider: ProviderEnum.ALIYUN, - securityToken: 'account id', - stackName: 'my-demo-stack', - stage: 'default', -}; - -export const esServerlessMinimumIac = { - service: 'my-demo-es-serverless-service', - version: '0.0.1', - provider: { - name: 'aliyun' as ProviderEnum, - region: 'cn-hangzhou', - }, - databases: [ - { - key: 'insight_es_db_test', - name: 'insight-poc-es-test', - type: DatabaseEnum.ELASTICSEARCH_SERVERLESS, - version: DatabaseVersionEnum['ES_SEARCH_7.10'], - security: { - basicAuth: { - username: 'test-username', - password: 'test-password', - }, - }, - cu: { min: 1, max: 8 }, - storage: { min: 20 }, - }, - ], -} as unknown as ServerlessIac; - -export const esServerlessMinimumRos = { - Description: 'my-demo-es-serverless-service stack', - Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } }, - ROSTemplateFormatVersion: '2015-09-01', - Resources: { - insight_es_db_test: { - Properties: { - AppName: 'insight-poc-es-test', - AppVersion: '7.10', - Authentication: { - BasicAuth: [ - { - Password: 'test-password', - }, - ], - }, - QuotaInfo: { - AppType: 'STANDARD', - Cu: 1, - Storage: 20, - }, - // Network: [ - // { - // Enabled: true, - // Type: 'PUBLIC_KIBANA', - // }, - // { - // Enabled: true, - // Type: 'PUBLIC_ES', - // }, - // ], - }, - Type: 'ALIYUN::ElasticSearchServerless::App', - }, - }, -}; - -export const bucketMinimumIac = { - version: '0.0.1', - provider: { - name: 'aliyun', - region: 'cn-hangzhou', - }, - service: 'my-bucket-service', - buckets: [ - { - key: 'my_bucket', - name: 'my-bucket', - }, - ], -} as unknown as ServerlessIac; - -export const bucketMinimumRos = { - Description: 'my-bucket-service stack', - Metadata: { 'ALIYUN::ROS::Interface': { TemplateTags: ['Create by ROS CDK'] } }, - ROSTemplateFormatVersion: '2015-09-01', - Resources: { - my_bucket: { - Properties: { - BucketName: 'my-bucket', - AccessControl: 'private', - DeletionForce: false, - EnableOssHdfsService: false, - RedundancyType: 'LRS', - }, - Type: 'ALIYUN::OSS::Bucket', - }, - }, -}; - -export const bucketWithWebsiteIac = { - version: '0.0.1', - provider: { - name: 'aliyun', - region: 'cn-hangzhou', - }, - service: 'my-bucket-service', - buckets: [ - { - key: 'my_bucket', - name: 'my-bucket', - website: { - code: 'tests/fixtures/artifacts/large-artifact.zip', - domain: 'my-bucket.com', - index: 'index.html', - error_page: '404.html', - error_code: 404, - }, - }, - ], -} as ServerlessIac; - -export const bucketWithWebsiteRos = { - Description: 'my-bucket-service stack', - Metadata: { - 'ALIYUN::ROS::Interface': { - TemplateTags: ['Create by ROS CDK'], - }, - }, - ROSTemplateFormatVersion: '2015-09-01', - Resources: { - FCFunctionForsi_auto_my_bucket_bucket_code_deployment: { - Properties: { - CAPort: 9000, - Code: { - OssBucketName: { - 'Fn::Sub': expect.any(String), - }, - OssObjectName: 'c6a72ed7e7e83f01a000b75885758088fa050298a31a1e95d37ac88f08e42315.zip', - }, - FunctionName: { - 'Fn::Join': [ - '-', - [ - 'ros-cdk', - { - 'Fn::Select': [ - 0, - { - 'Fn::Split': [ - '-', - { - Ref: 'ALIYUN::StackId', - }, - ], - }, - ], - }, - ], - ], - }, - Handler: 'index.handler', - MemorySize: 128, - Runtime: 'python3.10', - ServiceName: { - 'Fn::GetAtt': ['FCServiceForsi_auto_my_bucket_bucket_code_deployment', 'ServiceName'], - }, - Timeout: 3000, - }, - Type: 'ALIYUN::FC::Function', - }, - FCServiceForsi_auto_my_bucket_bucket_code_deployment: { - Properties: { - DeletionForce: false, - Description: 'FC service for oss deployment by CDK', - Role: { - 'Fn::GetAtt': ['si_auto_od_bucket_role', 'Arn'], - }, - ServiceName: { - 'Fn::Join': [ - '-', - [ - 'ros-cdk', - { - 'Fn::Select': [ - 0, - { - 'Fn::Split': [ - '-', - { - Ref: 'ALIYUN::StackId', - }, - ], - }, - ], - }, - ], - ], - }, - }, - Type: 'ALIYUN::FC::Service', - }, - my_bucket: { - Properties: { - AccessControl: 'private', - BucketName: 'my-bucket', - DeletionForce: false, - EnableOssHdfsService: false, - RedundancyType: 'LRS', - WebsiteConfigurationV2: { - ErrorDocument: { - HttpStatus: '404', - Key: '404.html', - }, - IndexDocument: { - Suffix: 'index.html', - SupportSubDir: 'true', - Type: '0', - }, - }, - }, - Type: 'ALIYUN::OSS::Bucket', - }, - my_bucket_custom_domain_bXktYnVja2V0LmNvbQ: { - Properties: { - BucketName: { - 'Fn::GetAtt': ['my_bucket', 'Name'], - }, - DomainName: 'my-bucket.com', - }, - Type: 'ALIYUN::OSS::Domain', - }, - my_bucket_custom_domain_record_bXktYnVja2V0LmNvbQ: { - Properties: { - DomainName: 'my-bucket.com', - RR: '@', - TTL: 600, - Type: 'CNAME', - Value: { - 'Fn::GetAtt': ['my_bucket', 'InternalDomainName'], - }, - }, - Type: 'ALIYUN::DNS::DomainRecord', - }, - si_auto_my_bucket_bucket_code_deployment: { - Properties: { - Parameters: { - destinationBucket: { - 'Fn::GetAtt': ['my_bucket', 'Name'], - }, - retainOnCreate: false, - sources: [ - { - bucket: { - 'Fn::Sub': expect.any(String), - }, - fileName: 'large-artifact.zip', - objectKey: '2bfeafed8d3df0d44c235271cdf2aa7d908a3c2757af14a67d33d102847f46fd.zip', - }, - ], - }, - ServiceToken: { - 'Fn::GetAtt': ['FCFunctionForsi_auto_my_bucket_bucket_code_deployment', 'ARN'], - }, - Timeout: 3000, - }, - Type: 'ALIYUN::ROS::CustomResource', - }, - si_auto_od_bucket_role: { - Properties: { - AssumeRolePolicyDocument: { - Statement: [ - { - Action: 'sts:AssumeRole', - Effect: 'Allow', - Principal: { - Service: ['fc.aliyuncs.com'], - }, - }, - ], - Version: '1', - }, - DeletionForce: false, - Description: - 'roles created by ServerlessInsight for oss deployment to put files to oss bucket during deployment', - IgnoreExisting: false, - PolicyAttachments: { - System: ['AliyunOSSFullAccess', 'AliyunLogFullAccess'], - }, - RoleName: { - 'Fn::Sub': 'si-auto-od-bucket-role-${ALIYUN::StackId}', - }, - }, - Type: 'ALIYUN::RAM::Role', - }, - }, -}; diff --git a/tests/fixtures/templateFixture.ts b/tests/fixtures/templateFixture.ts index 611293d..4a21e5c 100644 --- a/tests/fixtures/templateFixture.ts +++ b/tests/fixtures/templateFixture.ts @@ -40,7 +40,7 @@ export const jsonTemplate = { }, }, Resources: { - 'insight-poc_sls': { + sls_project: { Type: 'ALIYUN::SLS::Project', Properties: { Name: 'insight-poc-sls', @@ -56,12 +56,12 @@ export const jsonTemplate = { ], }, }, - 'insight-poc_sls_logstore': { + sls_logstore: { Type: 'ALIYUN::SLS::Logstore', Properties: { LogstoreName: 'insight-poc-sls-logstore', ProjectName: { - 'Fn::GetAtt': ['insight-poc_sls', 'Name'], + 'Fn::GetAtt': ['sls_project', 'Name'], }, AppendMeta: false, AutoSplit: false, @@ -71,17 +71,17 @@ export const jsonTemplate = { TTL: 7, }, }, - 'insight-poc_sls_index': { + sls_index: { Type: 'ALIYUN::SLS::Index', Properties: { FullTextIndex: { Enable: true, }, LogstoreName: { - 'Fn::GetAtt': ['insight-poc_sls_logstore', 'LogstoreName'], + 'Fn::GetAtt': ['sls_logstore', 'LogstoreName'], }, ProjectName: { - 'Fn::GetAtt': ['insight-poc_sls', 'Name'], + 'Fn::GetAtt': ['sls_project', 'Name'], }, LogReduce: false, }, @@ -111,19 +111,19 @@ export const jsonTemplate = { }, LogConfig: { Project: { - 'Fn::GetAtt': ['insight-poc_sls_logstore', 'ProjectName'], + 'Fn::GetAtt': ['sls_logstore', 'ProjectName'], }, Logstore: { - 'Fn::GetAtt': ['insight-poc_sls_logstore', 'LogstoreName'], + 'Fn::GetAtt': ['sls_logstore', 'LogstoreName'], }, EnableRequestMetrics: true, }, MemorySize: 512, Timeout: 10, }, - DependsOn: ['insight-poc_sls', 'insight-poc_sls_logstore', 'insight-poc_sls_index'], + DependsOn: ['sls_project', 'sls_logstore', 'sls_index'], }, - gateway_event_role: { + gateway_event_agw_role: { Type: 'ALIYUN::RAM::Role', Properties: { AssumeRolePolicyDocument: { @@ -138,7 +138,7 @@ export const jsonTemplate = { }, ], }, - RoleName: 'insight-poc-insight-poc-gateway-agw-access-role', + RoleName: 'insight-poc-gateway-agw-access-role', Description: 'insight-poc role', Policies: [ { @@ -157,10 +157,10 @@ export const jsonTemplate = { ], }, }, - 'insight-poc_apigroup': { + gateway_event_agw_group: { Type: 'ALIYUN::ApiGateway::Group', Properties: { - GroupName: 'insight-poc_apigroup', + GroupName: 'insight-poc-agw-group', PassthroughHeaders: 'host', Tags: [ { @@ -174,12 +174,12 @@ export const jsonTemplate = { ], }, }, - gateway_event_api_R0VUXy9hcGkvaGVsbG8: { + gateway_event_agw_api_get_api_hello: { Type: 'ALIYUN::ApiGateway::Api', Properties: { - ApiName: 'insight-poc-gateway_api_R0VUXy9hcGkvaGVsbG8', + ApiName: 'insight-poc-gateway-agw-api-get-api-hello', GroupId: { - 'Fn::GetAtt': ['insight-poc_apigroup', 'GroupId'], + 'Fn::GetAtt': ['gateway_event_agw_group', 'GroupId'], }, RequestConfig: { RequestPath: '/api/hello', @@ -193,7 +193,7 @@ export const jsonTemplate = { Method: 'GET', FcRegionId: 'cn-hangzhou', RoleArn: { - 'Fn::GetAtt': ['gateway_event_role', 'Arn'], + 'Fn::GetAtt': ['gateway_event_agw_role', 'Arn'], }, FunctionName: { 'Fn::GetAtt': ['insight_poc_fn', 'FunctionName'], @@ -217,17 +217,17 @@ export const jsonTemplate = { ], }, }, - 'insight-poc_deployment': { + gateway_event_agw_api_deployment_get_api_hello: { Type: 'ALIYUN::ApiGateway::Deployment', Properties: { ApiId: { - 'Fn::GetAtt': ['gateway_event_api_R0VUXy9hcGkvaGVsbG8', 'ApiId'], + 'Fn::GetAtt': ['gateway_event_agw_api_get_api_hello', 'ApiId'], }, GroupId: { - 'Fn::GetAtt': ['insight-poc_apigroup', 'GroupId'], + 'Fn::GetAtt': ['gateway_event_agw_group', 'GroupId'], }, StageName: 'RELEASE', - Description: 'insight-poc Api Gateway deployment', + Description: 'insight-poc Api Gateway deployment for api: GET /api/hello', }, }, }, @@ -263,7 +263,7 @@ Mappings: prod: region: cn-shanghai Resources: - insight-poc_sls: + sls_project: Type: ALIYUN::SLS::Project Properties: Name: insight-poc-sls @@ -272,13 +272,13 @@ Resources: Key: iac-provider - Value: geek-fun Key: owner - insight-poc_sls_logstore: + sls_logstore: Type: ALIYUN::SLS::Logstore Properties: LogstoreName: insight-poc-sls-logstore ProjectName: Fn::GetAtt: - - insight-poc_sls + - sls_project - Name AppendMeta: false AutoSplit: false @@ -286,18 +286,18 @@ Resources: PreserveStorage: false ShardCount: 2 TTL: 7 - insight-poc_sls_index: + sls_index: Type: ALIYUN::SLS::Index Properties: FullTextIndex: Enable: true LogstoreName: Fn::GetAtt: - - insight-poc_sls_logstore + - sls_logstore - LogstoreName ProjectName: Fn::GetAtt: - - insight-poc_sls + - sls_project - Name LogReduce: false insight_poc_fn: @@ -322,20 +322,20 @@ Resources: LogConfig: Project: Fn::GetAtt: - - insight-poc_sls_logstore + - sls_logstore - ProjectName Logstore: Fn::GetAtt: - - insight-poc_sls_logstore + - sls_logstore - LogstoreName EnableRequestMetrics: true MemorySize: 512 Timeout: 10 DependsOn: - - insight-poc_sls - - insight-poc_sls_logstore - - insight-poc_sls_index - gateway_event_role: + - sls_project + - sls_logstore + - sls_index + gateway_event_agw_role: Type: ALIYUN::RAM::Role Properties: AssumeRolePolicyDocument: @@ -346,7 +346,7 @@ Resources: Principal: Service: - apigateway.aliyuncs.com - RoleName: insight-poc-insight-poc-gateway-agw-access-role + RoleName: insight-poc-gateway-agw-access-role Description: insight-poc role Policies: - PolicyName: insight-poc-insight-poc-gateway-policy @@ -358,23 +358,23 @@ Resources: Resource: - "*" Effect: Allow - insight-poc_apigroup: + gateway_event_agw_group: Type: ALIYUN::ApiGateway::Group Properties: - GroupName: insight-poc_apigroup + GroupName: insight-poc-agw-group PassthroughHeaders: host Tags: - Value: ServerlessInsight Key: iac-provider - Value: geek-fun Key: owner - gateway_event_api_R0VUXy9hcGkvaGVsbG8: + gateway_event_agw_api_get_api_hello: Type: ALIYUN::ApiGateway::Api Properties: - ApiName: insight-poc-gateway_api_R0VUXy9hcGkvaGVsbG8 + ApiName: insight-poc-gateway-agw-api-get-api-hello GroupId: Fn::GetAtt: - - insight-poc_apigroup + - gateway_event_agw_group - GroupId RequestConfig: RequestPath: /api/hello @@ -388,7 +388,7 @@ Resources: FcRegionId: cn-hangzhou RoleArn: Fn::GetAtt: - - gateway_event_role + - gateway_event_agw_role - Arn FunctionName: Fn::GetAtt: @@ -404,17 +404,17 @@ Resources: Key: iac-provider - Value: geek-fun Key: owner - insight-poc_deployment: + gateway_event_agw_api_deployment_get_api_hello: Type: ALIYUN::ApiGateway::Deployment Properties: ApiId: Fn::GetAtt: - - gateway_event_api_R0VUXy9hcGkvaGVsbG8 + - gateway_event_agw_api_get_api_hello - ApiId GroupId: Fn::GetAtt: - - insight-poc_apigroup + - gateway_event_agw_group - GroupId StageName: RELEASE - Description: insight-poc Api Gateway deployment + Description: "insight-poc Api Gateway deployment for api: GET /api/hello" `; diff --git a/tests/stack/deploy.test.ts b/tests/stack/deploy.test.ts index d4eb139..f66aee8 100644 --- a/tests/stack/deploy.test.ts +++ b/tests/stack/deploy.test.ts @@ -23,7 +23,7 @@ import { oneFcWithStageRos, referredServiceIac, referredServiceRos, -} from '../fixtures/deployFixture'; +} from '../fixtures/deploy-fixtures'; import { cloneDeep, set } from 'lodash'; const mockedEnterWith = jest.fn();