Skip to content

Commit

Permalink
feat(remote-config): instead of keeping just the command and the subc…
Browse files Browse the repository at this point in the history
…ommand inside the remote config keep the flags as passed (#1208)

Signed-off-by: instamenta <[email protected]>
  • Loading branch information
instamenta authored Jan 27, 2025
1 parent fb69435 commit a31498e
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 25 deletions.
16 changes: 8 additions & 8 deletions Taskfile.helper.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ tasks:
deps:
- task: "init"
cmds:
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node keys --gossip-keys --tls-keys --node-aliases-unparsed {{.node_identifiers}} -q --dev
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node keys --gossip-keys --tls-keys --node-aliases {{.node_identifiers}} -q --dev

solo:network:deploy:
silent: true
Expand All @@ -185,7 +185,7 @@ tasks:
if [[ "${SOLO_CHART_VERSION}" != "" ]]; then
export SOLO_CHART_FLAG='--solo-chart-version ${SOLO_CHART_VERSION}'
fi
SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- network deploy --namespace "${SOLO_NAMESPACE}" --node-aliases-unparsed {{.node_identifiers}} ${CONSENSUS_NODE_FLAG} ${SOLO_CHART_FLAG} ${VALUES_FLAG} ${SETTINGS_FLAG} ${LOG4J2_FLAG} ${APPLICATION_PROPERTIES_FLAG} ${GENESIS_THROTTLES_FLAG} ${DEBUG_NODE_FLAG} ${SOLO_CHARTS_DIR_FLAG} ${LOAD_BALANCER_FLAG} ${NETWORK_DEPLOY_EXTRA_FLAGS} -q --dev
SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- network deploy --namespace "${SOLO_NAMESPACE}" --node-aliases {{.node_identifiers}} ${CONSENSUS_NODE_FLAG} ${SOLO_CHART_FLAG} ${VALUES_FLAG} ${SETTINGS_FLAG} ${LOG4J2_FLAG} ${APPLICATION_PROPERTIES_FLAG} ${GENESIS_THROTTLES_FLAG} ${DEBUG_NODE_FLAG} ${SOLO_CHARTS_DIR_FLAG} ${LOAD_BALANCER_FLAG} ${NETWORK_DEPLOY_EXTRA_FLAGS} -q --dev
- task: "solo:node:setup"

solo:node:setup:
Expand All @@ -198,7 +198,7 @@ tasks:
if [[ "${CONSENSUS_NODE_VERSION}" != "" ]]; then
export CONSENSUS_NODE_FLAG='--release-tag {{.CONSENSUS_NODE_VERSION}}'
fi
SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node setup --namespace "${SOLO_NAMESPACE}" --node-aliases-unparsed {{.node_identifiers}} ${CONSENSUS_NODE_FLAG} ${LOCAL_BUILD_FLAG} -q --dev
SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node setup --namespace "${SOLO_NAMESPACE}" --node-aliases {{.node_identifiers}} ${CONSENSUS_NODE_FLAG} ${LOCAL_BUILD_FLAG} -q --dev
solo:network:destroy:
silent: true
Expand All @@ -218,7 +218,7 @@ tasks:
if [[ "${DEBUG_NODE_ALIAS}" != "" ]]; then
export DEBUG_NODE_FLAG="--debug-node-alias {{ .DEBUG_NODE_ALIAS }}"
fi
SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node start --namespace "${SOLO_NAMESPACE}" --node-aliases-unparsed {{.node_identifiers}} ${DEBUG_NODE_FLAG} -q {{ .CLI_ARGS }} --dev
SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node start --namespace "${SOLO_NAMESPACE}" --node-aliases {{.node_identifiers}} ${DEBUG_NODE_FLAG} -q {{ .CLI_ARGS }} --dev
- |
if [[ "{{ .use_port_forwards }}" == "true" ]];then
echo "Port forwarding for Hedera Network Node: grpc:50211"
Expand All @@ -233,7 +233,7 @@ tasks:
deps:
- task: "init"
cmds:
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node stop --namespace "${SOLO_NAMESPACE}" --node-aliases-unparsed {{.node_identifiers}} -q {{ .CLI_ARGS }} --dev
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node stop --namespace "${SOLO_NAMESPACE}" --node-aliases {{.node_identifiers}} -q {{ .CLI_ARGS }} --dev

solo:relay:
silent: true
Expand Down Expand Up @@ -289,8 +289,8 @@ tasks:
cmds:
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node prepare-upgrade --namespace "${SOLO_NAMESPACE}" -q --dev
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node freeze-upgrade --namespace "${SOLO_NAMESPACE}" -q --dev
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node stop --namespace "${SOLO_NAMESPACE}" --node-aliases-unparsed {{.node_identifiers}} -q --dev
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node start --namespace "${SOLO_NAMESPACE}" --node-aliases-unparsed {{.node_identifiers}} -q --dev
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node stop --namespace "${SOLO_NAMESPACE}" --node-aliases {{.node_identifiers}} -q --dev
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node start --namespace "${SOLO_NAMESPACE}" --node-aliases {{.node_identifiers}} -q --dev

cluster:create:
silent: true
Expand Down Expand Up @@ -360,7 +360,7 @@ tasks:
solo:node:logs:
silent: true
cmds:
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node logs --namespace "${SOLO_NAMESPACE}" --node-aliases-unparsed {{.node_identifiers}} -q --dev
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node logs --namespace "${SOLO_NAMESPACE}" --node-aliases {{.node_identifiers}} -q --dev

start:
desc: solo node start
Expand Down
8 changes: 4 additions & 4 deletions docs/content/User/SoloCLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ Kubernetes Cluster : kind-solo-e2e
--debug-node-alias Enable default jvm debug port (5005) for the given node id [string]
--log4j2-xml log4j2.xml file for node [string]
-n, --namespace Namespace [string]
-i, --node-aliases-unparsed Comma separated node aliases (empty means all nodes) [string]
-i, --node-aliases Comma separated node aliases (empty means all nodes) [string]
--pvcs Enable persistent volume claims to store data outside the pod, required for node add
[boolean]
--profile-file Resource profile definition (e.g. custom-spec.yaml) [string]
Expand Down Expand Up @@ -297,7 +297,7 @@ Kubernetes Cluster : kind-solo-e2e
--debug-node-alias Enable default jvm debug port (5005) for the given node id [string]
--log4j2-xml log4j2.xml file for node [string]
-n, --namespace Namespace [string]
-i, --node-aliases-unparsed Comma separated node aliases (empty means all nodes) [string]
-i, --node-aliases Comma separated node aliases (empty means all nodes) [string]
--pvcs Enable persistent volume claims to store data outside the pod, required for node add
[boolean]
--profile-file Resource profile definition (e.g. custom-spec.yaml) [string]
Expand Down Expand Up @@ -399,7 +399,7 @@ solo node command is used to manage hedera network nodes, it has the following s
-l, --ledger-id Ledger ID (a.k.a. Chain ID) [string]
-d, --chart-dir Local chart directory path (e.g. ~/solo-charts/charts [string]
-n, --namespace Namespace [string]
-i, --node-aliases-unparsed Comma separated node aliases (empty means all nodes) [string]
-i, --node-aliases Comma separated node aliases (empty means all nodes) [string]
--operator-id Operator ID [string]
--operator-key Operator Key [string]
--profile-file Resource profile definition (e.g. custom-spec.yaml) [string]
Expand All @@ -417,5 +417,5 @@ solo node command is used to manage hedera network nodes, it has the following s
```text
-d, --chart-dir Local chart directory path (e.g. ~/solo-charts/charts [string]
-n, --namespace Namespace [string]
-i, --node-aliases-unparsed Comma separated node aliases (empty means all nodes) [string] [string]
-i, --node-aliases Comma separated node aliases (empty means all nodes) [string] [string]
```
61 changes: 60 additions & 1 deletion src/commands/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {IllegalArgumentError, SoloError} from '../core/errors.js';
import {ListrEnquirerPromptAdapter} from '@listr2/prompt-adapter-enquirer';
import * as helpers from '../core/helpers.js';
import validator from 'validator';
import type {AnyObject} from '../types/aliases.js';

export class Flags {
private static async prompt(
Expand Down Expand Up @@ -475,7 +476,7 @@ export class Flags {

static readonly nodeAliasesUnparsed: CommandFlag = {
constName: 'nodeAliasesUnparsed',
name: 'node-aliases-unparsed',
name: 'node-aliases',
definition: {
describe: 'Comma separated node aliases (empty means all nodes)',
alias: 'i',
Expand Down Expand Up @@ -621,6 +622,7 @@ export class Flags {
describe: 'Operator Key',
defaultValue: undefined,
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: async function promptOperatorKey(task: ListrTaskWrapper<any, any, any>, input: any) {
return await Flags.promptText(
Expand All @@ -641,6 +643,7 @@ export class Flags {
describe: 'Show private key information',
defaultValue: false,
type: 'boolean',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: async function promptPrivateKey(task: ListrTaskWrapper<any, any, any>, input: any) {
return await Flags.promptText(
Expand Down Expand Up @@ -989,6 +992,7 @@ export class Flags {
describe: 'path and file name of the private key for signing gossip in PEM key format to be used',
defaultValue: '',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: undefined,
};
Expand All @@ -1011,6 +1015,7 @@ export class Flags {
describe: 'path and file name of the private TLS key to be used',
defaultValue: '',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: undefined,
};
Expand Down Expand Up @@ -1054,6 +1059,7 @@ export class Flags {
describe: 'ED25519 private key for the Hedera account',
defaultValue: '',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: async function promptPrivateKey(task: ListrTaskWrapper<any, any, any>, input: any) {
return await Flags.promptText(
Expand Down Expand Up @@ -1085,6 +1091,7 @@ export class Flags {
describe: 'ECDSA private key for the Hedera account',
defaultValue: '',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: async function promptPrivateKey(task: ListrTaskWrapper<any, any, any>, input: any) {
return await Flags.promptText(
Expand Down Expand Up @@ -1326,6 +1333,7 @@ export class Flags {
describe: 'Admin key',
defaultValue: constants.GENESIS_KEY,
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: undefined,
};
Expand Down Expand Up @@ -1528,6 +1536,7 @@ export class Flags {
'with multiple nodes comma seperated)',
defaultValue: '',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: async function promptGrpcTlsKeyPath(task: ListrTaskWrapper<any, any, any>, input: any) {
return await Flags.promptText(
Expand All @@ -1551,6 +1560,7 @@ export class Flags {
'with multiple nodes comma seperated)',
defaultValue: '',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: async function promptGrpcWebTlsKeyPath(task: ListrTaskWrapper<any, any, any>, input: any) {
return await Flags.promptText(
Expand Down Expand Up @@ -1619,6 +1629,7 @@ export class Flags {
defaultValue: '',
describe: 'storage access key',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: undefined,
};
Expand All @@ -1630,6 +1641,7 @@ export class Flags {
defaultValue: '',
describe: 'storage secret key',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: undefined,
};
Expand All @@ -1641,6 +1653,7 @@ export class Flags {
defaultValue: '',
describe: 'storage endpoint URL',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: undefined,
};
Expand All @@ -1652,6 +1665,7 @@ export class Flags {
defaultValue: '',
describe: 'name of storage bucket',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: undefined,
};
Expand All @@ -1663,6 +1677,7 @@ export class Flags {
defaultValue: '',
describe: 'name of bucket for backing up state files',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: undefined,
};
Expand All @@ -1674,6 +1689,7 @@ export class Flags {
defaultValue: '',
describe: 'path of google credential file in json format',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: undefined,
};
Expand Down Expand Up @@ -1811,4 +1827,47 @@ export class Flags {
requiredFlagsWithDisabledPrompt: [Flags.namespace, Flags.cacheDir, Flags.releaseTag],
optionalFlags: [Flags.devMode, Flags.quiet],
};

/**
* Processes the Argv arguments and returns them as string, all with full flag names.
* - removes flags that match the default value.
* - removes flags with undefined and null values.
* - removes boolean flags that are false.
* - masks all sensitive flags with their dataMask property.
*/
public static stringifyArgv(argv: AnyObject): string {
const processedFlags: string[] = [];

for (const [name, value] of Object.entries(argv)) {
// Remove non-flag data and boolean presence based flags that are false
if (name === '_' || name === '$0' || value === '' || value === false || value === undefined || value === null) {
continue;
}

// remove flags that use the default value
const flag = Flags.allFlags.find(flag => flag.name === name);
if (!flag || (flag.definition.defaultValue && flag.definition.defaultValue === value)) {
continue;
}

const flagName = flag.name;

// if the flag is boolean based, render it without value
if (value === true) {
processedFlags.push(`--${flagName}`);
}

// if the flag's data is masked, display it without the value
else if (flag.definition.dataMask) {
processedFlags.push(`--${flagName} ${flag.definition.dataMask}`);
}

// else display the full flag data
else {
processedFlags.push(`--${flagName} ${value}`);
}
}

return processedFlags.join(' ');
}
}
10 changes: 5 additions & 5 deletions src/core/config/remote/remote_config_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ import {ErrorMessages} from '../../error_messages.js';
import {CommonFlagsDataWrapper} from './common_flags_data_wrapper.js';
import {type AnyObject} from '../../../types/aliases.js';

interface ListrContext {
config: object;
}

/**
* Uses Kubernetes ConfigMaps to manage the remote configuration data by creating, loading, modifying,
* and saving the configuration data to and from a Kubernetes cluster.
Expand Down Expand Up @@ -211,8 +207,12 @@ export class RemoteConfigManager {

await RemoteConfigValidator.validateComponents(self.remoteConfig.components, self.k8);

const additionalCommandData = `Executed by ${self.localConfig.userEmailAddress}: `;

const currentCommand = argv._.join(' ');
self.remoteConfig!.addCommandToHistory(currentCommand);
const commandArguments = flags.stringifyArgv(argv);

self.remoteConfig!.addCommandToHistory(additionalCommandData + (currentCommand + ' ' + commandArguments).trim());

await self.remoteConfig.flags.handleFlags(argv);

Expand Down
2 changes: 1 addition & 1 deletion src/core/config/remote/remote_config_validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {SoloError} from '../../errors.js';

import type {K8} from '../../k8.js';
import type {ComponentsDataWrapper} from './components_data_wrapper.js';
import {type BaseComponent} from './components/base_component.js';
import type {BaseComponent} from './components/base_component.js';

/**
* Static class is used to validate that components in the remote config
Expand Down
2 changes: 2 additions & 0 deletions src/core/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ export const PROFILE_LOCAL = 'local';
export const ALL_PROFILES = [PROFILE_LOCAL, PROFILE_TINY, PROFILE_SMALL, PROFILE_MEDIUM, PROFILE_LARGE];
export const DEFAULT_PROFILE_FILE = path.join(SOLO_CACHE_DIR, 'profiles', 'custom-spec.yaml');

export const STANDARD_DATAMASK = '***';

// ------ Hedera SDK Related ------
export const NODE_CLIENT_MAX_ATTEMPTS = +process.env.NODE_CLIENT_MAX_ATTEMPTS || 600;
export const NODE_CLIENT_MIN_BACKOFF = +process.env.NODE_CLIENT_MIN_BACKOFF || 1_000;
Expand Down
10 changes: 5 additions & 5 deletions src/core/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ import {Templates} from './templates.js';
import {ROOT_DIR} from './constants.js';
import * as constants from './constants.js';
import {PrivateKey, ServiceEndpoint} from '@hashgraph/sdk';
import {type NodeAlias, type NodeAliases} from '../types/aliases.js';
import {type CommandFlag} from '../types/flag_types.js';
import {type SoloLogger} from './logging.js';
import {type Duration} from './time/duration.js';
import {type NodeAddConfigClass} from '../commands/node/node_add_config.js';
import type {NodeAlias, NodeAliases} from '../types/aliases.js';
import type {CommandFlag} from '../types/flag_types.js';
import type {SoloLogger} from './logging.js';
import type {Duration} from './time/duration.js';
import type {NodeAddConfigClass} from '../commands/node/node_add_config.js';

export function sleep(duration: Duration) {
return new Promise<void>(resolve => {
Expand Down
5 changes: 5 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,17 @@ export function main(argv: any) {
// 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(context.name));
logger.showUser(chalk.cyan('Kubernetes Cluster\t:'), chalk.yellow(clusterName));
logger.showUser(chalk.cyan('Current Command\t\t:'), chalk.yellow(commandData));
if (configManager.getFlag(flags.namespace) !== undefined) {
logger.showUser(chalk.cyan('Kubernetes Namespace\t:'), chalk.yellow(configManager.getFlag(flags.namespace)));
}
Expand Down
1 change: 1 addition & 0 deletions src/types/flag_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ export interface Definition {
alias?: string;
type?: string;
disablePrompt?: boolean;
dataMask?: string;
}
Loading

0 comments on commit a31498e

Please sign in to comment.