@hashgraph/solo
Version:
An opinionated CLI tool to deploy and manage private Hedera Networks.
167 lines (135 loc) • 5.55 kB
text/typescript
/**
* SPDX-License-Identifier: Apache-2.0
*/
import {SoloError} from '../../errors.js';
import * as yaml from 'yaml';
import {RemoteConfigMetadata} from './metadata.js';
import {ComponentsDataWrapper} from './components_data_wrapper.js';
import * as constants from '../../constants.js';
import {CommonFlagsDataWrapper} from './common_flags_data_wrapper.js';
import {type ClusterRef, type RemoteConfigDataStructure, type Version} from './types.js';
import type * as k8s from '@kubernetes/client-node';
import {type ToObject, type Validate} from '../../../types/index.js';
import {type ConfigManager} from '../../config_manager.js';
import {type RemoteConfigData} from './remote_config_data.js';
import {Cluster} from './cluster.js';
export class RemoteConfigDataWrapper implements Validate, ToObject<RemoteConfigDataStructure> {
private readonly _version: Version = '1.0.0';
private _metadata: RemoteConfigMetadata;
private _clusters: Record<ClusterRef, Cluster>;
private _components: ComponentsDataWrapper;
private _commandHistory: string[];
private _lastExecutedCommand: string;
private readonly _flags: CommonFlagsDataWrapper;
public constructor(data: RemoteConfigData) {
this._metadata = data.metadata;
this._clusters = Cluster.fromClustersMapObject(data.clusters);
this._components = data.components;
this._commandHistory = data.commandHistory;
this._lastExecutedCommand = data.lastExecutedCommand ?? '';
this._flags = data.flags;
this.validate();
}
//! -------- Modifiers -------- //
public addCommandToHistory(command: string): void {
this._commandHistory.push(command);
this.lastExecutedCommand = command;
if (this._commandHistory.length > constants.SOLO_REMOTE_CONFIG_MAX_COMMAND_IN_HISTORY) {
this._commandHistory.shift();
}
this.validate();
}
//! -------- Getters & Setters -------- //
private get version(): Version {
return this._version;
}
public get metadata(): RemoteConfigMetadata {
return this._metadata;
}
public set metadata(metadata: RemoteConfigMetadata) {
this._metadata = metadata;
this.validate();
}
public get clusters(): Record<ClusterRef, Cluster> {
return this._clusters;
}
public set clusters(clusters: Record<ClusterRef, Cluster>) {
this._clusters = clusters;
this.validate();
}
public get components(): ComponentsDataWrapper {
return this._components;
}
public set components(components: ComponentsDataWrapper) {
this._components = components;
this.validate();
}
public get lastExecutedCommand(): string {
return this._lastExecutedCommand;
}
private set lastExecutedCommand(lastExecutedCommand: string) {
this._lastExecutedCommand = lastExecutedCommand;
this.validate();
}
public get commandHistory(): string[] {
return this._commandHistory;
}
private set commandHistory(commandHistory: string[]) {
this._commandHistory = commandHistory;
this.validate();
}
public get flags() {
return this._flags;
}
//! -------- Utilities -------- //
public static fromConfigmap(configManager: ConfigManager, configMap: k8s.V1ConfigMap): RemoteConfigDataWrapper {
const data = yaml.parse(configMap.data['remote-config-data']);
return new RemoteConfigDataWrapper({
metadata: RemoteConfigMetadata.fromObject(data.metadata),
components: ComponentsDataWrapper.fromObject(data.components),
clusters: data.clusters,
commandHistory: data.commandHistory,
lastExecutedCommand: data.lastExecutedCommand,
flags: CommonFlagsDataWrapper.fromObject(configManager, data.flags),
});
}
public validate(): void {
if (!this._version || typeof this._version !== 'string') {
throw new SoloError(`Invalid remote config version: ${this._version}`);
}
if (!this.metadata || !(this.metadata instanceof RemoteConfigMetadata)) {
throw new SoloError(`Invalid remote config metadata: ${this.metadata}`);
}
if (!this.lastExecutedCommand || typeof this.lastExecutedCommand !== 'string') {
throw new SoloError(`Invalid remote config last executed command: ${this.lastExecutedCommand}`);
}
if (!Array.isArray(this.commandHistory) || this.commandHistory.some(c => typeof c !== 'string')) {
throw new SoloError(`Invalid remote config command history: ${this.commandHistory}`);
}
Object.entries(this.clusters).forEach(([clusterRef, cluster]: [ClusterRef, Cluster]): void => {
if (!clusterRef || typeof clusterRef !== 'string') {
throw new SoloError(`Invalid remote config cluster-ref: ${clusterRef}`);
}
if (!cluster) {
throw new SoloError(`No cluster info is found for cluster-ref: ${clusterRef}`);
}
if (!cluster.name || typeof cluster.name !== 'string') {
throw new SoloError(`Invalid remote config cluster name: ${cluster.name} for cluster-ref: ${clusterRef}`);
}
if (!cluster.namespace || typeof cluster.namespace !== 'string') {
throw new SoloError(`Invalid remote config namespace: ${cluster.namespace} for cluster-ref: ${clusterRef}`);
}
});
}
public toObject(): RemoteConfigDataStructure {
return {
metadata: this.metadata.toObject(),
version: this.version,
clusters: Cluster.toClustersMapObject(this.clusters),
components: this.components.toObject(),
commandHistory: this.commandHistory,
lastExecutedCommand: this.lastExecutedCommand,
flags: this.flags.toObject(),
};
}
}