"use strict";
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 __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
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 __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
Object.defineProperty(exports, "__esModule", { value: true });
var typescript_ioc_1 = require("typescript-ioc");
var SimpleConfigClient_1 = require("./SimpleConfigClient");
var cm_tools_1 = require("../refs/cm-tools");
var SysBasicCache_1 = require("./SysBasicCache");
var K8SClientFactory_1 = require("./K8SClientFactory");
var cm_models_1 = require("../refs/cm-models");
var mslib_1 = require("mslib");
var K8SDeployParamBuilder = /** @class */ (function () {
    function K8SDeployParamBuilder() {
    }
    /**
     * 构建K8S部署参数
     * @param deployConfig 基础服务部署配置信息
     * @param logloggerBuilder 日志构建器，用于管理后台显示部署日志详情
     */
    K8SDeployParamBuilder.prototype.build = function (deployConfig, loggerBuilder) {
        return __awaiter(this, void 0, void 0, function () {
            var op, appOptionsConfig, k8sClient, envs, k8sConfig, appName, data, i, uuid, podName, deployParam, podDeployParam, pvcParam, ports, param;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        op = this.acquireAppOptionsConfig(deployConfig, loggerBuilder);
                        if (!op.isSuccess()) {
                            return [2 /*return*/, op];
                        }
                        loggerBuilder.appendln("\u89E3\u6790\u5E94\u7528\u9009\u9879\u914D\u7F6E\u5B8C\u6210......");
                        appOptionsConfig = op.data;
                        k8sClient = this.k8sClientFactory.getClient(deployConfig.k8sId);
                        return [4 /*yield*/, this.acquireEnvs(deployConfig, appOptionsConfig, k8sClient.config.cloudProvider, loggerBuilder)];
                    case 1:
                        op = _a.sent();
                        if (!op.isSuccess()) {
                            return [2 /*return*/, op];
                        }
                        loggerBuilder.appendln('解析配置环境变量完成......');
                        envs = op.data;
                        k8sConfig = k8sClient.config;
                        appName = this.buildAppName(deployConfig.appType, deployConfig.id);
                        data = {
                            deployParams: []
                        };
                        for (i = 0; i < appOptionsConfig.elasticConfig.minInstance; i++) {
                            uuid = cm_tools_1.DaoUtils.uuid();
                            podName = appName + "-" + uuid.substring(0, 10) + "-" + i;
                            deployParam = {
                                deployId: deployConfig.id,
                                appName: podName,
                                cpu: appOptionsConfig.specConfig.instanceCpu,
                                memory: appOptionsConfig.specConfig.instanceMemory,
                                image: deployConfig.image,
                                command: deployConfig.startScript,
                                replicas: 1,
                                labels: {
                                    appType: deployConfig.appType,
                                    deployId: deployConfig.id,
                                    deployTag: "" + deployConfig.deployTag
                                },
                                envs: envs,
                                imagePullSecret: k8sConfig.defaultImagePullSecret,
                                pvc: {
                                    name: podName,
                                    mountPath: '/ext'
                                },
                                ports: this.parsePorts(deployConfig.imagePortMapping),
                            };
                            podDeployParam = { deployParam: deployParam };
                            if (appOptionsConfig.pvcConfig && appOptionsConfig.pvcConfig.enabled === true) {
                                pvcParam = {
                                    name: podName,
                                    storage: (appOptionsConfig.pvcConfig.diskSize || (k8sConfig.defaultStorage || 20)) + '',
                                    storageClassName: k8sConfig.defaultStorageClassName
                                };
                                podDeployParam.pvcParam = pvcParam;
                            }
                            data.deployParams.push(podDeployParam);
                        }
                        if (deployConfig.slbPortMapping) {
                            ports = this.parseServicePorts(deployConfig.slbPortMapping);
                            if (ports.length > 0) {
                                param = {
                                    name: appName,
                                    podLabel: deployConfig.id,
                                    networkType: deployConfig.networkType,
                                    slbId: deployConfig.slbId,
                                    ports: ports
                                };
                                data.serviceParam = param;
                            }
                        }
                        loggerBuilder.appendln('参数构建完成，准备开始部署K8S---');
                        return [2 /*return*/, mslib_1.OpResult.success('OK', data)];
                }
            });
        });
    };
    K8SDeployParamBuilder.prototype.buildAppName = function (appType, deployId) {
        return (appType + "-" + deployId).toLowerCase();
    };
    /**
     * 解析获取应用选项配置信息
     */
    K8SDeployParamBuilder.prototype.acquireAppOptionsConfig = function (deployConfig, loggerBuilder) {
        if (!deployConfig.appOptionsConfig) {
            loggerBuilder.appendln("\u90E8\u7F72\u5931\u8D25\uFF0C\u5E94\u7528\u9009\u9879\u914D\u7F6EJSON\u4E3A\u7A7A[appOptionsConfig]");
            return mslib_1.OpResult.error(loggerBuilder.toString());
        }
        var appOptionsConfig = deployConfig.appOptionsConfig;
        var op = cm_models_1.AppOptionsConfigChcker.check(appOptionsConfig);
        if (!op.isSuccess()) {
            loggerBuilder.appendln("\u90E8\u7F72\u5931\u8D25\uFF0C" + op.message);
            return mslib_1.OpResult.error(loggerBuilder.toString());
        }
        return mslib_1.OpResult.success('OK', appOptionsConfig);
    };
    /**
     * 获取环境变量信息
     */
    K8SDeployParamBuilder.prototype.acquireEnvs = function (deployConfig, appOptionsConfig, cloudProvider, loggerBuilder) {
        return __awaiter(this, void 0, void 0, function () {
            var op, envs, logConfig, logKafkaServer, logKafkaTopic, logKafkaHost, logKafkaPort, hosts, key;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.acquireConfigs(deployConfig, loggerBuilder)];
                    case 1:
                        op = _a.sent();
                        if (!op.isSuccess()) {
                            return [2 /*return*/, op];
                        }
                        envs = Object.assign(deployConfig.envs || {}, op.data);
                        //3. 中台固有环境变量设置
                        envs['KT_ENV_CODE'] = deployConfig.envCode.toUpperCase();
                        envs['KT_APP_TYPE'] = deployConfig.appType;
                        envs['KT_DEPLOY_ID'] = deployConfig.id;
                        envs['KT_PROJECT_NAME'] = deployConfig.name;
                        envs['KT_APP_NAME'] = deployConfig.name;
                        envs['KT_LOG_FILE_NAME'] = 'output.log';
                        envs['KT_LOG_PATH'] = '/ext/logs';
                        envs['KT_K8S_ID'] = deployConfig.k8sId;
                        envs['KT_K8S_DEPLOYMENT'] = deployConfig.id;
                        envs['KT_CONFIG_SERVER_URL'] = this.getConfigServerUrl(deployConfig);
                        logConfig = appOptionsConfig.logConfig;
                        logKafkaServer = logConfig.server;
                        logKafkaTopic = logConfig.topic;
                        logKafkaHost = cloudProvider !== 'ALIYUN' ? logConfig.internetIp : logConfig.ip;
                        logKafkaPort = cloudProvider !== 'ALIYUN' ? logConfig.internetPort : logConfig.port;
                        envs['KT_KAFKA_TOPIC'] = logKafkaTopic;
                        envs['KT_KAFKA_SERVER'] = logKafkaServer;
                        envs['KT_KAFKA_PORT'] = logKafkaPort;
                        hosts = [];
                        //业务系统配置在配置中心的KT_ME_HOSTS参数
                        if (envs['KT_ME_HOSTS'] && envs['KT_ME_HOSTS'].length > 0) {
                            hosts = hosts.concat(envs['KT_ME_HOSTS'].toString().split('|'));
                        }
                        //中台服务的HOST设置
                        if (this.ktMeHosts && this.ktMeHosts.length > 0) {
                            hosts = hosts.concat(this.ktMeHosts);
                        }
                        //kafka host
                        hosts.push(logKafkaServer + ":" + logKafkaHost);
                        if (hosts.length > 0) {
                            envs['KT_ME_HOSTS'] = hosts.join('|');
                        }
                        for (key in envs) {
                            if (!envs[key] && envs[key] != 0 && envs[key] != false) {
                                delete envs[key];
                                continue;
                            }
                            envs[key] = envs[key].toString();
                        }
                        return [2 /*return*/, mslib_1.OpResult.success('OK', envs)];
                }
            });
        });
    };
    /**
     * 从配置中心获取配置
     * @param deployConfig 部署配置
     * @param
     */
    K8SDeployParamBuilder.prototype.acquireConfigs = function (deployConfig, loggerBuilder) {
        return __awaiter(this, void 0, void 0, function () {
            var serviceCenter, sysEnv, configCodes, configObj, _i, configCodes_1, config, configCode, configVersion, configServerUrl, op;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (cm_tools_1.DaoUtils.isEmpty(deployConfig.configCenterCode)) {
                            return [2 /*return*/, mslib_1.OpResult.success('OK', {})];
                        }
                        serviceCenter = this.sysBasicCache.getServiceCenter(deployConfig.serviceCenterId);
                        sysEnv = this.sysBasicCache.getSysEnv(deployConfig.envId);
                        configCodes = deployConfig.configCenterCode;
                        configObj = {};
                        _i = 0, configCodes_1 = configCodes;
                        _a.label = 1;
                    case 1:
                        if (!(_i < configCodes_1.length)) return [3 /*break*/, 4];
                        config = configCodes_1[_i];
                        configCode = serviceCenter.code + "." + config.code;
                        configVersion = config.version;
                        loggerBuilder.appendln("\u51C6\u5907\u52A0\u8F7D\u914D\u7F6E\u6587\u4EF6" + configCode + "/" + configVersion + "......");
                        configServerUrl = this.getConfigServerUrl(deployConfig) + '/getConfigFile/json';
                        return [4 /*yield*/, this.configClient.getConfig(configServerUrl, deployConfig.envCode, sysEnv.envKey, configCode, configVersion)];
                    case 2:
                        op = _a.sent();
                        if (op.isSuccess()) {
                            loggerBuilder.appendln("\u52A0\u8F7D\u914D\u7F6E\u6587\u4EF6\u6210\u529F" + configCode + "/" + configVersion);
                            configObj = Object.assign(configObj, op.data);
                        }
                        else {
                            loggerBuilder.appendln("\u52A0\u8F7D\u914D\u7F6E\u6587\u4EF6\u5931\u8D25" + configCode + "/" + configVersion + ",message:" + op.message);
                            return [2 /*return*/, op];
                        }
                        _a.label = 3;
                    case 3:
                        _i++;
                        return [3 /*break*/, 1];
                    case 4: return [2 /*return*/, mslib_1.OpResult.success('OK', configObj)];
                }
            });
        });
    };
    K8SDeployParamBuilder.prototype.getConfigServerUrl = function (deployConfig) {
        var configServerUrl = process.env['KT_CONFIG_SERVER_URL'];
        if (deployConfig.serviceCenterId === 'b049c1c4fd1c4baa8982521de3a3de16') { //开发环境服务中心
            configServerUrl = 'http://47.114.9.86:3008/conf';
        }
        return configServerUrl;
    };
    /**
     * 端口号配置解析
     * @param
     */
    K8SDeployParamBuilder.prototype.parseServicePorts = function (ports) {
        if (!ports) {
            return [];
        }
        var result = [];
        for (var _i = 0, ports_1 = ports; _i < ports_1.length; _i++) {
            var portConfig = ports_1[_i];
            if (portConfig.targetPort && portConfig.slbPort) {
                var obj = {
                    targetPort: parseInt(portConfig.targetPort.toString()),
                    protocol: portConfig.protocol,
                    nodePort: parseInt(portConfig.slbPort.toString()),
                };
                result.push(obj);
            }
        }
        return result;
    };
    /**
     * 端口号配置解析
     * @param
     */
    K8SDeployParamBuilder.prototype.parsePorts = function (ports) {
        if (!ports) {
            return [];
        }
        var result = [];
        for (var _i = 0, ports_2 = ports; _i < ports_2.length; _i++) {
            var portConfig = ports_2[_i];
            if (portConfig.port.indexOf('-') > -1) {
                var range = portConfig.port.split('-');
                if (range.length == 2) {
                    var portRange = this.getRangePorts(range[0], range[1]);
                    for (var _a = 0, portRange_1 = portRange; _a < portRange_1.length; _a++) {
                        var p = portRange_1[_a];
                        var obj = {
                            port: p,
                            protocol: portConfig.protocol
                        };
                        result.push(obj);
                    }
                }
            }
            else {
                var obj = {
                    port: portConfig.port,
                    protocol: portConfig.protocol
                };
                result.push(obj);
            }
        }
        return result;
    };
    K8SDeployParamBuilder.prototype.getRangePorts = function (begin, end) {
        var result = [];
        var _begin = parseInt(begin);
        var _end = parseInt(end);
        for (var i = _begin; i <= _end; i++) {
            result.push(i);
        }
        return result;
    };
    __decorate([
        typescript_ioc_1.Inject,
        __metadata("design:type", SimpleConfigClient_1.SimpleConfigClient)
    ], K8SDeployParamBuilder.prototype, "configClient", void 0);
    __decorate([
        typescript_ioc_1.Inject,
        __metadata("design:type", SysBasicCache_1.SysBasicCache)
    ], K8SDeployParamBuilder.prototype, "sysBasicCache", void 0);
    __decorate([
        typescript_ioc_1.Inject,
        __metadata("design:type", K8SClientFactory_1.K8SClientFactory)
    ], K8SDeployParamBuilder.prototype, "k8sClientFactory", void 0);
    __decorate([
        mslib_1.Value('kt-me-hosts'),
        __metadata("design:type", Object)
    ], K8SDeployParamBuilder.prototype, "ktMeHosts", void 0);
    K8SDeployParamBuilder = __decorate([
        typescript_ioc_1.Singleton
    ], K8SDeployParamBuilder);
    return K8SDeployParamBuilder;
}());
exports.K8SDeployParamBuilder = K8SDeployParamBuilder;
//# sourceMappingURL=K8SDeployParamBuilder.js.map