Add Security Groups steps into creation dialog

To specify security groups options when create container,
this patch adds Security Groups step into the creation dialog.

The Security Groups step is not shown in update dialog.

Also, security group infomations are shown in table view
and details view.

Change-Id: Ic67baa367eb1210dde8e6d7610fe2c5332631aa7
Implements: bluepring add-security-groups
This commit is contained in:
Shu Muto 2017-07-25 12:03:45 +09:00
parent 8c9516a9a2
commit edfb81d7cf
10 changed files with 267 additions and 6 deletions

View File

@ -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":

View File

@ -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;
}
}
})();

View File

@ -0,0 +1,22 @@
<table st-table="row.security_group_rules" class="table table-condensed table-rsp security-group-details">
<thead>
<tr>
<th st-sort="direction" st-sort-default translate>Direction</th>
<th st-sort="ethertype" translate>Ether Type</th>
<th st-sort="protocol" translate>Protocol</th>
<th st-sort="port_range_min" translate>Min Port</th>
<th st-sort="port_range_max" translate>Max Port</th>
<th st-sort="remote_ip_prefix" translate>Remote</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="d in row.security_group_rules">
<td>{$ d.direction | noValue $}</td>
<td>{$ d.ethertype | noValue $}</td>
<td>{$ d.protocol | noValue $}</td>
<td>{$ d.port_range_min | noValue $}</td>
<td>{$ d.port_range_max | noValue $}</td>
<td>{$ d.remote_ip_prefix | noValue $}</td>
</tr>
</tbody>
</table>

View File

@ -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);
}
}
})();

View File

@ -0,0 +1,4 @@
<dl>
<dt translate>Security Groups</dt>
<dd translate>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 <b>Network | Security Groups</b> view, then find the security group and click <b>Manage Rules</b>.</dd>
</dl>

View File

@ -0,0 +1,106 @@
<div ng-controller="horizon.dashboard.container.containers.workflow.security-group as ctrl">
<p class="step-description" translate>Select the security groups to create the container in.</p>
<transfer-table tr-model="ctrl.tableData"
help-text="ctrl.tableHelp"
limits="ctrl.tableLimits">
<!-- Security Groups Allocated -->
<allocated>
<table st-table="ctrl.tableData.displayedAllocated"
st-safe-src="ctrl.tableData.allocated" hz-table
class="table table-striped table-rsp table-detail">
<thead>
<tr>
<th class="expander"></th>
<th st-sort="name" st-sort-default class="rsp-p1" translate>Name</th>
<th st-sort="description" class="rsp-p2" translate>Description</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-if="ctrl.tableData.allocated.length === 0">
<td colspan="8">
<div class="no-rows-help">
{$ ::trCtrl.helpText.noneAllocText $}
</div>
</td>
</tr>
<tr ng-repeat-start="row in ctrl.tableData.displayedAllocated track by row.id">
<td class="expander">
<span class="fa fa-chevron-right" hz-expand-detail
title="{$ ::trCtrl.helpText.expandDetailsText $}"></span>
</td>
<td class="rsp-p1 word-break">{$ row.name $}</td>
<td class="rsp-p2">{$ row.description $}</td>
<td class="actions_column">
<action-list>
<action action-classes="'btn btn-default'"
callback="trCtrl.deallocate" item="row">
<span class="fa fa-arrow-down"></span>
</action>
</action-list>
</td>
</tr>
<tr ng-repeat-end class="detail-row">
<td></td>
<td class="detail" colspan="3" ng-include="ctrl.tableDetails">
</td>
</tr>
</tbody>
</table>
</allocated>
<!-- Security Groups Available -->
<available>
<hz-magic-search-context filter-facets="ctrl.filterFacets">
<hz-magic-search-bar></hz-magic-search-bar>
<table st-table="ctrl.tableData.displayedAvailable"
st-magic-search
st-safe-src="ctrl.tableData.available"
hz-table class="table table-striped table-rsp table-detail">
<thead>
<tr>
<th class="expander"></th>
<th st-sort="name" st-sort-default class="rsp-p1" translate>Name</th>
<th st-sort="description" class="rsp-p1" translate>Description</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-if="trCtrl.numAvailable() === 0">
<td colspan="8">
<div class="no-rows-help">
{$ ::trCtrl.helpText.noneAvailText $}
</div>
</td>
</tr>
<tr ng-repeat-start="row in ctrl.tableData.displayedAvailable track by row.id"
ng-if="!trCtrl.allocatedIds[row.id]">
<td class="expander">
<span class="fa fa-chevron-right" hz-expand-detail
title="{$ ::trCtrl.helpText.expandDetailsText $}"></span>
</td>
<td class="rsp-p1 word-break">{$ row.name$}</td>
<td class="rsp-p1">{$ row.description $}</td>
<td class="actions_column">
<action-list>
<action action-classes="'btn btn-default'"
callback="trCtrl.allocate" item="row">
<span class="fa fa-arrow-up"></span>
</action>
</action-list>
</td>
</tr>
<tr ng-repeat-end class="detail-row" ng-if="!trCtrl.allocatedIds[row.id]">
<td class="detail" colspan="4" ng-include="ctrl.tableDetails">
</td>
</tr>
</tbody>
</table>
</hz-magic-search-context>
</available>
</transfer-table> <!-- End Security Groups Transfer Table -->
</div> <!-- End Controller -->

View File

@ -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: "",

View File

@ -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'] },

View File

@ -3,5 +3,5 @@
item="item"
property-groups="[['id', 'image'],
['status', 'task_state'],
['command', 'ports']]">
['command', 'ports', 'security_groups']]">
</hz-resource-property-list>

View File

@ -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']]">
</hz-resource-property-list>
</div>
</div>