@geek-fun/serverlessinsight
Version:
Full life cycle cross providers serverless application management for your fast-growing business.
260 lines (259 loc) • 12.5 kB
JavaScript
;
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;