Skip to content

Commit

Permalink
Chart version in helm install and upgrade (microsoft#13126)
Browse files Browse the repository at this point in the history
* Adding chart version input to install and upgrade commands

* Updating tests

* Adding validation for version

* Resolving PR comments

* Adding invalid version to logs
  • Loading branch information
shigupt202 committed Jun 29, 2020
1 parent a87b202 commit a503a57
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 19 deletions.
53 changes: 38 additions & 15 deletions Tasks/HelmDeployV0/Tests/L0.ts
Expand Up @@ -27,19 +27,21 @@ describe("HelmDeployV0 Suite", function () {
delete process.env[shared.TestEnvVars.connectionType];
delete process.env[shared.TestEnvVars.command];
delete process.env[shared.TestEnvVars.chartType];
delete process.env[shared.TestEnvVars.version];
});

after((done) => {
done();
});

it("Run successfully with Helm install (version 3) with chart name", function(done: MochaDone) {
it("Run successfully with Helm install (version 3) with chart name", function (done: MochaDone) {
const tp = path.join(__dirname, "TestSetup.js");
const tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.connectionType] = shared.ConnectionTypes.KubernetesServiceConnection;
process.env[shared.TestEnvVars.command] = shared.Commands.install;
process.env[shared.TestEnvVars.chartType] = shared.ChartTypes.Name;
process.env[shared.TestEnvVars.chartName] = shared.testChartName;
process.env[shared.TestEnvVars.version] = shared.testChartVersion;
process.env[shared.TestEnvVars.releaseName] = shared.testReleaseName;
process.env[shared.TestEnvVars.failOnStderr] = "true";
process.env[shared.isHelmV3] = "true";
Expand All @@ -53,7 +55,7 @@ describe("HelmDeployV0 Suite", function () {
done();
});

it("Run successfully with Helm install (version 2) with chart name", function(done: MochaDone) {
it("Run successfully with Helm install (version 2) with chart name", function (done: MochaDone) {
const tp = path.join(__dirname, "TestSetup.js");
const tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.connectionType] = shared.ConnectionTypes.KubernetesServiceConnection;
Expand All @@ -73,7 +75,7 @@ describe("HelmDeployV0 Suite", function () {
done();
});

it("Run successfully with Helm install (version 3) with chart path", function(done: MochaDone) {
it("Run successfully with Helm install (version 3) with chart path", function (done: MochaDone) {
const tp = path.join(__dirname, "TestSetup.js");
const tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.connectionType] = shared.ConnectionTypes.KubernetesServiceConnection;
Expand All @@ -93,7 +95,7 @@ describe("HelmDeployV0 Suite", function () {
done();
});

it("Run successfully with Helm install (version 3) when release name is not given", function(done: MochaDone) {
it("Run successfully with Helm install (version 3) when release name is not given", function (done: MochaDone) {
const tp = path.join(__dirname, "TestSetup.js");
const tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.connectionType] = shared.ConnectionTypes.KubernetesServiceConnection;
Expand All @@ -112,7 +114,7 @@ describe("HelmDeployV0 Suite", function () {
done();
});

it("Run successfully with Helm install (version 3) when mulitple value files are given", function(done: MochaDone) {
it("Run successfully with Helm install (version 3) when mulitple value files are given", function (done: MochaDone) {
const tp = path.join(__dirname, "TestSetup.js");
const tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.connectionType] = shared.ConnectionTypes.KubernetesServiceConnection;
Expand All @@ -133,7 +135,7 @@ describe("HelmDeployV0 Suite", function () {
done();
});

it("Run successfully with Helm install (version 3) when single value file is given", function(done: MochaDone) {
it("Run successfully with Helm install (version 3) when single value file is given", function (done: MochaDone) {
const tp = path.join(__dirname, "TestSetup.js");
const tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.connectionType] = shared.ConnectionTypes.KubernetesServiceConnection;
Expand All @@ -154,7 +156,28 @@ describe("HelmDeployV0 Suite", function () {
done();
});

it("Run successfully with Helm upgrade (version 3) when chart name is given and release name is not", function(done: MochaDone) {
it("Run successfully with Helm install (version 3) when invalid chart version is given", function (done: MochaDone) {
const tp = path.join(__dirname, "TestSetup.js");
const tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.connectionType] = shared.ConnectionTypes.KubernetesServiceConnection;
process.env[shared.TestEnvVars.command] = shared.Commands.install;
process.env[shared.TestEnvVars.chartType] = shared.ChartTypes.Name;
process.env[shared.TestEnvVars.chartName] = shared.testChartName;
process.env[shared.TestEnvVars.version] = "abcd";
process.env[shared.TestEnvVars.failOnStderr] = "false";
process.env[shared.isHelmV3] = "true";

tr.run();
assert(tr.stdout.indexOf("v3") != -1, "Helm version 3 should have been installed");
assert(tr.stdout.indexOf("STATUS: deployed") != -1, "Release should have been created");
assert(tr.stdout.indexOf("The given version " + process.env[shared.TestEnvVars.version] + " is not valid. Running the helm install command with latest version") != -1, "Version should not have been accepted");
assert(tr.stdout.indexOf("# Source: testChartName/templates/serviceaccount.yaml") != -1, `Manifests should have been extracted from release ${shared.testReleaseName}`);
assert(tr.stdout.indexOf(`DeploymentDetailsApiResponse: {"mockKey":"mockValue"}`) != -1, "Web response should have been received for pushing metadata to evidence store");
assert(tr.succeeded, "task should have succeeded");
done();
});

it("Run successfully with Helm upgrade (version 3) when chart name is given and release name is not", function (done: MochaDone) {
const tp = path.join(__dirname, "TestSetup.js");
const tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.connectionType] = shared.ConnectionTypes.KubernetesServiceConnection;
Expand All @@ -172,7 +195,7 @@ describe("HelmDeployV0 Suite", function () {
done();
});

it("Run successfully with Helm upgrade (version 3) when chart name and release name are given", function(done: MochaDone) {
it("Run successfully with Helm upgrade (version 3) when chart name and release name are given", function (done: MochaDone) {
const tp = path.join(__dirname, "TestSetup.js");
const tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.connectionType] = shared.ConnectionTypes.KubernetesServiceConnection;
Expand All @@ -182,7 +205,7 @@ describe("HelmDeployV0 Suite", function () {
process.env[shared.TestEnvVars.releaseName] = shared.testReleaseName;
process.env[shared.TestEnvVars.failOnStderr] = "false";
process.env[shared.isHelmV3] = "true";

tr.run();
assert(tr.stdout.indexOf(`Release "${shared.testReleaseName}" has been upgraded`) != -1, "Release should have been upgraded");
assert(tr.stdout.indexOf("# Source: testChartName/templates/serviceaccount.yaml") != -1, `Manifests should have been extracted from release ${shared.testReleaseName}`);
Expand All @@ -191,7 +214,7 @@ describe("HelmDeployV0 Suite", function () {
done();
});

it("Run successfully with Helm init (version 2)", function(done: MochaDone) {
it("Run successfully with Helm init (version 2)", function (done: MochaDone) {
const tp = path.join(__dirname, "TestSetup.js");
const tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.connectionType] = shared.ConnectionTypes.KubernetesServiceConnection;
Expand All @@ -204,7 +227,7 @@ describe("HelmDeployV0 Suite", function () {
done();
});

it("Helm init should fail (version 3)", function(done: MochaDone) {
it("Helm init should fail (version 3)", function (done: MochaDone) {
const tp = path.join(__dirname, "TestSetup.js");
const tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.connectionType] = shared.ConnectionTypes.KubernetesServiceConnection;
Expand All @@ -218,7 +241,7 @@ describe("HelmDeployV0 Suite", function () {
done();
});

it("Run successfully with Helm package command (version 3)", function(done: MochaDone) {
it("Run successfully with Helm package command (version 3)", function (done: MochaDone) {
const tp = path.join(__dirname, "TestSetup.js");
const tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.connectionType] = shared.ConnectionTypes.KubernetesServiceConnection;
Expand All @@ -228,13 +251,13 @@ describe("HelmDeployV0 Suite", function () {
process.env[shared.TestEnvVars.destination] = shared.testDestinationPath;
process.env[shared.TestEnvVars.failOnStderr] = "false";
process.env[shared.isHelmV3] = "true";

tr.run();
assert(tr.stdout.indexOf(`Successfully packaged chart and saved it to: ${shared.testDestinationPath}/testChartName.tgz`) !=-1 , "Chart should have been successfully packaged");
assert(tr.stdout.indexOf(`Successfully packaged chart and saved it to: ${shared.testDestinationPath}/testChartName.tgz`) != -1, "Chart should have been successfully packaged");
assert(tr.succeeded, "task should have succeeded");
done();
});

it("Run successfully with Helm save command (version 3)", function (done: MochaDone) {
const tp = path.join(__dirname, "TestSetup.js");
const tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
Expand Down
7 changes: 7 additions & 0 deletions Tasks/HelmDeployV0/Tests/TestSetup.ts
@@ -1,6 +1,7 @@
import * as ma from 'azure-pipelines-task-lib/mock-answer';
import * as tmrm from 'azure-pipelines-task-lib/mock-run';
import * as path from 'path';
import * as semver from 'semver';

import * as shared from './TestShared';

Expand Down Expand Up @@ -139,6 +140,9 @@ if (process.env[shared.TestEnvVars.command] === shared.Commands.install) {
else if (process.env[shared.TestEnvVars.chartPath])
helmInstallCommand = helmInstallCommand.concat(` ${process.env[shared.TestEnvVars.chartPath]}`);

if (process.env[shared.TestEnvVars.version] && semver.valid(process.env[shared.TestEnvVars.version]))
helmInstallCommand = helmInstallCommand.concat(` --version ${process.env[shared.TestEnvVars.version]}`);

a.exec[helmInstallCommand] = {
"code": 0,
"stdout": `NAME: ${shared.testReleaseName} \nLAST DEPLOYED: Mon Jun 8 10:30:31 2020 \nNAMESPACE: ${process.env[shared.TestEnvVars.namespace]} \nSTATUS: deployed \nREVISION: 1 \nNOTES: \n1. Get the application URL by running these commands: \n export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=demo-chart,app.kubernetes.io/ \n instance=mytestv2" -o jsonpath="{.items[0].metadata.name}") \n echo "Visit http://127.0.0.1:8080 to use your application" \n kubectl --namespace default port-forward $POD_NAME 8080:80`
Expand Down Expand Up @@ -194,6 +198,9 @@ if (process.env[shared.TestEnvVars.command] === shared.Commands.upgrade) {
else if (process.env[shared.TestEnvVars.chartPath])
helmUpgradeCommand = helmUpgradeCommand.concat(` ${process.env[shared.TestEnvVars.chartPath]}`);

if (process.env[shared.TestEnvVars.version] && semver.valid(process.env[shared.TestEnvVars.version]))
helmUpgradeCommand = helmUpgradeCommand.concat(` --version ${process.env[shared.TestEnvVars.version]}`);

a.exec[helmUpgradeCommand] = {
"code": 0,
"stdout": `Release "${shared.testReleaseName}" has been upgraded. Happy Helming!\nNAME: ${shared.testReleaseName} \nLAST DEPLOYED: Mon Jun 8 10:30:31 2020 \nNAMESPACE: ${process.env[shared.TestEnvVars.namespace]} \nSTATUS: deployed \nREVISION: 1 \nNOTES: \n1. Get the application URL by running these commands: \n export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=demo-chart,app.kubernetes.io/ \n instance=mytestv2" -o jsonpath="{.items[0].metadata.name}") \n echo "Visit http://127.0.0.1:8080 to use your application" \n kubectl --namespace default port-forward $POD_NAME 8080:80`
Expand Down
1 change: 1 addition & 0 deletions Tasks/HelmDeployV0/Tests/TestShared.ts
Expand Up @@ -62,6 +62,7 @@ export let OperatingSystems = {

export const testChartName = "testChartName";
export const testChartPath = "test/testChartPath";
export const testChartVersion = "1.1.1";
export const testReleaseName = "testReleaseName";
export const isHelmV3 = "__isHelmV3__";
export const testNamespace = "testNamespace";
Expand Down
9 changes: 9 additions & 0 deletions Tasks/HelmDeployV0/src/helmcommands/helminstall.ts
Expand Up @@ -4,6 +4,7 @@ import tl = require('azure-pipelines-task-lib/task');
import helmcli from "./../helmcli";
import * as helmutil from "./../utils";
import { addHelmTlsSettings } from "./../tlssetting";
import * as semver from 'semver';

/*supported chart install
By chart reference: helm install stable/mariadb
Expand All @@ -28,6 +29,7 @@ export function addArguments(helmCli: helmcli): void {
var argumentsInput = tl.getInput("arguments", false);
var valueFilesInput = tl.getInput("valueFile", false);
var enableTls = tl.getBoolInput("enableTls", false);
var version = tl.getInput('version', false);

if (namespace) {
helmCli.addArgument("--namespace ".concat(namespace));
Expand Down Expand Up @@ -79,4 +81,11 @@ export function addArguments(helmCli: helmcli): void {
var chartPath = tl.getInput("chartPath", true);
helmCli.addArgument("\"" + helmutil.resolvePath(chartPath) + "\"");
}

if (version) {
if (semver.valid(version))
helmCli.addArgument("--version ".concat(version));
else
console.log("The given version " + version + " is not valid. Running the helm install command with latest version");
}
}
9 changes: 9 additions & 0 deletions Tasks/HelmDeployV0/src/helmcommands/helmupgrade.ts
Expand Up @@ -4,6 +4,7 @@ import tl = require('azure-pipelines-task-lib/task');
import helmcli from "./../helmcli";
import * as helmutil from "./../utils";
import { addHelmTlsSettings } from "./../tlssetting";
import * as semver from 'semver';

export function addArguments(helmCli: helmcli): void {
var chartType = tl.getInput("chartType", true);
Expand All @@ -19,6 +20,7 @@ export function addArguments(helmCli: helmcli): void {
var resetValues = tl.getBoolInput("resetValues", false);
var force = tl.getBoolInput("force", false);
var enableTls = tl.getBoolInput("enableTls", false);
var version = tl.getInput("version", false);

if (!releaseName) {
var hostType = tl.getVariable("SYSTEM_HOSTTYPE");
Expand Down Expand Up @@ -77,4 +79,11 @@ export function addArguments(helmCli: helmcli): void {
var chartPath = tl.getInput("chartPath", true);
helmCli.addArgument("\"" + helmutil.resolvePath(chartPath) + "\"");
}

if (version) {
if (semver.valid(version))
helmCli.addArgument("--version ".concat(version));
else
tl.debug("The given version " + version + " is not valid. Running the helm upgrade command with latest version");
}
}
8 changes: 8 additions & 0 deletions Tasks/HelmDeployV0/src/utils.ts
Expand Up @@ -5,6 +5,7 @@ import * as path from "path";
import * as tl from "azure-pipelines-task-lib/task";
import * as os from "os";
import * as yaml from 'js-yaml';
import * as semver from 'semver';

import helmcli from "./helmcli";

Expand Down Expand Up @@ -90,6 +91,13 @@ export function getHelmPathForACR() {
return acr + "/helm/" + chartName;
}

export function addVersion(helmCli: helmcli, version: string) {
if (semver.valid(version))
helmCli.addArgument("--version ".concat(version));
else
console.log("The given version is not valid. Running the helm install command with latest version");
}

export function addValueFiles(helmCli: helmcli, valueFiles) {
if (valueFiles && valueFiles.length > 0) {
valueFiles.forEach((file) => {
Expand Down
4 changes: 2 additions & 2 deletions Tasks/HelmDeployV0/task.json
Expand Up @@ -14,7 +14,7 @@
"version": {
"Major": 0,
"Minor": 172,
"Patch": 0
"Patch": 1
},
"demands": [],
"groups": [
Expand Down Expand Up @@ -237,7 +237,7 @@
"type": "string",
"helpMarkDown": "Specify the exact chart version to install. If this is not specified, the latest version is installed. Set the version on the chart to this semver version​",
"defaultValue": "",
"visibleRule": "command == package",
"visibleRule": "command == package || command == install || command == upgrade",
"groupName": "commands"
},
{
Expand Down
4 changes: 2 additions & 2 deletions Tasks/HelmDeployV0/task.loc.json
Expand Up @@ -14,7 +14,7 @@
"version": {
"Major": 0,
"Minor": 172,
"Patch": 0
"Patch": 1
},
"demands": [],
"groups": [
Expand Down Expand Up @@ -237,7 +237,7 @@
"type": "string",
"helpMarkDown": "ms-resource:loc.input.help.version",
"defaultValue": "",
"visibleRule": "command == package",
"visibleRule": "command == package || command == install || command == upgrade",
"groupName": "commands"
},
{
Expand Down

0 comments on commit a503a57

Please sign in to comment.