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

Added configMaps section in Kubernetes #6646

Merged
merged 7 commits into from
Mar 27, 2018
Merged
Show file tree
Hide file tree
Changes from 6 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
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"loc.instanceNameFormat": "kubectl $(command)",
"loc.group.displayName.commands": "Commands",
"loc.group.displayName.secrets": "Secrets",
"loc.group.displayName.configMaps": "ConfigMaps",
"loc.group.displayName.advanced": "Advanced",
"loc.group.displayName.output": "Output",
"loc.input.label.kubernetesServiceEndpoint": "Kubernetes Service Connection",
Expand All @@ -22,7 +23,7 @@
"loc.input.label.secretType": "Type of secret",
"loc.input.help.secretType": "Select a type of secret",
"loc.input.label.secretArguments": "Arguments",
"loc.input.help.secretArguments": "Specify keys and literal values to insert in secret.For example, --from-literal=key1=value1 --from-literal=key2=\"top secret\". Please use double quotes to specify any literals that have spaces.",
"loc.input.help.secretArguments": "Specify keys and literal values to insert in secret.For example, --from-literal=key1=value1 --from-literal=key2=\"top secret\".",
"loc.input.label.containerRegistryType": "Container Registry type",
"loc.input.help.containerRegistryType": "Select a Container registry type.",
"loc.input.label.dockerRegistryEndpoint": "Docker Registry Connection",
Expand All @@ -35,6 +36,16 @@
"loc.input.help.secretName": "Name of the secret. You can use this secret name in the Kubernetes YAML configuration file.",
"loc.input.label.forceUpdate": "Force update secret",
"loc.input.help.forceUpdate": "Delete the secret if it exists and create a new one with updated values.",
"loc.input.label.configMapName": "ConfigMap Name",
"loc.input.help.configMapName": "Name of ConfigMap.",
"loc.input.label.forceUpdateConfigMap": "Force update configmap",
"loc.input.help.forceUpdateConfigMap": "Delete the configmap if it exists and create a new one with updated values.",
"loc.input.label.useConfigMapFile": "Use file",
"loc.input.help.useConfigMapFile": "Use a file or directory to create the configMap.",
"loc.input.label.configMapFile": "ConfigMap File",
"loc.input.help.configMapFile": "Specify a file or directory that contains the configMaps",
"loc.input.label.configMapArguments": "Arguments",
"loc.input.help.configMapArguments": "Specify keys and literal values to insert in configMap.For example, --from-literal=key1=value1 --from-literal=key2=\"top secret\".",
"loc.input.label.versionOrLocation": "Kubectl",
"loc.input.label.versionSpec": "Version Spec",
"loc.input.help.versionSpec": "Version Spec of version to get. Examples: 1.7.0, 1.x.0, 4.x.0, 6.10.0, >=6.10.0",
Expand All @@ -51,6 +62,10 @@
"loc.messages.DownloadingClient": "Downloading kubernetes client.",
"loc.messages.CreatingSecret": "Executing create %s secret.",
"loc.messages.DeleteSecret": "Executing delete %s secret",
"loc.messages.CreatingConfigMap": "Executing create %s configmap.",
"loc.messages.DeleteConfigMap": "Executing delete %s configmap",
"loc.messages.ConfigMapExists": "ConfigMap %s already exists",
"loc.messages.GetConfigMap": "Executing get %s configmap",
"loc.messages.DockerRegistryConnectionNotSpecified": "Docker Registry connection details not specified",
"loc.messages.FileNotFoundException": "Can not find file at location: %s",
"loc.messages.DownloadingKubeCtlFromUrl": "Downloading Kubectl from Url: %s",
Expand Down
157 changes: 157 additions & 0 deletions Tasks/Kubernetes/Tests/L0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ describe('Kubernetes Suite', function() {
delete process.env[shared.TestEnvVars.secretArguments];
delete process.env[shared.TestEnvVars.secretName];
delete process.env[shared.TestEnvVars.forceUpdate];
delete process.env[shared.TestEnvVars.configMapName];
delete process.env[shared.TestEnvVars.useConfigMapFile];
delete process.env[shared.TestEnvVars.forceUpdateConfigMap];
delete process.env[shared.TestEnvVars.configMapArguments];
delete process.env[shared.TestEnvVars.outputFormat];
delete process.env[shared.TestEnvVars.kubectlOutput];
});
Expand Down Expand Up @@ -311,6 +315,88 @@ describe('Kubernetes Suite', function() {
console.log(tr.stderr);
done();
});

