@topgroup/diginext
Version:
A BUILD SERVER & CLI to deploy apps to any Kubernetes clusters.
154 lines (153 loc) • 6.85 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClusterService = void 0;
const Cluster_1 = require("../entities/Cluster");
const k8s_1 = __importDefault(require("../modules/k8s"));
const image_pull_secret_1 = require("../modules/k8s/image-pull-secret");
const kube_config_1 = require("../modules/k8s/kube-config");
const user_utils_1 = require("../plugins/user-utils");
const BaseService_1 = __importDefault(require("./BaseService"));
class ClusterService extends BaseService_1.default {
constructor(ownership) {
super(Cluster_1.clusterSchema, ownership);
}
find(filter, options, pagination) {
var _a, _b, _c, _d, _e;
let includePublicFilter = { $or: [] };
// include all public clusters
// if (!filter.workspace) {
includePublicFilter.$or.push(filter);
// includePublicFilter.$or.push({ ...filter, workspace: { $exists: false } }, { ...filter, workspace: null });
// }
// check access permissions
if ((_c = (_b = (_a = this.user) === null || _a === void 0 ? void 0 : _a.allowAccess) === null || _b === void 0 ? void 0 : _b.clusters) === null || _c === void 0 ? void 0 : _c.length)
includePublicFilter.$or.push({ _id: { $in: (_e = (_d = this.user) === null || _d === void 0 ? void 0 : _d.allowAccess) === null || _e === void 0 ? void 0 : _e.clusters } });
// if none of the above conditions -> filter normally
if (includePublicFilter.$or.length === 0)
includePublicFilter = filter;
// console.log("includePublicFilter :>> ", includePublicFilter);
return super.find(includePublicFilter, options, pagination);
}
findAll(filter, options, pagination) {
var _a, _b, _c, _d, _e;
let includePublicFilter = { $or: [] };
// include all public clusters
// if (!filter.workspace) {
includePublicFilter.$or.push(filter);
includePublicFilter.$or.push({ ...filter, workspace: { $exists: false } }, { ...filter, workspace: null });
// }
// check access permissions
if ((_c = (_b = (_a = this.user) === null || _a === void 0 ? void 0 : _a.allowAccess) === null || _b === void 0 ? void 0 : _b.clusters) === null || _c === void 0 ? void 0 : _c.length)
includePublicFilter.$or.push({ _id: { $in: (_e = (_d = this.user) === null || _d === void 0 ? void 0 : _d.allowAccess) === null || _e === void 0 ? void 0 : _e.clusters } });
// if none of the above conditions -> filter normally
if (includePublicFilter.$or.length === 0)
includePublicFilter = filter;
// console.log("includePublicFilter :>> ", includePublicFilter);
return super.find(includePublicFilter, options, pagination);
}
async findOne(filter, options) {
const [item] = await this.find(filter, options, { limit: 1 });
if (!item)
throw new Error(`Item not found.`);
return item;
}
async update(filter, data, options) {
// check permissions
await (0, user_utils_1.checkPermissionsByFilter)("clusters", this, filter, this.user);
return super.update(filter, data, options);
}
async updateOne(filter, data, options) {
let cluster = await this.findOne(filter, { ...options, populate: ["provider"] });
if (!cluster) {
if (filter.owner) {
throw new Error(`Unauthorized.`);
}
else {
throw new Error(`Cluster not found.`);
}
}
// check permissions
await (0, user_utils_1.checkPermissions)("clusters", cluster, this.user);
// get cloud provider of this cluster
const cloudProvider = cluster.provider;
if (!cloudProvider)
throw new Error(`Cloud Provider not found.`);
// validation - check cluster accessibility
if (cloudProvider.shortName === "gcloud") {
if (!cluster.serviceAccount && !data.serviceAccount)
throw new Error(`Google Service Account (JSON) is required.`);
if (!cluster.zone && !data.zone)
throw new Error(`Google cluster zone is required.`);
}
if (cloudProvider.shortName === "digitalocean") {
if (!cluster.apiAccessToken)
throw new Error(`Digital Ocean API Access Token is required.`);
}
if (cloudProvider.shortName === "custom") {
if (!cluster.kubeConfig && !data.kubeConfig)
throw new Error(`Kube config data (YAML) is required.`);
}
// update to database
cluster = await super.updateOne({ _id: cluster._id }, data, options);
return cluster;
}
async delete(filter, options) {
// try to delete "context" in "~/.kube/config"
try {
const cluster = await this.findOne(filter, options);
// check permissions
await (0, user_utils_1.checkPermissionsById)("clusters", cluster._id, this.user);
await (0, kube_config_1.deleteClusterInKubeConfig)(cluster);
}
catch (e) {
throw new Error(`Unable to delete cluster: ${e}`);
}
return super.delete(filter, options);
}
// verify accessibility...
async authCluster(cluster, options) {
return k8s_1.default.authCluster(cluster, options);
}
/**
* Check if required stacks are installed within the cluster
* @param cluster
*/
async checkStackInstalled(cluster, options) {
/**
* Check for required stack installations, if not -> install them:
*/
try {
// [1] NGINX Ingress
await k8s_1.default.installNginxIngressStack(cluster, options);
// [2] Cert Manager
await k8s_1.default.installCertManagerStack(cluster, options);
return true;
}
catch (e) {
return false;
}
}
/**
* Create "imagePullSecret" in a namespace of a cluster
*/
async createImagePullSecret(filter, data, options) {
// find cluster
const { clusterSlug } = data;
let cluster = await this.findOne({ slug: clusterSlug });
if (!cluster) {
if (filter.owner) {
throw new Error(`Unauthorized.`);
}
else {
throw new Error(`Cluster not found.`);
}
}
// check permissions
await (0, user_utils_1.checkPermissionsById)("clusters", cluster._id, this.user);
return (0, image_pull_secret_1.createImagePullSecrets)(data);
}
}
exports.ClusterService = ClusterService;