Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(remote-config): instead of keeping just the command and the subcommand inside the remote config keep the flags as passed #1208

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {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 @@

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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
describe: 'Admin key',
defaultValue: constants.GENESIS_KEY,
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: undefined,
};
Expand Down Expand Up @@ -1528,6 +1536,7 @@
'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 @@
'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 @@
defaultValue: '',
describe: 'storage access key',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: undefined,
};
Expand All @@ -1630,6 +1641,7 @@
defaultValue: '',
describe: 'storage secret key',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: undefined,
};
Expand All @@ -1641,6 +1653,7 @@
defaultValue: '',
describe: 'storage endpoint URL',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: undefined,
};
Expand All @@ -1652,6 +1665,7 @@
defaultValue: '',
describe: 'name of storage bucket',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: undefined,
};
Expand All @@ -1663,6 +1677,7 @@
defaultValue: '',
describe: 'name of bucket for backing up state files',
type: 'string',
dataMask: constants.STANDARD_DATAMASK,
},
prompt: undefined,
};
Expand All @@ -1674,6 +1689,7 @@
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 @@
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;
}

Check warning on line 1845 in src/commands/flags.ts

View check run for this annotation

Codecov / codecov/patch

src/commands/flags.ts#L1844-L1845

Added lines #L1844 - L1845 were not covered by tests

// 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;
}

Check warning on line 1851 in src/commands/flags.ts

View check run for this annotation

Codecov / codecov/patch

src/commands/flags.ts#L1850-L1851

Added lines #L1850 - L1851 were not covered by tests

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 {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 @@

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

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

Check warning on line 211 in src/core/config/remote/remote_config_manager.ts

View check run for this annotation

Codecov / codecov/patch

src/core/config/remote/remote_config_manager.ts#L210-L211

Added lines #L210 - L211 were not covered by tests
const currentCommand = argv._.join(' ');
self.remoteConfig!.addCommandToHistory(currentCommand);
const commandArguments = flags.stringifyArgv(argv);

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

Check warning on line 215 in src/core/config/remote/remote_config_manager.ts

View check run for this annotation

Codecov / codecov/patch

src/core/config/remote/remote_config_manager.ts#L213-L215

Added lines #L213 - L215 were not covered by tests

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
Loading