it('Runs successfully for kubectl create configMap from file or directory with forceUpdate', (done:MochaDone) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add test cases to validate following scenerios.

  1. create secret -> create configmap -> kubectl commad execution. All three commands are getting executed.
  2. create configmap -> kubectl commad. These two commands are independently getting executed.
  3. create secret -> kubectl commad. These two commands are independently getting executed.

let tp = path.join(__dirname, 'TestSetup.js');
let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.command] = shared.Commands.get;
process.env[shared.TestEnvVars.arguments] = "pods";
process.env[shared.TestEnvVars.configMapName] = "myConfigMap";
process.env[shared.TestEnvVars.useConfigMapFile] = "true";
process.env[shared.TestEnvVars.forceUpdateConfigMap] = "true";
tr.run();

assert(tr.invokedToolCount == 2, 'should have invoked tool one times. actual: ' + tr.invokedToolCount);
assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr');
assert(tr.succeeded, 'task should have succeeded');
assert(tr.stdout.indexOf(`GetConfigMap myConfigMap`) == -1, "kubectl get should not run");
assert(tr.stdout.indexOf(`DeleteConfigMap myConfigMap`) != -1, "kubectl delete should run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} create configmap myConfigMap --from-file=${shared.formatPath("configMapDir/configMap.properties")}`) != -1, "kubectl create should run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} get pods`) != -1, "kubectl get should run");
console.log(tr.stderr);
done();
});

it('Runs successfully for kubectl create configMap from file or directory without forceUpdate', (done:MochaDone) => {
let tp = path.join(__dirname, 'TestSetup.js');
let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.command] = shared.Commands.get;
process.env[shared.TestEnvVars.arguments] = "pods";
process.env[shared.TestEnvVars.configMapName] = "myConfigMap";
process.env[shared.TestEnvVars.useConfigMapFile] = "true";
tr.run();

assert(tr.invokedToolCount == 2, 'should have invoked tool one times. actual: ' + tr.invokedToolCount);
assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr');
assert(tr.succeeded, 'task should have succeeded');
assert(tr.stdout.indexOf(`GetConfigMap myConfigMap`) != -1, "kubectl get should run");
assert(tr.stdout.indexOf(`DeleteConfigMap myConfigMap`) == -1, "kubectl delete should not run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} create configmap myConfigMap --from-file=${shared.formatPath("configMapDir/configMap.properties")}`) != -1, "kubectl create should run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} get pods`) != -1, "kubectl get should run");
console.log(tr.stderr);
done();
});

it('Runs successfully for kubectl create configMap using literal values with forceUpdate', (done:MochaDone) => {
let tp = path.join(__dirname, 'TestSetup.js');
let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.command] = shared.Commands.get;
process.env[shared.TestEnvVars.arguments] = "pods";
process.env[shared.TestEnvVars.configMapName] = "myConfigMap";
process.env[shared.TestEnvVars.configMapArguments] = "--from-literal=key1=value1 --from-literal=key2=value2";
process.env[shared.TestEnvVars.forceUpdateConfigMap] = "true";
tr.run();

assert(tr.invokedToolCount == 2, 'should have invoked tool one times. actual: ' + tr.invokedToolCount);
assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr');
assert(tr.succeeded, 'task should have succeeded');
assert(tr.stdout.indexOf(`GetConfigMap myConfigMap`) == -1, "kubectl get should not run");
assert(tr.stdout.indexOf(`DeleteConfigMap myConfigMap`) != -1, "kubectl delete should run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} create configmap myConfigMap --from-literal=key1=value1 --from-literal=key2=value2`) != -1, "kubectl create should run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} get pods`) != -1, "kubectl get should run");
console.log(tr.stderr);
done();
});

it('Runs successfully for kubectl kubectl create configMap using literal values without forceUpdate', (done:MochaDone) => {
let tp = path.join(__dirname, 'TestSetup.js');
let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.command] = shared.Commands.get;
process.env[shared.TestEnvVars.arguments] = "pods";
process.env[shared.TestEnvVars.configMapName] = "myConfigMap";
process.env[shared.TestEnvVars.configMapArguments] = "--from-literal=key1=value1 --from-literal=key2=value2";
tr.run();

assert(tr.invokedToolCount == 2, 'should have invoked tool one times. actual: ' + tr.invokedToolCount);
assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr');
assert(tr.succeeded, 'task should have succeeded');
assert(tr.stdout.indexOf(`GetConfigMap myConfigMap`) != -1, "kubectl get should run");
assert(tr.stdout.indexOf(`DeleteConfigMap myConfigMap`) == -1, "kubectl delete should not run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} create configmap myConfigMap --from-literal=key1=value1 --from-literal=key2=value2`) != -1, "kubectl create should run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} get pods`) != -1, "kubectl get should run");
console.log(tr.stderr);
done();
});

