@hashgraph/solo
Version:
An opinionated CLI tool to deploy and manage private Hedera Networks.
186 lines • 8.82 kB
JavaScript
// SPDX-License-Identifier: Apache-2.0
import { readFileSync } from 'node:fs';
import { parse } from 'yaml';
import { expect } from 'chai';
import { beforeEach } from 'mocha';
import os from 'node:os';
import { instanceToPlain, plainToInstance } from 'class-transformer';
import { RemoteConfigSchema } from '../../../../../../src/data/schema/model/remote/remote-config-schema.js';
import { LedgerPhase } from '../../../../../../src/data/schema/model/remote/ledger-phase.js';
import { DeploymentPhase } from '../../../../../../src/data/schema/model/remote/deployment-phase.js';
function migrateVersionPrefix(version) {
const strippedVersionPrefix = version.replace(/^v/, '');
const parts = strippedVersionPrefix.split('.').map(Number); // Split and convert to numbers
while (parts.length < 3) {
parts.push(0); // Add missing minor/patch as 0
}
return parts.join('.');
}
function migrateVersions(plainObject) {
plainObject.versions = {};
plainObject.versions.cli = migrateVersionPrefix(plainObject.metadata?.soloVersion || '0.0.0');
plainObject.versions.chart = migrateVersionPrefix(plainObject.metadata?.soloChartVersion || '0.0.0');
plainObject.versions.consensusNode = migrateVersionPrefix(plainObject.metadata?.hederaPlatformVersion || plainObject.flags?.releaseTag || '0.0.0');
plainObject.versions.mirrorNodeChart = migrateVersionPrefix(plainObject.metadata?.hederaMirrorNodeChartVersion || plainObject.flags?.mirrorNodeVersion || '0.0.0');
plainObject.versions.explorerChart = migrateVersionPrefix(plainObject.metadata?.explorerChartVersion || plainObject.flags?.explorerVersion || '0.0.0');
plainObject.versions.jsonRpcRelayChart = migrateVersionPrefix(plainObject.metadata?.hederaJsonRpcRelayChartVersion || plainObject.flags?.relayReleaseTag || '0.0.0');
plainObject.versions.blockNodeChart = 'v0.0.0';
}
function migrateClusters(plainObject) {
const clusters = plainObject.clusters;
const clustersArray = [];
for (const key in clusters) {
expect(clusters[key]).to.not.be.undefined.and.to.not.be.null;
const cluster = clusters[key];
clustersArray.push(cluster);
}
plainObject.clusters = clustersArray;
}
function migrateHistory(plainObject) {
plainObject.history = {};
plainObject.history.commands = [];
for (const historyItem of plainObject.commandHistory) {
plainObject.history.commands.push(historyItem);
}
}
function migrateConsensusNodes(plainObject) {
plainObject.state.consensusNodes = [];
for (const plainConsensusNodeKey of Object.keys(plainObject.components?.consensusNodes)) {
const oldConsensusNode = plainObject.components.consensusNodes[plainConsensusNodeKey];
let migratedState;
switch (oldConsensusNode.state) {
case 'requested': {
migratedState = DeploymentPhase.REQUESTED;
break;
}
case 'initialized': {
migratedState = DeploymentPhase.DEPLOYED;
break;
}
case 'setup': {
migratedState = DeploymentPhase.CONFIGURED;
break;
}
case 'started': {
migratedState = DeploymentPhase.STARTED;
break;
}
case 'freezed': {
migratedState = DeploymentPhase.FROZEN;
break;
}
case 'stopped': {
migratedState = DeploymentPhase.STOPPED;
break;
}
}
const newConsensusNode = {
id: oldConsensusNode.nodeId + 1,
namespace: oldConsensusNode.namespace,
cluster: oldConsensusNode.cluster,
phase: migratedState,
};
plainObject.state.consensusNodes.push({ metadata: newConsensusNode });
}
}
function migrateHaProxies(plainObject) {
plainObject.state.haProxies = [];
}
function migrateEnvoyProxies(plainObject) {
plainObject.state.envoyProxies = [];
}
function migrateMirrorNodes(plainObject) {
plainObject.state.mirrorNodes = [];
}
function migrateExplorers(plainObject) {
plainObject.state.explorers = [];
}
function migrateJsonRpcRelays(plainObject) {
plainObject.state.relayNodes = [];
}
function migrateState(plainObject) {
plainObject.state = {};
plainObject.state.ledgerPhase = LedgerPhase.UNINITIALIZED;
migrateConsensusNodes(plainObject);
migrateHaProxies(plainObject);
migrateEnvoyProxies(plainObject);
migrateMirrorNodes(plainObject);
migrateExplorers(plainObject);
migrateJsonRpcRelays(plainObject);
}
function migrate(plainObject) {
plainObject.schemaVersion = 0;
const meta = plainObject.metadata;
meta.lastUpdatedBy = {
name: os.userInfo().username,
hostname: os.hostname(),
};
migrateClusters(plainObject);
migrateVersions(plainObject);
migrateHistory(plainObject);
migrateState(plainObject);
}
describe('RemoteConfig', () => {
const remoteConfigPath = 'test/data/v0-35-1-remote-config.yaml';
describe('Class Transformer', () => {
let yamlData;
let plainObject;
beforeEach(() => {
yamlData = readFileSync(remoteConfigPath, 'utf8');
expect(yamlData).to.not.be.undefined.and.to.not.be.null;
plainObject = parse(yamlData);
expect(plainObject).to.not.be.undefined.and.to.not.be.null;
migrate(plainObject);
});
function expectRemoteConfigClass(rc) {
expect(rc).to.not.be.undefined.and.to.not.be.null;
expect(rc.history.commands.length).to.be.equal(9);
expect(rc.versions.cli.toString()).to.equal('0.34.0');
expect(rc.versions.chart.toString()).to.equal('0.44.0');
expect(rc.versions.consensusNode.toString()).to.equal('0.58.10');
expect(rc.versions.mirrorNodeChart.toString()).to.equal('0.122.0');
expect(rc.versions.explorerChart.toString()).to.equal('24.12.0');
expect(rc.versions.jsonRpcRelayChart.toString()).to.equal('0.63.2');
expect(rc.clusters.length).to.be.equal(1);
expect(rc.state.consensusNodes.length).to.be.equal(4);
expect(rc.state.consensusNodes[0].metadata.id).to.be.equal(1);
expect(rc.state.consensusNodes[0].metadata.namespace).to.be.equal('solo-alpha-prod');
expect(rc.state.consensusNodes[0].metadata.cluster).to.be.equal('gke-alpha-prod-us-central1');
expect(rc.state.consensusNodes[0].metadata.phase).to.be.equal(DeploymentPhase.STARTED);
expect(rc.state.ledgerPhase).to.be.equal(LedgerPhase.UNINITIALIZED);
}
function expectRemoteConfigPlain(object) {
expect(object).to.not.be.undefined.and.to.not.be.null;
expect(object.history.commands.length).to.be.equal(9);
expect(object.versions.cli).to.equal('0.34.0');
expect(object.versions.chart).to.equal('0.44.0');
expect(object.versions.consensusNode).to.equal('0.58.10');
expect(object.versions.mirrorNodeChart).to.equal('0.122.0');
expect(object.versions.explorerChart).to.equal('24.12.0');
expect(object.versions.jsonRpcRelayChart).to.equal('0.63.2');
expect(object.clusters.length).to.be.equal(1);
expect(object.state.consensusNodes.length).to.be.equal(4);
expect(object.state.consensusNodes[0].metadata.id).to.be.equal(1);
expect(object.state.consensusNodes[0].metadata.namespace).to.be.equal('solo-alpha-prod');
expect(object.state.consensusNodes[0].metadata.cluster).to.be.equal('gke-alpha-prod-us-central1');
expect(object.state.consensusNodes[0].metadata.phase).to.be.equal(DeploymentPhase.STARTED);
expect(object.state.ledgerPhase).to.be.equal(LedgerPhase.UNINITIALIZED);
}
it('should transform plain to class', async () => {
const rc = plainToInstance(RemoteConfigSchema, plainObject);
expectRemoteConfigClass(rc);
});
it('should transform class to plain', async () => {
const rc = plainToInstance(RemoteConfigSchema, plainObject);
const plainRemoteConfigObject = instanceToPlain(rc);
expectRemoteConfigPlain(plainRemoteConfigObject);
});
it('should be able to go from a class to an object back to a class', async () => {
const rc = plainToInstance(RemoteConfigSchema, plainObject);
const plainRemoteConfigObject = instanceToPlain(rc);
const rc2 = plainToInstance(RemoteConfigSchema, plainRemoteConfigObject);
expectRemoteConfigClass(rc2);
});
});
});
//# sourceMappingURL=remote-config.test.js.map