UNPKG

@topgroup/diginext

Version:

A BUILD SERVER & CLI to deploy apps to any Kubernetes clusters.

312 lines (311 loc) 15.1 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 __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const class_validator_1 = require("class-validator"); const log_1 = require("diginext-utils/dist/xconsole/log"); const fs_1 = require("fs"); const dist_1 = require("tsoa/dist"); const entities = __importStar(require("../entities")); const interfaces = __importStar(require("../interfaces")); const SystemTypes_1 = require("../interfaces/SystemTypes"); const digitalocean_1 = __importDefault(require("../modules/providers/digitalocean")); const gcloud_1 = __importDefault(require("../modules/providers/gcloud")); const connect_registry_1 = require("../modules/registry/connect-registry"); const plugins_1 = require("../plugins"); const mongodb_1 = require("../plugins/mongodb"); const ContainerRegistryService_1 = require("../services/ContainerRegistryService"); const BaseController_1 = __importDefault(require("./BaseController")); let ContainerRegistryController = class ContainerRegistryController extends BaseController_1.default { constructor() { super(new ContainerRegistryService_1.ContainerRegistryService()); } /** * List of container registry */ read(queryParams) { return super.read(); } /** * List of K8S clusters (include system default clusters) */ async readAll(queryParams) { try { const data = await this.service.findAll(this.filter, this.options, this.pagination); return interfaces.respondSuccess({ data }); } catch (e) { return interfaces.respondFailure(`Unable to get container registries: ${e}`); } } async create(body, queryParams) { var _a, _b; let { name, organization, serviceAccount, provider: providerShortName, host, imageBaseURL, apiAccessToken, dockerUsername, dockerPassword, dockerServer, dockerEmail, } = body; // TODO: add dockerUsername, dockerPassword, dockerServer, dockerEmail // TODO: encrypt "dockerPassword" const errors = []; if (!name) errors.push(`Name is required.`); if (!providerShortName) errors.push(`Container registry provider is required (eg. gcloud, digitalocean, dockerhub,...)`); if ((0, class_validator_1.isNotIn)(providerShortName, SystemTypes_1.registryProviderList)) errors.push(`Container registry provider should be one of [${SystemTypes_1.registryProviderList.join(", ")}]`); if (errors.length > 0) return { status: 0, messages: errors }; if (providerShortName === "gcloud") { if (!host) host = "asia-docker.pkg.dev"; if (!serviceAccount) return interfaces.respondFailure({ msg: `Service Account (JSON) is required to authenticate Google Container Registry.` }); organization = JSON.parse(serviceAccount).project_id; } if (providerShortName === "digitalocean") { if (!host) host = "registry.digitalocean.com"; if (!apiAccessToken) return interfaces.respondFailure({ msg: `API access token is required to authenticate DigitalOcean Container Registry.` }); if (!organization) organization = this.workspace.slug; } if (providerShortName === "dockerhub") { if (!dockerUsername) return interfaces.respondFailure({ msg: `Docker username is required.` }); if (!dockerPassword) return interfaces.respondFailure({ msg: `Docker password is required.` }); if (!dockerServer) dockerServer = "https://index.docker.io/v2/"; if (!host) host = "docker.io"; if (!organization) organization = dockerUsername; // const saltRounds = 10; // dockerPassword = await bcrypt.hash(dockerPassword, saltRounds); } if (!imageBaseURL) imageBaseURL = `${host}/${organization}`; const newRegistryData = { name, organization, host, provider: providerShortName, serviceAccount, imageBaseURL, apiAccessToken, dockerUsername, dockerPassword, dockerServer, dockerEmail, isVerified: false, }; let newRegistry = await this.service.create(newRegistryData); // console.log("newRegistry :>> ", newRegistry); // console.log("this.workspace :>> ", this.workspace); // verify container registry connection... const authRes = await (0, connect_registry_1.connectRegistry)(newRegistry, { userId: (_a = this.user) === null || _a === void 0 ? void 0 : _a._id, workspaceId: (_b = this.workspace) === null || _b === void 0 ? void 0 : _b._id }); const { DB } = await Promise.resolve().then(() => __importStar(require("../modules/api/DB"))); if (authRes) newRegistry = await DB.updateOne("registry", { _id: newRegistry._id }, { isVerified: true }); // const newRegistry = await connectRegistry(newRegistryData, { userId: this.user?._id, workspaceId: this.workspace?._id }); return interfaces.respondSuccess({ data: newRegistry }); } async update(body, queryParams) { var _a, _b; let { organization, serviceAccount, provider: providerShortName, host, imageBaseURL, apiAccessToken, dockerUsername, dockerPassword, dockerServer, } = body; const updateData = body; if (providerShortName && (0, class_validator_1.isNotIn)(providerShortName, SystemTypes_1.registryProviderList)) return interfaces.respondFailure({ msg: `Container registry provider should be one of [${SystemTypes_1.registryProviderList.join(", ")}]` }); if (providerShortName === "gcloud") { if (!host) host = "gcr.io"; if (!serviceAccount) return interfaces.respondFailure({ msg: `Service Account (JSON) is required to authenticate Google Container Registry.` }); if (!imageBaseURL) imageBaseURL = `${host}/${organization}`; } if (providerShortName === "digitalocean") { if (!host) host = "registry.digitalocean.com"; if (!apiAccessToken) return interfaces.respondFailure({ msg: `API access token is required to authenticate DigitalOcean Container Registry.` }); if (!imageBaseURL) imageBaseURL = `${host}/${organization}`; } if (providerShortName === "dockerhub") { if (!dockerUsername) return interfaces.respondFailure({ msg: `Docker username is required.` }); if (!dockerPassword) return interfaces.respondFailure({ msg: `Docker password is required.` }); if (!dockerServer) dockerServer = "https://index.docker.io/v2/"; if (!host) host = "docker.io"; if (!imageBaseURL) imageBaseURL = `${host}/${organization}`; } const { DB } = await Promise.resolve().then(() => __importStar(require("../modules/api/DB"))); // update db let [updatedRegistry] = await DB.update("registry", this.filter, updateData); if (!updatedRegistry) return interfaces.respondFailure({ msg: `Failed to update.` }); // verify container registry connection... let verifiedRegistry; const authRes = await (0, connect_registry_1.connectRegistry)(updatedRegistry, { userId: (_a = this.user) === null || _a === void 0 ? void 0 : _a._id, workspaceId: (_b = this.workspace) === null || _b === void 0 ? void 0 : _b._id }); [verifiedRegistry] = await DB.update("registry", { _id: updatedRegistry._id }, { isVerified: authRes ? true : false }); return interfaces.respondSuccess({ data: updatedRegistry }); } delete(queryParams) { return super.delete(); } async connect(queryParams) { var _a, _b; const result = { status: 1, messages: [], data: {} }; const options = { userId: mongodb_1.MongoDB.toString((_a = this.user) === null || _a === void 0 ? void 0 : _a._id), workspaceId: mongodb_1.MongoDB.toString((_b = this.user) === null || _b === void 0 ? void 0 : _b.activeWorkspace) }; // console.log("options :>> ", options); const { slug } = this.filter.query; if (!slug) { result.status = 0; result.messages = [`Param "slug" is required.`]; return result; } const registry = await this.service.findOne({ slug }); if (!registry) { result.status = 0; result.messages = [`Container Registry not found: ${slug}.`]; return result; } // console.log("registry :>> ", registry); const { provider, host } = registry; switch (provider) { case "gcloud": const { serviceAccount } = registry; const tmpFilePath = (0, plugins_1.createTmpFile)(`gsa.json`, serviceAccount); const authResult = await gcloud_1.default.authenticate({ filePath: tmpFilePath, host, ...options }); // console.log("authResult :>> ", authResult); if (authResult) { result.status = 1; result.messages = ["Ok"]; } else { result.status = 0; result.messages = [`Google Cloud Container Registry authentication failed.`]; } // delete temporary service account (0, fs_1.unlink)(tmpFilePath, (err) => err && (0, log_1.logError)(`[REGISTRY CONTROLLER] Remove tmp file:`, err)); return result; case "digitalocean": const { apiAccessToken } = registry; const doResult = await digitalocean_1.default.authenticate({ key: apiAccessToken, ...options }); if (doResult) { result.status = 1; result.messages = ["Ok"]; } else { result.status = 0; result.messages = [`Digital Ocean Container Registry authentication failed.`]; } return result; default: result.status = 0; result.messages = [`This container registry is not supported (${provider}), only "gcloud" and "digitalocean" are supported.`]; return result; } } }; __decorate([ (0, dist_1.Security)("api_key"), (0, dist_1.Security)("jwt"), (0, dist_1.Get)("/"), __param(0, (0, dist_1.Queries)()), __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", void 0) ], ContainerRegistryController.prototype, "read", null); __decorate([ (0, dist_1.Security)("api_key"), (0, dist_1.Security)("jwt"), (0, dist_1.Get)("/all"), __param(0, (0, dist_1.Queries)()), __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", Promise) ], ContainerRegistryController.prototype, "readAll", null); __decorate([ (0, dist_1.Security)("api_key"), (0, dist_1.Security)("jwt"), (0, dist_1.Post)("/"), __param(0, (0, dist_1.Body)()), __param(1, (0, dist_1.Queries)()), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], ContainerRegistryController.prototype, "create", null); __decorate([ (0, dist_1.Security)("api_key"), (0, dist_1.Security)("jwt"), (0, dist_1.Patch)("/"), __param(0, (0, dist_1.Body)()), __param(1, (0, dist_1.Queries)()), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], ContainerRegistryController.prototype, "update", null); __decorate([ (0, dist_1.Security)("api_key"), (0, dist_1.Security)("jwt"), (0, dist_1.Delete)("/"), __param(0, (0, dist_1.Queries)()), __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", void 0) ], ContainerRegistryController.prototype, "delete", null); __decorate([ (0, dist_1.Security)("api_key"), (0, dist_1.Security)("jwt"), (0, dist_1.Get)("/connect"), __param(0, (0, dist_1.Queries)()), __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", Promise) ], ContainerRegistryController.prototype, "connect", null); ContainerRegistryController = __decorate([ (0, dist_1.Tags)("Container Registry"), (0, dist_1.Route)("registry"), __metadata("design:paramtypes", []) ], ContainerRegistryController); exports.default = ContainerRegistryController;