UNPKG

@hashgraph/solo

Version:

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

211 lines 10.9 kB
// SPDX-License-Identifier: Apache-2.0 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); } }; import { SoloError } from '../core/errors/solo-error.js'; import { ShellRunner } from '../core/shell-runner.js'; import * as constants from '../core/constants.js'; import fs from 'node:fs'; import { Flags as flags, Flags } from './flags.js'; import { inject } from 'tsyringe-neo'; import { patchInject } from '../core/dependency-injection/container-helper.js'; import { InjectTokens } from '../core/dependency-injection/inject-tokens.js'; import { NamespaceName } from '../types/namespace/namespace-name.js'; import { resolveNamespaceFromDeployment } from '../core/resolvers.js'; import { Templates } from '../core/templates.js'; import { ComponentTypes } from '../core/config/remote/enumerations/component-types.js'; import { NodeCommandTasks } from './node/tasks.js'; import { SoloConfig } from '../business/runtime-state/config/solo/solo-config.js'; let BaseCommand = class BaseCommand extends ShellRunner { helm; k8Factory; chartManager; configManager; depManager; leaseManager; localConfig; remoteConfig; taskList; componentFactory; oneShotState; nodeCommandTasks; configProvider; soloConfig; constructor(helm, k8Factory, chartManager, configManager, depManager, leaseManager, localConfig, remoteConfig, taskList, componentFactory, oneShotState, nodeCommandTasks, configProvider) { super(); this.helm = helm; this.k8Factory = k8Factory; this.chartManager = chartManager; this.configManager = configManager; this.depManager = depManager; this.leaseManager = leaseManager; this.localConfig = localConfig; this.remoteConfig = remoteConfig; this.taskList = taskList; this.componentFactory = componentFactory; this.oneShotState = oneShotState; this.nodeCommandTasks = nodeCommandTasks; this.configProvider = configProvider; this.helm = patchInject(helm, InjectTokens.Helm, this.constructor.name); this.k8Factory = patchInject(k8Factory, InjectTokens.K8Factory, this.constructor.name); this.chartManager = patchInject(chartManager, InjectTokens.ChartManager, this.constructor.name); this.configManager = patchInject(configManager, InjectTokens.ConfigManager, this.constructor.name); this.depManager = patchInject(depManager, InjectTokens.DependencyManager, this.constructor.name); this.leaseManager = patchInject(leaseManager, InjectTokens.LockManager, this.constructor.name); this.localConfig = patchInject(localConfig, InjectTokens.LocalConfigRuntimeState, this.constructor.name); this.remoteConfig = patchInject(remoteConfig, InjectTokens.RemoteConfigRuntimeState, this.constructor.name); this.taskList = patchInject(taskList, InjectTokens.TaskList, this.constructor.name); this.componentFactory = patchInject(componentFactory, InjectTokens.ComponentFactory, this.constructor.name); this.oneShotState = patchInject(oneShotState, InjectTokens.OneShotState, this.constructor.name); this.nodeCommandTasks = patchInject(nodeCommandTasks, InjectTokens.NodeCommandTasks, this.constructor.name); this.configProvider = patchInject(configProvider, InjectTokens.ConfigProvider, this.constructor.name); this.soloConfig = SoloConfig.getConfig(this.configProvider); } async loadRemoteConfigOrWarn(argv, validate = true, skipConsensusNodesValidation = true) { try { await this.remoteConfig.loadAndValidate(argv, validate, skipConsensusNodesValidation); return true; } catch (error) { this.logger.warn(`Failed to load remote config; continuing destroy: ${error instanceof Error ? error.message : error}`); return false; } } /** * Setup home directories * @param directories */ setupHomeDirectory(directories = []) { if (!directories || directories?.length === 0) { directories = [ constants.SOLO_HOME_DIR, constants.SOLO_LOGS_DIR, this.configManager.getFlag(Flags.cacheDir) || constants.SOLO_CACHE_DIR, constants.SOLO_VALUES_DIR, ]; } try { for (const directoryPath of directories) { if (!fs.existsSync(directoryPath)) { fs.mkdirSync(directoryPath, { recursive: true }); } this.logger.debug(`OK: setup directory: ${directoryPath}`); } } catch (error) { throw new SoloError(`failed to create directory: ${error.message}`, error); } return directories; } getClusterReference() { const flagValue = this.configManager.getFlag(flags.clusterRef); // If flag is provided, use it if (flagValue) { return flagValue; } // Try to auto-select if only one cluster exists in the deployment try { if (this.remoteConfig?.isLoaded()) { const clusterReferences = this.remoteConfig.getClusterRefs(); if (clusterReferences.size === 1) { // Auto-select the only available cluster const clusterReference = [...clusterReferences.keys()][0]; this.logger.debug(`Auto-selected cluster reference: ${clusterReference} (only cluster in deployment)`); return clusterReference; } else if (clusterReferences.size > 1) { // Multiple clusters exist - list them in error message const clusterList = [...clusterReferences.keys()].join(', '); throw new SoloError(`Multiple clusters found (${clusterList}). Please specify --cluster-ref to select one.`); } } } catch (error) { // If it's our SoloError about multiple clusters, re-throw it if (error instanceof SoloError && error.message.includes('Multiple clusters found')) { throw error; } // Otherwise, fall through to default behavior this.logger.debug(`Could not auto-select cluster: ${error.message}`); } // Fall back to current cluster from kubeconfig return this.k8Factory.default().clusters().readCurrent(); } getClusterContext(clusterReference) { return clusterReference ? this.localConfig.configuration.clusterRefs.get(clusterReference)?.toString() : this.k8Factory.default().contexts().readCurrent(); } getNamespace(task) { return resolveNamespaceFromDeployment(this.localConfig, this.configManager, task); } async throwIfNamespaceIsMissing(context, namespace) { if (!(await this.k8Factory.getK8(context).namespaces().has(namespace))) { throw new SoloError(`namespace ${namespace} does not exist`); } } inferMirrorNodeDataFromRemoteConfig(namespace) { let mirrorNodeId = this.configManager.getFlag(flags.mirrorNodeId); let mirrorNamespace = this.configManager.getFlag(flags.mirrorNamespace); const mirrorNodeComponent = this.remoteConfig.configuration.components.state.mirrorNodes[0]; if (!mirrorNodeId) { mirrorNodeId = mirrorNodeComponent?.metadata.id ?? 1; } if (!mirrorNamespace) { mirrorNamespace = mirrorNodeComponent?.metadata.namespace ?? namespace.name; } return { mirrorNodeId, mirrorNamespace }; } async inferMirrorNodeData(namespace, context) { const { mirrorNodeId, mirrorNamespace } = this.inferMirrorNodeDataFromRemoteConfig(namespace); const mirrorNodeReleaseName = await this.inferMirrorNodeReleaseName(mirrorNodeId, mirrorNamespace, context); return { mirrorNodeId, mirrorNamespace, mirrorNodeReleaseName }; } async inferMirrorNodeReleaseName(mirrorNodeId, mirrorNodeNamespace, context) { if (mirrorNodeId !== 1) { return Templates.renderMirrorNodeName(mirrorNodeId); } // Try to get the component and use the precise cluster context try { const mirrorNodeComponent = this.remoteConfig.configuration.components.getComponentById(ComponentTypes.MirrorNode, mirrorNodeId); if (mirrorNodeComponent) { context = this.getClusterContext(mirrorNodeComponent.metadata.cluster); } } catch { // Guard } const isLegacyChartInstalled = await this.chartManager.isChartInstalled(NamespaceName.of(mirrorNodeNamespace), constants.MIRROR_NODE_RELEASE_NAME, context); return isLegacyChartInstalled ? constants.MIRROR_NODE_RELEASE_NAME : Templates.renderMirrorNodeName(mirrorNodeId); } async resolveNamespaceFromDeployment(task) { return await resolveNamespaceFromDeployment(this.localConfig, this.configManager, task); } }; BaseCommand = __decorate([ __param(0, inject(InjectTokens.Helm)), __param(1, inject(InjectTokens.K8Factory)), __param(2, inject(InjectTokens.ChartManager)), __param(3, inject(InjectTokens.ConfigManager)), __param(4, inject(InjectTokens.DependencyManager)), __param(5, inject(InjectTokens.LockManager)), __param(6, inject(InjectTokens.LocalConfigRuntimeState)), __param(7, inject(InjectTokens.RemoteConfigRuntimeState)), __param(8, inject(InjectTokens.TaskList)), __param(9, inject(InjectTokens.ComponentFactory)), __param(10, inject(InjectTokens.OneShotState)), __param(11, inject(InjectTokens.NodeCommandTasks)), __param(12, inject(InjectTokens.ConfigProvider)), __metadata("design:paramtypes", [Object, Object, Function, Function, Function, Function, Function, Object, Object, Object, Function, NodeCommandTasks, Object]) ], BaseCommand); export { BaseCommand }; //# sourceMappingURL=base.js.map