From f230e96da5089c33825b5a2d2bf6711e01f12363 Mon Sep 17 00:00:00 2001 From: Elizabeth Elwell Date: Thu, 4 Feb 2016 13:32:24 +0000 Subject: [PATCH] Added node details page to the plugin Added details page files to the plugin. Change-Id: I17e4c749038dfa9f4a8423796186c133d248fba0 Co-Authored-By: Peter Piela --- .../ironic/templates/ironic/node_detail.html | 11 ++ .../dashboard/admin/ironic/ironic.service.js | 2 +- .../node-details/node-details.controller.js | 88 +++++++++++++ .../node-details.controller.spec.js | 103 +++++++++++++++ .../ironic/node-details/node-details.html | 45 +++++++ .../node-details/sections/configuration.html | 120 ++++++++++++++++++ .../node-details/sections/overview.html | 50 ++++++++ 7 files changed, 418 insertions(+), 1 deletion(-) create mode 100644 ironic_ui/content/ironic/templates/ironic/node_detail.html create mode 100755 ironic_ui/static/dashboard/admin/ironic/node-details/node-details.controller.js create mode 100755 ironic_ui/static/dashboard/admin/ironic/node-details/node-details.controller.spec.js create mode 100644 ironic_ui/static/dashboard/admin/ironic/node-details/node-details.html create mode 100644 ironic_ui/static/dashboard/admin/ironic/node-details/sections/configuration.html create mode 100644 ironic_ui/static/dashboard/admin/ironic/node-details/sections/overview.html diff --git a/ironic_ui/content/ironic/templates/ironic/node_detail.html b/ironic_ui/content/ironic/templates/ironic/node_detail.html new file mode 100644 index 00000000..e53ced6e --- /dev/null +++ b/ironic_ui/content/ironic/templates/ironic/node_detail.html @@ -0,0 +1,11 @@ +{% extends 'base.html' %} +{% load i18n %} +{% block title %}{% trans "Node Details" %}{% endblock %} + +{% block page_header %} + +{% endblock %} + +{% block main %} + +{% endblock %} diff --git a/ironic_ui/static/dashboard/admin/ironic/ironic.service.js b/ironic_ui/static/dashboard/admin/ironic/ironic.service.js index cf4f6799..1dd14f33 100755 --- a/ironic_ui/static/dashboard/admin/ironic/ironic.service.js +++ b/ironic_ui/static/dashboard/admin/ironic/ironic.service.js @@ -110,7 +110,7 @@ function putNodeInMaintenanceMode(uuid, reason) { var data = { - maint_reason: (reason ? reason : gettext('No maintenance reason given.')) + maint_reason: (reason ? reason : gettext("No maintenance reason given.")) }; return apiService.patch('/api/ironic/nodes/' + uuid + '/maintenance', data).error(function() { toastService.add('error', diff --git a/ironic_ui/static/dashboard/admin/ironic/node-details/node-details.controller.js b/ironic_ui/static/dashboard/admin/ironic/node-details/node-details.controller.js new file mode 100755 index 00000000..fa58a12a --- /dev/null +++ b/ironic_ui/static/dashboard/admin/ironic/node-details/node-details.controller.js @@ -0,0 +1,88 @@ +/* + * Copyright 2015 Hewlett Packard Enterprise Development Company LP + * Copyright 2016 Cray Inc. + * + * 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.admin.ironic') + .controller('horizon.dashboard.admin.ironic.NodeDetailsController', + IronicNodeDetailsController); + + IronicNodeDetailsController.$inject = [ + '$location', + 'horizon.app.core.openstack-service-api.ironic', + 'horizon.dashboard.admin.ironic.actions', + 'horizon.dashboard.admin.basePath' + ]; + + function IronicNodeDetailsController($location, ironic, actions, basePath) { + var ctrl = this; + var path = basePath + 'ironic/node-details/sections/'; + + ctrl.actions = actions; + + ctrl.sections = [ + { + heading: gettext('Overview'), + templateUrl: path + 'overview.html' + }, + { + heading: gettext('Configuration'), + templateUrl: path + 'configuration.html' + } + ]; + + ctrl.basePath = basePath; + ctrl.init = init; + + /////////////// + + function init() { + // Fetch the Node ID from the URL. + var pattern = /(.*\/admin\/ironic\/)(.+)\/(detail)?/; + var uuid = $location.absUrl().match(pattern)[2]; + + retrieveNode(uuid).then(function () { + retrievePorts(uuid); + }); + } + + function retrieveNode(uuid) { + return ironic.getNode(uuid).then(function (response) { + var node = response.data; + ctrl.node = node; + if (node['target_power_state']) { + actions.updateNode(node); + } + }); + } + + function retrievePorts(node_id) { + ironic.getPortsWithNode(node_id).then(function (response) { + ctrl.ports = response.data.items; + // Ensure that the vif_port_id property exists for all ports + angular.forEach(ctrl.ports, + function(port, key) { + if (angular.isUndefined(port.extra.vif_port_id)) { + port.extra.vif_port_id = ""; + } + }); + }); + } + } + +})(); diff --git a/ironic_ui/static/dashboard/admin/ironic/node-details/node-details.controller.spec.js b/ironic_ui/static/dashboard/admin/ironic/node-details/node-details.controller.spec.js new file mode 100755 index 00000000..223253a0 --- /dev/null +++ b/ironic_ui/static/dashboard/admin/ironic/node-details/node-details.controller.spec.js @@ -0,0 +1,103 @@ +/* + * Copyright 2015 Hewlett Packard Enterprise Development Company LP + * Copyright 2016 Cray Inc. + * + * 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('horizon.dashboard.admin.ironic.node-details', function () { + var ctrl, $q; + var nodeUuid = "0123abcd-0123-4567-abcd-0123456789ab"; + var nodeName = "herp"; + var numPorts = 2; + + function portUuid(nodeUuid, index) { + return '' + index + index + nodeUuid.substring(2); + } + + function createPort(nodeUuid, index, extra) { + return {uuid: portUuid(nodeUuid, index), extra: extra}; + } + + function createNode(name, uuid) { + return {name: name, uuid: uuid}; + } + + var ironicAPI = { + getNode: function (uuid) { + var node = createNode(nodeName, uuid); + return $q.when({data: node}); + }, + + getPortsWithNode: function (uuid) { + var ports = []; + for (var i = 0; i < numPorts; i++) { + ports.push(createPort(uuid, i, {})); + } + return $q.when({data: {items: ports}}); + } + }; + + beforeEach(module('horizon.dashboard.admin.ironic')); + + beforeEach(module('horizon.app.core.openstack-service-api', function($provide) { + $provide.value('horizon.app.core.openstack-service-api.ironic', ironicAPI); + })); + + beforeEach(inject(function ($injector, _$rootScope_, _$location_) { + var scope = _$rootScope_.$new(); + $q = $injector.get('$q'); + var controller = $injector.get('$controller'); + var $location = _$location_; + $location.path('/admin/ironic/' + nodeUuid + '/'); + + ctrl = controller('horizon.dashboard.admin.ironic.NodeDetailsController', { + $scope: scope, + $location: $location, + 'horizon.dashboard.admin.ironic.actions': {}, + 'horizon.dashboard.admin.basePath': '/static'}); + ctrl.init(); + + scope.$apply(); + })); + + it('should be defined', function () { + expect(ctrl).toBeDefined(); + }); + + it('should have a basePath', function () { + expect(ctrl.basePath).toBeDefined(); + expect(ctrl.basePath).toEqual('/static'); + }); + + it('should have a node', function () { + expect(ctrl.node).toBeDefined(); + expect(ctrl.node).toEqual(createNode(nodeName, nodeUuid)) + }); + + it('should have ports', function () { + expect(ctrl.ports).toBeDefined(); + expect(ctrl.ports.length).toEqual(numPorts); + + var ports = []; + for (var i = 0; i < ctrl.ports.length; i++) { + ports.push(createPort(ctrl.node.uuid, i, {vif_port_id: ''})); + } + expect(ctrl.ports).toEqual(ports); + }); + + }); + +})(); diff --git a/ironic_ui/static/dashboard/admin/ironic/node-details/node-details.html b/ironic_ui/static/dashboard/admin/ironic/node-details/node-details.html new file mode 100644 index 00000000..044bf063 --- /dev/null +++ b/ironic_ui/static/dashboard/admin/ironic/node-details/node-details.html @@ -0,0 +1,45 @@ +
+ +
+ + + {$ 'Power on' | translate $} + + + + {$ 'Power off' | translate $} + + + {$ 'Maintenance on' | translate $} + + + {$ 'Maintenance off' | translate $} + + + +
+ +
+ + + + + + +
diff --git a/ironic_ui/static/dashboard/admin/ironic/node-details/sections/configuration.html b/ironic_ui/static/dashboard/admin/ironic/node-details/sections/configuration.html new file mode 100644 index 00000000..c39e7c21 --- /dev/null +++ b/ironic_ui/static/dashboard/admin/ironic/node-details/sections/configuration.html @@ -0,0 +1,120 @@ +
+ + +
+

General

+
+
+
Node ID
+
{$ ctrl.node['uuid'] $}
+
Chassis ID
+
{$ ctrl.node['chassis_uuid'] $}
+
Created At
+
{$ ctrl.node['created_at'] $}
+
Extra
+
{$ ctrl.node['extra'] $}
+
+
+ + +
+

Ports

+
+
+
+ {$ 'MAC ' + (1 + $index) $}
+
+ + {$ port.address $} + +
+
+ {$ port.address $} +
+

+
+
+
+ +
+ +
+

Properties

+
+
+
Memory
+
{$ ctrl.node['properties']['memory_mb'] + ' MB' $}
+
CPU Arch
+
{$ ctrl.node['properties']['cpu_arch'] $}
+
Local GB
+
{$ ctrl.node['properties']['local_gb'] $}
+
CPUs
+
{$ ctrl.node['properties']['cpus'] $}
+
+
+ + +
+

Driver Info

+
+
+
+
Driver
+
{$ ctrl.node['driver'] $}
+
SSH Port
+
{$ ctrl.node['driver_info']['ssh_port'] $}
+
SSH Username
+
{$ ctrl.node['driver_info']['ssh_username'] $}
+
Deploy Kernel
+
+ + {$ ctrl.node['driver_info']['deploy_kernel'] $} + +
+
Deploy Ramdisk
+
+ + {$ ctrl.node['driver_info']['deploy_ramdisk'] $} + +
+
+
+
{$ id $}
+
{$ value $}
+
+
+
+
+ +
+ +
+

Capabilities

+
+
+
{$ ctrl.node['capabilities'] $}
+
+
+ + +
+

Instance Info

+
+
+
Instance Name
+
{$ ctrl.node['instance_info']['display_name'] $}
+
Ramdisk
+
+ + {$ ctrl.node['instance_info']['ramdisk'] $} + +
+
Kernel
+
+ + {$ ctrl.node['instance_info']['kernel'] $} + +
+
+
+
diff --git a/ironic_ui/static/dashboard/admin/ironic/node-details/sections/overview.html b/ironic_ui/static/dashboard/admin/ironic/node-details/sections/overview.html new file mode 100644 index 00000000..d54477cd --- /dev/null +++ b/ironic_ui/static/dashboard/admin/ironic/node-details/sections/overview.html @@ -0,0 +1,50 @@ +
+ + +
+

General

+
+
+
Name
+
{$ ctrl.node['name'] $}
+
Maintenance
+
{$ ctrl.node['maintenance'] ? 'True' : 'False' $}
+
Maintenance Reason
+
{$ ctrl.node['maintenance_reason'] $}
+
Inspection Started At
+
{$ ctrl.node['inspection_started_at'] $}
+
Inspection Finished At
+
{$ ctrl.node['inspection_finished_at'] $}
+
Reservation
+
{$ ctrl.node['reservation'] $}
+
Console Enabled
+
{$ ctrl.node['console_enabled'] ? 'True' : 'False' $}
+
+
+ + +
+

Provisioning Status

+
+
+
Instance ID
+
+ + {$ ctrl.node['instance_uuid'] $} + +
+
Power State
+
{$ ctrl.node['power_state'] $}
+
Target Power State
+
{$ ctrl.node['target_power_state'] $}
+
Provision State
+
{$ ctrl.node['provision_state'] $}
+
Target Provision State
+
{$ ctrl.node['target_provision_state'] $}
+
Last Error
+
{$ ctrl.node['last_error'] $}
+
Updated At
+
{$ ctrl.node['updated_at'] $}
+
+
+