[Launch Instance Fix] Split Security & Access in 2
This splits the single Security and Access step so that the two panes in that step (Security Groups / Keypairs) have their own steps in the wizard, thus making everything much more consistent. This also now uses the Controller As syntax which is considered to be a best practice. Change-Id: Ib1d79ce8019e5361faccf77360989c38ce1cab2c Co-Authored-By: Travis Tripp <travis.tripp@hp.com> Closes-Bug: 1435636
This commit is contained in:
parent
c502d69290
commit
61d2fcd7e6
@ -32,7 +32,8 @@ ADD_JS_FILES = [
|
||||
LAUNCH_INST + 'source/source.js',
|
||||
LAUNCH_INST + 'flavor/flavor.js',
|
||||
LAUNCH_INST + 'network/network.js',
|
||||
LAUNCH_INST + 'access-and-security/access-and-security.js',
|
||||
LAUNCH_INST + 'security-groups/security-groups.js',
|
||||
LAUNCH_INST + 'keypair/keypair.js',
|
||||
LAUNCH_INST + 'configuration/configuration.js',
|
||||
]
|
||||
|
||||
@ -43,6 +44,7 @@ ADD_JS_SPEC_FILES = [
|
||||
LAUNCH_INST + 'source/source.spec.js',
|
||||
LAUNCH_INST + 'flavor/flavor.spec.js',
|
||||
LAUNCH_INST + 'network/network.spec.js',
|
||||
LAUNCH_INST + 'access-and-security/access-and-security.spec.js',
|
||||
LAUNCH_INST + 'security-groups/security-groups.spec.js',
|
||||
LAUNCH_INST + 'keypair/keypair.spec.js',
|
||||
LAUNCH_INST + 'configuration/configuration.spec.js',
|
||||
]
|
||||
|
@ -1,4 +0,0 @@
|
||||
<div ng-controller="LaunchInstanceAccessAndSecurityHelpCtrl as accessSecHelpCtrl">
|
||||
<h1>{$ ::accessSecHelpCtrl.title $}</h1>
|
||||
<p ng-repeat="paragraph in accessSecHelpCtrl.paragraphs" ng-bind-html="::paragraph"></p>
|
||||
</div>
|
@ -1,261 +0,0 @@
|
||||
<div ng-controller="LaunchInstanceAccessAndSecurityCtrl">
|
||||
<h1>{$ ::label.title $}</h1>
|
||||
|
||||
<div class="content">
|
||||
<div class="subtitle">{$ ::label.subtitle $}</div>
|
||||
|
||||
<div role="tabpanel">
|
||||
<ul id="tabs" class="nav nav-tabs" data-tabs="tabs">
|
||||
<li role="presentation" class="active">
|
||||
<a href="#security_groups" data-toggle="tab">{$ ::label.security_groups $}</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="#key_pairs" data-toggle="tab">{$ ::label.key_pairs $}</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div id="li-secgroup-keypairs" class="tab-content">
|
||||
|
||||
<!-- Security Groups Tab Content -->
|
||||
<div role="tabpanel" class="tab-pane active" id="security_groups">
|
||||
|
||||
<transfer-table tr-model="secGroupTableData"
|
||||
help-text="secGroupTableHelp"
|
||||
limits="secGroupTableLimits">
|
||||
|
||||
<!-- Security Groups Allocated -->
|
||||
<allocated>
|
||||
<table st-table="secGroupTableData.displayedAllocated"
|
||||
st-safe-src="secGroupTableData.allocated" hz-table
|
||||
class="table-striped table-rsp table-detail modern">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="expander"></th>
|
||||
<th class="rsp-p1">{$ ::label.name $}</th>
|
||||
<th class="rsp-p2">{$ ::label.description $}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-if="secGroupTableData.allocated.length === 0">
|
||||
<td colspan="8">
|
||||
<div class="no-rows-help">
|
||||
{$ ::trCtrl.helpText.noneAllocText $}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-repeat-start="row in secGroupTableData.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">{$ row.name $}</td>
|
||||
<td class="rsp-p2">{$ row.description $}</td>
|
||||
<td class="action-col">
|
||||
<action-list>
|
||||
<action action-classes="'btn btn-sm btn-default'"
|
||||
callback="trCtrl.deallocate" item="row">
|
||||
<span class="fa fa-minus"></span>
|
||||
</action>
|
||||
</action-list>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-repeat-end class="detail-row">
|
||||
<td></td>
|
||||
<td class="detail" colspan="3" ng-include="secGroupTableDetails">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</allocated>
|
||||
|
||||
<!-- Security Groups Available -->
|
||||
<available>
|
||||
<table st-table="secGroupTableData.displayedAvailable"
|
||||
st-safe-src="secGroupTableData.available"
|
||||
hz-table class="table-striped table-rsp table-detail modern">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="search-header" colspan="7">
|
||||
<search-bar group-classes="input-group-sm"
|
||||
icon-classes="fa-search">
|
||||
</search-bar>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="expander"></th>
|
||||
<th st-sort="name" st-sort-default class="rsp-p1">{$ ::label.name $}</th>
|
||||
<th st-sort="description" class="rsp-p1">{$ ::label.description $}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-if="trCtrl.numDisplayedAvailable() === 0">
|
||||
<td colspan="8">
|
||||
<div class="no-rows-help">
|
||||
{$ ::trCtrl.helpText.noneAvailText $}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-repeat-start="row in secGroupTableData.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">{$ row.name$}</td>
|
||||
<td class="rsp-p1">{$ row.description $}</td>
|
||||
<td class="action-col">
|
||||
<action-list button-tooltip="row.warningMessage"
|
||||
bt-model="trCtrl.tooltipModel"
|
||||
bt-disabled="!row.disabled"
|
||||
warning-classes="'invalid'">
|
||||
<notifications>
|
||||
<span class="fa fa-exclamation-circle invalid"
|
||||
ng-show="row.disabled"></span>
|
||||
</notifications>
|
||||
<action action-classes="'btn btn-sm btn-default'"
|
||||
callback="trCtrl.allocate" item="row"
|
||||
disabled="row.disabled">
|
||||
<span class="fa fa-plus"></span>
|
||||
</action>
|
||||
</action-list>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-repeat-end class="detail-row" ng-if="!trCtrl.allocatedIds[row.id]">
|
||||
<td></td>
|
||||
<td class="detail" colspan="3" ng-include="secGroupTableDetails">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</available>
|
||||
|
||||
</transfer-table> <!-- End Security Groups Transfer Table -->
|
||||
|
||||
</div> <!-- End Security Groups Tab Content -->
|
||||
|
||||
<!-- Key Pairs Tab Content -->
|
||||
<div role="tabpanel" class="tab-pane" id="key_pairs">
|
||||
|
||||
<transfer-table tr-model="keyPairTableData"
|
||||
help-text="keyPairTableHelp"
|
||||
limits="keyPairTableLimits">
|
||||
|
||||
<!-- Key Pairs Allocated-->
|
||||
<allocated>
|
||||
<table st-table="keyPairTableData.displayedAllocated"
|
||||
st-safe-src="keyPairTableData.allocated" hz-table
|
||||
class="table-striped table-rsp table-detail modern">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="expander"></th>
|
||||
<th class="rsp-p1">{$ ::label.name $}</th>
|
||||
<th class="rsp-p2">{$ ::keyPairTableLabels.fingerprint $}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-if="keyPairTableData.allocated.length === 0">
|
||||
<td colspan="8">
|
||||
<div class="no-rows-help">
|
||||
{$ ::trCtrl.helpText.noneAllocText $}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-repeat-start="row in keyPairTableData.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">{$ row.name $}</td>
|
||||
<td class="rsp-p2">{$ row.fingerprint $}</td>
|
||||
<td class="action-col">
|
||||
<action-list>
|
||||
<action action-classes="'btn btn-sm btn-default'"
|
||||
callback="trCtrl.deallocate" item="row">
|
||||
<span class="fa fa-minus"></span>
|
||||
</action>
|
||||
</action-list>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-repeat-end class="detail-row">
|
||||
<td></td>
|
||||
<td class="detail" colspan="3">
|
||||
<dl class="dl-horizontal" ng-include="keyPairTableDetails">
|
||||
</dl>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</allocated>
|
||||
|
||||
<!-- Key Pairs Available -->
|
||||
<available>
|
||||
<table st-table="keyPairTableData.displayedAvailable"
|
||||
st-safe-src="keyPairTableData.available"
|
||||
hz-table class="table-striped table-rsp table-detail modern">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="search-header" colspan="7">
|
||||
<search-bar group-classes="input-group-sm"
|
||||
icon-classes="fa-search">
|
||||
</search-bar>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="expander"></th>
|
||||
<th st-sort="name" st-sort-default class="rsp-p1">{$ ::label.name $}</th>
|
||||
<th st-sort="fingerprint" class="rsp-p1">{$ ::keyPairTableLabels.fingerprint $}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-if="trCtrl.numDisplayedAvailable() === 0">
|
||||
<td colspan="8">
|
||||
<div class="no-rows-help">
|
||||
{$ ::trCtrl.helpText.noneAvailText $}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-repeat-start="row in keyPairTableData.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">{$ row.name$}</td>
|
||||
<td class="rsp-p1">{$ row.fingerprint $}</td>
|
||||
<td class="action-col">
|
||||
<action-list button-tooltip="row.warningMessage"
|
||||
bt-model="trCtrl.tooltipModel"
|
||||
bt-disabled="!row.disabled"
|
||||
warning-classes="'invalid'">
|
||||
<notifications>
|
||||
<span class="fa fa-exclamation-circle invalid"
|
||||
ng-show="row.disabled"></span>
|
||||
</notifications>
|
||||
<action action-classes="'btn btn-sm btn-default'"
|
||||
callback="trCtrl.allocate" item="row"
|
||||
disabled="row.disabled">
|
||||
<span class="fa fa-plus"></span>
|
||||
</action>
|
||||
</action-list>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-repeat-end class="detail-row" ng-if="!trCtrl.allocatedIds[row.id]">
|
||||
<td></td>
|
||||
<td class="detail" colspan="3" ng-include="keyPairTableDetails">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</available>
|
||||
|
||||
</transfer-table> <!-- End Key Pairs Table -->
|
||||
|
||||
</div> <!-- End Key Pairs Tab Content -->
|
||||
</div> <!-- End Tab Content -->
|
||||
</div> <!-- End Tab Panel-->
|
||||
</div> <!-- End Content -->
|
||||
</div> <!-- End Controller -->
|
@ -1,113 +0,0 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('hz.dashboard.launch-instance');
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name hz.dashboard.launch-instance.LaunchInstanceAccessAndSecurityCtrl
|
||||
* @description
|
||||
* Allows selection of security groups and key pairs.
|
||||
*/
|
||||
module.controller('LaunchInstanceAccessAndSecurityCtrl', [
|
||||
'$scope',
|
||||
function ($scope) {
|
||||
$scope.label = {
|
||||
title: gettext('Access and Security'),
|
||||
subtitle: gettext('Select the security groups and a key pair.'),
|
||||
security_groups: gettext('Security Groups'),
|
||||
key_pairs: gettext('Key Pairs'),
|
||||
name: gettext('Name'),
|
||||
description: gettext('Description')
|
||||
};
|
||||
|
||||
$scope.secGroupTableLabels = {
|
||||
direction: gettext('Direction'),
|
||||
ethertype: gettext('Ether Type'),
|
||||
protocol: gettext('Protocol'),
|
||||
port_range_min: gettext('Min Port'),
|
||||
port_range_max: gettext('Max Port'),
|
||||
remote_ip_prefix: gettext('Remote')
|
||||
};
|
||||
|
||||
$scope.secGroupTableData = {
|
||||
available: $scope.model.securityGroups,
|
||||
allocated: $scope.model.newInstanceSpec.security_groups,
|
||||
displayedAvailable: [],
|
||||
displayedAllocated: []
|
||||
};
|
||||
|
||||
$scope.secGroupTableDetails =
|
||||
'/static/dashboard/launch-instance/access-and-security/security-group-details.html';
|
||||
|
||||
$scope.secGroupTableHelp = {
|
||||
noneAllocText: gettext('Select one or more security groups from the available groups below.'),
|
||||
availHelpText: gettext('Select one or more')
|
||||
};
|
||||
|
||||
$scope.secGroupTableLimits = {
|
||||
maxAllocation: -1
|
||||
};
|
||||
|
||||
$scope.keyPairTableLabels = {
|
||||
fingerprint: gettext('Fingerprint'),
|
||||
public_key: gettext('Public Key')
|
||||
};
|
||||
|
||||
$scope.keyPairTableData = {
|
||||
available: $scope.model.keypairs,
|
||||
allocated: $scope.model.newInstanceSpec.key_pair,
|
||||
displayedAvailable: [],
|
||||
displayedAllocated: []
|
||||
};
|
||||
|
||||
$scope.keyPairTableDetails =
|
||||
'/static/dashboard/launch-instance/access-and-security/keypair-details.html';
|
||||
|
||||
$scope.keyPairTableHelp = {
|
||||
noneAllocText: gettext('Select a key pair from the available key pairs below.')
|
||||
};
|
||||
|
||||
$scope.keyPairTableLimits = {
|
||||
maxAllocation: 1
|
||||
};
|
||||
|
||||
}
|
||||
]);
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name hz.dashboard.launch-instance.LaunchInstanceAccessAndSecurityHelpCtrl
|
||||
* @description
|
||||
* Provide help for selection of security groups and key pairs.
|
||||
*/
|
||||
module.controller('LaunchInstanceAccessAndSecurityHelpCtrl', [
|
||||
'$scope',
|
||||
function ($scope) {
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.title = gettext('Access and Security Help');
|
||||
|
||||
var genKeyPairsMap = { genKeyPairCmd: 'ssh-keygen' };
|
||||
var genKeyPairsText = gettext('There are two ways to generate a key pair. From a Linux system, generate the key pair with the <samp>%(genKeyPairCmd)s</samp> command:');
|
||||
|
||||
var keyPathsMap = { privateKeyPath: 'cloud.key', publicKeyPath: 'cloud.key.pub' };
|
||||
var keyPathText = gettext('This command generates a pair of keys: a private key (%(privateKeyPath)s) and a public key (%(publicKeyPath)s).');
|
||||
|
||||
var windowsCmdMap = { authorizeKeysFile: '.ssh/authorized_keys' };
|
||||
var windowsCmd = gettext('From a Windows system, you can use PuTTYGen to create private/public keys. Use the PuTTY Key Generator to create and save the keys, then copy the public key in the red highlighted box to your <samp>%(authorizeKeysFile)s</samp> file.');
|
||||
|
||||
ctrl.paragraphs = [
|
||||
gettext('Security groups define a set of IP filter rules that determine how network traffic flows to and from an instance. Users can add additional rules to an existing security group to further define the access options for an instance. To create additional rules, go to the <b>Compute | Access & Security</b> view, then find the security group and click <b>Manage Rules</b>.'),
|
||||
gettext('Security groups are project-specific and cannot be shared across projects.'),
|
||||
gettext('If a security group is not associated with an instance before it is launched, then you will have very limited access to the instance after it is deployed. You will only be able to access the instance from a VNC console.'),
|
||||
gettext('The key pair allows you to SSH into the instance.'),
|
||||
interpolate(genKeyPairsText, genKeyPairsMap, true),
|
||||
'<samp>ssh-keygen -t rsa -f cloud.key</samp>',
|
||||
interpolate(keyPathText, keyPathsMap, true),
|
||||
interpolate(windowsCmd, windowsCmdMap, true)
|
||||
];
|
||||
}
|
||||
]);
|
||||
})();
|
@ -1,28 +0,0 @@
|
||||
[ng-controller="LaunchInstanceAccessAndSecurityCtrl"] {
|
||||
|
||||
dl.key-pair-details {
|
||||
|
||||
dt {
|
||||
width: 15%;
|
||||
}
|
||||
dd {
|
||||
width: 85%;
|
||||
margin-left: 15%;
|
||||
padding-right: 25px;
|
||||
|
||||
pre {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-rsp.security-group-details {
|
||||
background: none;
|
||||
|
||||
td {
|
||||
background: none !important;
|
||||
padding: 15px !important;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
<table class="table-rsp modern security-group-details">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{$ secGroupTableLabels.direction $}</th>
|
||||
<th>{$ secGroupTableLabels.ethertype $}</th>
|
||||
<th>{$ secGroupTableLabels.protocol $}</th>
|
||||
<th>{$ secGroupTableLabels.port_range_min $}</th>
|
||||
<th>{$ secGroupTableLabels.port_range_max $}</th>
|
||||
<th>{$ secGroupTableLabels.remote_ip_prefix $}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr ng-repeat="x in row.security_group_rules | orderBy : 'direction'">
|
||||
<td>{$ x.direction || '-' $}</td>
|
||||
<td>{$ x.ethertype || '-' $}</td>
|
||||
<td>{$ x.protocol || '-' $}</td>
|
||||
<td>{$ x.port_range_min || '-' $}</td>
|
||||
<td>{$ x.port_range_max || '-' $}</td>
|
||||
<td>{$ x.remote_ip_prefix || '-' $}</td>
|
||||
</tr>
|
||||
</table>
|
@ -0,0 +1,6 @@
|
||||
<dl class="dl-horizontal key-pair-details">
|
||||
<dt>{$ ctrl.tableLabels.public_key $}</dt>
|
||||
<dd>
|
||||
<pre><code>{$ row.public_key $}</code></pre>
|
||||
</dd>
|
||||
</dl>
|
@ -0,0 +1,4 @@
|
||||
<div ng-controller="LaunchInstanceKeypairHelpCtrl as helpCtrl">
|
||||
<h1>{$ ::helpCtrl.title $}</h1>
|
||||
<p ng-repeat="paragraph in ::helpCtrl.paragraphs" ng-bind-html="::paragraph"></p>
|
||||
</div>
|
@ -0,0 +1,116 @@
|
||||
<div ng-controller="LaunchInstanceKeypairCtrl as ctrl">
|
||||
<h1>{$ ::ctrl.label.title $}</h1>
|
||||
|
||||
<div class="content">
|
||||
<div class="subtitle">{$ ::ctrl.label.subtitle $}</div>
|
||||
|
||||
<transfer-table tr-model="ctrl.tableData"
|
||||
help-text="ctrl.tableHelp"
|
||||
limits="ctrl.tableLimits">
|
||||
|
||||
<!-- Key Pairs Allocated-->
|
||||
<allocated>
|
||||
<table st-table="ctrl.tableData.displayedAllocated"
|
||||
st-safe-src="ctrl.tableData.allocated" hz-table
|
||||
class="table-striped table-rsp table-detail modern">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="expander"></th>
|
||||
<th class="rsp-p1">{$ ::ctrl.label.name $}</th>
|
||||
<th class="rsp-p2">{$ ::ctrl.tableLabels.fingerprint $}</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">{$ row.name $}</td>
|
||||
<td class="rsp-p2">{$ row.fingerprint $}</td>
|
||||
<td class="action-col">
|
||||
<action-list>
|
||||
<action action-classes="'btn btn-sm btn-default'"
|
||||
callback="trCtrl.deallocate" item="row">
|
||||
<span class="fa fa-minus"></span>
|
||||
</action>
|
||||
</action-list>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-repeat-end class="detail-row">
|
||||
<td></td>
|
||||
<td class="detail" colspan="3">
|
||||
<dl class="dl-horizontal" ng-include="ctrl.tableDetails">
|
||||
</dl>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</allocated>
|
||||
|
||||
<!-- Key Pairs Available -->
|
||||
<available>
|
||||
<table st-table="ctrl.tableData.displayedAvailable"
|
||||
st-safe-src="ctrl.tableData.available"
|
||||
hz-table class="table-striped table-rsp table-detail modern">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="search-header" colspan="7">
|
||||
<search-bar group-classes="input-group-sm"
|
||||
icon-classes="fa-search">
|
||||
</search-bar>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="expander"></th>
|
||||
<th st-sort="name" st-sort-default class="rsp-p1">{$ ::ctrl.label.name $}</th>
|
||||
<th st-sort="fingerprint" class="rsp-p1">{$ ::ctrl.tableLabels.fingerprint $}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-if="trCtrl.numDisplayedAvailable() === 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">{$ row.name$}</td>
|
||||
<td class="rsp-p1">{$ row.fingerprint $}</td>
|
||||
<td class="action-col">
|
||||
<action-list>
|
||||
<action action-classes="'btn btn-sm btn-default'"
|
||||
callback="trCtrl.allocate" item="row">
|
||||
<span class="fa fa-plus"></span>
|
||||
</action>
|
||||
</action-list>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-repeat-end class="detail-row" ng-if="!trCtrl.allocatedIds[row.id]">
|
||||
<td></td>
|
||||
<td class="detail" colspan="3" ng-include="ctrl.tableDetails">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</available>
|
||||
|
||||
</transfer-table> <!-- End Key Pairs Table -->
|
||||
|
||||
</div> <!-- End Content -->
|
||||
</div> <!-- End Controller -->
|
@ -0,0 +1,79 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('hz.dashboard.launch-instance');
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name hz.dashboard.launch-instance.LaunchInstanceKeypairCtrl
|
||||
* @description
|
||||
* Allows selection of key pairs.
|
||||
*/
|
||||
module.controller('LaunchInstanceKeypairCtrl', [
|
||||
'launchInstanceModel',
|
||||
function (launchInstanceModel) {
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.label = {
|
||||
title: gettext('Key Pair'),
|
||||
subtitle: gettext('Select a key pair.'),
|
||||
name: gettext('Name'),
|
||||
description: gettext('Description')
|
||||
};
|
||||
|
||||
ctrl.tableLabels = {
|
||||
fingerprint: gettext('Fingerprint'),
|
||||
public_key: gettext('Public Key')
|
||||
};
|
||||
|
||||
ctrl.tableData = {
|
||||
available: launchInstanceModel.keypairs,
|
||||
allocated: launchInstanceModel.newInstanceSpec.key_pair,
|
||||
displayedAvailable: [],
|
||||
displayedAllocated: []
|
||||
};
|
||||
|
||||
ctrl.tableDetails =
|
||||
'/static/dashboard/launch-instance/keypair/keypair-details.html';
|
||||
|
||||
ctrl.tableHelp = {
|
||||
noneAllocText: gettext('Select a key pair from the available key pairs below.')
|
||||
};
|
||||
|
||||
ctrl.tableLimits = {
|
||||
maxAllocation: 1
|
||||
};
|
||||
|
||||
}
|
||||
]);
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name hz.dashboard.launch-instance.LaunchInstanceKeypairHelpCtrl
|
||||
* @description
|
||||
* Provide help for selection of security groups and key pairs.
|
||||
*/
|
||||
module.controller('LaunchInstanceKeypairHelpCtrl', [function () {
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.title = gettext('Key Pair Help');
|
||||
|
||||
var genKeyPairsMap = { genKeyPairCmd: 'ssh-keygen' };
|
||||
var genKeyPairsText = gettext('There are two ways to generate a key pair. From a Linux system, generate the key pair with the <samp>%(genKeyPairCmd)s</samp> command:');
|
||||
|
||||
var keyPathsMap = { privateKeyPath: 'cloud.key', publicKeyPath: 'cloud.key.pub' };
|
||||
var keyPathText = gettext('This command generates a pair of keys: a private key (%(privateKeyPath)s) and a public key (%(publicKeyPath)s).');
|
||||
|
||||
var windowsCmdMap = { authorizeKeysFile: '.ssh/authorized_keys' };
|
||||
var windowsCmd = gettext('From a Windows system, you can use PuTTYGen to create private/public keys. Use the PuTTY Key Generator to create and save the keys, then copy the public key in the red highlighted box to your <samp>%(authorizeKeysFile)s</samp> file.');
|
||||
|
||||
ctrl.paragraphs = [
|
||||
gettext('The key pair allows you to SSH into the instance.'),
|
||||
interpolate(genKeyPairsText, genKeyPairsMap, true),
|
||||
'<samp>ssh-keygen -t rsa -f cloud.key</samp>',
|
||||
interpolate(keyPathText, keyPathsMap, true),
|
||||
interpolate(windowsCmd, windowsCmdMap, true)
|
||||
]; }
|
||||
]);
|
||||
})();
|
@ -0,0 +1,18 @@
|
||||
[ng-controller="LaunchInstanceKeypairCtrl as ctrl"] {
|
||||
|
||||
dl.key-pair-details {
|
||||
|
||||
dt {
|
||||
width: 15%;
|
||||
}
|
||||
dd {
|
||||
width: 85%;
|
||||
margin-left: 15%;
|
||||
padding-right: 25px;
|
||||
|
||||
pre {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('Launch Instance Access and Security Step', function() {
|
||||
describe('Launch Instance Keypair Step', function() {
|
||||
});
|
||||
|
||||
})();
|
@ -28,11 +28,17 @@
|
||||
formName: 'launchInstanceNetworkForm'
|
||||
},
|
||||
{
|
||||
title: gettext('Access and Security'),
|
||||
templateUrl: path + 'launch-instance/access-and-security/access-and-security.html',
|
||||
helpUrl: path + 'launch-instance/access-and-security/access-and-security.help.html',
|
||||
title: gettext('Security Groups'),
|
||||
templateUrl: path + 'launch-instance/security-groups/security-groups.html',
|
||||
helpUrl: path + 'launch-instance/security-groups/security-groups.help.html',
|
||||
formName: 'launchInstanceAccessAndSecurityForm'
|
||||
},
|
||||
{
|
||||
title: gettext('Key Pair'),
|
||||
templateUrl: path + 'launch-instance/keypair/keypair.html',
|
||||
helpUrl: path + 'launch-instance/keypair/keypair.help.html',
|
||||
formName: 'launchInstanceKeypairForm'
|
||||
},
|
||||
{
|
||||
title: gettext('Configuration'),
|
||||
templateUrl: path + 'launch-instance/configuration/configuration.html',
|
||||
|
@ -1,5 +1,6 @@
|
||||
@import "source/source";
|
||||
@import "flavor/flavor";
|
||||
@import "network/network";
|
||||
@import "access-and-security/access-and-security";
|
||||
@import "keypair/keypair";
|
||||
@import "security-groups/security-groups";
|
||||
@import "configuration/configuration";
|
||||
|
@ -0,0 +1,20 @@
|
||||
<table st-table="row.security_group_rules" class="table-rsp modern security-group-details">
|
||||
<thead>
|
||||
<tr>
|
||||
<th st-sort="direction" st-sort-default>{$ ctrl.tableLabels.direction $}</th>
|
||||
<th st-sort="ethertype">{$ ctrl.tableLabels.ethertype $}</th>
|
||||
<th st-sort="protocol">{$ ctrl.tableLabels.protocol $}</th>
|
||||
<th st-sort="port_range_min">{$ ctrl.tableLabels.port_range_min $}</th>
|
||||
<th st-sort="port_range_max">{$ ctrl.tableLabels.port_range_max $}</th>
|
||||
<th st-sort="remote_ip_prefix">{$ ctrl.tableLabels.remote_ip_prefix $}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr ng-repeat="d in row.security_group_rules">
|
||||
<td>{$ d.direction || '-' $}</td>
|
||||
<td>{$ d.ethertype || '-' $}</td>
|
||||
<td>{$ d.protocol || '-' $}</td>
|
||||
<td>{$ d.port_range_min || '-' $}</td>
|
||||
<td>{$ d.port_range_max || '-' $}</td>
|
||||
<td>{$ d.remote_ip_prefix || '-' $}</td>
|
||||
</tr>
|
||||
</table>
|
@ -0,0 +1,4 @@
|
||||
<div ng-controller="LaunchInstanceSecurityGroupsHelpCtrl as helpCtrl">
|
||||
<h1>{$ ::helpCtrl.title $}</h1>
|
||||
<p ng-repeat="paragraph in ::helpCtrl.paragraphs" ng-bind-html="::paragraph"></p>
|
||||
</div>
|
@ -0,0 +1,114 @@
|
||||
<div ng-controller="LaunchInstanceSecurityGroupsCtrl as ctrl">
|
||||
<h1>{$ ::ctrl.label.title $}</h1>
|
||||
|
||||
<div class="content">
|
||||
<div class="subtitle">{$ ::ctrl.label.subtitle $}</div>
|
||||
|
||||
<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-striped table-rsp table-detail modern">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="expander"></th>
|
||||
<th st-sort="name" st-sort-default class="rsp-p1">{$ ::ctrl.label.name $}</th>
|
||||
<th st-sort="description" class="rsp-p2">{$ ::ctrl.label.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">{$ row.name $}</td>
|
||||
<td class="rsp-p2">{$ row.description $}</td>
|
||||
<td class="action-col">
|
||||
<action-list>
|
||||
<action action-classes="'btn btn-sm btn-default'"
|
||||
callback="trCtrl.deallocate" item="row">
|
||||
<span class="fa fa-minus"></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>
|
||||
<table st-table="ctrl.tableData.displayedAvailable"
|
||||
st-safe-src="ctrl.tableData.available"
|
||||
hz-table class="table-striped table-rsp table-detail modern">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="search-header" colspan="7">
|
||||
<search-bar group-classes="input-group-sm"
|
||||
icon-classes="fa-search">
|
||||
</search-bar>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="expander"></th>
|
||||
<th st-sort="name" st-sort-default class="rsp-p1">{$ ::ctrl.label.name $}</th>
|
||||
<th st-sort="description" class="rsp-p1">{$ ::ctrl.label.description $}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-if="trCtrl.numDisplayedAvailable() === 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">{$ row.name$}</td>
|
||||
<td class="rsp-p1">{$ row.description $}</td>
|
||||
<td class="action-col">
|
||||
<action-list>
|
||||
<action action-classes="'btn btn-sm btn-default'"
|
||||
callback="trCtrl.allocate" item="row">
|
||||
<span class="fa fa-plus"></span>
|
||||
</action>
|
||||
</action-list>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-repeat-end class="detail-row" ng-if="!trCtrl.allocatedIds[row.id]">
|
||||
<td></td>
|
||||
<td class="detail" colspan="3" ng-include="ctrl.tableDetails">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</available>
|
||||
|
||||
</transfer-table> <!-- End Security Groups Transfer Table -->
|
||||
|
||||
</div> <!-- End Content -->
|
||||
</div> <!-- End Controller -->
|
@ -0,0 +1,73 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('hz.dashboard.launch-instance');
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name hz.dashboard.launch-instance.LaunchInstanceSecurityGroupsCtrl
|
||||
* @description
|
||||
* Allows selection of security groups.
|
||||
*/
|
||||
module.controller('LaunchInstanceSecurityGroupsCtrl', [
|
||||
'launchInstanceModel',
|
||||
function (launchInstanceModel) {
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.label = {
|
||||
title: gettext('Security Groups'),
|
||||
subtitle: gettext('Select the security groups.'),
|
||||
name: gettext('Name'),
|
||||
description: gettext('Description')
|
||||
};
|
||||
|
||||
ctrl.tableLabels = {
|
||||
direction: gettext('Direction'),
|
||||
ethertype: gettext('Ether Type'),
|
||||
protocol: gettext('Protocol'),
|
||||
port_range_min: gettext('Min Port'),
|
||||
port_range_max: gettext('Max Port'),
|
||||
remote_ip_prefix: gettext('Remote')
|
||||
};
|
||||
|
||||
ctrl.tableData = {
|
||||
available: launchInstanceModel.securityGroups,
|
||||
allocated: launchInstanceModel.newInstanceSpec.security_groups,
|
||||
displayedAvailable: [],
|
||||
displayedAllocated: []
|
||||
};
|
||||
|
||||
ctrl.tableDetails =
|
||||
'/static/dashboard/launch-instance/security-groups/security-group-details.html';
|
||||
|
||||
ctrl.tableHelp = {
|
||||
noneAllocText: gettext('Select one or more security groups from the available groups below.'),
|
||||
availHelpText: gettext('Select one or more')
|
||||
};
|
||||
|
||||
ctrl.tableLimits = {
|
||||
maxAllocation: -1
|
||||
};
|
||||
}
|
||||
]);
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name hz.dashboard.launch-instance.LaunchInstanceSecurityGroupsHelpCtrl
|
||||
* @description
|
||||
* Provide help for selection of security groups and key pairs.
|
||||
*/
|
||||
module.controller('LaunchInstanceSecurityGroupsHelpCtrl', [function () {
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.title = gettext('Security Groups Help');
|
||||
|
||||
ctrl.paragraphs = [
|
||||
gettext('Security groups define a set of IP filter rules that determine how network traffic flows to and from an instance. Users can add additional rules to an existing security group to further define the access options for an instance. To create additional rules, go to the <b>Compute | Access & Security</b> view, then find the security group and click <b>Manage Rules</b>.'),
|
||||
gettext('Security groups are project-specific and cannot be shared across projects.'),
|
||||
gettext('If a security group is not associated with an instance before it is launched, then you will have very limited access to the instance after it is deployed. You will only be able to access the instance from a VNC console.'),
|
||||
];
|
||||
}
|
||||
]);
|
||||
})();
|
@ -0,0 +1,11 @@
|
||||
[ng-controller="LaunchInstanceSecurityGroupsCtrl as ctrl"] {
|
||||
.table-rsp.security-group-details {
|
||||
background: none;
|
||||
|
||||
td {
|
||||
background: none !important;
|
||||
padding: 15px !important;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
/* jshint globalstrict: true */
|
||||
/*
|
||||
* (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* 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';
|
||||
|
||||
describe('Launch Instance Security Groups Step', function() {
|
||||
});
|
||||
|
||||
})();
|
||||
|
@ -24,7 +24,8 @@ class ServicesTests(test.JasmineTests):
|
||||
sources = [
|
||||
LAUNCH_INST + "/launch-instance.js",
|
||||
LAUNCH_INST + "/launch-instance.model.js",
|
||||
LAUNCH_INST + "/access-and-security/access-and-security.js",
|
||||
LAUNCH_INST + 'security-groups/security-groups.js',
|
||||
LAUNCH_INST + 'keypair/keypair.js',
|
||||
LAUNCH_INST + "/configuration/configuration.js",
|
||||
LAUNCH_INST + "/flavor/flavor.js",
|
||||
LAUNCH_INST + "/network/network.js",
|
||||
@ -34,7 +35,8 @@ class ServicesTests(test.JasmineTests):
|
||||
specs = [
|
||||
LAUNCH_INST + "/launch-instance.spec.js",
|
||||
LAUNCH_INST + "/launch-instance.model.spec.js",
|
||||
LAUNCH_INST + "/access-and-security/access-and-security.spec.js",
|
||||
LAUNCH_INST + 'security-groups/security-groups.spec.js',
|
||||
LAUNCH_INST + 'keypair/keypair.spec.js',
|
||||
LAUNCH_INST + "/configuration/configuration.spec.js",
|
||||
LAUNCH_INST + "/flavor/flavor.spec.js",
|
||||
LAUNCH_INST + "/network/network.spec.js",
|
||||
|
Loading…
Reference in New Issue
Block a user