diff --git a/zun_ui/api/client.py b/zun_ui/api/client.py
index ad8eefa..91603f7 100644
--- a/zun_ui/api/client.py
+++ b/zun_ui/api/client.py
@@ -51,11 +51,11 @@ def _cleanup_params(attrs, check, **params):
if key == "run":
run = value
elif key == "cpu":
- args["cpu"] = float(value)
+ args[key] = float(value)
elif key == "memory":
- args["memory"] = int(value)
- elif key == "interactive":
- args["interactive"] = value
+ args[key] = int(value)
+ elif key == "interactive" or key == "security_groups":
+ args[key] = value
elif key == "restart_policy":
args[key] = utils.check_restart_policy(value)
elif key == "environment" or key == "labels":
diff --git a/zun_ui/static/dashboard/container/containers/actions/create.service.js b/zun_ui/static/dashboard/container/containers/actions/create.service.js
index 8591211..5874ab8 100644
--- a/zun_ui/static/dashboard/container/containers/actions/create.service.js
+++ b/zun_ui/static/dashboard/container/containers/actions/create.service.js
@@ -79,6 +79,7 @@
context.model.restart_policy_max_retry;
}
delete context.model.restart_policy_max_retry;
+ context.model.security_groups = setSecurityGroups(context.model);
context.model = cleanNullProperties(context.model);
return zun.createContainer(context.model).then(success);
}
@@ -101,5 +102,14 @@
}
return model;
}
+
+ function setSecurityGroups(model) {
+ // pull out the ids from the security groups objects
+ var securityGroups = [];
+ model.security_groups.forEach(function(securityGroup) {
+ securityGroups.push(securityGroup.name);
+ });
+ return securityGroups;
+ }
}
})();
diff --git a/zun_ui/static/dashboard/container/containers/actions/workflow/security-groups/security-group-details.html b/zun_ui/static/dashboard/container/containers/actions/workflow/security-groups/security-group-details.html
new file mode 100644
index 0000000..58012e5
--- /dev/null
+++ b/zun_ui/static/dashboard/container/containers/actions/workflow/security-groups/security-group-details.html
@@ -0,0 +1,22 @@
+
+
+
+ Direction |
+ Ether Type |
+ Protocol |
+ Min Port |
+ Max Port |
+ Remote |
+
+
+
+
+ {$ d.direction | noValue $} |
+ {$ d.ethertype | noValue $} |
+ {$ d.protocol | noValue $} |
+ {$ d.port_range_min | noValue $} |
+ {$ d.port_range_max | noValue $} |
+ {$ d.remote_ip_prefix | noValue $} |
+
+
+
diff --git a/zun_ui/static/dashboard/container/containers/actions/workflow/security-groups/security-groups.controller.js b/zun_ui/static/dashboard/container/containers/actions/workflow/security-groups/security-groups.controller.js
new file mode 100644
index 0000000..2ef2a2d
--- /dev/null
+++ b/zun_ui/static/dashboard/container/containers/actions/workflow/security-groups/security-groups.controller.js
@@ -0,0 +1,93 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+(function () {
+ 'use strict';
+
+ angular
+ .module('horizon.dashboard.container.containers')
+ .controller('horizon.dashboard.container.containers.workflow.security-group',
+ SecurityGroupsController);
+
+ SecurityGroupsController.$inject = [
+ '$scope',
+ 'horizon.app.core.openstack-service-api.security-group',
+ 'horizon.dashboard.container.basePath'
+ ];
+
+ /**
+ * @ngdoc controller
+ * @name SecurityGroupsController
+ * @param {Object} containerModel
+ * @param {string} basePath
+ * @description
+ * Allows selection of security groups.
+ * @returns {undefined} No return value
+ */
+ function SecurityGroupsController($scope, securityGroup, basePath) {
+ var push = Array.prototype.push;
+
+ var ctrl = this;
+ var availableSecurityGroups = [];
+ securityGroup.query().then(onGetSecurityGroups);
+
+ ctrl.tableData = {
+ available: availableSecurityGroups,
+ allocated: $scope.model.security_groups,
+ displayedAvailable: [],
+ displayedAllocated: []
+ };
+
+ /* eslint-disable max-len */
+ ctrl.tableDetails = basePath + 'containers/actions/workflow/security-groups/security-group-details.html';
+ /* eslint-enable max-len */
+
+ ctrl.tableHelp = {
+ /* eslint-disable max-len */
+ noneAllocText: gettext('Select one or more security groups from the available groups below.'),
+ /* eslint-enable max-len */
+ availHelpText: gettext('Select one or more')
+ };
+
+ ctrl.tableLimits = {
+ maxAllocation: -1
+ };
+
+ ctrl.filterFacets = [
+ {
+ label: gettext('Name'),
+ name: 'name',
+ singleton: true
+ },
+ {
+ label: gettext('Description'),
+ name: 'description',
+ singleton: true
+ }
+ ];
+
+ // Security Groups
+ function onGetSecurityGroups(data) {
+ angular.forEach(data.data.items, function addDefault(item) {
+ // 'default' is a special security group in neutron. It can not be
+ // deleted and is guaranteed to exist. It by default contains all
+ // of the rules needed for an instance to reach out to the network
+ // so the instance can provision itself.
+ if (item.name === 'default') {
+ $scope.model.security_groups.push(item);
+ }
+ });
+ push.apply(availableSecurityGroups, data.data.items);
+ }
+ }
+})();
diff --git a/zun_ui/static/dashboard/container/containers/actions/workflow/security-groups/security-groups.help.html b/zun_ui/static/dashboard/container/containers/actions/workflow/security-groups/security-groups.help.html
new file mode 100644
index 0000000..3692e82
--- /dev/null
+++ b/zun_ui/static/dashboard/container/containers/actions/workflow/security-groups/security-groups.help.html
@@ -0,0 +1,4 @@
+
+ - Security Groups
+ - Security groups define a set of IP filter rules that determine how network traffic flows to and from a container. Users can add additional rules to an existing security group to further define the access options for a container. To create additional rules, go to the Network | Security Groups view, then find the security group and click Manage Rules.
+
diff --git a/zun_ui/static/dashboard/container/containers/actions/workflow/security-groups/security-groups.html b/zun_ui/static/dashboard/container/containers/actions/workflow/security-groups/security-groups.html
new file mode 100644
index 0000000..c0e429a
--- /dev/null
+++ b/zun_ui/static/dashboard/container/containers/actions/workflow/security-groups/security-groups.html
@@ -0,0 +1,106 @@
+
+
Select the security groups to create the container in.
+
+
+
+
+
+
+
+
+ |
+ Name |
+ Description |
+ |
+
+
+
+
+
+
+ {$ ::trCtrl.helpText.noneAllocText $}
+
+ |
+
+
+
+
+ |
+ {$ row.name $} |
+ {$ row.description $} |
+
+
+
+
+
+
+ |
+
+
+ |
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+ Name |
+ Description |
+ |
+
+
+
+
+
+
+ {$ ::trCtrl.helpText.noneAvailText $}
+
+ |
+
+
+
+
+ |
+ {$ row.name$} |
+ {$ row.description $} |
+
+
+
+
+
+
+ |
+
+
+
+ |
+
+
+
+
+
+
+
+
+
diff --git a/zun_ui/static/dashboard/container/containers/actions/workflow/workflow.service.js b/zun_ui/static/dashboard/container/containers/actions/workflow/workflow.service.js
index 1ab1688..0284311 100644
--- a/zun_ui/static/dashboard/container/containers/actions/workflow/workflow.service.js
+++ b/zun_ui/static/dashboard/container/containers/actions/workflow/workflow.service.js
@@ -240,6 +240,29 @@
}
]
},
+ {
+ "title": gettext("Security Groups"),
+ /* eslint-disable max-len */
+ help: basePath + "containers/actions/workflow/security-groups/security-groups.help.html",
+ /* eslint-disable max-len */
+ type: "section",
+ htmlClass: "row",
+ items: [
+ {
+ type: "section",
+ htmlClass: "col-xs-12",
+ items: [
+ {
+ type: "template",
+ /* eslint-disable max-len */
+ templateUrl: basePath + "containers/actions/workflow/security-groups/security-groups.html"
+ /* eslint-disable max-len */
+ }
+ ]
+ }
+ ],
+ condition: action === "update"
+ },
{
"title": gettext("Miscellaneous"),
help: basePath + "containers/actions/workflow/misc.help.html",
@@ -304,6 +327,8 @@
memory: "",
restart_policy: "",
restart_policy_max_retry: "",
+ // security groups
+ security_groups: [],
// misc
workdir: "",
environment: "",
diff --git a/zun_ui/static/dashboard/container/containers/containers.module.js b/zun_ui/static/dashboard/container/containers/containers.module.js
index 52d7ee8..4039a92 100644
--- a/zun_ui/static/dashboard/container/containers/containers.module.js
+++ b/zun_ui/static/dashboard/container/containers/containers.module.js
@@ -133,6 +133,7 @@
'memory': {label: gettext('Memory'), filters: ['noValue'] },
'name': {label: gettext('Name'), filters: ['noName'] },
'ports': {label: gettext('Ports'), filters: ['noValue', 'json'] },
+ 'security_groups': {label: gettext('Security Groups'), filters: ['noValue', 'json'] },
'restart_policy': {label: gettext('Restart Policy'), filters: ['noValue', 'json'] },
'status': {label: gettext('Status'), filters: ['noValue'] },
'status_detail': {label: gettext('Status Detail'), filters: ['noValue'] },
diff --git a/zun_ui/static/dashboard/container/containers/details/drawer.html b/zun_ui/static/dashboard/container/containers/details/drawer.html
index a1a2f75..a052add 100644
--- a/zun_ui/static/dashboard/container/containers/details/drawer.html
+++ b/zun_ui/static/dashboard/container/containers/details/drawer.html
@@ -3,5 +3,5 @@
item="item"
property-groups="[['id', 'image'],
['status', 'task_state'],
- ['command', 'ports']]">
+ ['command', 'ports', 'security_groups']]">
\ No newline at end of file
diff --git a/zun_ui/static/dashboard/container/containers/details/overview.html b/zun_ui/static/dashboard/container/containers/details/overview.html
index e58dee0..f904c14 100644
--- a/zun_ui/static/dashboard/container/containers/details/overview.html
+++ b/zun_ui/static/dashboard/container/containers/details/overview.html
@@ -20,7 +20,7 @@
item="ctrl.container"
property-groups="[['image', 'image_driver', 'image_pull_policy',
'cpu', 'memory', 'restart_policy',
- 'hostname', 'addresses', 'ports']]">
+ 'hostname', 'addresses', 'ports', 'security_groups']]">