UNPKG

@hashgraph/solo

Version:

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

697 lines 33.3 kB
/** * SPDX-License-Identifier: Apache-2.0 */ import * as helpers from '../../core/helpers.js'; import * as NodeFlags from './flags.js'; import { addConfigBuilder, deleteConfigBuilder, downloadGeneratedFilesConfigBuilder, keysConfigBuilder, logsConfigBuilder, prepareUpgradeConfigBuilder, refreshConfigBuilder, setupConfigBuilder, startConfigBuilder, statesConfigBuilder, stopConfigBuilder, updateConfigBuilder, upgradeConfigBuilder, } from './configs.js'; import * as constants from '../../core/constants.js'; import { IllegalArgumentError, SoloError } from '../../core/errors.js'; import { ComponentType, ConsensusNodeStates } from '../../core/config/remote/enumerations.js'; import { NodeSubcommandType } from '../../core/enumerations.js'; import { NodeHelper } from './helper.js'; import { ConsensusNodeComponent } from '../../core/config/remote/components/consensus_node_component.js'; import chalk from 'chalk'; export class NodeCommandHandlers { accountManager; configManager; platformInstaller; logger; k8Factory; tasks; leaseManager; remoteConfigManager; contexts; consensusNodes; getConfig; prepareChartPath; parent; constructor(opts) { if (!opts || !opts.accountManager) throw new IllegalArgumentError('An instance of core/AccountManager is required', opts.accountManager); if (!opts || !opts.configManager) throw new Error('An instance of core/ConfigManager is required'); if (!opts || !opts.logger) throw new Error('An instance of core/Logger is required'); if (!opts || !opts.tasks) throw new Error('An instance of NodeCommandTasks is required'); if (!opts || !opts.k8Factory) throw new Error('An instance of core/K8Factory is required'); if (!opts || !opts.platformInstaller) throw new IllegalArgumentError('An instance of core/PlatformInstaller is required', opts.platformInstaller); this.logger = opts.logger; this.tasks = opts.tasks; this.accountManager = opts.accountManager; this.configManager = opts.configManager; this.k8Factory = opts.k8Factory; this.platformInstaller = opts.platformInstaller; this.leaseManager = opts.leaseManager; this.remoteConfigManager = opts.remoteConfigManager; this.getConfig = opts.parent.getConfig.bind(opts.parent); this.prepareChartPath = opts.parent.prepareChartPath.bind(opts.parent); this.parent = opts.parent; } static ADD_CONTEXT_FILE = 'node-add.json'; static DELETE_CONTEXT_FILE = 'node-delete.json'; static UPDATE_CONTEXT_FILE = 'node-update.json'; static UPGRADE_CONTEXT_FILE = 'node-upgrade.json'; init() { this.consensusNodes = this.parent.getConsensusNodes(); this.contexts = this.parent.getContexts(); } /** ******** Task Lists **********/ deletePrepareTaskList(argv, lease) { return [ this.tasks.initialize(argv, deleteConfigBuilder.bind(this), lease), this.validateSingleNodeState({ excludedStates: [] }), this.tasks.identifyExistingNodes(), this.tasks.loadAdminKey(), this.tasks.prepareUpgradeZip(), this.tasks.checkExistingNodesStakedAmount(), ]; } deleteSubmitTransactionsTaskList(argv) { return [ this.tasks.sendNodeDeleteTransaction(), this.tasks.sendPrepareUpgradeTransaction(), this.tasks.sendFreezeUpgradeTransaction(), ]; } deleteExecuteTaskList(argv) { return [ this.tasks.checkAllNodesAreFrozen('existingNodeAliases'), this.tasks.downloadNodeGeneratedFiles(), this.tasks.prepareStagingDirectory('existingNodeAliases'), this.tasks.refreshNodeList(), this.tasks.copyNodeKeysToSecrets(), this.tasks.getNodeLogsAndConfigs(), this.tasks.updateChartWithConfigMap('Delete network node', NodeSubcommandType.DELETE), this.tasks.killNodes(), this.tasks.sleep('Give time for pods to come up after being killed', 20000), this.tasks.checkNodePodsAreRunning(), this.tasks.populateServiceMap(), this.tasks.fetchPlatformSoftware('allNodeAliases'), this.tasks.setupNetworkNodes('allNodeAliases', false), this.tasks.startNodes('allNodeAliases'), this.tasks.enablePortForwarding(), this.tasks.checkAllNodesAreActive('allNodeAliases'), this.tasks.checkAllNodeProxiesAreActive(), this.tasks.triggerStakeWeightCalculate(NodeSubcommandType.DELETE), this.tasks.finalize(), ]; } addPrepareTasks(argv, lease) { return [ this.tasks.initialize(argv, addConfigBuilder.bind(this), lease), // TODO instead of validating the state we need to do a remote config add component, and we will need to manually // the nodeAlias based on the next available node ID + 1 // this.validateSingleNodeState({excludedStates: []}), this.tasks.checkPVCsEnabled(), this.tasks.identifyExistingNodes(), this.tasks.determineNewNodeAccountNumber(), this.tasks.copyGrpcTlsCertificates(), this.tasks.generateGossipKey(), this.tasks.generateGrpcTlsKey(), this.tasks.loadSigningKeyCertificate(), this.tasks.computeMTLSCertificateHash(), this.tasks.prepareGossipEndpoints(), this.tasks.prepareGrpcServiceEndpoints(), this.tasks.prepareUpgradeZip(), this.tasks.checkExistingNodesStakedAmount(), ]; } addSubmitTransactionsTasks(argv) { return [ this.tasks.sendNodeCreateTransaction(), this.tasks.sendPrepareUpgradeTransaction(), this.tasks.sendFreezeUpgradeTransaction(), ]; } addExecuteTasks(argv) { return [ this.tasks.checkAllNodesAreFrozen('existingNodeAliases'), this.tasks.downloadNodeGeneratedFiles(), this.tasks.prepareStagingDirectory('allNodeAliases'), this.tasks.copyNodeKeysToSecrets(), this.tasks.getNodeLogsAndConfigs(), this.tasks.updateChartWithConfigMap('Deploy new network node', NodeSubcommandType.ADD), this.tasks.killNodes(), this.tasks.checkNodePodsAreRunning(), this.tasks.populateServiceMap(), this.tasks.fetchPlatformSoftware('allNodeAliases'), this.tasks.downloadLastState(), this.tasks.uploadStateToNewNode(), this.tasks.setupNetworkNodes('allNodeAliases', false), this.tasks.startNodes('allNodeAliases'), this.tasks.enablePortForwarding(), this.tasks.checkAllNodesAreActive('allNodeAliases'), this.tasks.checkAllNodeProxiesAreActive(), this.tasks.stakeNewNode(), this.tasks.triggerStakeWeightCalculate(NodeSubcommandType.ADD), this.tasks.finalize(), ]; } updatePrepareTasks(argv, lease) { return [ this.tasks.initialize(argv, updateConfigBuilder.bind(this), lease), this.validateSingleNodeState({ excludedStates: [] }), this.tasks.identifyExistingNodes(), this.tasks.loadAdminKey(), this.tasks.prepareUpgradeZip(), this.tasks.checkExistingNodesStakedAmount(), ]; } updateSubmitTransactionsTasks(argv) { return [ this.tasks.sendNodeUpdateTransaction(), this.tasks.sendPrepareUpgradeTransaction(), this.tasks.sendFreezeUpgradeTransaction(), ]; } updateExecuteTasks(argv) { return [ this.tasks.checkAllNodesAreFrozen('existingNodeAliases'), this.tasks.downloadNodeGeneratedFiles(), this.tasks.prepareStagingDirectory('allNodeAliases'), this.tasks.copyNodeKeysToSecrets(), this.tasks.getNodeLogsAndConfigs(), this.tasks.updateChartWithConfigMap('Update chart to use new configMap due to account number change', NodeSubcommandType.UPDATE, (ctx) => !ctx.config.newAccountNumber && !ctx.config.debugNodeAlias), this.tasks.killNodesAndUpdateConfigMap(), this.tasks.checkNodePodsAreRunning(), this.tasks.fetchPlatformSoftware('allNodeAliases'), this.tasks.setupNetworkNodes('allNodeAliases', false), this.tasks.startNodes('allNodeAliases'), this.tasks.enablePortForwarding(), this.tasks.checkAllNodesAreActive('allNodeAliases'), this.tasks.checkAllNodeProxiesAreActive(), this.tasks.triggerStakeWeightCalculate(NodeSubcommandType.UPDATE), this.tasks.finalize(), ]; } upgradePrepareTasks(argv, lease) { return [ this.tasks.initialize(argv, upgradeConfigBuilder.bind(this), lease), this.validateAllNodeStates({ excludedStates: [] }), this.tasks.identifyExistingNodes(), this.tasks.loadAdminKey(), this.tasks.prepareUpgradeZip(), this.tasks.checkExistingNodesStakedAmount(), ]; } upgradeSubmitTransactionsTasks(argv) { return [this.tasks.sendPrepareUpgradeTransaction(), this.tasks.sendFreezeUpgradeTransaction()]; } upgradeExecuteTasks(argv) { return [ this.tasks.checkAllNodesAreFrozen('existingNodeAliases'), this.tasks.downloadNodeUpgradeFiles(), this.tasks.getNodeLogsAndConfigs(), this.tasks.startNodes('allNodeAliases'), this.tasks.enablePortForwarding(), this.tasks.checkAllNodesAreActive('allNodeAliases'), this.tasks.checkAllNodeProxiesAreActive(), this.tasks.finalize(), ]; } /** ******** Handlers **********/ async prepareUpgrade(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.DEFAULT_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ this.tasks.initialize(argv, prepareUpgradeConfigBuilder.bind(this), lease), this.tasks.prepareUpgradeZip(), this.tasks.sendPrepareUpgradeTransaction(), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in preparing node upgrade', lease); await action(argv, this); return true; } async freezeUpgrade(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.DEFAULT_FLAGS); const action = this.parent.commandActionBuilder([ this.tasks.initialize(argv, prepareUpgradeConfigBuilder.bind(this), null), this.tasks.prepareUpgradeZip(), this.tasks.sendFreezeUpgradeTransaction(), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in executing node freeze upgrade', null); await action(argv, this); return true; } async downloadGeneratedFiles(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.DEFAULT_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ this.tasks.initialize(argv, downloadGeneratedFilesConfigBuilder.bind(this), lease), this.tasks.identifyExistingNodes(), this.tasks.downloadNodeGeneratedFiles(), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in downloading generated files', lease); await action(argv, this); return true; } async update(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.UPDATE_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ ...this.updatePrepareTasks(argv, lease), ...this.updateSubmitTransactionsTasks(argv), ...this.updateExecuteTasks(argv), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in updating nodes', lease); await action(argv, this); return true; } async updatePrepare(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.UPDATE_PREPARE_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ ...this.updatePrepareTasks(argv, lease), this.tasks.saveContextData(argv, NodeCommandHandlers.UPDATE_CONTEXT_FILE, NodeHelper.updateSaveContextParser), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in preparing node update', lease); await action(argv, this); return true; } async updateSubmitTransactions(argv) { const lease = await this.leaseManager.create(); argv = helpers.addFlagsToArgv(argv, NodeFlags.UPDATE_SUBMIT_TRANSACTIONS_FLAGS); const action = this.parent.commandActionBuilder([ this.tasks.initialize(argv, updateConfigBuilder.bind(this), lease), this.tasks.loadContextData(argv, NodeCommandHandlers.UPDATE_CONTEXT_FILE, NodeHelper.updateLoadContextParser), ...this.updateSubmitTransactionsTasks(argv), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in submitting transactions for node update', lease); await action(argv, this); return true; } async updateExecute(argv) { const lease = await this.leaseManager.create(); argv = helpers.addFlagsToArgv(argv, NodeFlags.UPDATE_EXECUTE_FLAGS); const action = this.parent.commandActionBuilder([ this.tasks.initialize(argv, updateConfigBuilder.bind(this), lease, false), this.tasks.loadContextData(argv, NodeCommandHandlers.UPDATE_CONTEXT_FILE, NodeHelper.updateLoadContextParser), ...this.updateExecuteTasks(argv), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in executing network upgrade', lease); await action(argv, this); return true; } async upgradePrepare(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.UPGRADE_PREPARE_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ ...this.upgradePrepareTasks(argv, lease), this.tasks.saveContextData(argv, NodeCommandHandlers.UPGRADE_CONTEXT_FILE, NodeHelper.upgradeSaveContextParser), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in preparing node upgrade', lease); await action(argv, this); return true; } async upgradeSubmitTransactions(argv) { const lease = await this.leaseManager.create(); argv = helpers.addFlagsToArgv(argv, NodeFlags.UPGRADE_SUBMIT_TRANSACTIONS_FLAGS); const action = this.parent.commandActionBuilder([ this.tasks.initialize(argv, upgradeConfigBuilder.bind(this), lease), this.tasks.loadContextData(argv, NodeCommandHandlers.UPGRADE_CONTEXT_FILE, NodeHelper.upgradeLoadContextParser), ...this.upgradeSubmitTransactionsTasks(argv), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in submitting transactions for node upgrade', lease); await action(argv, this); return true; } async upgradeExecute(argv) { const lease = await this.leaseManager.create(); argv = helpers.addFlagsToArgv(argv, NodeFlags.UPGRADE_FLAGS); const action = this.parent.commandActionBuilder([ this.tasks.initialize(argv, upgradeConfigBuilder.bind(this), lease, false), this.tasks.loadContextData(argv, NodeCommandHandlers.UPGRADE_CONTEXT_FILE, NodeHelper.upgradeLoadContextParser), ...this.upgradeExecuteTasks(argv), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in executing network upgrade', lease); await action(argv, this); return true; } async upgrade(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.UPGRADE_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ ...this.upgradePrepareTasks(argv, lease), ...this.upgradeSubmitTransactionsTasks(argv), ...this.upgradeExecuteTasks(argv), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in upgrade network', lease); await action(argv, this); return true; } async delete(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.DELETE_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ ...this.deletePrepareTaskList(argv, lease), ...this.deleteSubmitTransactionsTaskList(argv), ...this.deleteExecuteTaskList(argv), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in deleting nodes', lease); await action(argv, this); return true; } async deletePrepare(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.DELETE_PREPARE_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ ...this.deletePrepareTaskList(argv, lease), this.tasks.saveContextData(argv, NodeCommandHandlers.DELETE_CONTEXT_FILE, NodeHelper.deleteSaveContextParser), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in preparing to delete a node', lease); await action(argv, this); return true; } async deleteSubmitTransactions(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.DELETE_SUBMIT_TRANSACTIONS_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ this.tasks.initialize(argv, deleteConfigBuilder.bind(this), lease), this.tasks.loadContextData(argv, NodeCommandHandlers.DELETE_CONTEXT_FILE, NodeHelper.deleteLoadContextParser), ...this.deleteSubmitTransactionsTaskList(argv), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in deleting a node', lease); await action(argv, this); return true; } async deleteExecute(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.DELETE_EXECUTE_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ this.tasks.initialize(argv, deleteConfigBuilder.bind(this), lease, false), this.tasks.loadContextData(argv, NodeCommandHandlers.DELETE_CONTEXT_FILE, NodeHelper.deleteLoadContextParser), ...this.deleteExecuteTaskList(argv), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in deleting a node', lease); await action(argv, this); return true; } async add(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.ADD_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([...this.addPrepareTasks(argv, lease), ...this.addSubmitTransactionsTasks(argv), ...this.addExecuteTasks(argv)], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in adding node', lease); await action(argv, this); return true; } async addPrepare(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.ADD_PREPARE_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ ...this.addPrepareTasks(argv, lease), this.tasks.saveContextData(argv, NodeCommandHandlers.ADD_CONTEXT_FILE, helpers.addSaveContextParser), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in preparing node', lease); await action(argv, this); return true; } async addSubmitTransactions(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.ADD_SUBMIT_TRANSACTIONS_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ this.tasks.initialize(argv, addConfigBuilder.bind(this), lease), this.tasks.loadContextData(argv, NodeCommandHandlers.ADD_CONTEXT_FILE, helpers.addLoadContextParser), ...this.addSubmitTransactionsTasks(argv), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, '`Error in submitting transactions to node', lease); await action(argv, this); return true; } async addExecute(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.ADD_EXECUTE_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ this.tasks.initialize(argv, addConfigBuilder.bind(this), lease, false), this.tasks.identifyExistingNodes(), this.tasks.loadContextData(argv, NodeCommandHandlers.ADD_CONTEXT_FILE, helpers.addLoadContextParser), ...this.addExecuteTasks(argv), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in adding node', lease); await action(argv, this); return true; } async logs(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.LOGS_FLAGS); const action = this.parent.commandActionBuilder([this.tasks.initialize(argv, logsConfigBuilder.bind(this), null), this.tasks.getNodeLogsAndConfigs()], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in downloading log from nodes', null); await action(argv, this); return true; } async states(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.STATES_FLAGS); const action = this.parent.commandActionBuilder([this.tasks.initialize(argv, statesConfigBuilder.bind(this), null), this.tasks.getNodeStateFiles()], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in downloading states from nodes', null); await action(argv, this); return true; } async refresh(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.REFRESH_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ this.tasks.initialize(argv, refreshConfigBuilder.bind(this), lease), this.validateAllNodeStates({ acceptedStates: [ConsensusNodeStates.STARTED, ConsensusNodeStates.SETUP, ConsensusNodeStates.INITIALIZED], }), this.tasks.identifyNetworkPods(), this.tasks.dumpNetworkNodesSaveState(), this.tasks.fetchPlatformSoftware('nodeAliases'), this.tasks.setupNetworkNodes('nodeAliases', true), this.tasks.startNodes('nodeAliases'), this.tasks.checkAllNodesAreActive('nodeAliases'), this.tasks.checkNodeProxiesAreActive(), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in refreshing nodes', lease); await action(argv, this); return true; } async keys(argv) { this.init(); argv = helpers.addFlagsToArgv(argv, NodeFlags.KEYS_FLAGS); const action = this.parent.commandActionBuilder([ this.tasks.initialize(argv, keysConfigBuilder.bind(this), null), this.tasks.generateGossipKeys(), this.tasks.generateGrpcTlsKeys(), this.tasks.finalize(), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error generating keys', null); await action(argv, this); return true; } async stop(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.STOP_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ this.tasks.initialize(argv, stopConfigBuilder.bind(this), lease), this.validateAllNodeStates({ acceptedStates: [ConsensusNodeStates.STARTED, ConsensusNodeStates.SETUP], }), this.tasks.identifyNetworkPods(1), this.tasks.stopNodes(), this.changeAllNodeStates(ConsensusNodeStates.INITIALIZED), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error stopping node', lease); await action(argv, this); return true; } async start(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.START_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ this.tasks.initialize(argv, startConfigBuilder.bind(this), lease), this.validateAllNodeStates({ acceptedStates: [ConsensusNodeStates.SETUP] }), this.tasks.identifyExistingNodes(), this.tasks.uploadStateFiles((ctx) => ctx.config.stateFile.length === 0), this.tasks.startNodes('nodeAliases'), this.tasks.enablePortForwarding(), this.tasks.checkAllNodesAreActive('nodeAliases'), this.tasks.checkNodeProxiesAreActive(), this.changeAllNodeStates(ConsensusNodeStates.STARTED), this.tasks.addNodeStakes(), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error starting node', lease); await action(argv, this); return true; } async setup(argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.SETUP_FLAGS); const lease = await this.leaseManager.create(); const action = this.parent.commandActionBuilder([ this.tasks.initialize(argv, setupConfigBuilder.bind(this), lease), this.validateAllNodeStates({ acceptedStates: [ConsensusNodeStates.INITIALIZED], }), this.tasks.identifyNetworkPods(), this.tasks.fetchPlatformSoftware('nodeAliases'), this.tasks.setupNetworkNodes('nodeAliases', true), this.changeAllNodeStates(ConsensusNodeStates.SETUP), ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION, }, 'Error in setting up nodes', lease); await action(argv, this); return true; } /** Removes the consensus node, envoy and haproxy components from remote config. */ removeNodeAndProxies() { return { skip: () => !this.remoteConfigManager.isLoaded(), title: 'Remove node and proxies from remote config', task: async () => { await this.remoteConfigManager.modify(async (remoteConfig) => { remoteConfig.components.remove('Consensus node name', ComponentType.ConsensusNode); remoteConfig.components.remove('Envoy proxy name', ComponentType.EnvoyProxy); remoteConfig.components.remove('HaProxy name', ComponentType.HaProxy); }); }, }; } /** * Changes the state from all consensus nodes components in remote config. * * @param state - to which to change the consensus node component */ changeAllNodeStates(state) { return { title: `Change node state to ${state} in remote config`, skip: () => !this.remoteConfigManager.isLoaded(), task: async (ctx) => { await this.remoteConfigManager.modify(async (remoteConfig) => { const { config: { namespace }, } = ctx; for (const consensusNode of ctx.config.consensusNodes) { remoteConfig.components.edit(consensusNode.name, new ConsensusNodeComponent(consensusNode.name, consensusNode.cluster, namespace.name, state, consensusNode.nodeId)); } }); }, }; } /** * Creates tasks to validate that each node state is either one of the accepted states or not one of the excluded. * * @param acceptedStates - the state at which the nodes can be, not matching any of the states throws an error * @param excludedStates - the state at which the nodes can't be, matching any of the states throws an error */ validateAllNodeStates({ acceptedStates, excludedStates, }) { return { title: 'Validate nodes states', skip: () => !this.remoteConfigManager.isLoaded(), task: (ctx, task) => { const nodeAliases = ctx.config.nodeAliases; const components = this.remoteConfigManager.components; const subTasks = nodeAliases.map(nodeAlias => ({ title: `Validating state for node ${nodeAlias}`, task: (_, task) => { const state = this.validateNodeState(nodeAlias, components, acceptedStates, excludedStates); task.title += ` - ${chalk.green('valid state')}: ${chalk.cyan(state)}`; }, })); return task.newListr(subTasks, { concurrent: false, rendererOptions: { collapseSubtasks: false }, }); }, }; } /** * Creates tasks to validate that specific node state is either one of the accepted states or not one of the excluded. * * @param acceptedStates - the state at which the node can be, not matching any of the states throws an error * @param excludedStates - the state at which the node can't be, matching any of the states throws an error */ validateSingleNodeState({ acceptedStates, excludedStates, }) { return { title: 'Validate nodes state', skip: () => !this.remoteConfigManager.isLoaded(), task: (ctx, task) => { const nodeAlias = ctx.config.nodeAlias; task.title += ` ${nodeAlias}`; const components = this.remoteConfigManager.components; const state = this.validateNodeState(nodeAlias, components, acceptedStates, excludedStates); task.title += ` - ${chalk.green('valid state')}: ${chalk.cyan(state)}`; }, }; } /** * @param nodeAlias - the alias of the node whose state to validate * @param components - the component data wrapper * @param acceptedStates - the state at which the node can be, not matching any of the states throws an error * @param excludedStates - the state at which the node can't be, matching any of the states throws an error */ validateNodeState(nodeAlias, components, acceptedStates, excludedStates) { let nodeComponent; try { nodeComponent = components.getComponent(ComponentType.ConsensusNode, nodeAlias); } catch { throw new SoloError(`${nodeAlias} not found in remote config`); } // TODO: Enable once the states have been mapped // if (acceptedStates && !acceptedStates.includes(nodeComponent.state)) { // const errorMessageData = // `accepted states: ${acceptedStates.join(', ')}, ` + `current state: ${nodeComponent.state}`; // // throw new SoloError(`${nodeAlias} has invalid state - ` + errorMessageData); // } // // if (excludedStates && excludedStates.includes(nodeComponent.state)) { // const errorMessageData = // `excluded states: ${excludedStates.join(', ')}, ` + `current state: ${nodeComponent.state}`; // // throw new SoloError(`${nodeAlias} has invalid state - ` + errorMessageData); // } return nodeComponent.state; } } //# sourceMappingURL=handlers.js.map