it('Runs successfully for kubectl get and print the output in a particular format', (done:MochaDone) => {
let tp = path.join(__dirname, 'TestSetup.js');
Expand All @@ -327,5 +413,76 @@ describe('Kubernetes Suite', function() {
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} get secrets my-secret -o yaml`) != -1, "kubectl get should run");
console.log(tr.stderr);
done();
});


it('Runs successfully for checking whether secrets, configmaps and kubectl commands are run in a consecutive manner', (done:MochaDone) => {
let tp = path.join(__dirname, 'TestSetup.js');
let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.command] = shared.Commands.get;
process.env[shared.TestEnvVars.arguments] = "pods";
process.env[shared.TestEnvVars.secretType] = "generic";
process.env[shared.TestEnvVars.secretArguments] = "--from-literal=key1=value1 --from-literal=key2=value2";
process.env[shared.TestEnvVars.secretName] = "my-secret";
process.env[shared.TestEnvVars.configMapName] = "myConfigMap";
process.env[shared.TestEnvVars.useConfigMapFile] = "true";
process.env[shared.TestEnvVars.forceUpdateConfigMap] = "true";
tr.run();

assert(tr.invokedToolCount == 3, 'should have invoked tool one times. actual: ' + tr.invokedToolCount);
assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr');
assert(tr.succeeded, 'task should have succeeded');
assert(tr.stdout.indexOf(`DeleteSecret my-secret`) != -1, "kubectl delete should run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} create secret generic my-secret --from-literal=key1=value1 --from-literal=key2=value2`) != -1, "kubectl create should run");
assert(tr.stdout.indexOf(`DeleteConfigMap myConfigMap`) != -1, "kubectl delete should run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} create configmap myConfigMap --from-file=${shared.formatPath("configMapDir/configMap.properties")}`) != -1, "kubectl create should run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} get pods`) != -1, "kubectl get should run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} create secret generic my-secret --from-literal=key1=value1 --from-literal=key2=value2`) < tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} create configmap myConfigMap --from-file=${shared.formatPath("configMapDir/configMap.properties")}`), "kubectl create secrets should run before create configMap");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} create configmap myConfigMap --from-literal=key1=value1 --from-literal=key2=value2`) < tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} get pods`), "kubectl create configMap should run before get");
console.log(tr.stderr);
done();
});

it('Runs fails if create config command fails even if create secret is successful', (done:MochaDone) => {
let tp = path.join(__dirname, 'TestSetup.js');
let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.command] = shared.Commands.get;
process.env[shared.TestEnvVars.arguments] = "pods";
process.env[shared.TestEnvVars.secretType] = "generic";
process.env[shared.TestEnvVars.secretArguments] = "--from-literal=key1=value1 --from-literal=key2=value2";
process.env[shared.TestEnvVars.secretName] = "my-secret";
process.env[shared.TestEnvVars.configMapName] = "someConfigMap";
process.env[shared.TestEnvVars.useConfigMapFile] = "true";
tr.run();

assert(tr.invokedToolCount == 2, 'should have invoked tool one times. actual: ' + tr.invokedToolCount);
assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr');
assert(tr.failed, 'task should have failed');
assert(tr.stdout.indexOf(`GetConfigMap someConfigMap`) != -1, "kubectl get should run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} create secret generic my-secret --from-literal=key1=value1 --from-literal=key2=value2`) != -1, "kubectl create should run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} create configmap someConfigMap --from-file=${shared.formatPath("configMapDir/configMap.properties")}`) != -1, "kubectl create should run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} get pods`) == -1, "kubectl get should not run");
console.log(tr.stderr);
done();
});

it('Runs successfully when forceUpdateConfigMap is false and configMap exists', (done:MochaDone) => {
let tp = path.join(__dirname, 'TestSetup.js');
let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.command] = shared.Commands.get;
process.env[shared.TestEnvVars.arguments] = "pods";
process.env[shared.TestEnvVars.configMapName] = "existingConfigMap";
process.env[shared.TestEnvVars.useConfigMapFile] = "true";
tr.run();

assert(tr.invokedToolCount == 1, 'should have invoked tool one times. actual: ' + tr.invokedToolCount);
assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr');
assert(tr.succeeded, 'task should have succeeded');
assert(tr.stdout.indexOf(`GetConfigMap existingConfigMap`) != -1, "kubectl get should run");
assert(tr.stdout.indexOf(`DeleteConfigMap existingConfigMap`) == -1, "kubectl delete should not run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} create configmap existingConfigMap --from-file=${shared.formatPath("configMapDir/configMap.properties")}`) == -1, "kubectl create should not run");
assert(tr.stdout.indexOf(`[command]kubectl --kubeconfig ${shared.formatPath("newUserDir/config")} get pods`) != -1, "kubectl get should run");
console.log(tr.stderr);
done();
});
});
34 changes: 32 additions & 2 deletions Tasks/Kubernetes/Tests/TestSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const ConfigurationFilePath = shared.formatPath("dir/deployment.yaml");
const newUserDirPath = shared.formatPath("newUserDir/");
const KubconfigFile = shared.formatPath("newUserDir/config");
const KubectlPath = shared.formatPath("newUserDir/kubectl.exe");
const ConfigMapFilePath = shared.formatPath("configMapDir/configMap.properties");

