UNPKG

@geek-fun/serverlessinsight

Version:

Full life cycle cross providers serverless application management for your fast-growing business.

260 lines (259 loc) 12.5 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.resolveFunctions = void 0; const types_1 = require("../../types"); const common_1 = require("../../common"); const fc = __importStar(require("@alicloud/ros-cdk-fc3")); const lodash_1 = require("lodash"); const ossDeployment = __importStar(require("@alicloud/ros-cdk-ossdeployment")); const sls = __importStar(require("@alicloud/ros-cdk-sls")); const nas = __importStar(require("@alicloud/ros-cdk-nas")); const ecs = __importStar(require("@alicloud/ros-cdk-ecs")); const vpc = __importStar(require("@alicloud/ros-cdk-vpc")); const storageClassMap = { [types_1.NasStorageClassEnum.STANDARD_CAPACITY]: { fileSystemType: 'standard', storageType: 'Capacity' }, [types_1.NasStorageClassEnum.STANDARD_PERFORMANCE]: { fileSystemType: 'standard', storageType: 'Performance', }, [types_1.NasStorageClassEnum.EXTREME_STANDARD]: { fileSystemType: 'extreme', storageType: 'standard' }, [types_1.NasStorageClassEnum.EXTREME_ADVANCE]: { fileSystemType: 'extreme', storageType: 'advance' }, }; const securityGroupRangeMap = { TCP: '1/65535', UDP: '1/65535', ICMP: '-1/-1', GRE: '-1/-1', ALL: '-1/-1', }; const gpuConfigMap = { [types_1.FunctionGpuEnum.TESLA_8]: { gpuMemorySize: 8192, gpuType: 'fc.gpu.tesla.1' }, [types_1.FunctionGpuEnum.TESLA_12]: { gpuMemorySize: 12288, gpuType: 'fc.gpu.tesla.1' }, [types_1.FunctionGpuEnum.TESLA_16]: { gpuMemorySize: 16384, gpuType: 'fc.gpu.tesla.1' }, [types_1.FunctionGpuEnum.AMPERE_8]: { gpuMemorySize: 8192, gpuType: 'fc.gpu.ampere.1' }, [types_1.FunctionGpuEnum.AMPERE_12]: { gpuMemorySize: 12288, gpuType: 'fc.gpu.ampere.1' }, [types_1.FunctionGpuEnum.AMPERE_16]: { gpuMemorySize: 16384, gpuType: 'fc.gpu.ampere.1' }, [types_1.FunctionGpuEnum.AMPERE_24]: { gpuMemorySize: 24576, gpuType: 'fc.gpu.ampere.1' }, [types_1.FunctionGpuEnum.ADA_48]: { gpuMemorySize: 49152, gpuType: 'fc.gpu.ada.1' }, }; const transformSecurityRules = (rules, ruleType) => { return rules.map((rule) => { const [protocol, cidrIp, portRange] = rule.split(':'); return { ipProtocol: protocol.toLowerCase(), portRange: portRange.toUpperCase() === 'ALL' ? securityGroupRangeMap[protocol.toUpperCase()] : portRange.includes('/') ? portRange : `${portRange}/${portRange}`, [ruleType === 'INGRESS' ? 'sourceCidrIp' : 'destCidrIp']: cidrIp, }; }); }; const transformGpuConfig = (gpu) => { if (!gpu) { return undefined; } return gpuConfigMap[gpu]; }; const resolveFunctions = (scope, functions, tags, context, service) => { if ((0, lodash_1.isEmpty)(functions)) { return undefined; } let logConfig = undefined; const enableLog = functions?.some(({ log }) => log); const slsProjectId = 'sls_project'; const slsLogstoreId = 'sls_logstore'; const slsIndexId = 'sls_index'; const slsProject = new sls.Project(scope, slsProjectId, { name: (0, common_1.calcRefs)(`${service}-sls`, context), tags: (0, common_1.calcRefs)(tags, context) }, true); const slsLogstore = new sls.Logstore(scope, slsLogstoreId, { logstoreName: (0, common_1.calcRefs)(`${service}-sls-logstore`, context), projectName: slsProject.attrName, ttl: 7, }, true); new sls.Index(scope, slsIndexId, { projectName: slsProject.attrName, logstoreName: slsLogstore.attrLogstoreName, fullTextIndex: { enable: true }, }, true); if (enableLog) { logConfig = { project: slsLogstore.attrProjectName, logstore: slsLogstore.attrLogstoreName, enableRequestMetrics: true, }; } const fileSources = functions ?.filter(({ code }) => code?.path && (0, common_1.readCodeSize)(code.path) > common_1.CODE_ZIP_SIZE_LIMIT) .map(({ code, name }) => { const fcName = (0, common_1.calcRefs)(name, context); return { fcName, ...(0, common_1.getFileSource)(fcName, code.path) }; }); const destinationBucketName = `${common_1.SI_BOOTSTRAP_BUCKET_PREFIX}-${context.accountId}-${context.region}`; const ossDeploymentId = 'si_auto_artifacts_code_deployment'; if (!(0, lodash_1.isEmpty)(fileSources)) { new ossDeployment.BucketDeployment(scope, ossDeploymentId, { sources: fileSources.map(({ source }) => source), destinationBucket: destinationBucketName, timeout: common_1.OSS_DEPLOYMENT_TIMEOUT, logMonitoring: false, retainOnCreate: false, }, true); } functions?.forEach((fnc) => { let runtimeConfig; const storeInBucket = !!fnc.code?.path && (0, common_1.readCodeSize)((0, common_1.calcValue)(fnc.code.path, context)) > common_1.CODE_ZIP_SIZE_LIMIT; if (fnc.container) { runtimeConfig = { runtime: 'custom-container', handler: 'index.handler', customContainerConfig: { image: (0, common_1.calcRefs)(fnc.container.image, context), command: (0, common_1.calcRefs)(fnc.container.cmd, context)?.split(' '), port: (0, common_1.calcRefs)(fnc.container.port, context), }, }; } else { let code = { zipFile: (0, common_1.resolveCode)((0, common_1.calcValue)(fnc.code.path, context)), }; if (storeInBucket) { code = { ossBucketName: destinationBucketName, ossObjectName: fileSources?.find(({ fcName }) => fcName === (0, common_1.calcRefs)(fnc.name, context)) ?.objectKey, }; } runtimeConfig = { code, handler: (0, common_1.calcRefs)(fnc.code.handler, context), runtime: (0, common_1.calcRefs)(fnc.code.runtime, context), }; } let vpcConfig = undefined; if (fnc.network) { const securityGroup = new ecs.SecurityGroup(scope, (0, common_1.formatRosId)(`${fnc.key}_security_group`), { securityGroupName: fnc.network.security_group.name, vpcId: (0, common_1.calcRefs)(fnc.network.vpc_id, context), tags: (0, common_1.calcRefs)(tags, context), securityGroupIngress: transformSecurityRules(fnc.network.security_group.ingress, 'INGRESS'), securityGroupEgress: transformSecurityRules(fnc.network.security_group.egress, 'EGRESS'), }, true); vpcConfig = { vpcId: (0, common_1.calcRefs)(fnc.network.vpc_id, context), vSwitchIds: (0, common_1.calcRefs)(fnc.network.subnet_ids, context), securityGroupId: securityGroup.attrSecurityGroupId, }; } let fcNas; if (fnc.storage?.nas) { fcNas = fnc.storage.nas.map((nasItem) => { const storageClass = (0, common_1.calcValue)(nasItem.storage_class, context); const { fileSystemType, storageType } = storageClassMap[storageClass]; const mountPathValue = (0, common_1.formatRosId)((0, common_1.calcValue)(nasItem.mount_path, context)); const nasMountTargetId = (0, common_1.formatRosId)(`${fnc.key}_nas_mount_${mountPathValue}`); const accessGroup = new nas.AccessGroup(scope, (0, common_1.formatRosId)(`${fnc.key}_nas_access_${mountPathValue}`), { accessGroupName: (0, common_1.calcRefs)(`${fnc.name}-nas-access-${mountPathValue.replace(/_/g, '-')}`, context), accessGroupType: 'Vpc', }, true); const fcVpcSubnets = fnc.network?.subnet_ids.map((subnet) => new vpc.datasource.VSwitch(scope, (0, common_1.formatRosId)((0, common_1.calcValue)(`${fnc.key}_datasource_subnet_${subnet}`, context)), { vSwitchId: subnet, refreshOptions: 'Always', })); fcVpcSubnets?.forEach((subnetDatasource, index) => { new nas.AccessRule(scope, (0, common_1.formatRosId)((0, common_1.calcValue)(`${fnc.key}_nas_rule_${fnc.network.subnet_ids[index]}`, context)), { accessGroupName: accessGroup.attrAccessGroupName, sourceCidrIp: subnetDatasource.attrCidrBlock, }, true); }); const nasResource = new nas.FileSystem(scope, (0, common_1.formatRosId)(`${fnc.key}_nas_${mountPathValue}`), { fileSystemType, storageType, protocolType: 'NFS', tags: [ ...((0, common_1.calcRefs)(tags, context) ?? []), { key: 'function-name', value: (0, common_1.calcRefs)(fnc.name, context) }, ], }, true); const nasMountTarget = new nas.MountTarget(scope, nasMountTargetId, { fileSystemId: nasResource.attrFileSystemId, networkType: 'Vpc', accessGroupName: accessGroup.attrAccessGroupName, vpcId: (0, common_1.calcRefs)(fnc.network.vpc_id, context), vSwitchId: (0, common_1.calcRefs)(fnc.network.subnet_ids[0], context), }, true); return { nas: nasResource, nasMount: nasMountTarget, mountDir: (0, common_1.calcRefs)(nasItem.mount_path, context), nasMountTargetId, }; }); } const fcn = new fc.RosFunction(scope, fnc.key, { functionName: (0, common_1.calcRefs)(fnc.name, context), memorySize: (0, common_1.calcRefs)(fnc.memory, context), diskSize: (0, common_1.calcRefs)(fnc.storage?.disk, context), gpuConfig: transformGpuConfig(fnc.gpu), timeout: (0, common_1.calcRefs)(fnc.timeout, context), environmentVariables: (0, common_1.calcRefs)(fnc.environment, context), logConfig, vpcConfig, ...runtimeConfig, nasConfig: fcNas?.length ? { mountPoints: fcNas?.map(({ nasMount, mountDir }) => ({ mountDir, serverAddr: `${nasMount.attrMountTargetDomain}:/`, })), } : undefined, }, true); if (enableLog) { fcn.addRosDependency(slsProjectId); fcn.addRosDependency(slsLogstoreId); fcn.addRosDependency(slsIndexId); } if (storeInBucket) { fcn.addRosDependency(ossDeploymentId); } if (fcNas?.length) { fcNas.forEach(({ nasMountTargetId }) => fcn.addRosDependency(nasMountTargetId)); } }); }; exports.resolveFunctions = resolveFunctions;