@cloudbase/framework-plugin-container
Advanced tools
| "use strict"; | ||
| var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
| function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
| return new (P || (P = Promise))(function (resolve, reject) { | ||
| function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
| function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
| function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
| step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
| }); | ||
| }; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.ContainerBuilder = void 0; | ||
| const path_1 = __importDefault(require("path")); | ||
| const fs_extra_1 = __importDefault(require("fs-extra")); | ||
| const archiver_1 = __importDefault(require("archiver")); | ||
| const framework_core_1 = require("@cloudbase/framework-core"); | ||
| class ContainerBuilder extends framework_core_1.Builder { | ||
| constructor(options) { | ||
| super(Object.assign({ type: "container" }, options)); | ||
| } | ||
| build(localDir, options) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| const { distDir } = this; | ||
| fs_extra_1.default.ensureDirSync(distDir); | ||
| const distFileName = path_1.default.join(distDir, `${options.name || "container"}.zip`); | ||
| yield this.zipDir(localDir, distFileName); | ||
| return { | ||
| containers: [ | ||
| { | ||
| name: options.name, | ||
| options: {}, | ||
| source: distFileName, | ||
| }, | ||
| ], | ||
| routes: [ | ||
| { | ||
| path: options.path, | ||
| targetType: "container", | ||
| target: options.name, | ||
| }, | ||
| ], | ||
| }; | ||
| }); | ||
| } | ||
| zipDir(src, dest) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| return new Promise((resolve, reject) => { | ||
| // create a file to stream archive data to. | ||
| var output = fs_extra_1.default.createWriteStream(dest); | ||
| var archive = archiver_1.default("zip", { | ||
| zlib: { level: 9 }, | ||
| }); | ||
| output.on("close", resolve); | ||
| archive.on("error", reject); | ||
| archive.directory(src, false); | ||
| archive.pipe(output); | ||
| archive.finalize(); | ||
| }); | ||
| }); | ||
| } | ||
| } | ||
| exports.ContainerBuilder = ContainerBuilder; |
| "use strict"; | ||
| var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
| function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
| return new (P || (P = Promise))(function (resolve, reject) { | ||
| function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
| function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
| function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
| step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
| }); | ||
| }; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.ContainerApi = void 0; | ||
| const fs_1 = __importDefault(require("fs")); | ||
| class ContainerApi { | ||
| constructor(cloudApi) { | ||
| this.cloudApi = cloudApi; | ||
| } | ||
| /** | ||
| * | ||
| * 上传代码到 Coding | ||
| * @param packageName | ||
| * @param version | ||
| * @param filePath | ||
| */ | ||
| upload(packageName, version, filePath) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| const res = yield this.describeCloudBaseRunBuildServer(); | ||
| const { TeamGlobalKey, ProjectName, PackageRepositoryName, ProjectGlobalKey, ProjectToken, } = res; | ||
| const url = `https://${TeamGlobalKey}-generic.pkg.coding.net/${ProjectName}/${PackageRepositoryName}/${packageName}?version=${version}`; | ||
| const authorization = Buffer.from(`${ProjectGlobalKey}:${ProjectToken}`).toString("base64"); | ||
| const response = yield this.cloudApi.fetchStream(url, { | ||
| method: "PUT", | ||
| body: fs_1.default.createReadStream(filePath), | ||
| headers: { | ||
| Authorization: `Basic ${authorization}`, | ||
| ContentType: "application/octet-stream", | ||
| }, | ||
| }, process.env.http_proxy); | ||
| const text = yield (yield response.text()).trim(); | ||
| if (text !== "success") { | ||
| console.error(text); | ||
| throw new Error("部署云应用代码失败"); | ||
| } | ||
| }); | ||
| } | ||
| /** | ||
| * 查询 Coding 部署信息 | ||
| */ | ||
| describeCloudBaseRunBuildServer() { | ||
| return this.cloudApi.tcbService.request("DescribeCloudBaseRunBuildServer", { | ||
| Business: "framework", | ||
| }); | ||
| } | ||
| } | ||
| exports.ContainerApi = ContainerApi; |
+155
| "use strict"; | ||
| var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
| function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
| return new (P || (P = Promise))(function (resolve, reject) { | ||
| function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
| function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
| function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
| step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
| }); | ||
| }; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.plugin = void 0; | ||
| const framework_core_1 = require("@cloudbase/framework-core"); | ||
| const container_api_1 = require("./container-api"); | ||
| const builder_1 = require("./builder"); | ||
| const path_1 = __importDefault(require("path")); | ||
| class ContainerPlugin extends framework_core_1.Plugin { | ||
| constructor(name, api, inputs) { | ||
| super(name, api, inputs); | ||
| this.name = name; | ||
| this.api = api; | ||
| this.inputs = inputs; | ||
| const DEFAULT_INPUTS = { | ||
| description: "基于云开发 CloudBase Framework 部署的云应用", | ||
| isPublic: true, | ||
| flowRatio: 100, | ||
| cpu: 1, | ||
| mem: 1, | ||
| minNum: 1, | ||
| maxNum: 1000, | ||
| policyType: "cpu", | ||
| policyThreshold: 60, | ||
| containerPort: 80, | ||
| dockerfilePath: "./Dockerfile", | ||
| buildDir: "./", | ||
| version: "1.0.0", | ||
| localPath: "./", | ||
| }; | ||
| this.resolvedInputs = resolveInputs(this.inputs, DEFAULT_INPUTS); | ||
| this.containerApi = new container_api_1.ContainerApi(this.api.cloudApi); | ||
| this.builder = new builder_1.ContainerBuilder({ | ||
| projectPath: this.api.projectPath, | ||
| }); | ||
| } | ||
| /** | ||
| * 初始化 | ||
| */ | ||
| init() { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| this.api.logger.debug("ContainerPlugin: init", this.resolvedInputs); | ||
| }); | ||
| } | ||
| /** | ||
| * 删除资源 | ||
| */ | ||
| remove() { | ||
| return __awaiter(this, void 0, void 0, function* () { }); | ||
| } | ||
| /** | ||
| * 生成代码 | ||
| */ | ||
| genCode() { | ||
| return __awaiter(this, void 0, void 0, function* () { }); | ||
| } | ||
| /** | ||
| * 构建 | ||
| */ | ||
| build() { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| this.api.logger.debug("ContainerPlugin: build", this.resolvedInputs); | ||
| const { serviceName, version } = this.resolvedInputs; | ||
| const localPath = this.resolvedInputs.localAbsolutePath || | ||
| path_1.default.join(this.api.projectPath, this.resolvedInputs.localPath); | ||
| const result = yield this.builder.build(localPath, { | ||
| path: this.resolvedInputs.servicePath, | ||
| name: this.resolvedInputs.serviceName, | ||
| }); | ||
| const distFileName = result.containers[0].source; | ||
| yield this.containerApi.upload(serviceName, version, distFileName); | ||
| this.builder.clean(); | ||
| }); | ||
| } | ||
| /** | ||
| * 生成SAM文件 | ||
| */ | ||
| compile() { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| this.api.logger.debug("ContainerPlugin: compile", this.resolvedInputs); | ||
| return { | ||
| Resources: { | ||
| [this.toConstantCase(this.resolvedInputs.serviceName)]: this.toSAM(), | ||
| }, | ||
| }; | ||
| }); | ||
| } | ||
| /** | ||
| * 部署 | ||
| */ | ||
| deploy() { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| this.api.logger.debug("ContainerPlugin: deploy", this.resolvedInputs, this.buildOutput); | ||
| }); | ||
| } | ||
| toSAM() { | ||
| const { description, serviceName, isPublic, flowRatio, cpu, mem, minNum, maxNum, policyType, policyThreshold, containerPort, dockerfilePath, buildDir, version, servicePath, } = this.resolvedInputs; | ||
| return { | ||
| Type: "CloudBase::CloudBaseRun", | ||
| Properties: { | ||
| ServerName: serviceName, | ||
| Description: description, | ||
| isPublic: isPublic, | ||
| UploadType: "package", | ||
| FlowRatio: flowRatio, | ||
| Cpu: cpu, | ||
| Mem: mem, | ||
| MinNum: minNum, | ||
| MaxNum: maxNum, | ||
| PolicyType: policyType, | ||
| PolicyThreshold: policyThreshold, | ||
| ContainerPort: containerPort, | ||
| DockerfilePath: dockerfilePath, | ||
| BuildDir: buildDir, | ||
| PackageName: serviceName, | ||
| PackageVersion: version, | ||
| Path: servicePath, | ||
| }, | ||
| }; | ||
| } | ||
| toConstantCase(name) { | ||
| let result = ""; | ||
| let lastIsDivide = true; | ||
| for (let i = 0; i < name.length; i++) { | ||
| let letter = name[i]; | ||
| if (letter === "-" || letter === "_") { | ||
| lastIsDivide = true; | ||
| } | ||
| else if (lastIsDivide) { | ||
| result += letter.toUpperCase(); | ||
| lastIsDivide = false; | ||
| } | ||
| else { | ||
| result += letter.toLowerCase(); | ||
| lastIsDivide = false; | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| } | ||
| function resolveInputs(inputs, defaultInputs) { | ||
| return Object.assign({}, defaultInputs, inputs); | ||
| } | ||
| exports.plugin = ContainerPlugin; |
+3
-3
| { | ||
| "name": "@cloudbase/framework-plugin-container", | ||
| "version": "0.2.27-alpha.0", | ||
| "version": "0.2.28-alpha.0", | ||
| "description": "云开发 Tencent CloudBase Framework Container Plugin 插件,将项目下的后端应用一键部署云开发云应用环境,提供自动弹性伸缩的高性能容器服务。", | ||
@@ -34,3 +34,3 @@ "author": "Tencent CloudBase Team", | ||
| "@cloudbase/cloud-api": "^0.1.4", | ||
| "@cloudbase/framework-core": "^0.2.27-alpha.0", | ||
| "@cloudbase/framework-core": "^0.2.28-alpha.0", | ||
| "@types/archiver": "^3.1.0", | ||
@@ -47,3 +47,3 @@ "@types/fs-extra": "^9.0.1", | ||
| }, | ||
| "gitHead": "fd1b884fb6b6c0ccf03d25a98e2513cafe208636" | ||
| "gitHead": "741b434c5a287be47983e49592ba8f2efb9e6051" | ||
| } |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
34820
46.88%12
33.33%441
170.55%3
Infinity%+ Added
- Removed