From 36c999d9fa16ff9ce8c9aee642c7f8c880d50fb7 Mon Sep 17 00:00:00 2001 From: andrii-codefresh <41997149+andrii-codefresh@users.noreply.github.com> Date: Tue, 16 Oct 2018 21:46:49 +0300 Subject: [PATCH] Saas 489 cli helm promotion (#221) --- README.md | 1 + .../pipeline/dynamic/promote-chart.cmd.js | 120 ++++++++++++++++++ lib/logic/api/helm.js | 49 +++++++ package.json | 2 +- 4 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 lib/interface/cli/commands/pipeline/dynamic/promote-chart.cmd.js diff --git a/README.md b/README.md index 50030a1b9..13d5d7dcd 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ Commands: codefresh run Run a pipeline by id or name and attach the created workflow logs. codefresh delete-release [name] Delete a helm release from a kubernetes cluster. codefresh install-chart Install or upgrade a Helm chart Repository flag can be either absolute url or saved repository in Codefresh. + codefresh helm-promotion Promote a Helm release in another environment. codefresh test-release [name] Test a helm release. Options: diff --git a/lib/interface/cli/commands/pipeline/dynamic/promote-chart.cmd.js b/lib/interface/cli/commands/pipeline/dynamic/promote-chart.cmd.js new file mode 100644 index 000000000..c9775450c --- /dev/null +++ b/lib/interface/cli/commands/pipeline/dynamic/promote-chart.cmd.js @@ -0,0 +1,120 @@ +const Command = require('../../../Command'); +const { + promoteChart, +} = require('./../../../../../logic/api/helm'); +const { printError } = require('./../../../helpers/general'); +const { log, workflow } = require('../../../../../logic').api; + +const promote = new Command({ + root: true, + command: 'helm-promotion', + description: 'Promote a Helm release in another environment', + webDocs: { + category: 'Predefined Pipelines', + title: 'Promote Helm Release', + weight: 20, + }, + builder: (yargs) => { + return yargs + .option('board', { + description: 'Board for promotion', + type: 'string', + required: false, + }) + .option('source', { + description: 'Source column', + type: 'string', + required: false, + }) + .option('target', { + description: 'Target column', + type: 'string', + required: false, + }) + .option('namespace', { + description: 'Promote to namespace', + default: 'default', + type: 'string', + }) + .option('source-tiller-namespace', { + description: 'Where tiller has been installed in source cluster', + default: 'kube-system', + type: 'string', + }) + .option('target-tiller-namespace', { + description: 'Where tiller has been installed in target cluster', + default: 'kube-system', + type: 'string', + }) + .option('source-release', { + description: 'The name of source release', + }) + .option('revision', { + description: 'Revision of source release', + type: 'string', + required: false, + }) + .option('target-release', { + description: 'The name to set to the release', + }) + .option('context', { + description: 'Contexts (yaml || secret-yaml) to be passed to the install', + array: true, + }) + .option('set', { + description: 'set of KEY=VALUE to be passed to the install', + array: true, + }) + .option('detach', { + alias: 'd', + describe: 'Run pipeline and print build ID', + }) + .example( + 'codefresh helm-promotion --board app --source dev --target test --source-release application', + `Promote 'application' release on board 'app' from 'dev' to 'test' environment`); + }, + handler: async (argv) => { + try { + const workflowId = await promoteChart({ + board: argv.board, + sourceSection: argv.source, + targetSection: argv.target, + sourceCluster: argv.sourceCluster, + tillerNamespace: argv.sourceTillerNamespace, + releaseName: argv.sourceRelease, + revision: argv.revision, + targetCluster: argv.targetCluster, + targetTillerNamespace: argv.targetTillerNamespace, + targetNamespace: argv.namespace, + targetReleaseName: argv.targetRelease, + values: argv.context, + setValues: argv.set, + }); + if (argv.detach) { + console.log(workflowId); + } else { + await log.showWorkflowLogs(workflowId, true); + const workflowInstance = await workflow.getWorkflowById(workflowId); + switch (workflowInstance.getStatus()) { + case 'success': + process.exit(0); + break; + case 'error': + process.exit(1); + break; + case 'terminated': + process.exit(2); + break; + default: + process.exit(100); + break; + } + } + } catch (err) { + printError(err); + process.exit(1); + } + }, +}); + +module.exports = promote; diff --git a/lib/logic/api/helm.js b/lib/logic/api/helm.js index a84408625..8f20a4698 100644 --- a/lib/logic/api/helm.js +++ b/lib/logic/api/helm.js @@ -89,6 +89,54 @@ const installChart = async ({ return res.id; }; +const promoteChart = async ({ + board, + sourceSection, + targetSection, + sourceCluster, + tillerNamespace, + releaseName, + revision, + targetCluster, + targetTillerNamespace, + targetNamespace, + targetReleaseName, + values, + setValues, +}) => { + let normalizedValues = []; + if (values && _.isArray(values) && values.length > 0) { + normalizedValues = await _normalizeValues(values); + } + + const normalizedSetValues = await _normalizeSetValues(setValues); + const options = { + url: '/api/kubernetes/chart/promote', + method: 'POST', + qs: { + selector: sourceCluster, + tillerNamespace, + }, + body: { + board, + sourceSection, + targetSection, + sourceCluster, + releaseName, + revision, + targetSelector: targetCluster, + targetTillerNamespace, + targetNamespace, + targetReleaseName, + values: normalizedValues, + set: normalizedSetValues, + }, + }; + + const res = await sendHttpRequest(options); + return res.id; +}; + const testRelease = async ({ releaseName, cluster, @@ -198,6 +246,7 @@ const deleteRepo = async (name) => { module.exports = { installChart, + promoteChart, testRelease, deleteRelease, getAllRepos, diff --git a/package.json b/package.json index b9a2a3fde..9202816e2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codefresh", - "version": "0.8.77", + "version": "0.8.78", "description": "Codefresh command line utility", "main": "index.js", "preferGlobal": true,