UNPKG

@hashgraph/solo

Version:

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

167 lines (147 loc) 7.48 kB
/** * SPDX-License-Identifier: Apache-2.0 */ import chalk from 'chalk'; import yargs from 'yargs'; import {hideBin} from 'yargs/helpers'; import 'dotenv/config'; // eslint-disable-next-line n/no-extraneous-import import 'reflect-metadata'; import {container} from 'tsyringe-neo'; import {ListrLogger} from 'listr2'; import {Flags as flags} from './commands/flags.js'; import * as commands from './commands/index.js'; import {type DependencyManager} from './core/dependency_managers/index.js'; import * as constants from './core/constants.js'; import {type PackageDownloader} from './core/package_downloader.js'; import {type Helm} from './core/helm.js'; import {type ChartManager} from './core/chart_manager.js'; import {type ConfigManager} from './core/config_manager.js'; import {type AccountManager} from './core/account_manager.js'; import {type PlatformInstaller} from './core/platform_installer.js'; import {type KeyManager} from './core/key_manager.js'; import {type ProfileManager} from './core/profile_manager.js'; import {type LeaseManager} from './core/lease/lease_manager.js'; import {type CertificateManager} from './core/certificate_manager.js'; import {type LocalConfig} from './core/config/local_config.js'; import {type RemoteConfigManager} from './core/config/remote/remote_config_manager.js'; import * as helpers from './core/helpers.js'; import {type K8Factory} from './core/kube/k8_factory.js'; import {CustomProcessOutput} from './core/process_output.js'; import {type SoloLogger} from './core/logging.js'; import {Container} from './core/dependency_injection/container_init.js'; import {InjectTokens} from './core/dependency_injection/inject_tokens.js'; import {type NamespaceName} from './core/kube/resources/namespace/namespace_name.js'; import {type Opts} from './commands/base.js'; export function main(argv: any) { Container.getInstance().init(); const logger = container.resolve<SoloLogger>(InjectTokens.SoloLogger); constants.LISTR_DEFAULT_RENDERER_OPTION.logger = new ListrLogger({processOutput: new CustomProcessOutput(logger)}); if (argv.length >= 3 && ['-version', '--version', '-v', '--v'].includes(argv[2])) { logger.showUser(chalk.cyan('\n******************************* Solo *********************************************')); logger.showUser(chalk.cyan('Version\t\t\t:'), chalk.yellow(helpers.getSoloVersion())); logger.showUser(chalk.cyan('**********************************************************************************')); process.exit(0); } try { // prepare dependency manger registry const downloader: PackageDownloader = container.resolve(InjectTokens.PackageDownloader); const depManager: DependencyManager = container.resolve(InjectTokens.DependencyManager); const helm: Helm = container.resolve(InjectTokens.Helm); const chartManager: ChartManager = container.resolve(InjectTokens.ChartManager); const configManager: ConfigManager = container.resolve(InjectTokens.ConfigManager); const k8Factory: K8Factory = container.resolve(InjectTokens.K8Factory); const accountManager: AccountManager = container.resolve(InjectTokens.AccountManager); const platformInstaller: PlatformInstaller = container.resolve(InjectTokens.PlatformInstaller); const keyManager: KeyManager = container.resolve(InjectTokens.KeyManager); const profileManager: ProfileManager = container.resolve(InjectTokens.ProfileManager); const leaseManager: LeaseManager = container.resolve(InjectTokens.LeaseManager); const certificateManager: CertificateManager = container.resolve(InjectTokens.CertificateManager); const localConfig: LocalConfig = container.resolve(InjectTokens.LocalConfig); const remoteConfigManager: RemoteConfigManager = container.resolve(InjectTokens.RemoteConfigManager); // set cluster and namespace in the global configManager from kubernetes context // so that we don't need to prompt the user const contextNamespace: NamespaceName = k8Factory.default().contexts().readCurrentNamespace(); const currentClusterName: string = k8Factory.default().clusters().readCurrent(); const contextName: string = k8Factory.default().contexts().readCurrent(); const opts: Opts = { logger, helm, k8Factory, downloader, platformInstaller, chartManager, configManager, depManager, keyManager, accountManager, profileManager, leaseManager, remoteConfigManager, certificateManager, localConfig, }; const processArguments = (argv: any, yargs: any): any => { if (argv._[0] === 'init') { configManager.reset(); } const clusterName = configManager.getFlag(flags.clusterRef) || currentClusterName; if (contextNamespace?.name) { configManager.setFlag(flags.namespace, contextNamespace); } // apply precedence for flags argv = configManager.applyPrecedence(argv, yargs.parsed.aliases); // update configManager.update(argv); const currentCommand = argv._.join(' ') as string; const commandArguments = flags.stringifyArgv(argv); const commandData = (currentCommand + ' ' + commandArguments).trim(); logger.showUser( chalk.cyan('\n******************************* Solo *********************************************'), ); logger.showUser(chalk.cyan('Version\t\t\t:'), chalk.yellow(configManager.getVersion())); logger.showUser(chalk.cyan('Kubernetes Context\t:'), chalk.yellow(contextName)); logger.showUser(chalk.cyan('Kubernetes Cluster\t:'), chalk.yellow(clusterName)); logger.showUser(chalk.cyan('Current Command\t\t:'), chalk.yellow(commandData)); if (typeof configManager.getFlag<NamespaceName>(flags.namespace)?.name !== 'undefined') { logger.showUser(chalk.cyan('Kubernetes Namespace\t:'), chalk.yellow(configManager.getFlag(flags.namespace))); } logger.showUser(chalk.cyan('**********************************************************************************')); return argv; }; const loadRemoteConfig = async (argv: any, yargs: any): Promise<any> => { const command = argv._[0]; const subCommand = argv._[1]; const skip = command === 'init' || (command === 'node' && subCommand === 'keys') || (command === 'cluster' && subCommand === 'connect') || (command === 'cluster' && subCommand === 'info') || (command === 'cluster' && subCommand === 'list') || (command === 'cluster' && subCommand === 'setup') || (command === 'deployment' && subCommand === 'create') || (command === 'deployment' && subCommand === 'list'); if (!skip) { await remoteConfigManager.loadAndValidate(argv); } return argv; }; const rootCmd = yargs(hideBin(argv)) .scriptName('') .usage('Usage:\n solo <command> [options]') .alias('h', 'help') .alias('v', 'version') // @ts-ignore .command(commands.Initialize(opts)) .strict() .demand(1, 'Select a command') // @ts-ignore .middleware([processArguments, loadRemoteConfig], false); // applyBeforeValidate = false as otherwise middleware is called twice // set root level flags flags.setCommandFlags(rootCmd, ...[flags.devMode, flags.forcePortForward]); return rootCmd.parse(); } catch (e: Error | any) { logger.showUserError(e); process.exit(1); } }