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 @@ + + + + + + + + + + + + + + + + + + + + + +
DirectionEther TypeProtocolMin PortMax PortRemote
{$ 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.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescription
+
+ {$ ::trCtrl.helpText.noneAllocText $} +
+
+ + {$ row.name $}{$ row.description $} + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescription
+
+ {$ ::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']]">