UNPKG

@hashgraph/solo

Version:

An opinionated CLI tool to deploy and manage private Hedera Networks.

219 lines 9.85 kB
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 __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; /** * SPDX-License-Identifier: Apache-2.0 */ import { IsEmail, IsNotEmpty, IsObject, IsString, validateSync } from 'class-validator'; import fs from 'fs'; import * as yaml from 'yaml'; import { Flags as flags } from '../../commands/flags.js'; import { MissingArgumentError, SoloError } from '../errors.js'; import { IsClusterRefs, IsDeployments } from '../validator_decorators.js'; import { ErrorMessages } from '../error_messages.js'; import * as helpers from '../helpers.js'; import { inject, injectable } from 'tsyringe-neo'; import { patchInject } from '../dependency_injection/container_helper.js'; import { InjectTokens } from '../dependency_injection/inject_tokens.js'; let LocalConfig = class LocalConfig { filePath; logger; configManager; userEmailAddress; soloVersion; // The string is the name of the deployment, will be used as the namespace, // so it needs to be available in all targeted clusters deployments; clusterRefs = {}; skipPromptTask = false; constructor(filePath, logger, configManager) { this.filePath = filePath; this.logger = logger; this.configManager = configManager; this.filePath = patchInject(filePath, InjectTokens.LocalConfigFilePath, this.constructor.name); this.logger = patchInject(logger, InjectTokens.SoloLogger, this.constructor.name); this.configManager = patchInject(configManager, InjectTokens.ConfigManager, this.constructor.name); if (!this.filePath || this.filePath === '') throw new MissingArgumentError('a valid filePath is required'); const allowedKeys = ['userEmailAddress', 'deployments', 'clusterRefs', 'soloVersion']; if (this.configFileExists()) { const fileContent = fs.readFileSync(filePath, 'utf8'); const parsedConfig = yaml.parse(fileContent); for (const key in parsedConfig) { if (!allowedKeys.includes(key)) { throw new SoloError(ErrorMessages.LOCAL_CONFIG_GENERIC); } this[key] = parsedConfig[key]; } this.validate(); this.skipPromptTask = true; } } validate() { const errors = validateSync(this, {}); if (errors.length) { // throw the first error: const prop = Object.keys(errors[0]?.constraints); if (prop[0]) { throw new SoloError(errors[0].constraints[prop[0]]); } else { throw new SoloError(ErrorMessages.LOCAL_CONFIG_GENERIC); } } } setUserEmailAddress(emailAddress) { this.userEmailAddress = emailAddress; this.validate(); return this; } setDeployments(deployments) { this.deployments = deployments; this.validate(); return this; } setClusterRefs(clusterRefs) { this.clusterRefs = clusterRefs; this.validate(); return this; } setSoloVersion(version) { this.soloVersion = version; this.validate(); return this; } configFileExists() { return fs.existsSync(this.filePath); } async write() { const yamlContent = yaml.stringify({ userEmailAddress: this.userEmailAddress, deployments: this.deployments, clusterRefs: this.clusterRefs, soloVersion: this.soloVersion, }); await fs.promises.writeFile(this.filePath, yamlContent); this.logger.info(`Wrote local config to ${this.filePath}: ${yamlContent}`); } promptLocalConfigTask(k8Factory) { const self = this; return { title: 'Prompt local configuration', skip: this.skipPromptTask, task: async (_, task) => { if (self.configFileExists()) { self.configManager.setFlag(flags.userEmailAddress, self.userEmailAddress); } const isQuiet = self.configManager.getFlag(flags.quiet); const contexts = self.configManager.getFlag(flags.context); const deploymentName = self.configManager.getFlag(flags.deployment); const namespace = self.configManager.getFlag(flags.namespace); let userEmailAddress = self.configManager.getFlag(flags.userEmailAddress); let deploymentClusters = self.configManager.getFlag(flags.deploymentClusters); if (!userEmailAddress) { if (isQuiet) throw new SoloError(ErrorMessages.LOCAL_CONFIG_INVALID_EMAIL); userEmailAddress = await flags.userEmailAddress.prompt(task, userEmailAddress); self.configManager.setFlag(flags.userEmailAddress, userEmailAddress); } if (!deploymentName) throw new SoloError('Deployment name was not specified'); if (!deploymentClusters) { if (isQuiet) { deploymentClusters = k8Factory.default().clusters().readCurrent(); } else { deploymentClusters = await flags.deploymentClusters.prompt(task, deploymentClusters); } self.configManager.setFlag(flags.deploymentClusters, deploymentClusters); } const parsedClusterRefs = helpers.splitFlagInput(deploymentClusters); const deployments = { [deploymentName]: { clusters: parsedClusterRefs, namespace: namespace.name, }, }; const parsedContexts = helpers.splitFlagInput(contexts); if (parsedContexts.length < parsedClusterRefs.length) { if (!isQuiet) { const promptedContexts = []; for (const clusterRef of parsedClusterRefs) { const kubeContexts = k8Factory.default().contexts().list(); const context = await flags.context.prompt(task, kubeContexts, clusterRef); self.clusterRefs[clusterRef] = context; promptedContexts.push(context); self.configManager.setFlag(flags.context, context); } self.configManager.setFlag(flags.context, promptedContexts.join(',')); } else { const context = k8Factory.default().contexts().readCurrent(); for (const clusterRef of parsedClusterRefs) { self.clusterRefs[clusterRef] = context; } self.configManager.setFlag(flags.context, context); } } else { for (let i = 0; i < parsedClusterRefs.length; i++) { const clusterRef = parsedClusterRefs[i]; self.clusterRefs[clusterRef] = parsedContexts[i]; self.configManager.setFlag(flags.context, parsedContexts[i]); } } self.userEmailAddress = userEmailAddress; self.deployments = deployments; self.soloVersion = helpers.getSoloVersion(); self.validate(); await self.write(); }, }; } }; __decorate([ IsEmail({}, { message: ErrorMessages.LOCAL_CONFIG_INVALID_EMAIL, }), __metadata("design:type", String) ], LocalConfig.prototype, "userEmailAddress", void 0); __decorate([ IsString({ message: ErrorMessages.LOCAL_CONFIG_INVALID_SOLO_VERSION }), IsNotEmpty({ message: ErrorMessages.LOCAL_CONFIG_INVALID_SOLO_VERSION }), __metadata("design:type", String) ], LocalConfig.prototype, "soloVersion", void 0); __decorate([ IsDeployments({ message: ErrorMessages.LOCAL_CONFIG_INVALID_DEPLOYMENTS_FORMAT, }), IsNotEmpty(), IsObject({ message: ErrorMessages.LOCAL_CONFIG_INVALID_DEPLOYMENTS_FORMAT, }), __metadata("design:type", Object) ], LocalConfig.prototype, "deployments", void 0); __decorate([ IsClusterRefs({ message: ErrorMessages.LOCAL_CONFIG_CONTEXT_CLUSTER_MAPPING_FORMAT, }), IsNotEmpty(), __metadata("design:type", Object) ], LocalConfig.prototype, "clusterRefs", void 0); LocalConfig = __decorate([ injectable(), __param(0, inject(InjectTokens.LocalConfigFilePath)), __param(1, inject(InjectTokens.SoloLogger)), __param(2, inject(InjectTokens.ConfigManager)), __metadata("design:paramtypes", [String, Function, Function]) ], LocalConfig); export { LocalConfig }; //# sourceMappingURL=local_config.js.map