@hashgraph/solo
Version:
An opinionated CLI tool to deploy and manage private Hedera Networks.
626 lines • 31.6 kB
JavaScript
// 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); }
};
var RelayCommand_1;
import { SoloError } from '../core/errors/solo-error.js';
import { MissingArgumentError } from '../core/errors/missing-argument-error.js';
import * as helpers from '../core/helpers.js';
import { showVersionBanner } from '../core/helpers.js';
import * as constants from '../core/constants.js';
import { BaseCommand } from './base.js';
import { Flags as flags } from './flags.js';
import { ListrLock } from '../core/lock/listr-lock.js';
import * as Base64 from 'js-base64';
import { inject, injectable } from 'tsyringe-neo';
import { InjectTokens } from '../core/dependency-injection/inject-tokens.js';
import { patchInject } from '../core/dependency-injection/container-helper.js';
import { ComponentTypes } from '../core/config/remote/enumerations/component-types.js';
import { Templates } from '../core/templates.js';
import { SemanticVersion } from '../business/utils/semantic-version.js';
import { assertUpgradeVersionNotOlder } from '../core/upgrade-version-guard.js';
import { MIRROR_INGRESS_CONTROLLER } from '../core/constants.js';
import { OperatingSystem } from '../business/utils/operating-system.js';
import { ImageReference } from '../business/utils/image-reference.js';
import { Duration } from '../core/time/duration.js';
import { DeploymentPhase } from '../data/schema/model/remote/deployment-phase.js';
import { optionFromFlag } from './command-helpers.js';
var RelayCommandType;
(function (RelayCommandType) {
RelayCommandType["ADD"] = "add";
RelayCommandType["UPGRADE"] = "upgrade";
RelayCommandType["DESTROY"] = "destroy";
})(RelayCommandType || (RelayCommandType = {}));
let RelayCommand = class RelayCommand extends BaseCommand {
static { RelayCommand_1 = this; }
accountManager;
constructor(accountManager) {
super();
this.accountManager = accountManager;
this.accountManager = patchInject(accountManager, InjectTokens.AccountManager, this.constructor.name);
}
static DEPLOY_CONFIGS_NAME = 'deployConfigs';
static UPGRADE_CONFIGS_NAME = 'deployConfigs';
static DEPLOY_FLAGS_LIST = {
required: [flags.deployment],
optional: [
flags.chainId,
flags.chartDirectory,
flags.relayChartDirectory,
flags.clusterRef,
flags.nodeAliasesUnparsed,
flags.operatorId,
flags.operatorKey,
flags.quiet,
flags.relayReleaseTag,
flags.componentImage,
flags.replicaCount,
flags.valuesFile,
flags.domainName,
flags.forcePortForward,
flags.externalAddress,
flags.cacheDir,
flags.devMode,
// Mirror Node
flags.mirrorNodeId,
flags.mirrorNamespace,
],
};
static UPGRADE_FLAGS_LIST = {
required: [flags.deployment],
optional: [
flags.chainId,
flags.chartDirectory,
flags.relayChartDirectory,
flags.clusterRef,
flags.nodeAliasesUnparsed,
flags.operatorId,
flags.operatorKey,
flags.quiet,
flags.relayReleaseTag,
flags.componentImage,
flags.replicaCount,
flags.valuesFile,
flags.domainName,
flags.forcePortForward,
flags.externalAddress,
flags.cacheDir,
flags.id,
flags.devMode,
// Mirror Node
flags.mirrorNodeId,
flags.mirrorNamespace,
],
};
static DESTROY_FLAGS_LIST = {
required: [flags.deployment],
optional: [flags.chartDirectory, flags.clusterRef, flags.nodeAliasesUnparsed, flags.quiet, flags.devMode, flags.id],
};
async prepareValuesArgForRelay({ valuesFile, nodeAliases, chainId, relayReleaseTag, componentImage, replicaCount, operatorId, operatorKey, namespace, domainName, context, releaseName, deployment, mirrorNamespace, }) {
let valuesArgument = '';
valuesArgument += helpers.prepareValuesFiles(constants.RELAY_VALUES_FILE);
valuesArgument += ' --install';
valuesArgument += helpers.populateHelmArguments({ nameOverride: releaseName });
valuesArgument += ' --set ws.enabled=true';
valuesArgument += ` --set relay.config.MIRROR_NODE_URL=http://${MIRROR_INGRESS_CONTROLLER}-${mirrorNamespace}.${mirrorNamespace}.svc.cluster.local`;
valuesArgument += ` --set relay.config.MIRROR_NODE_URL_WEB3=http://${MIRROR_INGRESS_CONTROLLER}-${mirrorNamespace}.${mirrorNamespace}.svc.cluster.local`;
valuesArgument += ` --set ws.config.MIRROR_NODE_URL=http://${MIRROR_INGRESS_CONTROLLER}-${mirrorNamespace}.${mirrorNamespace}.svc.cluster.local`;
if (chainId) {
valuesArgument += ` --set relay.config.CHAIN_ID=${chainId}`;
valuesArgument += ` --set ws.config.CHAIN_ID=${chainId}`;
}
if (relayReleaseTag) {
relayReleaseTag = SemanticVersion.getValidSemanticVersion(relayReleaseTag, false, 'Relay release');
valuesArgument += ` --set relay.image.tag=${relayReleaseTag}`;
valuesArgument += ` --set ws.image.tag=${relayReleaseTag}`;
}
if (componentImage) {
const parsedImageReference = ImageReference.parseImageReference(componentImage);
valuesArgument += ` --set relay.image.registry=${parsedImageReference.registry}`;
valuesArgument += ` --set ws.image.registry=${parsedImageReference.registry}`;
valuesArgument += ` --set relay.image.repository=${parsedImageReference.repository}`;
valuesArgument += ` --set ws.image.repository=${parsedImageReference.repository}`;
valuesArgument += ` --set relay.image.tag=${parsedImageReference.tag}`;
valuesArgument += ` --set ws.image.tag=${parsedImageReference.tag}`;
}
if (replicaCount) {
valuesArgument += ` --set relay.replicaCount=${replicaCount}`;
valuesArgument += ` --set ws.replicaCount=${replicaCount}`;
}
const operatorIdUsing = operatorId || this.accountManager.getOperatorAccountId(deployment).toString();
valuesArgument += ` --set relay.config.OPERATOR_ID_MAIN=${operatorIdUsing}`;
valuesArgument += ` --set ws.config.OPERATOR_ID_MAIN=${operatorIdUsing}`;
if (operatorKey) {
// use user provided operatorKey if available
valuesArgument += ` --set relay.config.OPERATOR_KEY_MAIN=${operatorKey}`;
valuesArgument += ` --set ws.config.OPERATOR_KEY_MAIN=${operatorKey}`;
}
else {
try {
const secrets = await this.k8Factory
.getK8(context)
.secrets()
.list(namespace, [`solo.hedera.com/account-id=${operatorIdUsing}`]);
if (secrets.length === 0) {
this.logger.info(`No k8s secret found for operator account id ${operatorIdUsing}, use default one`);
valuesArgument += ` --set relay.config.OPERATOR_KEY_MAIN=${constants.OPERATOR_KEY}`;
valuesArgument += ` --set ws.config.OPERATOR_KEY_MAIN=${constants.OPERATOR_KEY}`;
}
else {
this.logger.info('Using operator key from k8s secret');
const operatorKeyFromK8 = Base64.decode(secrets[0].data.privateKey);
valuesArgument += ` --set relay.config.OPERATOR_KEY_MAIN=${operatorKeyFromK8}`;
valuesArgument += ` --set ws.config.OPERATOR_KEY_MAIN=${operatorKeyFromK8}`;
}
}
catch (error) {
throw new SoloError(`Error getting operator key: ${error.message}`, error);
}
}
if (!nodeAliases) {
throw new MissingArgumentError('Node IDs must be specified');
}
const networkJsonString = await this.prepareNetworkJsonString(nodeAliases, namespace, deployment);
const quotedNetworkJsonString = OperatingSystem.isWin32()
? `"${networkJsonString.replaceAll('"', String.raw `\"`)}"`
: `'${networkJsonString}'`;
valuesArgument += ` --set-literal relay.config.HEDERA_NETWORK=${quotedNetworkJsonString}`;
valuesArgument += ` --set-literal ws.config.HEDERA_NETWORK=${quotedNetworkJsonString}`;
if (domainName) {
valuesArgument += helpers.populateHelmArguments({
'relay.ingress.enabled': true,
'relay.ingress.hosts[0].host': domainName,
'relay.ingress.hosts[0].paths[0].path': '/',
'relay.ingress.hosts[0].paths[0].pathType': 'ImplementationSpecific',
});
}
if (valuesFile) {
valuesArgument += helpers.prepareValuesFiles(valuesFile);
}
return valuesArgument;
}
/**
* created a JSON string to represent the map between the node keys and their ids
* output example '{"node-1": "0.0.3", "node-2": "0.004"}'
*/
async prepareNetworkJsonString(nodeAliases, namespace, deployment) {
if (!nodeAliases) {
throw new MissingArgumentError('Node IDs must be specified');
}
const networkIds = {};
const accountMap = this.accountManager.getNodeAccountMap(nodeAliases, deployment);
const networkNodeServicesMap = await this.accountManager.getNodeServiceMap(namespace, this.remoteConfig.getClusterRefs(), deployment);
for (const nodeAlias of nodeAliases) {
const haProxyClusterIp = networkNodeServicesMap.get(nodeAlias).haProxyClusterIp;
const haProxyGrpcPort = networkNodeServicesMap.get(nodeAlias).haProxyGrpcPort;
const networkKey = `${haProxyClusterIp}:${haProxyGrpcPort}`;
networkIds[networkKey] = accountMap.get(nodeAlias);
}
return JSON.stringify(networkIds);
}
getReleaseName() {
return this.renderReleaseName(this.remoteConfig.configuration.components.getNewComponentId(ComponentTypes.RelayNodes));
}
renderReleaseName(id) {
if (typeof id !== 'number') {
throw new SoloError(`Invalid component id: ${id}, type: ${typeof id}`);
}
return `${constants.JSON_RPC_RELAY_RELEASE_NAME}-${id}`;
}
prepareLegacyReleaseName(nodeAliases = []) {
let releaseName = constants.JSON_RPC_RELAY_RELEASE_NAME;
for (const nodeAlias of nodeAliases) {
releaseName += `-${nodeAlias}`;
}
return releaseName;
}
checkChartIsInstalledTask() {
return {
title: 'Check chart is installed',
task: async ({ config }) => {
config.isChartInstalled = await this.chartManager.isChartInstalled(config.namespace, config.releaseName, config.context);
},
};
}
prepareChartValuesTask() {
return {
title: 'Prepare chart values',
task: async ({ config }) => {
config.valuesArg = await this.prepareValuesArgForRelay(config);
},
};
}
deployJsonRpcRelayTask(commandType) {
return {
title: 'Deploy JSON RPC Relay',
task: async ({ config }) => {
await this.chartManager.upgrade(config.namespace, config.releaseName, constants.JSON_RPC_RELAY_CHART, config.relayChartDirectory || constants.JSON_RPC_RELAY_CHART, config.relayChartDirectory ? '' : config.relayReleaseTag, // pin chart version to match image version
config.valuesArg, config.context);
showVersionBanner(this.logger, config.releaseName, config.relayReleaseTag);
// wait for the pod to destroy in case it was an upgrade
if (commandType === RelayCommandType.UPGRADE) {
await helpers.sleep(Duration.ofSeconds(40));
// update relay version in remote config after successful upgrade
this.remoteConfig.updateComponentVersion(ComponentTypes.RelayNodes, new SemanticVersion(config.relayReleaseTag));
await this.remoteConfig.persist();
}
// Add component to remote config
else if (commandType === RelayCommandType.ADD) {
this.remoteConfig.configuration.components.changeComponentPhase(config.newRelayComponent.metadata.id, ComponentTypes.RelayNodes, DeploymentPhase.DEPLOYED);
await this.remoteConfig.persist();
}
},
};
}
checkRelayIsRunningTask() {
return {
title: 'Check relay is running',
task: async ({ config }) => {
try {
await this.k8Factory
.getK8(config.context)
.pods()
.waitForRunningPhase(config.namespace, Templates.renderRelayLabels(config.id, config.isLegacyChartInstalled ? config.releaseName : undefined), constants.RELAY_PODS_RUNNING_MAX_ATTEMPTS, constants.RELAY_PODS_RUNNING_DELAY);
}
catch (error) {
throw new SoloError(`Relay ${config.releaseName} is not running: ${error.message}`, error);
}
// reset nodeAlias
this.configManager.setFlag(flags.nodeAliasesUnparsed, '');
},
};
}
checkRelayIsReadyTask() {
return {
title: 'Check relay is ready',
task: async ({ config }) => {
try {
await this.k8Factory
.getK8(config.context)
.pods()
.waitForReadyStatus(config.namespace, Templates.renderRelayLabels(config.id, config.isLegacyChartInstalled ? config.releaseName : undefined), constants.RELAY_PODS_READY_MAX_ATTEMPTS, constants.RELAY_PODS_READY_DELAY);
}
catch (error) {
throw new SoloError(`Relay ${config.releaseName} is not ready: ${error.message}`, error);
}
},
};
}
enablePortForwardingTask() {
return {
title: 'Enable port forwarding for relay node',
skip: ({ config }) => !config.forcePortForward,
task: async ({ config }) => {
const externalAddress = this.configManager.getFlag(flags.externalAddress);
const pods = await this.k8Factory
.getK8(config.context)
.pods()
.list(config.namespace, Templates.renderRelayLabels(config.id, config.isLegacyChartInstalled ? config.releaseName : undefined));
if (pods.length === 0) {
throw new SoloError('No Relay pod found');
}
const podReference = pods[0].podReference;
const clusterReference = this.getClusterReference();
// always kill pre-existing port forward process first otherwise after upgrade
// the old port forward process tied with old relay pod will still be running and cause issues
await this.remoteConfig.configuration.components.stopPortForwards(clusterReference, podReference, constants.JSON_RPC_RELAY_PORT, // Pod port
constants.JSON_RPC_RELAY_LOCAL_PORT, // Local port
this.k8Factory.getK8(config.context), this.logger, ComponentTypes.RelayNodes, 'JSON RPC Relay');
await this.remoteConfig.persist();
await this.remoteConfig.configuration.components.managePortForward(clusterReference, podReference, constants.JSON_RPC_RELAY_PORT, // Pod port
constants.JSON_RPC_RELAY_LOCAL_PORT, // Local port
this.k8Factory.getK8(config.context), this.logger, ComponentTypes.RelayNodes, 'JSON RPC Relay', config.isChartInstalled, // Reuse existing port if chart is already installed
undefined, true, // persist: auto-restart on failure using persist-port-forward.js
externalAddress);
await this.remoteConfig.persist();
},
};
}
async add(argv) {
let lease;
const tasks = this.taskList.newTaskList([
{
title: 'Initialize',
task: async (context_, task) => {
await this.localConfig.load();
await this.loadRemoteConfigOrWarn(argv);
if (!this.oneShotState.isActive()) {
lease = await this.leaseManager.create();
}
// reset nodeAlias
this.configManager.setFlag(flags.nodeAliasesUnparsed, '');
this.configManager.update(argv);
flags.disablePrompts(RelayCommand_1.DEPLOY_FLAGS_LIST.optional);
const allFlags = [
...RelayCommand_1.DEPLOY_FLAGS_LIST.required,
...RelayCommand_1.DEPLOY_FLAGS_LIST.optional,
];
await this.configManager.executePrompt(task, allFlags);
// prompt if inputs are empty and set it in the context
const config = this.configManager.getConfig(RelayCommand_1.DEPLOY_CONFIGS_NAME, allFlags, ['nodeAliases']);
context_.config = config;
config.isLegacyChartInstalled = false;
config.namespace = await this.getNamespace(task);
config.nodeAliases = helpers.parseNodeAliases(config.nodeAliasesUnparsed, this.remoteConfig.getConsensusNodes(), this.configManager);
config.clusterRef = this.getClusterReference();
config.context = this.getClusterContext(config.clusterRef);
config.releaseName = this.getReleaseName();
const nodeIds = config.nodeAliases.map((nodeAlias) => Templates.nodeIdFromNodeAlias(nodeAlias));
const { mirrorNodeId, mirrorNamespace, mirrorNodeReleaseName } = await this.inferMirrorNodeData(config.namespace, config.context);
config.mirrorNodeId = mirrorNodeId;
config.mirrorNamespace = mirrorNamespace;
config.mirrorNodeReleaseName = mirrorNodeReleaseName;
config.newRelayComponent = this.componentFactory.createNewRelayComponent(config.clusterRef, config.namespace, nodeIds);
config.newRelayComponent.metadata.phase = DeploymentPhase.REQUESTED;
config.id = config.newRelayComponent.metadata.id;
if (!this.oneShotState.isActive()) {
return ListrLock.newAcquireLockTask(lease, task);
}
return ListrLock.newSkippedLockTask(task);
},
},
this.addRelayComponent(),
this.checkChartIsInstalledTask(),
this.prepareChartValuesTask(),
this.deployJsonRpcRelayTask(RelayCommandType.ADD),
this.checkRelayIsRunningTask(),
this.checkRelayIsReadyTask(),
this.enablePortForwardingTask(),
{
title: 'Show user messages',
skip: () => this.oneShotState.isActive(),
task: () => {
this.logger.showAllMessageGroups();
},
},
], constants.LISTR_DEFAULT_OPTIONS.DEFAULT, undefined, 'relay node add');
if (tasks.isRoot()) {
try {
await tasks.run();
}
catch (error) {
throw new SoloError(`Error deploying relay: ${error.message}`, error);
}
finally {
if (lease && !this.oneShotState.isActive()) {
await lease.release();
}
}
}
else {
this.taskList.registerCloseFunction(async () => {
if (!this.oneShotState.isActive()) {
await lease?.release();
}
});
}
return true;
}
async upgrade(argv) {
let lease;
const tasks = this.taskList.newTaskList([
{
title: 'Initialize',
task: async (context_, task) => {
await this.localConfig.load();
await this.remoteConfig.loadAndValidate(argv);
if (!this.oneShotState.isActive()) {
lease = await this.leaseManager.create();
}
// reset nodeAlias
this.configManager.setFlag(flags.nodeAliasesUnparsed, '');
this.configManager.update(argv);
flags.disablePrompts(RelayCommand_1.UPGRADE_FLAGS_LIST.optional);
const allFlags = [
...RelayCommand_1.UPGRADE_FLAGS_LIST.required,
...RelayCommand_1.UPGRADE_FLAGS_LIST.optional,
];
await this.configManager.executePrompt(task, allFlags);
// prompt if inputs are empty and set it in the context
const config = this.configManager.getConfig(RelayCommand_1.UPGRADE_CONFIGS_NAME, allFlags, []);
context_.config = config;
config.namespace = await this.getNamespace(task);
config.nodeAliases = helpers.parseNodeAliases(config.nodeAliasesUnparsed, this.remoteConfig.getConsensusNodes(), this.configManager);
config.clusterRef = this.getClusterReference();
config.context = this.getClusterContext(config.clusterRef);
const { id, isLegacyChartInstalled, isChartInstalled, releaseName, nodeAliases } = await this.inferRelayData(config.namespace, config.context);
config.id = id;
config.isLegacyChartInstalled = isLegacyChartInstalled;
config.isChartInstalled = isChartInstalled;
config.releaseName = releaseName;
config.nodeAliases = nodeAliases;
const { mirrorNodeId, mirrorNamespace, mirrorNodeReleaseName } = await this.inferMirrorNodeData(config.namespace, config.context);
config.mirrorNodeId = mirrorNodeId;
config.mirrorNamespace = mirrorNamespace;
config.mirrorNodeReleaseName = mirrorNodeReleaseName;
assertUpgradeVersionNotOlder('Relay', config.relayReleaseTag, this.remoteConfig.getComponentVersion(ComponentTypes.RelayNodes), optionFromFlag(flags.relayReleaseTag));
if (!this.oneShotState.isActive()) {
return ListrLock.newAcquireLockTask(lease, task);
}
return ListrLock.newSkippedLockTask(task);
},
},
this.prepareChartValuesTask(),
this.deployJsonRpcRelayTask(RelayCommandType.UPGRADE),
this.checkRelayIsRunningTask(),
this.checkRelayIsReadyTask(),
this.enablePortForwardingTask(),
], constants.LISTR_DEFAULT_OPTIONS.DEFAULT, undefined, 'relay node upgrade');
if (tasks.isRoot()) {
try {
await tasks.run();
}
catch (error) {
throw new SoloError(`Error upgrading relay: ${error.message}`, error);
}
finally {
if (!this.oneShotState.isActive()) {
await lease?.release();
}
}
}
else {
this.taskList.registerCloseFunction(async () => {
if (!this.oneShotState.isActive()) {
await lease?.release();
}
});
}
return true;
}
async destroy(argv) {
let lease;
const tasks = this.taskList.newTaskList([
{
title: 'Initialize',
task: async (context_, task) => {
await this.localConfig.load();
await this.remoteConfig.loadAndValidate(argv);
if (!this.oneShotState.isActive()) {
lease = await this.leaseManager.create();
}
// reset nodeAlias
this.configManager.setFlag(flags.nodeAliasesUnparsed, '');
this.configManager.update(argv);
flags.disablePrompts([flags.clusterRef, flags.id, flags.nodeAliasesUnparsed]);
const allFlags = [
...RelayCommand_1.DESTROY_FLAGS_LIST.required,
...RelayCommand_1.DESTROY_FLAGS_LIST.optional,
];
await this.configManager.executePrompt(task, allFlags);
const clusterReference = this.getClusterReference();
const context = this.getClusterContext(clusterReference);
const namespace = await this.getNamespace(task);
const { id, isLegacyChartInstalled, isChartInstalled, releaseName, nodeAliases } = await this.inferRelayData(namespace, context);
const config = {
chartDirectory: this.configManager.getFlag(flags.chartDirectory),
namespace,
nodeAliases,
clusterRef: clusterReference,
id,
isLegacyChartInstalled,
isChartInstalled,
releaseName,
deployment: this.configManager.getFlag(flags.deployment),
context,
};
context_.config = config;
if (!this.oneShotState.isActive()) {
return ListrLock.newAcquireLockTask(lease, task);
}
return ListrLock.newSkippedLockTask(task);
},
},
{
title: 'Destroy JSON RPC Relay',
task: async ({ config }) => {
await this.chartManager.uninstall(config.namespace, config.releaseName, config.context);
this.logger.showList('Destroyed Relays', await this.chartManager.getInstalledCharts(config.namespace, config.context));
// reset nodeAliasesUnparsed
this.configManager.setFlag(flags.nodeAliasesUnparsed, '');
},
skip: (context_) => !context_.config.isChartInstalled,
},
this.disableRelayComponent(),
], constants.LISTR_DEFAULT_OPTIONS.DEFAULT, undefined, 'relay node destroy');
if (tasks.isRoot()) {
try {
await tasks.run();
}
catch (error) {
throw new SoloError('Error uninstalling relays', error);
}
finally {
if (!this.oneShotState.isActive()) {
await lease?.release();
}
}
}
else {
this.taskList.registerCloseFunction(async () => {
if (!this.oneShotState.isActive()) {
await lease?.release();
}
});
}
return true;
}
/** Adds the relay component to remote config. */
addRelayComponent() {
return {
title: 'Add relay component in remote config',
skip: ({ config }) => !this.remoteConfig.isLoaded() || config.isChartInstalled || this.oneShotState.isActive(),
task: async ({ config }) => {
this.remoteConfig.configuration.components.addNewComponent(config.newRelayComponent, ComponentTypes.RelayNodes);
// save relay version in remote config
this.remoteConfig.updateComponentVersion(ComponentTypes.RelayNodes, new SemanticVersion(config.relayReleaseTag));
await this.remoteConfig.persist();
},
};
}
/** Remove the relay component from remote config. */
disableRelayComponent() {
return {
title: 'Remove relay component from remote config',
skip: () => !this.remoteConfig.isLoaded(),
task: async ({ config }) => {
this.remoteConfig.configuration.components.removeComponent(config.id, ComponentTypes.RelayNodes);
await this.remoteConfig.persist();
},
};
}
async close() { } // no-op
async checkIfLegacyChartIsInstalled(id, namespace, context, nodeAliases) {
return id <= 1
? await this.chartManager.isChartInstalled(namespace, this.prepareLegacyReleaseName(nodeAliases), context)
: false;
}
inferRelayId() {
const id = this.configManager.getFlag(flags.id);
if (typeof id === 'number') {
return id;
}
if (this.remoteConfig.configuration.components.state.relayNodes.length === 0) {
throw new SoloError('Relay node not found in remote config');
}
return this.remoteConfig.configuration.components.state.relayNodes[0].metadata.id;
}
async inferRelayData(namespace, context) {
const id = this.inferRelayId();
const nodeAliases = helpers.parseNodeAliases(this.configManager.getFlag(flags.nodeAliasesUnparsed), this.remoteConfig.getConsensusNodes(), this.configManager);
const isLegacyChartInstalled = await this.checkIfLegacyChartIsInstalled(id, namespace, context, nodeAliases);
if (isLegacyChartInstalled) {
return {
id,
nodeAliases,
releaseName: this.prepareLegacyReleaseName(nodeAliases),
isChartInstalled: true,
isLegacyChartInstalled,
};
}
const releaseName = this.renderReleaseName(id);
return {
id,
nodeAliases,
releaseName,
isChartInstalled: await this.chartManager.isChartInstalled(namespace, releaseName, context),
isLegacyChartInstalled,
};
}
};
RelayCommand = RelayCommand_1 = __decorate([
injectable(),
__param(0, inject(InjectTokens.AccountManager)),
__metadata("design:paramtypes", [Function])
], RelayCommand);
export { RelayCommand };
//# sourceMappingURL=relay.js.map