let taskPath = path.join(__dirname, '../src', 'kubernetes.js');
let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath);
Expand All @@ -22,6 +23,11 @@ tr.setInput('secretType', process.env[shared.TestEnvVars.secretType] || 'dockerR
tr.setInput('secretArguments', process.env[shared.TestEnvVars.secretArguments] || '');
tr.setInput('secretName', process.env[shared.TestEnvVars.secretName] || '');
tr.setInput('forceUpdate', process.env[shared.TestEnvVars.forceUpdate] || "true");
tr.setInput('configMapName', process.env[shared.TestEnvVars.configMapName] || '');
tr.setInput('forceUpdateConfigMap', process.env[shared.TestEnvVars.forceUpdateConfigMap] || "false");
tr.setInput('useConfigMapFile', process.env[shared.TestEnvVars.useConfigMapFile] || "false");
tr.setInput('configMapFile', ConfigMapFilePath);
tr.setInput('configMapArguments', process.env[shared.TestEnvVars.configMapArguments] || '');
tr.setInput('versionOrLocation', process.env[shared.TestEnvVars.versionOrLocation] || 'version');
tr.setInput('versionSpec', process.env[shared.TestEnvVars.versionSpec] || "1.7.0");
tr.setInput('checkLatest', process.env[shared.TestEnvVars.checkLatest] || "false");
Expand Down Expand Up @@ -53,7 +59,8 @@ let a = {
},
"checkPath": {
[KubectlPath]: true,
[ConfigurationFilePath]: true
[ConfigurationFilePath]: true,
[ConfigMapFilePath]: true
},
"exist": {
[KubconfigFile]: true
Expand All @@ -64,6 +71,7 @@ let a = {

// Add extra answer definitions that need to be dynamically generated
a.exist[ConfigurationFilePath] = true;
a.exist[ConfigMapFilePath] = true;
a.exist[KubectlPath] = true;

if (JSON.parse(process.env[shared.isKubectlPresentOnMachine]))
Expand Down Expand Up @@ -103,6 +111,28 @@ a.exec[`kubectl --kubeconfig ${KubconfigFile} create secret docker-registry my-s
a.exec[`kubectl --kubeconfig ${KubconfigFile} create secret generic my-secret --from-literal=key1=value1 --from-literal=key2=value2`] = {
"code": 0
};
a.exec[`kubectl --kubeconfig ${KubconfigFile} delete configmap myConfigMap`] = {
"code": 0
};
a.exec[`kubectl --kubeconfig ${KubconfigFile} get configmap existingConfigMap`] = {
"code": 0
};
a.exec[`kubectl --kubeconfig ${KubconfigFile} get configmap someConfigMap`] = {
"code": 1
};
a.exec[`kubectl --kubeconfig ${KubconfigFile} get configmap myConfigMap`] = {
"code": 1
};
a.exec[`kubectl --kubeconfig ${KubconfigFile} create configmap myConfigMap --from-file=${ConfigMapFilePath}`] = {
"code": 0
};
a.exec[`kubectl --kubeconfig ${KubconfigFile} create configmap myConfigMap --from-literal=key1=value1 --from-literal=key2=value2`] = {
"code": 0
};
a.exec[`kubectl --kubeconfig ${KubconfigFile} create configmap someConfigMap --from-file=${ConfigMapFilePath}`] = {
"code": 1,
"stdout" : "Error in configMap creation"
};
a.exec[`kubectl --kubeconfig ${KubconfigFile} get secrets my-secret -o yaml`] = {
"code": 0,
"stdout": "successfully got secret my-secret and printed it in the specified format"
Expand Down Expand Up @@ -199,7 +229,7 @@ tr.registerMock('./utilities', {
},
assertFileExists: function(path) {
return true;
}
}
});

tr.run();
Loading