UNPKG

@hashgraph/solo

Version:

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

317 lines 14.7 kB
/** * SPDX-License-Identifier: Apache-2.0 */ import { FREEZE_ADMIN_ACCOUNT } from '../../core/constants.js'; import { Templates } from '../../core/templates.js'; import * as constants from '../../core/constants.js'; import { PrivateKey } from '@hashgraph/sdk'; import { SoloError } from '../../core/errors.js'; import * as helpers from '../../core/helpers.js'; import path from 'path'; import fs from 'fs'; import { validatePath } from '../../core/helpers.js'; import { resolveNamespaceFromDeployment } from '../../core/resolvers.js'; import { Flags as flags } from '../flags.js'; export const PREPARE_UPGRADE_CONFIGS_NAME = 'prepareUpgradeConfig'; export const DOWNLOAD_GENERATED_FILES_CONFIGS_NAME = 'downloadGeneratedFilesConfig'; export const ADD_CONFIGS_NAME = 'addConfigs'; export const DELETE_CONFIGS_NAME = 'deleteConfigs'; export const UPDATE_CONFIGS_NAME = 'updateConfigs'; export const UPGRADE_CONFIGS_NAME = 'upgradeConfigs'; export const REFRESH_CONFIGS_NAME = 'refreshConfigs'; export const KEYS_CONFIGS_NAME = 'keyConfigs'; export const SETUP_CONFIGS_NAME = 'setupConfigs'; export const START_CONFIGS_NAME = 'startConfigs'; const initializeSetup = async (config, k8Factory) => { // compute other config parameters config.keysDir = path.join(validatePath(config.cacheDir), 'keys'); config.stagingDir = Templates.renderStagingDir(config.cacheDir, config.releaseTag); config.stagingKeysDir = path.join(validatePath(config.stagingDir), 'keys'); if (!(await k8Factory.default().namespaces().has(config.namespace))) { throw new SoloError(`namespace ${config.namespace} does not exist`); } // prepare staging keys directory if (!fs.existsSync(config.stagingKeysDir)) { fs.mkdirSync(config.stagingKeysDir, { recursive: true }); } // create cached keys dir if it does not exist yet if (!fs.existsSync(config.keysDir)) { fs.mkdirSync(config.keysDir); } }; export const prepareUpgradeConfigBuilder = async function (argv, ctx, task) { const config = this.getConfig(PREPARE_UPGRADE_CONFIGS_NAME, argv.flags, [ 'nodeClient', 'freezeAdminPrivateKey', 'namespace', 'consensusNodes', 'contexts', ]); config.namespace = await resolveNamespaceFromDeployment(this.parent.localConfig, this.configManager, task); await initializeSetup(config, this.k8Factory); config.nodeClient = await this.accountManager.loadNodeClient(config.namespace, this.parent.getClusterRefs(), config.deployment); const accountKeys = await this.accountManager.getAccountKeysFromSecret(FREEZE_ADMIN_ACCOUNT, config.namespace); config.freezeAdminPrivateKey = accountKeys.privateKey; return config; }; export const downloadGeneratedFilesConfigBuilder = async function (argv, ctx, task) { const config = this.getConfig(DOWNLOAD_GENERATED_FILES_CONFIGS_NAME, argv.flags, [ 'allNodeAliases', 'existingNodeAliases', 'serviceMap', 'namespace', 'consensusNodes', 'contexts', ]); config.namespace = await resolveNamespaceFromDeployment(this.parent.localConfig, this.configManager, task); config.existingNodeAliases = []; await initializeSetup(config, this.k8Factory); return config; }; export const upgradeConfigBuilder = async function (argv, ctx, task, shouldLoadNodeClient = true) { const config = this.getConfig(UPGRADE_CONFIGS_NAME, argv.flags, [ 'allNodeAliases', 'existingNodeAliases', 'keysDir', 'nodeClient', 'podRefs', 'stagingDir', 'stagingKeysDir', 'namespace', 'consensusNodes', 'contexts', ]); config.namespace = await resolveNamespaceFromDeployment(this.parent.localConfig, this.configManager, task); config.curDate = new Date(); config.existingNodeAliases = []; config.nodeAliases = helpers.parseNodeAliases(config.nodeAliasesUnparsed); await initializeSetup(config, this.k8Factory); // set config in the context for later tasks to use ctx.config = config; ctx.config.chartPath = await this.prepareChartPath(ctx.config.chartDirectory, constants.SOLO_TESTING_CHART_URL, constants.SOLO_DEPLOYMENT_CHART); if (shouldLoadNodeClient) { ctx.config.nodeClient = await this.accountManager.loadNodeClient(ctx.config.namespace, this.parent.getClusterRefs(), config.deployment); } const accountKeys = await this.accountManager.getAccountKeysFromSecret(FREEZE_ADMIN_ACCOUNT, config.namespace); config.freezeAdminPrivateKey = accountKeys.privateKey; return config; }; export const updateConfigBuilder = async function (argv, ctx, task, shouldLoadNodeClient = true) { const config = this.getConfig(UPDATE_CONFIGS_NAME, argv.flags, [ 'allNodeAliases', 'existingNodeAliases', 'freezeAdminPrivateKey', 'keysDir', 'nodeClient', 'podRefs', 'serviceMap', 'stagingDir', 'stagingKeysDir', 'treasuryKey', 'namespace', 'consensusNodes', 'contexts', ]); config.namespace = await resolveNamespaceFromDeployment(this.parent.localConfig, this.configManager, task); config.curDate = new Date(); config.existingNodeAliases = []; await initializeSetup(config, this.k8Factory); // set config in the context for later tasks to use ctx.config = config; ctx.config.chartPath = await this.prepareChartPath(ctx.config.chartDirectory, constants.SOLO_TESTING_CHART_URL, constants.SOLO_DEPLOYMENT_CHART); if (shouldLoadNodeClient) { ctx.config.nodeClient = await this.accountManager.loadNodeClient(ctx.config.namespace, this.parent.getClusterRefs(), config.deployment); } const accountKeys = await this.accountManager.getAccountKeysFromSecret(FREEZE_ADMIN_ACCOUNT, config.namespace); config.freezeAdminPrivateKey = accountKeys.privateKey; const treasuryAccount = await this.accountManager.getTreasuryAccountKeys(config.namespace); const treasuryAccountPrivateKey = treasuryAccount.privateKey; config.treasuryKey = PrivateKey.fromStringED25519(treasuryAccountPrivateKey); return config; }; export const deleteConfigBuilder = async function (argv, ctx, task, shouldLoadNodeClient = true) { const config = this.getConfig(DELETE_CONFIGS_NAME, argv.flags, [ 'adminKey', 'allNodeAliases', 'existingNodeAliases', 'freezeAdminPrivateKey', 'keysDir', 'nodeClient', 'podRefs', 'serviceMap', 'stagingDir', 'stagingKeysDir', 'treasuryKey', 'namespace', 'consensusNodes', 'contexts', ]); config.curDate = new Date(); config.existingNodeAliases = []; config.namespace = await resolveNamespaceFromDeployment(this.parent.localConfig, this.configManager, task); await initializeSetup(config, this.k8Factory); // set config in the context for later tasks to use ctx.config = config; ctx.config.chartPath = await this.prepareChartPath(ctx.config.chartDirectory, constants.SOLO_TESTING_CHART_URL, constants.SOLO_DEPLOYMENT_CHART); if (shouldLoadNodeClient) { ctx.config.nodeClient = await this.accountManager.loadNodeClient(ctx.config.namespace, this.parent.getClusterRefs(), config.deployment); } const accountKeys = await this.accountManager.getAccountKeysFromSecret(FREEZE_ADMIN_ACCOUNT, config.namespace); config.freezeAdminPrivateKey = accountKeys.privateKey; const treasuryAccount = await this.accountManager.getTreasuryAccountKeys(config.namespace); const treasuryAccountPrivateKey = treasuryAccount.privateKey; config.treasuryKey = PrivateKey.fromStringED25519(treasuryAccountPrivateKey); return config; }; export const addConfigBuilder = async function (argv, ctx, task, shouldLoadNodeClient = true) { const config = this.getConfig(ADD_CONFIGS_NAME, argv.flags, [ 'allNodeAliases', 'chartPath', 'curDate', 'existingNodeAliases', 'freezeAdminPrivateKey', 'keysDir', 'lastStateZipPath', 'nodeClient', 'podRefs', 'serviceMap', 'stagingDir', 'stagingKeysDir', 'treasuryKey', 'namespace', 'consensusNodes', 'contexts', ]); ctx.adminKey = argv[flags.adminKey.name] ? PrivateKey.fromStringED25519(argv[flags.adminKey.name]) : PrivateKey.fromStringED25519(constants.GENESIS_KEY); config.namespace = await resolveNamespaceFromDeployment(this.parent.localConfig, this.configManager, task); config.curDate = new Date(); config.existingNodeAliases = []; await initializeSetup(config, this.k8Factory); // set config in the context for later tasks to use ctx.config = config; ctx.config.chartPath = await this.prepareChartPath(ctx.config.chartDirectory, constants.SOLO_TESTING_CHART_URL, constants.SOLO_DEPLOYMENT_CHART); if (shouldLoadNodeClient) { ctx.config.nodeClient = await this.accountManager.loadNodeClient(ctx.config.namespace, this.parent.getClusterRefs(), config.deployment); } const accountKeys = await this.accountManager.getAccountKeysFromSecret(FREEZE_ADMIN_ACCOUNT, config.namespace); config.freezeAdminPrivateKey = accountKeys.privateKey; const treasuryAccount = await this.accountManager.getTreasuryAccountKeys(config.namespace); const treasuryAccountPrivateKey = treasuryAccount.privateKey; config.treasuryKey = PrivateKey.fromStringED25519(treasuryAccountPrivateKey); config.serviceMap = await this.accountManager.getNodeServiceMap(config.namespace, this.parent.getClusterRefs(), config.deployment); config.consensusNodes = this.parent.getConsensusNodes(); config.contexts = this.parent.getContexts(); return config; }; export const logsConfigBuilder = async function (argv, ctx, task) { const config = { namespace: await resolveNamespaceFromDeployment(this.parent.localConfig, this.configManager, task), nodeAliases: helpers.parseNodeAliases(this.configManager.getFlag(flags.nodeAliasesUnparsed)), nodeAliasesUnparsed: this.configManager.getFlag(flags.nodeAliasesUnparsed), deployment: this.configManager.getFlag(flags.deployment), consensusNodes: this.parent.getConsensusNodes(), contexts: this.parent.getContexts(), }; ctx.config = config; return config; }; export const statesConfigBuilder = async function (argv, ctx, task) { const config = { namespace: await resolveNamespaceFromDeployment(this.parent.localConfig, this.configManager, task), nodeAliases: helpers.parseNodeAliases(this.configManager.getFlag(flags.nodeAliasesUnparsed)), nodeAliasesUnparsed: this.configManager.getFlag(flags.nodeAliasesUnparsed), deployment: this.configManager.getFlag(flags.deployment), consensusNodes: this.parent.getConsensusNodes(), contexts: this.parent.getContexts(), }; ctx.config = config; return config; }; export const refreshConfigBuilder = async function (argv, ctx, task) { ctx.config = this.getConfig(REFRESH_CONFIGS_NAME, argv.flags, [ 'nodeAliases', 'podRefs', 'namespace', 'consensusNodes', 'contexts', ]); ctx.config.namespace = await resolveNamespaceFromDeployment(this.parent.localConfig, this.configManager, task); ctx.config.nodeAliases = helpers.parseNodeAliases(ctx.config.nodeAliasesUnparsed); await initializeSetup(ctx.config, this.k8Factory); return ctx.config; }; export const keysConfigBuilder = function (argv, ctx, task) { const config = this.getConfig(KEYS_CONFIGS_NAME, argv.flags, [ 'curDate', 'keysDir', 'nodeAliases', 'consensusNodes', 'contexts', ]); config.curDate = new Date(); config.nodeAliases = helpers.parseNodeAliases(config.nodeAliasesUnparsed); if (config.nodeAliases.length === 0) { config.nodeAliases = this.consensusNodes.map((node) => { return node.name; }); if (config.nodeAliases.length === 0) { throw new SoloError('no node aliases provided via flags or RemoteConfig'); } } config.keysDir = path.join(this.configManager.getFlag(flags.cacheDir), 'keys'); if (!fs.existsSync(config.keysDir)) { fs.mkdirSync(config.keysDir); } return config; }; export const stopConfigBuilder = async function (argv, ctx, task) { ctx.config = { namespace: await resolveNamespaceFromDeployment(this.parent.localConfig, this.configManager, task), nodeAliases: helpers.parseNodeAliases(this.configManager.getFlag(flags.nodeAliasesUnparsed)), nodeAliasesUnparsed: this.configManager.getFlag(flags.nodeAliasesUnparsed), deployment: this.configManager.getFlag(flags.deployment), consensusNodes: this.parent.getConsensusNodes(), contexts: this.parent.getContexts(), }; if (!(await this.k8Factory.default().namespaces().has(ctx.config.namespace))) { throw new SoloError(`namespace ${ctx.config.namespace} does not exist`); } return ctx.config; }; export const startConfigBuilder = async function (argv, ctx, task) { const config = this.getConfig(START_CONFIGS_NAME, argv.flags, [ 'nodeAliases', 'namespace', 'consensusNodes', 'contexts', ]); config.namespace = await resolveNamespaceFromDeployment(this.parent.localConfig, this.configManager, task); config.consensusNodes = this.parent.getConsensusNodes(); for (const consensusNode of config.consensusNodes) { const k8 = this.k8Factory.getK8(consensusNode.context); if (!(await k8.namespaces().has(config.namespace))) { throw new SoloError(`namespace ${config.namespace} does not exist`); } } config.nodeAliases = helpers.parseNodeAliases(config.nodeAliasesUnparsed); return config; }; export const setupConfigBuilder = async function (argv, ctx, task) { const config = this.getConfig(SETUP_CONFIGS_NAME, argv.flags, [ 'nodeAliases', 'podRefs', 'namespace', 'consensusNodes', 'contexts', ]); config.namespace = await resolveNamespaceFromDeployment(this.parent.localConfig, this.configManager, task); config.nodeAliases = helpers.parseNodeAliases(config.nodeAliasesUnparsed); config.consensusNodes = this.parent.getConsensusNodes(); await initializeSetup(config, this.k8Factory); // set config in the context for later tasks to use ctx.config = config; return ctx.config; }; //# sourceMappingURL=configs.js.map