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(cli): reduce redundancy on context to cluster flags in command deployment create #1156

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
2 changes: 1 addition & 1 deletion src/commands/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export abstract class BaseCommand extends ShellRunner {
protected readonly depManager: DependencyManager;
protected readonly leaseManager: LeaseManager;
protected readonly _configMaps = new Map<string, any>();
protected readonly localConfig: LocalConfig;
public readonly localConfig: LocalConfig;
protected readonly remoteConfigManager: RemoteConfigManager;

constructor(opts: Opts) {
Expand Down
8 changes: 7 additions & 1 deletion src/commands/cluster/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,12 @@
// If one or more contexts are provided, use the first one
if (contexts.length) {
selectedContext = contexts[0];

if (clusters.length) {
selectedCluster = clusters[0];

Check warning on line 287 in src/commands/cluster/tasks.ts

View check run for this annotation

Codecov / codecov/patch

src/commands/cluster/tasks.ts#L287

Added line #L287 was not covered by tests
} else if (localConfig.deployments[deploymentName]) {
selectedCluster = localConfig.deployments[deploymentName].clusters[0];
}

Check warning on line 290 in src/commands/cluster/tasks.ts

View check run for this annotation

Codecov / codecov/patch

src/commands/cluster/tasks.ts#L289-L290

Added lines #L289 - L290 were not covered by tests
}

// If one or more clusters are provided, use the first one to determine the context
Expand Down Expand Up @@ -335,7 +341,7 @@

const connectionValid = await this.parent.getK8().testClusterConnection(selectedContext, selectedCluster);
if (!connectionValid) {
throw new SoloError(ErrorMessages.INVALID_CONTEXT_FOR_CLUSTER(selectedContext));
throw new SoloError(ErrorMessages.INVALID_CONTEXT_FOR_CLUSTER(selectedContext, selectedCluster));
}
this.parent.getK8().setCurrentContext(selectedContext);
this.parent.getConfigManager().setFlag(flags.context, selectedContext);
Expand Down
25 changes: 9 additions & 16 deletions src/commands/deployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,14 @@ import {SoloError} from '../core/errors.js';
import {BaseCommand} from './base.js';
import {Flags as flags} from './flags.js';
import * as constants from '../core/constants.js';
import {Templates} from '../core/templates.js';
import chalk from 'chalk';
import {ListrRemoteConfig} from '../core/config/remote/listr_config_tasks.js';
import {ClusterCommandTasks} from './cluster/tasks.js';
import type {Namespace} from '../core/config/remote/types.js';
import type {ContextClusterStructure} from '../types/config_types.js';
import type {CommandFlag} from '../types/flag_types.js';
import type {CommandBuilder} from '../types/aliases.js';
import type {Opts} from '../types/command_types.js';
import type {SoloListrTask} from '../types/index.js';
import type {Opts} from '../types/command_types.js';

export class DeploymentCommand extends BaseCommand {
readonly tasks: ClusterCommandTasks;
Expand All @@ -44,9 +42,9 @@ export class DeploymentCommand extends BaseCommand {
flags.quiet,
flags.context,
flags.namespace,
flags.clusterName,
flags.userEmailAddress,
flags.deploymentClusters,
flags.contextClusterUnparsed,
];
}

Expand All @@ -56,9 +54,8 @@ export class DeploymentCommand extends BaseCommand {
interface Config {
context: string;
namespace: Namespace;
contextClusterUnparsed: string;
contextCluster: ContextClusterStructure;
}

interface Context {
config: Config;
}
Expand All @@ -71,19 +68,12 @@ export class DeploymentCommand extends BaseCommand {
self.configManager.update(argv);
self.logger.debug('Updated config with argv', {config: self.configManager.config});

await self.configManager.executePrompt(task, [
flags.contextClusterUnparsed,
flags.namespace,
flags.deploymentClusters,
]);
await self.configManager.executePrompt(task, [flags.namespace]);

ctx.config = {
contextClusterUnparsed: self.configManager.getFlag<string>(flags.contextClusterUnparsed),
namespace: self.configManager.getFlag<Namespace>(flags.namespace),
} as Config;

ctx.config.contextCluster = Templates.parseContextCluster(ctx.config.contextClusterUnparsed);

self.logger.debug('Prepared config', {config: ctx.config, cachedConfig: self.configManager.config});
},
},
Expand Down Expand Up @@ -112,13 +102,16 @@ export class DeploymentCommand extends BaseCommand {
task: async (ctx, task) => {
const subTasks: SoloListrTask<Context>[] = [];

for (const context of Object.keys(ctx.config.contextCluster)) {
const cluster = ctx.config.contextCluster[context];
for (const cluster of self.localConfig.deployments[ctx.config.namespace].clusters) {
const context = self.localConfig.clusterContextMapping?.[cluster];
if (!context) continue;

subTasks.push({
title: `Testing connection to cluster: ${chalk.cyan(cluster)}`,
task: async (_, task) => {
if (!(await self.k8.testClusterConnection(context, cluster))) {
task.title = `${task.title} - ${chalk.red('Cluster connection failed')}`;

throw new SoloError(`Cluster connection failed for: ${cluster}`);
}
},
Expand Down
22 changes: 0 additions & 22 deletions src/commands/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1576,27 +1576,6 @@ export class Flags {
prompt: undefined,
};

static readonly contextClusterUnparsed: CommandFlag = {
constName: 'contextClusterUnparsed',
name: 'context-cluster',
definition: {
describe:
'Context cluster mapping where context is key = value is cluster and comma delimited if more than one, ' +
'(e.g.: --context-cluster kind-solo=kind-solo,kind-solo-2=kind-solo-2)',
type: 'string',
},
prompt: async function promptContextCluster(task: ListrTaskWrapper<any, any, any>, input: any) {
return await Flags.promptText(
task,
input,
null,
'Enter context cluster mapping: ',
'context-cluster cannot be empty',
Flags.contextClusterUnparsed.name,
);
},
};

static readonly haproxyIps: CommandFlag = {
constName: 'haproxyIps',
name: 'haproxy-ips',
Expand Down Expand Up @@ -1725,7 +1704,6 @@ export class Flags {
Flags.clusterName,
Flags.clusterSetupNamespace,
Flags.context,
Flags.contextClusterUnparsed,
Flags.createAmount,
Flags.debugNodeAlias,
Flags.deletePvcs,
Expand Down
4 changes: 2 additions & 2 deletions src/commands/mirror_node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ export class MirrorNodeCommand extends BaseCommand {
}

/** Removes the mirror node components from remote config. */
public removeMirrorNodeComponents(): SoloListrTask<object> {
public removeMirrorNodeComponents(): SoloListrTask<any> {
return {
title: 'Remove mirror node from remote config',
skip: (): boolean => !this.remoteConfigManager.isLoaded(),
Expand All @@ -583,7 +583,7 @@ export class MirrorNodeCommand extends BaseCommand {
}

/** Adds the mirror node components to remote config. */
public addMirrorNodeComponents(): SoloListrTask<{config: {namespace: Namespace}}> {
public addMirrorNodeComponents(): SoloListrTask<any> {
return {
title: 'Add mirror node to remote config',
skip: (): boolean => !this.remoteConfigManager.isLoaded(),
Expand Down
2 changes: 1 addition & 1 deletion src/commands/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,7 @@ export class NetworkCommand extends BaseCommand {
}

/** Adds the consensus node, envoy and haproxy components to remote config. */
public addNodesAndProxies(): SoloListrTask<{config: {namespace: Namespace; nodeAliases: NodeAliases}}> {
public addNodesAndProxies(): SoloListrTask<any> {
return {
title: 'Add node and proxies to remote config',
skip: (): boolean => !this.remoteConfigManager.isLoaded(),
Expand Down
5 changes: 3 additions & 2 deletions src/core/config/local_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
import {splitFlagInput} from '../helpers.js';
import {inject, injectable} from 'tsyringe-neo';
import {patchInject} from '../container_helper.js';
import type {SoloListrTask, SoloListrTaskWrapper} from '../../types/index.js';
import type {SoloListrTask} from '../../types/index.js';
import type {AnyObject} from '../../types/aliases.js';

@injectable()
export class LocalConfig implements LocalConfigData {
Expand Down Expand Up @@ -168,7 +169,7 @@
return {
title: 'Prompt local configuration',
skip: this.skipPromptTask,
task: async (_: any, task: SoloListrTaskWrapper<any>): Promise<void> => {
task: async (_, task): Promise<void> => {

Check warning on line 172 in src/core/config/local_config.ts

View check run for this annotation

Codecov / codecov/patch

src/core/config/local_config.ts#L172

Added line #L172 was not covered by tests
if (self.configFileExists()) {
self.configManager.setFlag(flags.userEmailAddress, self.userEmailAddress);
}
Expand Down
23 changes: 13 additions & 10 deletions src/core/config/remote/listr_config_tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@
* limitations under the License.
*
*/
import type {ListrTask} from 'listr2';
import chalk from 'chalk';
import type {BaseCommand} from '../../../commands/base.js';
import {type Cluster, type Context, type Namespace} from './types.js';
import type {Cluster, Context, Namespace} from './types.js';
import type {SoloListrTask} from '../../../types/index.js';
import type {AnyObject} from '../../../types/aliases.js';

/**
* Static class that handles all tasks related to remote config used by other commands.
Expand All @@ -38,10 +39,10 @@
* @param command - the BaseCommand object on which an action will be performed
* @param argv - used to update the last executed command and command history
*/
public static loadRemoteConfig(command: BaseCommand, argv: any): ListrTask<any, any, any> {
public static loadRemoteConfig(command: BaseCommand, argv: {_: string[]} & AnyObject): SoloListrTask<any> {
return {
title: 'Load remote config',
task: async (_, task): Promise<void> => {
task: async (): Promise<void> => {
await command.getRemoteConfigManager().loadAndValidate(argv);
},
};
Expand All @@ -59,10 +60,10 @@
cluster: Cluster,
context: Context,
namespace: Namespace,
): ListrTask<any, any, any> {
): SoloListrTask<any> {

Check warning on line 63 in src/core/config/remote/listr_config_tasks.ts

View check run for this annotation

Codecov / codecov/patch

src/core/config/remote/listr_config_tasks.ts#L63

Added line #L63 was not covered by tests
return {
title: `Create remote config in cluster: ${cluster}`,
task: async (_, task): Promise<void> => {
title: `Create remote config in cluster: ${chalk.cyan(cluster)}`,
task: async (): Promise<void> => {

Check warning on line 66 in src/core/config/remote/listr_config_tasks.ts

View check run for this annotation

Codecov / codecov/patch

src/core/config/remote/listr_config_tasks.ts#L65-L66

Added lines #L65 - L66 were not covered by tests
await command.getRemoteConfigManager().createAndValidate(cluster, context, namespace);
},
};
Expand All @@ -73,14 +74,16 @@
*
* @param command - the BaseCommand object on which an action will be performed
*/
public static createRemoteConfigInMultipleClusters(command: BaseCommand): ListrTask<any, any, any> {
public static createRemoteConfigInMultipleClusters(command: BaseCommand): SoloListrTask<any> {
return {
title: 'Create remoteConfig in clusters',
task: async (ctx, task) => {
const subTasks: SoloListrTask<Context>[] = [];

for (const context of Object.keys(ctx.config.contextCluster)) {
const cluster = ctx.config.contextCluster[context];
for (const cluster of command.localConfig.deployments[ctx.config.namespace].clusters) {
const context = command.localConfig.clusterContextMapping?.[cluster];
if (!context) continue;

Check warning on line 86 in src/core/config/remote/listr_config_tasks.ts

View check run for this annotation

Codecov / codecov/patch

src/core/config/remote/listr_config_tasks.ts#L83-L86

Added lines #L83 - L86 were not covered by tests
subTasks.push(ListrRemoteConfig.createRemoteConfig(command, cluster, context, ctx.config.namespace));
}

Expand Down
8 changes: 4 additions & 4 deletions src/core/config/remote/remote_config_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@ import {SoloLogger} from '../../logging.js';
import {ConfigManager} from '../../config_manager.js';
import {LocalConfig} from '../local_config.js';
import type {DeploymentStructure} from '../local_config_data.js';
import {type ContextClusterStructure} from '../../../types/config_types.js';
import {type EmptyContextConfig, type Optional, type SoloListrTask} from '../../../types/index.js';
import type {Optional} from '../../../types/index.js';
import type * as k8s from '@kubernetes/client-node';
import {StatusCodes} from 'http-status-codes';
import {inject, injectable} from 'tsyringe-neo';
import {patchInject} from '../../container_helper.js';
import {ErrorMessages} from '../../error_messages.js';
import {type AnyObject} from '../../../types/aliases.js';

interface ListrContext {
config: {contextCluster: ContextClusterStructure};
config: object;
}

/**
Expand Down Expand Up @@ -189,7 +189,7 @@ export class RemoteConfigManager {
*
* @param argv - arguments containing command input for historical reference.
*/
public async loadAndValidate(argv: {_: string[]}) {
public async loadAndValidate(argv: {_: string[]} & AnyObject) {
const self = this;
try {
self.setDefaultNamespaceIfNotSet();
Expand Down
32 changes: 1 addition & 31 deletions src/core/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ import * as constants from './constants.js';
import {type AccountId} from '@hashgraph/sdk';
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, Namespace} from './config/remote/types.js';
import type {Namespace} from './config/remote/types.js';
import {HEDERA_PLATFORM_VERSION} from '../../version.js';

export class Templates {
Expand Down Expand Up @@ -228,35 +227,6 @@ export class Templates {
}
}

/**
* Parsed and validates the unparsed value of flag clusterMappings
*
* @param unparsed - value of flag clusterMappings
*/
public static parseContextCluster(unparsed: string): ContextClusterStructure {
const mapping = {};
const errorMessage =
'Invalid context in context-cluster, expected structure where context' +
' is key = value is cluster and comma delimited if more than one, ' +
'(e.g.: --context-cluster kind-solo=kind-solo,kind-solo-2=kind-solo-2)';

unparsed.split(',').forEach(data => {
const [context, cluster] = data.split('=') as [Context, Cluster];

if (!context || typeof context !== 'string') {
throw new SoloError(errorMessage, null, {data});
}

if (!cluster || typeof cluster !== 'string') {
throw new SoloError(errorMessage, null, {data});
}

mapping[context] = cluster;
});

return mapping;
}

public static renderEnvoyProxyName(nodeAlias: NodeAlias): string {
return `envoy-proxy-${nodeAlias}`;
}
Expand Down
19 changes: 0 additions & 19 deletions src/types/config_types.ts

This file was deleted.

Loading