summaryrefslogtreecommitdiff
path: root/openstack_dashboard/dashboards/project/static
diff options
context:
space:
mode:
Diffstat (limited to 'openstack_dashboard/dashboards/project/static')
-rw-r--r--openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.controller.js10
-rw-r--r--openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.controller.spec.js16
-rw-r--r--openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.html52
-rw-r--r--openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.spec.js2
-rw-r--r--openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/port-details.html18
-rw-r--r--openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/ports.controller.js90
-rw-r--r--openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/ports.html165
-rw-r--r--openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/ports.spec.js45
8 files changed, 212 insertions, 186 deletions
diff --git a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.controller.js b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.controller.js
index 824cb9d31..f1c23a83e 100644
--- a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.controller.js
+++ b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.controller.js
@@ -60,6 +60,7 @@
ctrl.createKeyPair = createKeyPair;
ctrl.importKeyPair = importKeyPair;
ctrl.setKeypairRequired = setKeypairRequired;
+ ctrl.setAdminPasswordChange = setAdminPasswordChange;
ctrl.tableData = {
available: launchInstanceModel.keypairs,
@@ -105,6 +106,10 @@
'OPENSTACK_HYPERVISOR_FEATURES.requires_keypair'
).then(setKeypairRequired);
+ ctrl.setAdminPassword = false;
+
+ ctrl.adminPassConfError = gettext('Passwords do not match.');
+
//////////
/**
@@ -200,6 +205,11 @@
function setKeypairRequired(setting) {
ctrl.isKeypairRequired = setting ? 1 : 0;
}
+
+ function setAdminPasswordChange() {
+ ctrl.confirmedAdminPassword = null;
+ launchInstanceModel.newInstanceSpec.admin_pass = null;
+ }
}
})();
diff --git a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.controller.spec.js b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.controller.spec.js
index 6e2e06244..c277f1470 100644
--- a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.controller.spec.js
+++ b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.controller.spec.js
@@ -19,7 +19,7 @@
describe('Launch Instance Keypair Step', function() {
describe('LaunchInstanceKeypairController', function() {
- var ctrl, q, settings;
+ var ctrl, q, settings, model;
var $uibModal = { open: angular.noop };
var toastServiceMock = {add: angular.noop};
@@ -28,6 +28,7 @@
beforeEach(function() {
settings = {
OPENSTACK_HYPERVISOR_FEATURES: {
+ can_set_password: true,
requires_keypair: false
}
};
@@ -48,7 +49,7 @@
beforeEach(inject(function($controller, $q) {
q = $q;
- var model = {
+ model = {
newInstanceSpec: {
key_pair: ['key1']
},
@@ -189,6 +190,17 @@
ctrl.setKeypairRequired(false);
expect(ctrl.isKeypairRequired).toBe(0);
});
+
+ it('defines setAdminPassword', function() {
+ expect(ctrl.setAdminPassword).toBeDefined();
+ expect(ctrl.setAdminPassword).toBe(false);
+ });
+
+ it('clears password fields when setAdminPassword is changed', function() {
+ ctrl.setAdminPasswordChange();
+ expect(ctrl.confirmedAdminPassword).toBe(null);
+ expect(model.newInstanceSpec.admin_pass).toBe(null);
+ });
});
});
diff --git a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.html b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.html
index 4271bcaac..040fa408e 100644
--- a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.html
+++ b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.html
@@ -25,4 +25,56 @@
table="ctrl">
</hz-dynamic-table>
</transfer-table> <!-- End Key Pairs Table -->
+
+ <settings-service required-settings='["OPENSTACK_HYPERVISOR_FEATURES.can_set_password"]'>
+ <div class="admin-password">
+ <div class="themable-checkbox">
+ <input ng-change="ctrl.setAdminPasswordChange()"
+ ng-model="ctrl.setAdminPassword"
+ type="checkbox"
+ id="setPassword">
+ <label for="setPassword">
+ <span translate>Set admin password</span>
+ </label>
+ </div>
+
+ <div class="container">
+ <div class="row">
+
+ <div ng-if="ctrl.setAdminPassword" ng-form="adminPasswordForm">
+ <div class="col-sm-3">
+ <div class="form-group">
+ <label class="control-label" translate for="adminPassword">Password</label>
+ <input class="form-control"
+ id="adminPassword"
+ name="adminPassword"
+ ng-model="model.newInstanceSpec.admin_pass"
+ type="password">
+ </div>
+ </div>
+
+ <div class="col-sm-3">
+ <div class="form-group"
+ ng-class="{ 'has-error':
+ adminPasswordForm['confirmPassword'].$invalid &&
+ adminPasswordForm['confirmPassword'].$dirty }">
+ <label class="control-label" translate for="confirmPassword">Confirm password</label>
+ <input id="confirmPassword"
+ name="confirmPassword"
+ class="form-control"
+ hz-password-match="model.newInstanceSpec.admin_pass"
+ ng-model="ctrl.confirmedAdminPassword"
+ type="password">
+ <span class="help-block"
+ ng-show="adminPasswordForm['confirmPassword'].$invalid &&
+ adminPasswordForm['confirmPassword'].$dirty">
+ {$ ctrl.adminPassConfError $}
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </settings-service> <!-- End Admin Password Form-->
</div> <!-- End Controller -->
diff --git a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.spec.js b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.spec.js
index 8e33169d8..21f34cd60 100644
--- a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.spec.js
+++ b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.spec.js
@@ -1041,7 +1041,7 @@
expect(finalSpec.key_pair).toBeUndefined();
});
- it('stips null properties', function() {
+ it('strips null properties', function() {
model.newInstanceSpec.useless = null;
var finalSpec = model.createInstance();
diff --git a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/port-details.html b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/port-details.html
new file mode 100644
index 000000000..ae8d82997
--- /dev/null
+++ b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/port-details.html
@@ -0,0 +1,18 @@
+<div ng-controller="LaunchInstanceNetworkPortController as ctrl">
+ <dl class="port-details dl-horizontal">
+ <dt translate>ID</dt>
+ <dd>{$ item.id $}</dd>
+ <dt translate>Project ID</dt>
+ <dd>{$ item.tenant_id $}</dd>
+ <dt translate>Network ID</dt>
+ <dd>{$ item.network_id $}</dd>
+ <dt translate>Network</dt>
+ <dd>{$ item.network_name $}</dd>
+ <dt translate>VNIC type</dt>
+ <dd>{$ item['binding:vnic_type'] | decode:ctrl.vnicTypes $}</dd>
+ <div ng-if="item['binding:host_id']">
+ <dt translate>Host ID</dt>
+ <dd>{$ item['binding:host_id'] $}</dd>
+ </div>
+ </dl>
+</div>
diff --git a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/ports.controller.js b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/ports.controller.js
index 1a4cc4dd0..462a8573e 100644
--- a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/ports.controller.js
+++ b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/ports.controller.js
@@ -27,11 +27,12 @@
.controller('LaunchInstanceNetworkPortController', LaunchInstanceNetworkPortController);
LaunchInstanceNetworkPortController.$inject = [
- '$scope',
+ 'horizon.dashboard.project.workflow.launch-instance.basePath',
+ 'launchInstanceModel',
'horizon.framework.widgets.action-list.button-tooltip.row-warning.service'
];
- function LaunchInstanceNetworkPortController($scope, tooltipService) {
+ function LaunchInstanceNetworkPortController(basePath, launchInstanceModel, tooltipService) {
var ctrl = this;
ctrl.portStatuses = {
@@ -53,19 +54,78 @@
'virtio-forwarder': gettext('Virtio Forwarder')
};
+ function getPortStatus(status) {
+ return ctrl.portStatuses[status];
+ }
+
+ function getPortAdminState(state) {
+ return ctrl.portAdminStates[state];
+ }
+
+ var portsArr = launchInstanceModel.ports;
+ ctrl.portsObj = {};
+ ctrl.isPortsObjGenerated = false;
+
+ function getNameOrID(id) {
+ ctrl.portsObj = ctrl.getPortsObj(portsArr);
+ var port = ctrl.portsObj[id];
+ return ctrl.nameOrID(port);
+ }
+
+ function getPortFixedIPs(id) {
+ var port = ctrl.portsObj[id];
+ var fixedIPs = '';
+ for (var ip in port.subnet_names) {
+ fixedIPs += ip + ' on subnet ' + port.subnet_names[ip] + '\n';
+ }
+ return fixedIPs;
+ }
+
ctrl.tableDataMulti = {
- available: $scope.model.ports,
- allocated: $scope.model.newInstanceSpec.ports,
- displayedAvailable: [],
- displayedAllocated: []
+ available: launchInstanceModel.ports,
+ allocated: launchInstanceModel.newInstanceSpec.ports
};
- ctrl.tableLimits = {
- maxAllocation: -1
+ ctrl.availableTableConfig = {
+ selectAll: false,
+ trackId: 'id',
+ detailsTemplateUrl: basePath + 'networkports/port-details.html',
+ columns: [
+ {id: 'id', title: gettext('Name'), priority: 1, filters: [getNameOrID]},
+ {id: 'id', title: gettext('IP'), priority: 2, filters: [getPortFixedIPs]},
+ {id: 'admin_state', title: gettext('Admin State'), priority: 2,
+ filters: [getPortAdminState]},
+ {id: 'status', title: gettext('Status'), priority: 2, filters: [getPortStatus]}
+ ]
};
+ ctrl.allocatedTableConfig = angular.copy(ctrl.availableTableConfig);
+
ctrl.tableHelpText = {
- allocHelpText: gettext('Select ports from those listed below.')
+ allocHelpText: gettext('Select ports from those listed below.'),
+ availHelpText: gettext('Select one or more ports')
+ };
+
+ ctrl.filterFacets = [{
+ label: gettext('Name'),
+ name: 'name',
+ singleton: true
+ }, {
+ label: gettext('ID'),
+ name: 'id',
+ singleton: true
+ }, {
+ label: gettext('Admin State'),
+ name: 'admin_state',
+ singleton: true
+ }, {
+ label: gettext('Status'),
+ name: 'status',
+ singleton: true
+ }];
+
+ ctrl.tableLimits = {
+ maxAllocation: -1
};
ctrl.tooltipModel = tooltipService;
@@ -73,5 +133,17 @@
ctrl.nameOrID = function nameOrId(data) {
return angular.isDefined(data.name) && data.name !== '' ? data.name : data.id;
};
+
+ ctrl.getPortsObj = function (data) {
+ if (!ctrl.isPortsObjGenerated) {
+ var ports = data.reduce(function (acc, cur) {
+ acc[cur.id] = cur;
+ return acc;
+ }, {});
+ ctrl.isPortsObjGenerated = true;
+ return ports;
+ }
+ else { return ctrl.portsObj; }
+ };
}
})();
diff --git a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/ports.html b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/ports.html
index a315416b5..9cce91105 100644
--- a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/ports.html
+++ b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/ports.html
@@ -3,160 +3,13 @@
Ports provide extra communication channels to your instances. You can select ports instead of networks or a mix of both.
</p>
- <transfer-table tr-model="ctrl.tableDataMulti" help-text="ctrl.tableHelpText" limits="ctrl.tableLimits">
- <allocated>
- <table st-table="ctrl.tableDataMulti.displayedAllocated" st-safe-src="ctrl.tableDataMulti.allocated"
- hz-table class="table table-striped table-rsp table-detail">
- <thead>
- <tr>
- <th class="reorder"></th>
- <th class="expander"></th>
- <th st-sort="name" st-sort-default class="rsp-p1" translate>Name</th>
- <th class="rsp-p2" translate>IP</th>
- <th st-sort="admin_state" class="rsp-p1" translate>Admin State</th>
- <th st-sort="status" class="rsp-p1" translate>Status</th>
- <th class="actions_column"></th>
- </tr>
- </thead>
- <tbody>
- <tr ng-if="ctrl.tableDataMulti.allocated.length === 0">
- <td colspan="7">
- <div class="no-rows-help" translate>
- Select an item from Available items below
- </div>
- </td>
- </tr>
- <tr ng-repeat-start="item in ctrl.tableDataMulti.displayedAllocated track by item.id"
- lr-drag-data="ctrl.tableDataMulti.displayedAllocated" lr-drag-src="reorder"
- lr-drop-target="reorder" lr-drop-success="trCtrl.updateAllocated(e, item, collection)">
- <td class="reorder">
- <span class="fa fa-sort" title="{$ 'Re-order items using drag and drop'|translate $}"></span>
- {$ $index + 1 $}
- </td>
- <td class="expander">
- <span class="fa fa-chevron-right" hz-expand-detail
- title="{$ 'Click to see more details'|translate $}"></span>
- </td>
- <td class="rsp-p1 word-break">{$ ctrl.nameOrID(item) $}</td>
- <td class="rsp-p2">
- <div ng-repeat="ip in item.fixed_ips">
- <span translate
- translate-params-address="ip.ip_address"
- translate-params-subnet="item.subnet_names[ip.ip_address]">
- {$ address $} on subnet {$ subnet $}
- </span>
- </div>
- </td>
- <td class="rsp-p1">{$ item.admin_state | decode:ctrl.portAdminStates $}</td>
- <td class="rsp-p1">{$ item.status | decode:ctrl.portStatuses $}</td>
- <td class="actions_column">
- <action-list>
- <action action-classes="'btn btn-default'"
- callback="trCtrl.deallocate" item="item">
- <span class="fa fa-arrow-down"></span>
- </action>
- </action-list>
- </td>
- </tr>
- <tr ng-repeat-end class="detail-row">
- <td colspan="7" class="detail">
- <dl class="dl-horizontal">
- <dt translate>ID</dt>
- <dd>{$ item.id $}</dd>
- <dt translate>Project ID</dt>
- <dd>{$ item.tenant_id $}</dd>
- <dt translate>Network ID</dt>
- <dd>{$ item.network_id $}</dd>
- <dt translate>Network</dt>
- <dd>{$ item.network_name $}</dd>
- <dt translate>VNIC type</dt>
- <dd>{$ item['binding:vnic_type'] | decode:ctrl.vnicTypes $}</dd>
- <div ng-if="item['binding:host_id']">
- <dt translate>Host ID</dt>
- <dd>{$ item['binding:host_id'] $}</dd>
- </div>
- </dl>
- </td>
- </tr>
- </tbody>
- </table>
- </allocated>
-
- <available>
- <table st-table="ctrl.tableDataMulti.displayedAvailable" st-safe-src="ctrl.tableDataMulti.available"
- hz-table class="table table-striped table-rsp table-detail">
- <thead>
- <tr>
- <th class="search-header" colspan="6">
- <hz-search-bar icon-classes="fa-search"></hz-search-bar>
- </th>
- </tr>
- <tr>
- <th class="expander"></th>
- <th st-sort="name" st-sort-default class="rsp-p1" translate>Name</th>
- <th class="rsp-p2" translate>IP</th>
- <th st-sort="admin_state" class="rsp-p1" translate>Admin State</th>
- <th st-sort="status" class="rsp-p1" translate>Status</th>
- <th class="actions_column"></th>
- </tr>
- </thead>
- <tbody>
- <tr ng-if="trCtrl.numAvailable() === 0">
- <td colspan="6">
- <div class="no-rows-help" translate>
- No available items
- </div>
- </td>
- </tr>
- <tr ng-repeat-start="item in ctrl.tableDataMulti.displayedAvailable track by item.id"
- ng-if="!trCtrl.allocatedIds[item.id]">
- <td class="expander">
- <span class="fa fa-chevron-right" hz-expand-detail
- title="{$ 'Click to see more details'|translate $}"></span>
- </td>
- <td class="rsp-p1 word-break">{$ ctrl.nameOrID(item) $}</td>
- <td class="rsp-p2">
- <div ng-repeat="ip in item.fixed_ips">
- <span translate
- translate-params-address="ip.ip_address"
- translate-params-subnet="item.subnet_names[ip.ip_address]">
- {$ address $} on subnet {$ subnet $}
- </span>
- </div>
- </td>
- <td class="rsp-p1">{$ item.admin_state | decode:ctrl.portAdminStates $}</td>
- <td class="rsp-p1">{$ item.status | decode:ctrl.portStatuses $}</td>
- <td class="actions_column">
- <action-list>
- <action action-classes="'btn btn-default'"
- callback="trCtrl.allocate" item="item">
- <span class="fa fa-arrow-up"></span>
- </action>
- </action-list>
- </td>
- </tr>
- <tr ng-repeat-end class="detail-row">
- <td colspan="6" class="detail">
- <dl class="dl-horizontal">
- <dt translate>ID</dt>
- <dd>{$ item.id $}</dd>
- <dt translate>Project ID</dt>
- <dd>{$ item.tenant_id $}</dd>
- <dt translate>Network ID</dt>
- <dd>{$ item.network_id $}</dd>
- <dt translate>Network</dt>
- <dd>{$ item.network_name $}</dd>
- <dt translate>VNIC type</dt>
- <dd>{$ item['binding:vnic_type'] | decode:ctrl.vnicTypes $}</dd>
- <div ng-if="item['binding:host_id']">
- <dt translate>Host ID</dt>
- <dd>{$ item['binding:host_id'] $}</dd>
- </div>
- </dl>
- </td>
- </tr>
- </tbody>
- </table>
- </available>
- </transfer-table>
+ <transfer-table tr-model="ctrl.tableDataMulti" help-text="ctrl.tableHelpText" limits="ctrl.tableLimits" clone-content>
+ <hz-dynamic-table
+ config="$isAvailableTable ? ctrl.availableTableConfig : ctrl.allocatedTableConfig"
+ items="$isAvailableTable ? ($sourceItems | filterAvailable:trCtrl.allocatedIds) : $sourceItems"
+ item-actions="trCtrl.itemActions"
+ filter-facets="$isAvailableTable && ctrl.filterFacets"
+ table="ctrl">
+ </hz-dynamic-table>
+ </transfer-table> <!-- End Network Ports Transfer Table -->
</div>
diff --git a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/ports.spec.js b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/ports.spec.js
index 0e25313c2..da5611aa1 100644
--- a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/ports.spec.js
+++ b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/networkports/ports.spec.js
@@ -23,20 +23,19 @@
beforeEach(module('horizon.dashboard.project.workflow.launch-instance'));
describe('LaunchInstanceNetworkPortController', function() {
- var scope, ctrl;
+ var ctrl;
+ var port = {name: 'test_name', id: 'test_id'};
beforeEach(inject(function($controller) {
- scope = {
- model: {
- newInstanceSpec: {
- ports: ['port-a']
- },
- ports: ['port-a', 'port-b']
- }
+ var model = {
+ newInstanceSpec: {
+ ports: ['port-a']
+ },
+ ports: ['port-a', 'port-b']
};
- ctrl = $controller('LaunchInstanceNetworkPortController', {
- $scope: scope
- });
+
+ ctrl = $controller('LaunchInstanceNetworkPortController',
+ { launchInstanceModel: model });
}));
it('has correct ports statuses', function() {
@@ -63,25 +62,35 @@
expect(ctrl.tableHelpText.allocHelpText).toBeDefined();
});
- it('nameOrId return the name', function() {
- var obj = {name: 'test_name', id: 'test_id'};
+ it('nameOrID returns the name', function() {
expect(ctrl.nameOrID).toBeDefined();
- expect(ctrl.nameOrID(obj)).toBe('test_name');
+ expect(ctrl.nameOrID(port)).toBe('test_name');
});
- it('nameOrId return the id if the name is missing', function() {
+ it('nameOrID returns the id if the name is missing', function() {
expect(ctrl.nameOrID).toBeDefined();
expect(ctrl.nameOrID({'id': 'testid'})).toBe('testid');
});
+ it('getPortsObj returns generated ports object', function() {
+ expect(ctrl.getPortsObj).toBeDefined();
+ expect(ctrl.isPortsObjGenerated).toBe(false);
+ expect(ctrl.getPortsObj([port])).toEqual({'test_id': port});
+ expect(ctrl.isPortsObjGenerated).toBe(true);
+ });
+
+ it('getPortsObj returns existing ports object', function() {
+ ctrl.portsObj = {'test_id': port};
+ ctrl.isPortsObjGenerated = true;
+ expect(ctrl.getPortsObj).toBeDefined();
+ expect(ctrl.getPortsObj([port])).toEqual({'test_id': port});
+ });
+
it('uses scope to set table data', function() {
expect(ctrl.tableDataMulti).toBeDefined();
expect(ctrl.tableDataMulti.available).toEqual(['port-a', 'port-b']);
expect(ctrl.tableDataMulti.allocated).toEqual(['port-a']);
- expect(ctrl.tableDataMulti.displayedAllocated).toEqual([]);
- expect(ctrl.tableDataMulti.displayedAvailable).toEqual([]);
});
});
-
});
})();