Skip to content

Commit a31498e

Browse files
authored
feat(remote-config): instead of keeping just the command and the subcommand inside the remote config keep the flags as passed (#1208)
Signed-off-by: instamenta <instamenta@abv.bg>
1 parent fb69435 commit a31498e

File tree

10 files changed

+110
-25
lines changed

10 files changed

+110
-25
lines changed

Taskfile.helper.yml

+8-8
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ tasks:
167167
deps:
168168
- task: "init"
169169
cmds:
170-
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node keys --gossip-keys --tls-keys --node-aliases-unparsed {{.node_identifiers}} -q --dev
170+
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node keys --gossip-keys --tls-keys --node-aliases {{.node_identifiers}} -q --dev
171171

172172
solo:network:deploy:
173173
silent: true
@@ -185,7 +185,7 @@ tasks:
185185
if [[ "${SOLO_CHART_VERSION}" != "" ]]; then
186186
export SOLO_CHART_FLAG='--solo-chart-version ${SOLO_CHART_VERSION}'
187187
fi
188-
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
188+
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
189189
- task: "solo:node:setup"
190190

191191
solo:node:setup:
@@ -198,7 +198,7 @@ tasks:
198198
if [[ "${CONSENSUS_NODE_VERSION}" != "" ]]; then
199199
export CONSENSUS_NODE_FLAG='--release-tag {{.CONSENSUS_NODE_VERSION}}'
200200
fi
201-
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
201+
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
202202
203203
solo:network:destroy:
204204
silent: true
@@ -218,7 +218,7 @@ tasks:
218218
if [[ "${DEBUG_NODE_ALIAS}" != "" ]]; then
219219
export DEBUG_NODE_FLAG="--debug-node-alias {{ .DEBUG_NODE_ALIAS }}"
220220
fi
221-
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
221+
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
222222
- |
223223
if [[ "{{ .use_port_forwards }}" == "true" ]];then
224224
echo "Port forwarding for Hedera Network Node: grpc:50211"
@@ -233,7 +233,7 @@ tasks:
233233
deps:
234234
- task: "init"
235235
cmds:
236-
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node stop --namespace "${SOLO_NAMESPACE}" --node-aliases-unparsed {{.node_identifiers}} -q {{ .CLI_ARGS }} --dev
236+
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node stop --namespace "${SOLO_NAMESPACE}" --node-aliases {{.node_identifiers}} -q {{ .CLI_ARGS }} --dev
237237

238238
solo:relay:
239239
silent: true
@@ -289,8 +289,8 @@ tasks:
289289
cmds:
290290
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node prepare-upgrade --namespace "${SOLO_NAMESPACE}" -q --dev
291291
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node freeze-upgrade --namespace "${SOLO_NAMESPACE}" -q --dev
292-
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node stop --namespace "${SOLO_NAMESPACE}" --node-aliases-unparsed {{.node_identifiers}} -q --dev
293-
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node start --namespace "${SOLO_NAMESPACE}" --node-aliases-unparsed {{.node_identifiers}} -q --dev
292+
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node stop --namespace "${SOLO_NAMESPACE}" --node-aliases {{.node_identifiers}} -q --dev
293+
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node start --namespace "${SOLO_NAMESPACE}" --node-aliases {{.node_identifiers}} -q --dev
294294

295295
cluster:create:
296296
silent: true
@@ -360,7 +360,7 @@ tasks:
360360
solo:node:logs:
361361
silent: true
362362
cmds:
363-
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node logs --namespace "${SOLO_NAMESPACE}" --node-aliases-unparsed {{.node_identifiers}} -q --dev
363+
- SOLO_HOME_DIR=${SOLO_HOME_DIR} npm run solo -- node logs --namespace "${SOLO_NAMESPACE}" --node-aliases {{.node_identifiers}} -q --dev
364364

365365
start:
366366
desc: solo node start

docs/content/User/SoloCLI.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ Kubernetes Cluster : kind-solo-e2e
248248
--debug-node-alias Enable default jvm debug port (5005) for the given node id [string]
249249
--log4j2-xml log4j2.xml file for node [string]
250250
-n, --namespace Namespace [string]
251-
-i, --node-aliases-unparsed Comma separated node aliases (empty means all nodes) [string]
251+
-i, --node-aliases Comma separated node aliases (empty means all nodes) [string]
252252
--pvcs Enable persistent volume claims to store data outside the pod, required for node add
253253
[boolean]
254254
--profile-file Resource profile definition (e.g. custom-spec.yaml) [string]
@@ -297,7 +297,7 @@ Kubernetes Cluster : kind-solo-e2e
297297
--debug-node-alias Enable default jvm debug port (5005) for the given node id [string]
298298
--log4j2-xml log4j2.xml file for node [string]
299299
-n, --namespace Namespace [string]
300-
-i, --node-aliases-unparsed Comma separated node aliases (empty means all nodes) [string]
300+
-i, --node-aliases Comma separated node aliases (empty means all nodes) [string]
301301
--pvcs Enable persistent volume claims to store data outside the pod, required for node add
302302
[boolean]
303303
--profile-file Resource profile definition (e.g. custom-spec.yaml) [string]
@@ -399,7 +399,7 @@ solo node command is used to manage hedera network nodes, it has the following s
399399
-l, --ledger-id Ledger ID (a.k.a. Chain ID) [string]
400400
-d, --chart-dir Local chart directory path (e.g. ~/solo-charts/charts [string]
401401
-n, --namespace Namespace [string]
402-
-i, --node-aliases-unparsed Comma separated node aliases (empty means all nodes) [string]
402+
-i, --node-aliases Comma separated node aliases (empty means all nodes) [string]
403403
--operator-id Operator ID [string]
404404
--operator-key Operator Key [string]
405405
--profile-file Resource profile definition (e.g. custom-spec.yaml) [string]
@@ -417,5 +417,5 @@ solo node command is used to manage hedera network nodes, it has the following s
417417
```text
418418
-d, --chart-dir Local chart directory path (e.g. ~/solo-charts/charts [string]
419419
-n, --namespace Namespace [string]
420-
-i, --node-aliases-unparsed Comma separated node aliases (empty means all nodes) [string] [string]
420+
-i, --node-aliases Comma separated node aliases (empty means all nodes) [string] [string]
421421
```

src/commands/flags.ts

+60-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {IllegalArgumentError, SoloError} from '../core/errors.js';
2424
import {ListrEnquirerPromptAdapter} from '@listr2/prompt-adapter-enquirer';
2525
import * as helpers from '../core/helpers.js';
2626
import validator from 'validator';
27+
import type {AnyObject} from '../types/aliases.js';
2728

2829
export class Flags {
2930
private static async prompt(
@@ -475,7 +476,7 @@ export class Flags {
475476

476477
static readonly nodeAliasesUnparsed: CommandFlag = {
477478
constName: 'nodeAliasesUnparsed',
478-
name: 'node-aliases-unparsed',
479+
name: 'node-aliases',
479480
definition: {
480481
describe: 'Comma separated node aliases (empty means all nodes)',
481482
alias: 'i',
@@ -621,6 +622,7 @@ export class Flags {
621622
describe: 'Operator Key',
622623
defaultValue: undefined,
623624
type: 'string',
625+
dataMask: constants.STANDARD_DATAMASK,
624626
},
625627
prompt: async function promptOperatorKey(task: ListrTaskWrapper<any, any, any>, input: any) {
626628
return await Flags.promptText(
@@ -641,6 +643,7 @@ export class Flags {
641643
describe: 'Show private key information',
642644
defaultValue: false,
643645
type: 'boolean',
646+
dataMask: constants.STANDARD_DATAMASK,
644647
},
645648
prompt: async function promptPrivateKey(task: ListrTaskWrapper<any, any, any>, input: any) {
646649
return await Flags.promptText(
@@ -989,6 +992,7 @@ export class Flags {
989992
describe: 'path and file name of the private key for signing gossip in PEM key format to be used',
990993
defaultValue: '',
991994
type: 'string',
995+
dataMask: constants.STANDARD_DATAMASK,
992996
},
993997
prompt: undefined,
994998
};
@@ -1011,6 +1015,7 @@ export class Flags {
10111015
describe: 'path and file name of the private TLS key to be used',
10121016
defaultValue: '',
10131017
type: 'string',
1018+
dataMask: constants.STANDARD_DATAMASK,
10141019
},
10151020
prompt: undefined,
10161021
};
@@ -1054,6 +1059,7 @@ export class Flags {
10541059
describe: 'ED25519 private key for the Hedera account',
10551060
defaultValue: '',
10561061
type: 'string',
1062+
dataMask: constants.STANDARD_DATAMASK,
10571063
},
10581064
prompt: async function promptPrivateKey(task: ListrTaskWrapper<any, any, any>, input: any) {
10591065
return await Flags.promptText(
@@ -1085,6 +1091,7 @@ export class Flags {
10851091
describe: 'ECDSA private key for the Hedera account',
10861092
defaultValue: '',
10871093
type: 'string',
1094+
dataMask: constants.STANDARD_DATAMASK,
10881095
},
10891096
prompt: async function promptPrivateKey(task: ListrTaskWrapper<any, any, any>, input: any) {
10901097
return await Flags.promptText(
@@ -1326,6 +1333,7 @@ export class Flags {
13261333
describe: 'Admin key',
13271334
defaultValue: constants.GENESIS_KEY,
13281335
type: 'string',
1336+
dataMask: constants.STANDARD_DATAMASK,
13291337
},
13301338
prompt: undefined,
13311339
};
@@ -1528,6 +1536,7 @@ export class Flags {
15281536
'with multiple nodes comma seperated)',
15291537
defaultValue: '',
15301538
type: 'string',
1539+
dataMask: constants.STANDARD_DATAMASK,
15311540
},
15321541
prompt: async function promptGrpcTlsKeyPath(task: ListrTaskWrapper<any, any, any>, input: any) {
15331542
return await Flags.promptText(
@@ -1551,6 +1560,7 @@ export class Flags {
15511560
'with multiple nodes comma seperated)',
15521561
defaultValue: '',
15531562
type: 'string',
1563+
dataMask: constants.STANDARD_DATAMASK,
15541564
},
15551565
prompt: async function promptGrpcWebTlsKeyPath(task: ListrTaskWrapper<any, any, any>, input: any) {
15561566
return await Flags.promptText(
@@ -1619,6 +1629,7 @@ export class Flags {
16191629
defaultValue: '',
16201630
describe: 'storage access key',
16211631
type: 'string',
1632+
dataMask: constants.STANDARD_DATAMASK,
16221633
},
16231634
prompt: undefined,
16241635
};
@@ -1630,6 +1641,7 @@ export class Flags {
16301641
defaultValue: '',
16311642
describe: 'storage secret key',
16321643
type: 'string',
1644+
dataMask: constants.STANDARD_DATAMASK,
16331645
},
16341646
prompt: undefined,
16351647
};
@@ -1641,6 +1653,7 @@ export class Flags {
16411653
defaultValue: '',
16421654
describe: 'storage endpoint URL',
16431655
type: 'string',
1656+
dataMask: constants.STANDARD_DATAMASK,
16441657
},
16451658
prompt: undefined,
16461659
};
@@ -1652,6 +1665,7 @@ export class Flags {
16521665
defaultValue: '',
16531666
describe: 'name of storage bucket',
16541667
type: 'string',
1668+
dataMask: constants.STANDARD_DATAMASK,
16551669
},
16561670
prompt: undefined,
16571671
};
@@ -1663,6 +1677,7 @@ export class Flags {
16631677
defaultValue: '',
16641678
describe: 'name of bucket for backing up state files',
16651679
type: 'string',
1680+
dataMask: constants.STANDARD_DATAMASK,
16661681
},
16671682
prompt: undefined,
16681683
};
@@ -1674,6 +1689,7 @@ export class Flags {
16741689
defaultValue: '',
16751690
describe: 'path of google credential file in json format',
16761691
type: 'string',
1692+
dataMask: constants.STANDARD_DATAMASK,
16771693
},
16781694
prompt: undefined,
16791695
};
@@ -1811,4 +1827,47 @@ export class Flags {
18111827
requiredFlagsWithDisabledPrompt: [Flags.namespace, Flags.cacheDir, Flags.releaseTag],
18121828
optionalFlags: [Flags.devMode, Flags.quiet],
18131829
};
1830+
1831+
/**
1832+
* Processes the Argv arguments and returns them as string, all with full flag names.
1833+
* - removes flags that match the default value.
1834+
* - removes flags with undefined and null values.
1835+
* - removes boolean flags that are false.
1836+
* - masks all sensitive flags with their dataMask property.
1837+
*/
1838+
public static stringifyArgv(argv: AnyObject): string {
1839+
const processedFlags: string[] = [];
1840+
1841+
for (const [name, value] of Object.entries(argv)) {
1842+
// Remove non-flag data and boolean presence based flags that are false
1843+
if (name === '_' || name === '$0' || value === '' || value === false || value === undefined || value === null) {
1844+
continue;
1845+
}
1846+
1847+
// remove flags that use the default value
1848+
const flag = Flags.allFlags.find(flag => flag.name === name);
1849+
if (!flag || (flag.definition.defaultValue && flag.definition.defaultValue === value)) {
1850+
continue;
1851+
}
1852+
1853+
const flagName = flag.name;
1854+
1855+
// if the flag is boolean based, render it without value
1856+
if (value === true) {
1857+
processedFlags.push(`--${flagName}`);
1858+
}
1859+
1860+
// if the flag's data is masked, display it without the value
1861+
else if (flag.definition.dataMask) {
1862+
processedFlags.push(`--${flagName} ${flag.definition.dataMask}`);
1863+
}
1864+
1865+
// else display the full flag data
1866+
else {
1867+
processedFlags.push(`--${flagName} ${value}`);
1868+
}
1869+
}
1870+
1871+
return processedFlags.join(' ');
1872+
}
18141873
}

src/core/config/remote/remote_config_manager.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@ import {ErrorMessages} from '../../error_messages.js';
3838
import {CommonFlagsDataWrapper} from './common_flags_data_wrapper.js';
3939
import {type AnyObject} from '../../../types/aliases.js';
4040

41-
interface ListrContext {
42-
config: object;
43-
}
44-
4541
/**
4642
* Uses Kubernetes ConfigMaps to manage the remote configuration data by creating, loading, modifying,
4743
* and saving the configuration data to and from a Kubernetes cluster.
@@ -211,8 +207,12 @@ export class RemoteConfigManager {
211207

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

210+
const additionalCommandData = `Executed by ${self.localConfig.userEmailAddress}: `;
211+
214212
const currentCommand = argv._.join(' ');
215-
self.remoteConfig!.addCommandToHistory(currentCommand);
213+
const commandArguments = flags.stringifyArgv(argv);
214+
215+
self.remoteConfig!.addCommandToHistory(additionalCommandData + (currentCommand + ' ' + commandArguments).trim());
216216

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

src/core/config/remote/remote_config_validator.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {SoloError} from '../../errors.js';
1919

2020
import type {K8} from '../../k8.js';
2121
import type {ComponentsDataWrapper} from './components_data_wrapper.js';
22-
import {type BaseComponent} from './components/base_component.js';
22+
import type {BaseComponent} from './components/base_component.js';
2323

2424
/**
2525
* Static class is used to validate that components in the remote config

src/core/constants.ts

+2
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ export const PROFILE_LOCAL = 'local';
173173
export const ALL_PROFILES = [PROFILE_LOCAL, PROFILE_TINY, PROFILE_SMALL, PROFILE_MEDIUM, PROFILE_LARGE];
174174
export const DEFAULT_PROFILE_FILE = path.join(SOLO_CACHE_DIR, 'profiles', 'custom-spec.yaml');
175175

176+
export const STANDARD_DATAMASK = '***';
177+
176178
// ------ Hedera SDK Related ------
177179
export const NODE_CLIENT_MAX_ATTEMPTS = +process.env.NODE_CLIENT_MAX_ATTEMPTS || 600;
178180
export const NODE_CLIENT_MIN_BACKOFF = +process.env.NODE_CLIENT_MIN_BACKOFF || 1_000;

src/core/helpers.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ import {Templates} from './templates.js';
2323
import {ROOT_DIR} from './constants.js';
2424
import * as constants from './constants.js';
2525
import {PrivateKey, ServiceEndpoint} from '@hashgraph/sdk';
26-
import {type NodeAlias, type NodeAliases} from '../types/aliases.js';
27-
import {type CommandFlag} from '../types/flag_types.js';
28-
import {type SoloLogger} from './logging.js';
29-
import {type Duration} from './time/duration.js';
30-
import {type NodeAddConfigClass} from '../commands/node/node_add_config.js';
26+
import type {NodeAlias, NodeAliases} from '../types/aliases.js';
27+
import type {CommandFlag} from '../types/flag_types.js';
28+
import type {SoloLogger} from './logging.js';
29+
import type {Duration} from './time/duration.js';
30+
import type {NodeAddConfigClass} from '../commands/node/node_add_config.js';
3131

3232
export function sleep(duration: Duration) {
3333
return new Promise<void>(resolve => {

src/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,17 @@ export function main(argv: any) {
117117
// update
118118
configManager.update(argv);
119119

120+
const currentCommand = argv._.join(' ') as string;
121+
const commandArguments = flags.stringifyArgv(argv);
122+
const commandData = (currentCommand + ' ' + commandArguments).trim();
123+
120124
logger.showUser(
121125
chalk.cyan('\n******************************* Solo *********************************************'),
122126
);
123127
logger.showUser(chalk.cyan('Version\t\t\t:'), chalk.yellow(configManager.getVersion()));
124128
logger.showUser(chalk.cyan('Kubernetes Context\t:'), chalk.yellow(context.name));
125129
logger.showUser(chalk.cyan('Kubernetes Cluster\t:'), chalk.yellow(clusterName));
130+
logger.showUser(chalk.cyan('Current Command\t\t:'), chalk.yellow(commandData));
126131
if (configManager.getFlag(flags.namespace) !== undefined) {
127132
logger.showUser(chalk.cyan('Kubernetes Namespace\t:'), chalk.yellow(configManager.getFlag(flags.namespace)));
128133
}

src/types/flag_types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,5 @@ export interface Definition {
3131
alias?: string;
3232
type?: string;
3333
disablePrompt?: boolean;
34+
dataMask?: string;
3435
}

0 commit comments

Comments
 (0)