Incorporate driver-validation into node-detail panels
Driver validation information has been added to the node-details/ configuration page. The driver validation information is located in close proximity to the driver properties section, and will update as property values are changed. To accomodate the driver validation information the following changes have been made to the layout and organization of the node-details/configuration page: (1) The list of Extra properties has been removed from the General section and is now treated as a separate collection in a similar manner to Properties and Instance_info. (2) The new grid layout is: Row 1 (top) General, Ports Row 2 Driver Info, Driver Validation Row 3 Properties, Instance Info Row 4 Extra (3) The list of instance_info items displayed for the pxe_ssh driver has been enhanced. Change-Id: I0ba8ac0fc1e4a1b0f2f4b03b738f56ed380a11c7
This commit is contained in:
parent
26574c7aa1
commit
eeaa2ecf06
@ -171,6 +171,23 @@ def node_update(request, node_id, patch):
|
||||
ironicclient(request).node.update(node_id, patch)
|
||||
|
||||
|
||||
def node_validate(request, node_id):
|
||||
"""Validate a specified node.
|
||||
|
||||
:param request: HTTP request.
|
||||
:param node_id: The id of the node.
|
||||
:return: Dictionary of interface statuses
|
||||
|
||||
http://docs.openstack.org/developer/python-ironicclient/api/ironicclient.v1.node.html#ironicclient.v1.node.NodeManager.validate
|
||||
"""
|
||||
node = ironicclient(request).node.validate(node_id)
|
||||
result = {}
|
||||
for interface, status in node.__dict__.iteritems():
|
||||
if isinstance(status, dict) and 'result' in status:
|
||||
result[interface] = status
|
||||
return result
|
||||
|
||||
|
||||
def driver_list(request):
|
||||
"""Retrieve a list of drivers.
|
||||
|
||||
|
@ -188,6 +188,22 @@ class Maintenance(generic.View):
|
||||
return ironic.node_set_maintenance(request, node_id, 'off')
|
||||
|
||||
|
||||
@urls.register
|
||||
class Validate(generic.View):
|
||||
|
||||
url_regex = r'ironic/nodes/(?P<node_id>[0-9a-f-]+)/validate$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request, node_id):
|
||||
"""Validate a specified node
|
||||
|
||||
:param request: HTTP request.
|
||||
:param node_id: Node name or uuid
|
||||
:return: Dictionary of interface statuses
|
||||
"""
|
||||
return ironic.node_validate(request, node_id)
|
||||
|
||||
|
||||
@urls.register
|
||||
class Drivers(generic.View):
|
||||
|
||||
|
@ -86,7 +86,8 @@
|
||||
putNodeInMaintenanceMode: putNodeInMaintenanceMode,
|
||||
removeNodeFromMaintenanceMode: removeNodeFromMaintenanceMode,
|
||||
setNodeProvisionState: setNodeProvisionState,
|
||||
updateNode: updateNode
|
||||
updateNode: updateNode,
|
||||
validateNode: validateNode
|
||||
};
|
||||
|
||||
return service;
|
||||
@ -337,6 +338,31 @@
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Validate the specified node
|
||||
*
|
||||
* http://docs.openstack.org/developer/ironic/webapi/v1.html#
|
||||
* validate--v1-nodes
|
||||
*
|
||||
* @param {string} nodeIdent – UUID or logical name of a node.
|
||||
* @return {promise} Promise
|
||||
*/
|
||||
function validateNode(nodeIdent) {
|
||||
var data = {
|
||||
node: nodeIdent
|
||||
};
|
||||
return apiService.get('/api/ironic/nodes/' + nodeIdent + '/validate',
|
||||
data)
|
||||
.success(function() {
|
||||
})
|
||||
.error(function(reason) {
|
||||
var msg = gettext('Unable to validate node %s: %s');
|
||||
toastService.add(
|
||||
'error',
|
||||
interpolate(msg, [nodeIdent, reason], false));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Retrieve the list of Ironic drivers
|
||||
*
|
||||
|
@ -66,6 +66,7 @@
|
||||
];
|
||||
|
||||
ctrl.node = null;
|
||||
ctrl.nodeValidation = {};
|
||||
ctrl.ports = [];
|
||||
ctrl.portsSrc = [];
|
||||
ctrl.basePath = basePath;
|
||||
@ -121,6 +122,9 @@
|
||||
|
||||
retrieveNode(uuid).then(function () {
|
||||
retrievePorts(uuid);
|
||||
ironic.validateNode(uuid).then(function(response) {
|
||||
ctrl.nodeValidation = response.data;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,10 @@
|
||||
ports.push(createPort(uuid, i));
|
||||
}
|
||||
return $q.when({data: {items: ports}});
|
||||
},
|
||||
|
||||
validateNode: function() {
|
||||
return $q.when({});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -11,8 +11,6 @@
|
||||
<dd>{$ ctrl.node.chassis_uuid | noValue $}</dd>
|
||||
<dt translate>Created At</dt>
|
||||
<dd>{$ ctrl.node.created_at | date:'medium' | noValue $}</dd>
|
||||
<dt translate>Extra</dt>
|
||||
<dd>{$ ctrl.node.extra | noValue $}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
@ -67,13 +65,7 @@
|
||||
<input type="checkbox"
|
||||
hz-select="port"
|
||||
ng-model="tCtrl.selections[port.id].checked"/>
|
||||
<td ng-if="vif_port_id = ctrl.getVifPortId(port)"
|
||||
class="rsp-p1">
|
||||
<a href="/dashboard/admin/networks/ports/{$ vif_port_id $}/detail">
|
||||
{$ port.address $}
|
||||
</a>
|
||||
</td>
|
||||
<td ng-if="!vif_port_id" class="rsp-p1">
|
||||
<td class="rsp-p1">
|
||||
{$ port.address $}
|
||||
</td>
|
||||
<td>
|
||||
@ -81,7 +73,12 @@
|
||||
<dt style="width:auto;" ng-repeat-start="(id, value) in port.extra">
|
||||
{$ id $}
|
||||
</dt>
|
||||
<dd>
|
||||
<dd ng-if="id === 'vif_port_id'">
|
||||
<a href="/dashboard/admin/networks/ports/{$ value $}/detail">
|
||||
{$ value $}
|
||||
</a>
|
||||
</dd>
|
||||
<dd ng-if="id !== 'vif_port_id'">
|
||||
{$ value $}
|
||||
</dd>
|
||||
<p ng-repeat-end></p>
|
||||
@ -107,17 +104,6 @@
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<!-- Properties -->
|
||||
<div class="col-md-6 status detail">
|
||||
<h4 translate>Properties</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
<dt ng-repeat-start="(propertyName, propertyValue) in ctrl.node.properties">
|
||||
{$ propertyName $}</dt>
|
||||
<dd ng-repeat-end>{$ propertyValue | noValue $}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<!-- Driver Info -->
|
||||
<div class="col-md-6 status detail">
|
||||
<h4 translate>Driver Info</h4>
|
||||
@ -126,13 +112,34 @@
|
||||
<dl ng-switch-when="pxe_ssh" class="dl-horizontal">
|
||||
<dt translate>Driver</dt>
|
||||
<dd>{$ ctrl.node.driver | noValue $}</dd>
|
||||
<dt translate>SSH Address</dt>
|
||||
<dd>{$ ctrl.node.driver_info.ssh_address | noValue $}</dd>
|
||||
<dt translate>SSH Port</dt>
|
||||
<dd>{$ ctrl.node.driver_info.ssh_port | noValue $}</dd>
|
||||
<dt translate>SSH Username</dt>
|
||||
<dd>{$ ctrl.node.driver_info.ssh_username | noValue $}</dd>
|
||||
<dt ng-if="ssh_key_filename = ctrl.node.driver_info.ssh_key_filename"
|
||||
translate>SSH Key File</dt>
|
||||
<dd ng-if="ssh_key_filename">
|
||||
{$ ssh_key_filename | noValue $}
|
||||
</dd>
|
||||
<dt ng-if="ssh_password = ctrl.node.driver_info.ssh_password"
|
||||
translate>SSH Password</dt>
|
||||
<dd ng-if="ssh_password">
|
||||
{$ ssh_password | noValue $}
|
||||
</dd>
|
||||
<dt ng-if="ssh_key_contents = ctrl.node.driver_info.ssh_key_contents"
|
||||
translate>SSH Key Contents</dt>
|
||||
<dd ng-if="ssh_key_contents">
|
||||
{$ ssh_key_contents | noValue $}
|
||||
</dd>
|
||||
<dt translate>SSH terminal port</dt>
|
||||
<dd>{$ ctrl.node.driver_info.ssh_terminal_port | noValue $}</dd>
|
||||
<dt translate>Virtualization Software</dt>
|
||||
<dd>{$ ctrl.node.driver_info.ssh_virt_type | noValue $}</dd>
|
||||
<dt translate>Deploy Kernel</dt>
|
||||
<dd>
|
||||
<a ng-if="deploy_kernel_is_uuid = ctrl.isUuid(ctrl.node.driver_info.deploy_kernel)"
|
||||
<a ng-if="deploy_kernel_is_uuid = angular.isDefined(ctrl.node.driver_info.deploy_kernel) ? ctrl.isUuid(ctrl.node.driver_info.deploy_kernel) : false"
|
||||
href="/dashboard/admin/images/{$ ctrl.node.driver_info.deploy_kernel $}/detail">
|
||||
{$ ctrl.node.driver_info.deploy_kernel | noValue $}
|
||||
</a>
|
||||
@ -142,7 +149,7 @@
|
||||
</dd>
|
||||
<dt translate>Deploy Ramdisk</dt>
|
||||
<dd>
|
||||
<a ng-if="deploy_ramdisk_is_uuid = ctrl.isUuid(ctrl.node.driver_info.deploy_ramdisk)"
|
||||
<a ng-if="deploy_ramdisk_is_uuid = angular.isDefined(ctrl.node.driver_info.deploy_ramdisk) ? ctrl.isUuid(ctrl.node.driver_info.deploy_ramdisk) : false"
|
||||
href="/dashboard/admin/images/{$ ctrl.node.driver_info.deploy_ramdisk $}/detail">
|
||||
{$ ctrl.node.driver_info.deploy_ramdisk | noValue $}
|
||||
</a>
|
||||
@ -157,9 +164,60 @@
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Validation -->
|
||||
<div class="col-md-6 status detail">
|
||||
<h4 translate>Driver Validation</h4>
|
||||
<hr class="header_rule">
|
||||
|
||||
<table hz-table ng-cloak
|
||||
st-table="ctrl.nodeValidation"
|
||||
st-safe-src="ctrl.nodeValidationSrc"
|
||||
class="table table-striped table-rsp table-detail">
|
||||
<thead>
|
||||
<tr>
|
||||
<th translate class="rsp-p1" style="white-space:nowrap">
|
||||
Interface
|
||||
</th>
|
||||
<th translate class="rsp-p1">
|
||||
Valid
|
||||
</th>
|
||||
<th translate class="rsp-p2" style="width:100%;">
|
||||
Reason
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="(interface, status) in ctrl.nodeValidation">
|
||||
<td class="rsp-p1">
|
||||
{$ interface $}
|
||||
</td>
|
||||
<td class="rsp-p1" ng-switch="status.result">
|
||||
<span ng-switch-when="true" class="fa fa-check text-success"></span>
|
||||
<span ng-switch-when="false" class="fa fa-close text-danger"></span>
|
||||
<span ng-switch-default class="fa fa-minus"></span>
|
||||
</td>
|
||||
<td class="rsp-p2">
|
||||
{$ status.reason $}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<!-- Properties -->
|
||||
<div class="col-md-6 status detail">
|
||||
<h4 translate>Properties</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
<dt ng-repeat-start="(propertyName, propertyValue) in ctrl.node.properties">
|
||||
{$ propertyName $}</dt>
|
||||
<dd ng-repeat-end>{$ propertyValue | noValue $}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<!-- Instance Info -->
|
||||
<div class="col-md-6 status detail">
|
||||
<h4 translate>Instance Info</h4>
|
||||
@ -180,6 +238,14 @@
|
||||
{$ ctrl.node.instance_info.kernel | noValue $}
|
||||
</a>
|
||||
</dd>
|
||||
<dt translate>Image Source</dt>
|
||||
<dd>
|
||||
<a href="/dashboard/admin/images/{$ ctrl.node.instance_info.image_source $}/detail">
|
||||
{$ ctrl.node.instance_info.image_source | noValue $}
|
||||
</a>
|
||||
</dd>
|
||||
<dt translate>Root GB</dt>
|
||||
<dd>{$ ctrl.node.instance_info.root_gb | noValue $}</dd>
|
||||
</dl>
|
||||
<dl ng-switch-default class="dl-horizontal">
|
||||
<dt ng-repeat-start="(id, value) in ctrl.node.instance_info">{$ id $}</dt>
|
||||
@ -187,5 +253,17 @@
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<!-- Extra -->
|
||||
<div class="col-md-6 status detail">
|
||||
<h4 translate>Extra</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
<dt ng-repeat-start="(propertyName, propertyValue) in ctrl.node.extra">
|
||||
{$ propertyName $}</dt>
|
||||
<dd ng-repeat-end>{$ propertyValue | noValue $}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user