Skip to content

Commit 0c7888b

Browse files
Saas 7228 - improved runner delete command (#471)
1 parent dd7d808 commit 0c7888b

File tree

4 files changed

+82
-26
lines changed

4 files changed

+82
-26
lines changed

lib/interface/cli/commands/hybrid/delete.cmd.js

Lines changed: 77 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
const Command = require('../../Command');
33
const runnerRoot = require('../root/runner.cmd');
44
const inquirer = require('inquirer');
5-
const { getAllKubeContexts, getKubeContext } = require('../../helpers/kubernetes');
5+
const { getAllKubeContexts, getKubeContext, getAllNamespaces } = require('../../helpers/kubernetes');
66
const unInstallRuntime = require('../runtimeEnvironments/uninstall.cmd');
77
const unInstallAgent = require('../agent/uninstall.cmd');
88
const unInstallMonitor = require('../monitor/uninstall.cmd');
@@ -25,6 +25,41 @@ async function handleError(error, message) {
2525
process.exit(1);
2626
}
2727

28+
// Try to get the most relevant namespaces
29+
async function getRelatedNamespaces(kubeConfigPath, kubeContextName, runtimes) {
30+
const [, namespacesOnCluster] = await to(getAllNamespaces(kubeConfigPath, kubeContextName));
31+
const nsOnCluster = new Set(namespacesOnCluster || []);
32+
33+
return _(runtimes)
34+
.filter(re => nsOnCluster.has(_.get(re, 'runtimeScheduler.cluster.namespace')))
35+
.map(re => _.get(re, 'runtimeScheduler.cluster.namespace'))
36+
.uniq()
37+
.value();
38+
}
39+
40+
async function getRelatedAgents(kubeNamespace, runtimes) {
41+
const [listAgentsErr, agents] = await to(sdk.agents.list({}));
42+
await handleError(listAgentsErr, 'Failed to get agents');
43+
44+
const relatedREs = new Set();
45+
_.forEach(runtimes, (r) => {
46+
if (_.get(r, 'runtimeScheduler.cluster.namespace') === kubeNamespace) {
47+
relatedREs.add(r.metadata.name);
48+
}
49+
});
50+
51+
const relatedAgents = [];
52+
_.forEach(agents, (a) => {
53+
_.forEach(_.get(a, 'runtimes', []), (r) => {
54+
if (relatedREs.has(r)) {
55+
relatedAgents.push(a);
56+
}
57+
});
58+
});
59+
60+
return relatedAgents;
61+
}
62+
2863
const deleteCmd = new Command({
2964
root: false,
3065
parent: runnerRoot,
@@ -68,50 +103,73 @@ const deleteCmd = new Command({
68103
name: agentName,
69104
} = argv;
70105

71-
const questions = [];
106+
const [listReErr, runtimes] = await to(sdk.runtimeEnvs.list({ }));
107+
await handleError(listReErr, 'Failed to get runtime environments');
108+
109+
console.log(colors.green('This uninstaller will guide you through the runner uninstallation process'));
110+
72111
if (!kubeContextName) {
73112
const contexts = getAllKubeContexts(kubeConfigPath);
74113
const currentKubeContext = getKubeContext(kubeConfigPath);
75114

76-
questions.push({
115+
const answer = await inquirer.prompt({
77116
type: 'list',
78117
name: 'context',
79118
message: 'Name of Kubernetes context to use',
80119
default: currentKubeContext,
81120
choices: contexts,
82121
});
122+
123+
kubeContextName = answer.context;
83124
}
125+
84126
if (!kubeNamespace) {
85-
questions.push({
86-
type: 'input',
87-
name: 'namespace',
88-
default: defaultNamespace,
89-
message: 'Kubernetes namespace to remove Codefresh Runner components from ',
90-
validate: value => (value !== undefined && value !== '') || 'Please enter namespace\'s name',
91-
});
127+
const relatedNamespaces = await getRelatedNamespaces(kubeConfigPath, kubeContextName, runtimes);
128+
let answer;
129+
if (!relatedNamespaces.length) {
130+
answer = await inquirer.prompt({
131+
type: 'input',
132+
name: 'namespace',
133+
default: defaultNamespace,
134+
message: 'Kubernetes namespace to remove Codefresh Runner components from',
135+
validate: value => (value !== undefined && value !== '') || 'Please enter namespace\'s name',
136+
});
137+
} else {
138+
answer = await inquirer.prompt({
139+
type: 'list',
140+
name: 'namespace',
141+
default: defaultNamespace,
142+
message: 'Kubernetes namespace to remove Codefresh Runner components from ',
143+
choices: relatedNamespaces,
144+
});
145+
}
146+
147+
kubeNamespace = answer.namespace;
92148
}
93-
const [listAgentsErr, agents] = await to(sdk.agents.list({}));
94-
await handleError(listAgentsErr, 'Failed to get agents');
149+
150+
const agents = await getRelatedAgents(kubeNamespace, runtimes);
151+
if (!agents.length) {
152+
console.log('No agents related to the specified kubernetes cluster and namespace were found');
153+
process.exit(1);
154+
}
155+
95156
if (!agentName) {
96-
questions.push({
157+
const answer = await inquirer.prompt({
97158
type: 'list',
98159
name: 'name',
99160
message: 'Agent name to uninstall',
100161
choices: agents,
101162
});
163+
agentName = answer.name;
102164
}
103-
console.log(colors.green('This uninstaller will guide you through the runner uninstallation process'));
104-
const answers = await inquirer.prompt(questions);
105-
kubeContextName = kubeContextName || answers.context;
106-
kubeNamespace = kubeNamespace || answers.namespace;
107-
agentName = agentName || answers.name;
165+
108166
// check that agent exists
109167
const agent = _.find(agents, curr => curr.name === agentName);
110168
if (!agent) {
111169
console.log(colors.red(`Agent with name ${agentName} doesn't exists`));
112170
return;
113171
}
114-
if (agent.runtimes && agent.runtimes > 1) {
172+
if (agent.runtimes && agent.runtimes.length > 1) {
115173
console.log('Can\'t delete runner with more than one runtime, use runtime delete command');
116174
return;
117175
}

lib/interface/cli/commands/hybrid/init.cmd.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,6 @@ const initCmd = new Command({
328328
};
329329
const [runnerErr, runtimeName] = await to(installAgent.handler(agentInstallOptions));
330330
await handleError(runnerErr, 'Runner installation failed', progressReporter, installationProgress.events.RUNNER_INSTALLED);
331-
332331
await to(progressReporter.report(installationProgress.events.RUNNER_INSTALLED, installationProgress.status.SUCCESS));
333332

334333
// Install monitoring
@@ -343,7 +342,6 @@ const initCmd = new Command({
343342
};
344343
const [monitorErr] = await to(installMonitoring.handler(monitorInstallOptions));
345344
await handleError(monitorErr, 'Monitor installation failed', progressReporter, installationProgress.events.MONITOR_INSTALLED);
346-
347345
await to(progressReporter.report(installationProgress.events.MONITOR_INSTALLED, installationProgress.status.SUCCESS));
348346

349347
// Post Installation

lib/interface/cli/helpers/kubernetes.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ const getAllNamespaces = async (kubeconfigPath, kubeContextName) => {
3535
const backend = new Request({ kubeconfig });
3636
const client = new Client({ backend, version: 1.13 });
3737
const resp = await client.api.v1.namespaces.get();
38-
if (resp.statusCode === 200) {
39-
const nsObjs = _.get(resp, 'body.items');
40-
return _.map(nsObjs, ns => _.get(ns, 'metadata.name'));
38+
if (resp.statusCode !== 200) {
39+
throw new Error(`could not get namespaces from cluster ${kubeContextName}, failed with status: ${resp.statusCode}`);
4140
}
42-
return [];
41+
const nsObjs = _.get(resp, 'body.items');
42+
return _.map(nsObjs, ns => _.get(ns, 'metadata.name'));
4343
};
4444

4545
module.exports = {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codefresh",
3-
"version": "0.63.11",
3+
"version": "0.63.13",
44
"description": "Codefresh command line utility",
55
"main": "index.js",
66
"preferGlobal": true,

0 commit comments

Comments
 (0)