Skip to content

Commit

Permalink
Should not be able to add the same secret or config map to an applica…
Browse files Browse the repository at this point in the history
…tion twice
  • Loading branch information
jhadvig committed Oct 17, 2017
1 parent 8b7c0d9 commit 3d5ae02
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 54 deletions.
16 changes: 15 additions & 1 deletion app/scripts/directives/addConfigToApplication.js
Expand Up @@ -26,6 +26,20 @@
var ctrl = this;
var humanizeKind = $filter('humanizeKind');

var conatinerHasRef = function(container) {
var addRefName = ctrl.apiObject.metadata.name;
if (ctrl.apiObject.kind === "ConfigMap") {
return _.some(container.envFrom, {configMapRef: {name: addRefName}});
} else {
return _.some(container.envFrom, {secretRef: {name: addRefName}});
}
};

ctrl.checkApplicationContainersRefs = function(application) {
var containers = _.get(application, 'spec.template.spec.containers');
ctrl.canAddRefToApplication = !_.every(containers, conatinerHasRef);
};

var getApplications = function() {
var context = {
namespace: ctrl.project.metadata.name
Expand Down Expand Up @@ -91,7 +105,7 @@

// For each container, add the new volume mount.
_.each(podTemplate.spec.containers, function(container) {
if (isContainerSelected(container)) {
if (isContainerSelected(container) && !conatinerHasRef(container)) {
container.envFrom = container.envFrom || [];
container.envFrom.push(newEnvFrom);
}
Expand Down
4 changes: 2 additions & 2 deletions app/styles/_add-config-to-application.less
Expand Up @@ -48,8 +48,8 @@
}
}

.env-warning {
margin-left: 20px;
.help-block {
margin-bottom: 10px;
}

.updating {
Expand Down
53 changes: 28 additions & 25 deletions app/views/directives/add-config-to-application.html
Expand Up @@ -6,9 +6,9 @@ <h3>Add to Application</h3>
<form name="addToApplicationForm" novalidate>
<fieldset ng-disabled="disableInputs">
<legend>Add this {{ctrl.apiObject.kind | humanizeKind}} to application:</legend>
<div class="form-group">
<div class="form-group" ng-class="{'has-error' : ctrl.addType === 'env' && ctrl.application && !ctrl.canAddRefToApplication}">
<div class="application-select">
<ui-select id="application" ng-model="ctrl.application" required="true" ng-disabled="ctrl.disableInputs">
<ui-select id="application" ng-model="ctrl.application" on-select="ctrl.checkApplicationContainersRefs($item)" required="true" ng-disabled="ctrl.disableInputs">
<ui-select-match placeholder="{{ctrl.applications.length ? 'Select an application' : 'There are no applications in this project'}}">
<span>
{{$select.selected.metadata.name}}
Expand All @@ -23,6 +23,11 @@ <h3>Add to Application</h3>
</ui-select>
</div>
</div>
<div class="has-error" ng-if="ctrl.addType === 'env' && ctrl.application && !ctrl.canAddRefToApplication">
<span class="help-block">
The {{ctrl.apiObject.kind | humanizeKind}} has already been added to this application.
</span>
</div>
<legend>Add {{ctrl.apiObject.kind | humanizeKind}} as:</legend>
<div class="form-group">
<div class="radio">
Expand All @@ -31,12 +36,8 @@ <h3>Add to Application</h3>
<input type="radio" ng-model="ctrl.addType" value="env" ng-disabled="ctrl.disableInputs">
Environment variables
</label>
<div class="alert alert-warning env-warning" ng-show="ctrl.hasInvalidEnvVars">
<span class="pficon pficon-warning-triangle-o" aria-hidden="true"></span>
<span>Some of the keys for {{ctrl.apiObject.kind | humanizeKind}}
<strong>{{ctrl.apiObject.metadata.name}}</strong> are not
valid environment variable names and will not be
added.</span>
<div class="has-warning" ng-if="ctrl.hasInvalidEnvVars">
<span class="help-block">Some of the keys for {{ctrl.apiObject.kind | humanizeKind}} <strong>{{ctrl.apiObject.metadata.name}}</strong> are not valid environment variable names and will not be added.</span>
</div>
</div>
<div>
Expand All @@ -56,7 +57,7 @@ <h3>Add to Application</h3>
ng-pattern="/^\/.*$/"
osc-unique="ctrl.existingMountPaths"
aria-describedby="mount-path-help"
ng-disabled="ctrl.addType !== 'volume' || ctrl.disableInputs"
ng-disabled="ctrl.addType !== 'volume' || ctrl.disableInputs || !ctrl.application"
ng-model="ctrl.mountVolume"
autocorrect="off"
autocapitalize="off"
Expand All @@ -80,21 +81,23 @@ <h3>Add to Application</h3>
</div>
</div>
</div>
<legend ng-if-start="ctrl.application.spec.template.spec.containers.length > 1">Containers:</legend>
<div ng-if-end class="form-group container-options">
<div ng-if="ctrl.attachAllContainers">
The {{ctrl.apiObject.kind | humanizeKind}} will be added to all containers. You can
<a href="" ng-click="ctrl.attachAllContainers = false">select specific containers</a>
instead.
</div>
<div ng-if="!ctrl.attachAllContainers" class="form-group">
<label class="sr-only required">Containers</label>
<select-containers
ng-model="ctrl.attachContainers"
pod-template="ctrl.application.spec.template"
ng-required="true"
help-text="Add the {{ctrl.apiObject.kind | humanizeKind}} to the selected containers.">
</select-containers>
<div ng-if="ctrl.canAddRefToApplication">
<legend ng-if-start="ctrl.application.spec.template.spec.containers.length > 1">Containers:</legend>
<div ng-if-end class="form-group container-options">
<div ng-if="ctrl.attachAllContainers">
The {{ctrl.apiObject.kind | humanizeKind}} will be added to all containers. You can
<a href="" ng-click="ctrl.attachAllContainers = false">select specific containers</a>
instead.
</div>
<div ng-if="!ctrl.attachAllContainers" class="form-group">
<label class="sr-only required">Containers</label>
<select-containers
ng-model="ctrl.attachContainers"
pod-template="ctrl.application.spec.template"
ng-required="true"
help-text="Add the {{ctrl.apiObject.kind | humanizeKind}} to the selected containers.">
</select-containers>
</div>
</div>
</div>
<div class="button-group pull-right">
Expand All @@ -108,7 +111,7 @@ <h3>Add to Application</h3>
class="btn btn-primary"
ng-class="{'dialog-btn': isDialog}"
ng-click="ctrl.addToApplication()"
ng-disabled="ctrl.addType === 'volume' && addToApplicationForm.$invalid || !ctrl.application"
ng-disabled="addToApplicationForm.$invalid || (ctrl.addType === 'env' && !ctrl.canAddRefToApplication)"
value="">
Save
</button>
Expand Down
46 changes: 31 additions & 15 deletions dist/scripts/scripts.js
Expand Up @@ -10993,7 +10993,23 @@ templateUrl: "views/directives/action-chip.html"
}), function() {
angular.module("openshiftConsole").component("addConfigToApplication", {
controller: [ "$filter", "$scope", "APIService", "ApplicationsService", "DataService", "Navigate", "NotificationsService", "StorageService", function(e, t, n, a, r, o, i, s) {
var c = this, l = e("humanizeKind"), u = function() {
var c = this, l = e("humanizeKind"), u = function(e) {
var t = c.apiObject.metadata.name;
return "ConfigMap" === c.apiObject.kind ? _.some(e.envFrom, {
configMapRef: {
name: t
}
}) : _.some(e.envFrom, {
secretRef: {
name: t
}
});
};
c.checkApplicationContainersRefs = function(e) {
var t = _.get(e, "spec.template.spec.containers");
c.canAddRefToApplication = !_.every(t, u);
};
var d = function() {
var e = {
namespace: c.project.metadata.name
};
Expand All @@ -11002,13 +11018,13 @@ c.applications = e, c.updating = !1;
});
};
c.$onInit = function() {
c.addType = "env", c.disableInputs = !1, u();
c.addType = "env", c.disableInputs = !1, d();
var e = new RegExp("^[A-Za-z_][A-Za-z0-9_]*$");
c.hasInvalidEnvVars = _.some(c.apiObject.data, function(t, n) {
return !e.test(n);
});
};
var d = function(e) {
var m = function(e) {
return c.attachAllContainers || c.attachContainers[e.name];
};
c.$postLink = function() {
Expand Down Expand Up @@ -11037,51 +11053,51 @@ name: c.apiObject.metadata.name
};
}
_.each(a.spec.containers, function(e) {
d(e) && (e.envFrom = e.envFrom || [], e.envFrom.push(s));
m(e) && !u(e) && (e.envFrom = e.envFrom || [], e.envFrom.push(s));
});
} else {
var l = e("generateName")(c.apiObject.metadata.name + "-"), u = {
var l = e("generateName")(c.apiObject.metadata.name + "-"), d = {
name: l,
mountPath: c.mountVolume,
readOnly: !0
};
_.each(a.spec.containers, function(e) {
d(e) && (e.volumeMounts = e.volumeMounts || [], e.volumeMounts.push(u));
m(e) && (e.volumeMounts = e.volumeMounts || [], e.volumeMounts.push(d));
});
var m = {
var p = {
name: l
};
switch (c.apiObject.kind) {
case "Secret":
m.secret = {
p.secret = {
secretName: c.apiObject.metadata.name
};
break;

case "ConfigMap":
m.configMap = {
p.configMap = {
name: c.apiObject.metadata.name
};
}
a.spec.volumes = a.spec.volumes || [], a.spec.volumes.push(m);
a.spec.volumes = a.spec.volumes || [], a.spec.volumes.push(p);
}
var p = e("humanizeKind"), f = p(c.apiObject.kind), g = p(t.kind), v = {
var f = e("humanizeKind"), g = f(c.apiObject.kind), v = f(t.kind), h = {
namespace: c.project.metadata.name
};
r.update(n.kindToResource(t.kind), t.metadata.name, t, v).then(function() {
r.update(n.kindToResource(t.kind), t.metadata.name, t, h).then(function() {
i.addNotification({
type: "success",
message: "Successfully added " + f + " " + c.apiObject.metadata.name + " to " + g + " " + t.metadata.name + ".",
message: "Successfully added " + g + " " + c.apiObject.metadata.name + " to " + v + " " + t.metadata.name + ".",
links: [ {
href: o.resourceURL(t),
label: "View " + p(t.kind, !0)
label: "View " + f(t.kind, !0)
} ]
}), angular.isFunction(c.onComplete) && c.onComplete();
}, function(n) {
var a = e("getErrorDetails");
i.addNotification({
type: "error",
message: "An error occurred adding " + f + " " + c.apiObject.metadata.name + " to " + g + " " + t.metadata.name + ". " + a(n)
message: "An error occurred adding " + g + " " + c.apiObject.metadata.name + " to " + v + " " + t.metadata.name + ". " + a(n)
});
}).finally(function() {
c.disableInputs = !1;
Expand Down
21 changes: 13 additions & 8 deletions dist/scripts/templates.js
Expand Up @@ -5677,9 +5677,9 @@ angular.module('openshiftConsoleTemplates', []).run(['$templateCache', function(
"<form name=\"addToApplicationForm\" novalidate>\n" +
"<fieldset ng-disabled=\"disableInputs\">\n" +
"<legend>Add this {{ctrl.apiObject.kind | humanizeKind}} to application:</legend>\n" +
"<div class=\"form-group\">\n" +
"<div class=\"form-group\" ng-class=\"{'has-error' : ctrl.addType === 'env' && ctrl.application && !ctrl.canAddRefToApplication}\">\n" +
"<div class=\"application-select\">\n" +
"<ui-select id=\"application\" ng-model=\"ctrl.application\" required=\"true\" ng-disabled=\"ctrl.disableInputs\">\n" +
"<ui-select id=\"application\" ng-model=\"ctrl.application\" on-select=\"ctrl.checkApplicationContainersRefs($item)\" required=\"true\" ng-disabled=\"ctrl.disableInputs\">\n" +
"<ui-select-match placeholder=\"{{ctrl.applications.length ? 'Select an application' : 'There are no applications in this project'}}\">\n" +
"<span>\n" +
"{{$select.selected.metadata.name}}\n" +
Expand All @@ -5692,6 +5692,11 @@ angular.module('openshiftConsoleTemplates', []).run(['$templateCache', function(
"</ui-select>\n" +
"</div>\n" +
"</div>\n" +
"<div class=\"has-error\" ng-if=\"ctrl.addType === 'env' && ctrl.application && !ctrl.canAddRefToApplication\">\n" +
"<span class=\"help-block\">\n" +
"The {{ctrl.apiObject.kind | humanizeKind}} has already been added to this application.\n" +
"</span>\n" +
"</div>\n" +
"<legend>Add {{ctrl.apiObject.kind | humanizeKind}} as:</legend>\n" +
"<div class=\"form-group\">\n" +
"<div class=\"radio\">\n" +
Expand All @@ -5700,10 +5705,8 @@ angular.module('openshiftConsoleTemplates', []).run(['$templateCache', function(
"<input type=\"radio\" ng-model=\"ctrl.addType\" value=\"env\" ng-disabled=\"ctrl.disableInputs\">\n" +
"Environment variables\n" +
"</label>\n" +
"<div class=\"alert alert-warning env-warning\" ng-show=\"ctrl.hasInvalidEnvVars\">\n" +
"<span class=\"pficon pficon-warning-triangle-o\" aria-hidden=\"true\"></span>\n" +
"<span>Some of the keys for {{ctrl.apiObject.kind | humanizeKind}}\n" +
"<strong>{{ctrl.apiObject.metadata.name}}</strong> are not valid environment variable names and will not be added.</span>\n" +
"<div class=\"has-warning\" ng-if=\"ctrl.hasInvalidEnvVars\">\n" +
"<span class=\"help-block\">Some of the keys for {{ctrl.apiObject.kind | humanizeKind}} <strong>{{ctrl.apiObject.metadata.name}}</strong> are not valid environment variable names and will not be added.</span>\n" +
"</div>\n" +
"</div>\n" +
"<div>\n" +
Expand All @@ -5714,7 +5717,7 @@ angular.module('openshiftConsoleTemplates', []).run(['$templateCache', function(
"</div>\n" +
"<div class=\"volume-options\">\n" +
"<div ng-class=\"{'has-error': (addToApplicationForm.mountVolume.$error.oscUnique || (addToApplicationForm.mountVolume.$error.pattern && addToApplicationForm.mountVolume.$touched))}\">\n" +
"<input class=\"form-control\" name=\"mountVolume\" id=\"mountVolume\" placeholder=\"Enter a mount path\" type=\"text\" required ng-pattern=\"/^\\/.*$/\" osc-unique=\"ctrl.existingMountPaths\" aria-describedby=\"mount-path-help\" ng-disabled=\"ctrl.addType !== 'volume' || ctrl.disableInputs\" ng-model=\"ctrl.mountVolume\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\">\n" +
"<input class=\"form-control\" name=\"mountVolume\" id=\"mountVolume\" placeholder=\"Enter a mount path\" type=\"text\" required ng-pattern=\"/^\\/.*$/\" osc-unique=\"ctrl.existingMountPaths\" aria-describedby=\"mount-path-help\" ng-disabled=\"ctrl.addType !== 'volume' || ctrl.disableInputs || !ctrl.application\" ng-model=\"ctrl.mountVolume\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\">\n" +
"</div>\n" +
"<div class=\"help-block bind-description\">\n" +
"Mount Path for the volume. A file will be created in this directory for each key from the {{ctrl.apiObject.kind | humanizeKind}}. The file contents will be the value of the key.\n" +
Expand All @@ -5732,6 +5735,7 @@ angular.module('openshiftConsoleTemplates', []).run(['$templateCache', function(
"</div>\n" +
"</div>\n" +
"</div>\n" +
"<div ng-if=\"ctrl.canAddRefToApplication\">\n" +
"<legend ng-if-start=\"ctrl.application.spec.template.spec.containers.length > 1\">Containers:</legend>\n" +
"<div ng-if-end class=\"form-group container-options\">\n" +
"<div ng-if=\"ctrl.attachAllContainers\">\n" +
Expand All @@ -5745,11 +5749,12 @@ angular.module('openshiftConsoleTemplates', []).run(['$templateCache', function(
"</select-containers>\n" +
"</div>\n" +
"</div>\n" +
"</div>\n" +
"<div class=\"button-group pull-right\">\n" +
"<button class=\"btn btn-default\" ng-class=\"{'dialog-btn': isDialog}\" ng-click=\"ctrl.onCancel()\">\n" +
"Cancel\n" +
"</button>\n" +
"<button type=\"submit\" class=\"btn btn-primary\" ng-class=\"{'dialog-btn': isDialog}\" ng-click=\"ctrl.addToApplication()\" ng-disabled=\"ctrl.addType === 'volume' && addToApplicationForm.$invalid || !ctrl.application\" value=\"\">\n" +
"<button type=\"submit\" class=\"btn btn-primary\" ng-class=\"{'dialog-btn': isDialog}\" ng-click=\"ctrl.addToApplication()\" ng-disabled=\"addToApplicationForm.$invalid || (ctrl.addType === 'env' && !ctrl.canAddRefToApplication)\" value=\"\">\n" +
"Save\n" +
"</button>\n" +
"</div>\n" +
Expand Down
6 changes: 3 additions & 3 deletions dist/styles/main.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 3d5ae02

Please sign in to comment.