Skip to content

Commit

Permalink
feat: allow settings a reserved static IP address for the consensus n…
Browse files Browse the repository at this point in the history
…odes HAProxy and Envoy Proxy though the cli with flags (#937)

Signed-off-by: instamenta <[email protected]>
  • Loading branch information
instamenta authored Dec 9, 2024
1 parent f5a69e7 commit de9ec2e
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 7 deletions.
26 changes: 26 additions & 0 deletions src/commands/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1580,6 +1580,30 @@ export class Flags {
},
};

static readonly haproxyIps: CommandFlag = {
constName: 'haproxyIps',
name: 'haproxy-ips',
definition: {
describe:
'IP mapping where key = value is node alias and static ip for haproxy, ' +
'(e.g.: --haproxy-ips node1=127.0.0.1,node2=127.0.0.1)',
type: 'string',
},
prompt: undefined,
};

static readonly envoyIps: CommandFlag = {
constName: 'envoyIps',
name: 'envoy-ips',
definition: {
describe:
'IP mapping where key = value is node alias and static ip for envoy proxy, ' +
'(e.g.: --envoy-ips node1=127.0.0.1,node2=127.0.0.1)',
type: 'string',
},
prompt: undefined,
};

static readonly allFlags: CommandFlag[] = [
Flags.accountId,
Flags.amount,
Expand Down Expand Up @@ -1657,6 +1681,8 @@ export class Flags {
Flags.grpcTlsKeyPath,
Flags.grpcWebTlsKeyPath,
Flags.contextClusterUnparsed,
Flags.haproxyIps,
Flags.envoyIps,
];

/** Resets the definition.disablePrompt for all flags */
Expand Down
38 changes: 37 additions & 1 deletion src/commands/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {type KeyManager} from '../core/key_manager.js';
import {type PlatformInstaller} from '../core/platform_installer.js';
import {type ProfileManager} from '../core/profile_manager.js';
import {type CertificateManager} from '../core/certificate_manager.js';
import {type CommandBuilder, type NodeAlias, type NodeAliases} from '../types/aliases.js';
import {type CommandBuilder, type IP, type NodeAlias, type NodeAliases} from '../types/aliases.js';
import {type Opts} from '../types/command_types.js';
import {ListrLease} from '../core/lease/listr_lease.js';
import {ConsensusNodeComponent} from '../core/config/remote/components/consensus_node_component.js';
Expand Down Expand Up @@ -62,6 +62,10 @@ export interface NetworkDeployConfigClass {
grpcTlsKeyPath: string;
grpcWebTlsKeyPath: string;
getUnusedConfigs: () => string[];
haproxyIps: string;
envoyIps: string;
haproxyIpsParsed?: Record<NodeAlias, IP>;
envoyIpsParsed?: Record<NodeAlias, IP>;
}

export class NetworkCommand extends BaseCommand {
Expand Down Expand Up @@ -121,6 +125,8 @@ export class NetworkCommand extends BaseCommand {
flags.grpcWebTlsCertificatePath,
flags.grpcTlsKeyPath,
flags.grpcWebTlsKeyPath,
flags.haproxyIps,
flags.envoyIps,
];
}

Expand All @@ -134,6 +140,8 @@ export class NetworkCommand extends BaseCommand {
releaseTag?: string;
persistentVolumeClaims?: string;
valuesFile?: string;
haproxyIpsParsed?: Record<NodeAlias, IP>;
envoyIpsParsed?: Record<NodeAlias, IP>;
} = {},
) {
let valuesArg = config.chartDirectory
Expand Down Expand Up @@ -167,6 +175,24 @@ export class NetworkCommand extends BaseCommand {

valuesArg += ` --set "defaults.volumeClaims.enabled=${config.persistentVolumeClaims}"`;

// Iterate over each node and set static IPs for HAProxy
if (config.haproxyIpsParsed) {
config.nodeAliases?.forEach((nodeAlias, index) => {
const ip = config.haproxyIpsParsed?.[nodeAlias];

if (ip) valuesArg += ` --set "hedera.nodes[${index}].haproxyStaticIP=${ip}"`;
});
}

// Iterate over each node and set static IPs for Envoy Proxy
if (config.envoyIpsParsed) {
config.nodeAliases?.forEach((nodeAlias, index) => {
const ip = config.envoyIpsParsed?.[nodeAlias];

if (ip) valuesArg += ` --set "hedera.nodes[${index}].envoyProxyStaticIP=${ip}"`;
});
}

if (config.valuesFile) {
valuesArg += this.prepareValuesFiles(config.valuesFile);
}
Expand Down Expand Up @@ -198,6 +224,8 @@ export class NetworkCommand extends BaseCommand {
flags.grpcWebTlsCertificatePath,
flags.grpcTlsKeyPath,
flags.grpcWebTlsKeyPath,
flags.haproxyIps,
flags.envoyIps,
]);

await flags.executePrompt(task, this.configManager, NetworkCommand.DEPLOY_FLAGS_LIST);
Expand All @@ -214,6 +242,14 @@ export class NetworkCommand extends BaseCommand {

config.nodeAliases = helpers.parseNodeAliases(config.nodeAliasesUnparsed);

if (config.haproxyIps) {
config.haproxyIpsParsed = Templates.parseNodeAliasToIpMapping(config.haproxyIps);
}

if (config.envoyIps) {
config.envoyIpsParsed = Templates.parseNodeAliasToIpMapping(config.envoyIps);
}

// compute values
config.chartPath = await this.prepareChartPath(
config.chartDirectory,
Expand Down
2 changes: 2 additions & 0 deletions src/commands/node/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,8 @@ export interface NodeAddConfigClass {
grpcWebTlsCertificatePath: string;
grpcTlsKeyPath: string;
grpcWebTlsKeyPath: string;
haproxyIps: string;
envoyIps: string;
getUnusedConfigs: () => string[];
}

Expand Down
4 changes: 2 additions & 2 deletions src/commands/node/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export const DELETE_EXECUTE_FLAGS = {
export const ADD_FLAGS = {
requiredFlags: [...COMMON_ADD_REQUIRED_FLAGS],
requiredFlagsWithDisabledPrompt: [...COMMON_ADD_REQUIRED_NO_PROMPT_FLAGS],
optionalFlags: [...COMMON_ADD_OPTIONAL_FLAGS, flags.adminKey],
optionalFlags: [...COMMON_ADD_OPTIONAL_FLAGS, flags.adminKey, flags.haproxyIps, flags.envoyIps],
};

export const ADD_PREPARE_FLAGS = {
Expand All @@ -173,7 +173,7 @@ export const ADD_SUBMIT_TRANSACTIONS_FLAGS = {
export const ADD_EXECUTE_FLAGS = {
requiredFlags: [...COMMON_ADD_REQUIRED_FLAGS, flags.inputDir],
requiredFlagsWithDisabledPrompt: [...COMMON_ADD_REQUIRED_NO_PROMPT_FLAGS],
optionalFlags: [...COMMON_ADD_OPTIONAL_FLAGS],
optionalFlags: [...COMMON_ADD_OPTIONAL_FLAGS, flags.haproxyIps, flags.envoyIps],
};

export const LOGS_FLAGS = {
Expand Down
30 changes: 29 additions & 1 deletion src/commands/node/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import {
type ConfigBuilder,
type NodeAlias,
type NodeAliases,
type NodeId,
type PodName,
type SkipCheck,
} from '../../types/aliases.js';
Expand Down Expand Up @@ -1373,10 +1374,37 @@ export class NodeCommandTasks {
}
}

// for the case of adding new node
// for the case of adding a new node
if (transactionType === NodeSubcommandType.ADD && ctx.newNode && ctx.newNode.accountId) {
valuesArg += ` --set "hedera.nodes[${index}].accountId=${ctx.newNode.accountId}" --set "hedera.nodes[${index}].name=${ctx.newNode.name}"`;

if (config.haproxyIps) {
config.haproxyIpsParsed = Templates.parseNodeAliasToIpMapping(config.haproxyIps);
}

if (config.envoyIps) {
config.envoyIpsParsed = Templates.parseNodeAliasToIpMapping(config.envoyIps);
}

const nodeAlias: NodeAlias = config.nodeAlias;
const nodeId: NodeId = Templates.nodeIdFromNodeAlias(nodeAlias);
const nodeIndexInValues = nodeId - 1;

// Set static IPs for HAProxy
if (config.haproxyIpsParsed) {
const ip: string = config.haproxyIpsParsed?.[nodeAlias];

if (ip) valuesArg += ` --set "hedera.nodes[${nodeIndexInValues}].haproxyStaticIP=${ip}"`;
}

// Set static IPs for Envoy Proxy
if (config.envoyIpsParsed) {
const ip: string = config.envoyIpsParsed?.[nodeAlias];

if (ip) valuesArg += ` --set "hedera.nodes[${nodeIndexInValues}].envoyProxyStaticIP=${ip}"`;
}
}

const profileValuesFile = await self.profileManager.prepareValuesForNodeAdd(
path.join(config.stagingDir, 'config.txt'),
path.join(config.stagingDir, 'templates', 'application.properties'),
Expand Down
16 changes: 14 additions & 2 deletions src/core/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import path from 'path';
import {DataValidationError, SoloError, IllegalArgumentError, MissingArgumentError} from './errors.js';
import * as constants from './constants.js';
import {type AccountId} from '@hashgraph/sdk';
import type {NodeAlias, PodName} from '../types/aliases.js';
import type {IP, NodeAlias, NodeId, PodName} from '../types/aliases.js';
import {GrpcProxyTlsEnums} from './enumerations.js';
import {type ContextClusterStructure} from '../types/config_types.js';
import type {Cluster, Context} from './config/remote/types.js';
Expand Down Expand Up @@ -168,14 +168,15 @@ export class Templates {
return this.nodeAliasFromNetworkSvcName(parts[0]);
}

// @ts-ignore
public static nodeIdFromNodeAlias(nodeAlias: NodeAlias): NodeId {
for (let i = nodeAlias.length - 1; i > 0; i--) {
// @ts-ignore
if (isNaN(nodeAlias[i])) {
return parseInt(nodeAlias.substring(i + 1, nodeAlias.length));
}
}

throw new SoloError(`Can't get node id from node ${nodeAlias}`);
}

public static renderGossipKeySecretName(nodeAlias: NodeAlias): string {
Expand Down Expand Up @@ -263,4 +264,15 @@ export class Templates {
public static renderHaProxyName(nodeAlias: NodeAlias): string {
return `haproxy-${nodeAlias}`;
}

public static parseNodeAliasToIpMapping(unparsed: string): Record<NodeAlias, IP> {
const mapping: Record<NodeAlias, IP> = {};

unparsed.split(',').forEach(data => {
const [nodeAlias, ip] = data.split('=') as [NodeAlias, IP];
mapping[nodeAlias] = ip;
});

return mapping;
}
}
9 changes: 9 additions & 0 deletions src/types/aliases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,23 @@ import {type ReadEntry} from 'tar';

export type NodeAlias = `node${number}`;
export type PodName = `network-${NodeAlias}-0`;
export type NodeId = number;

export type NodeAliases = NodeAlias[];

export type CommandBuilder = (yargs: any) => any;

export type UserPrompt = (task: ListrTaskWrapper<any, any, any>, input: any | string[]) => Promise<any>;

export type TarCreateFilter = (path: string, entry: Stats | ReadEntry) => boolean;

export type SkipCheck = (ctx: any) => Promise<boolean> | boolean;

export type TaskFunction = (
ctx: any,
task: ListrTaskWrapper<any, any, any>,
) => Promise<Listr<any, any, any>> | Listr<any, any, any> | Promise<void> | void;

export type ConfigBuilder = (argv, ctx, task) => Promise<any>;

export type IP = string;
2 changes: 1 addition & 1 deletion version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

export const JAVA_VERSION = '21.0.1+12';
export const HELM_VERSION = 'v3.14.2';
export const SOLO_CHART_VERSION = '0.34.1';
export const SOLO_CHART_VERSION = '0.35.0';
export const HEDERA_PLATFORM_VERSION = 'v0.56.5';
export const MIRROR_NODE_VERSION = '0.116.0';
export const HEDERA_EXPLORER_VERSION = '0.2.1';
Expand Down

0 comments on commit de9ec2e

Please sign in to comment.