Set target raid configuration on a node
Adds menu option to set basic target raid configuration. Unit tests to be added in a follow-up patch. Change-Id: I2886e5ca4e5757209ff6da5f9162f874f648e135 Partial-Bug: #1648553
This commit is contained in:
parent
791eecc71e
commit
5b9c6f61b7
|
@ -384,3 +384,18 @@ def portgroup_get_ports(request, portgroup_id):
|
|||
http://docs.openstack.org/developer/python-ironicclient/api/ironicclient.v1.portgroup.html#ironicclient.v1.portgroup.PortgroupManager.list_ports
|
||||
"""
|
||||
return ironicclient(request).portgroup.list_ports(portgroup_id)
|
||||
|
||||
|
||||
def node_set_raid_config(request, node_id, target_raid_config):
|
||||
"""Set target raid configuration for a given node.
|
||||
|
||||
:param request: HTTP request.
|
||||
:param node_id: The UUID or name of the node.
|
||||
:param target_raid_config: Target raid configuration.
|
||||
:return: Node.
|
||||
|
||||
http://docs.openstack.org/developer/python-ironicclient/api/ironicclient.v1.node.html#ironicclient.v1.node.NodeManager.set_target_raid_config
|
||||
"""
|
||||
return ironicclient(request).node.set_target_raid_config(
|
||||
node_id,
|
||||
target_raid_config)
|
||||
|
|
|
@ -416,3 +416,23 @@ class PortgroupPorts(generic.View):
|
|||
return {
|
||||
'ports': [i.to_dict() for i in ports]
|
||||
}
|
||||
|
||||
|
||||
@urls.register
|
||||
class RaidConfig(generic.View):
|
||||
|
||||
url_regex = r'ironic/nodes/(?P<node_id>{})/states/raid$'. \
|
||||
format(LOGICAL_NAME_PATTERN)
|
||||
|
||||
@rest_utils.ajax(data_required=True)
|
||||
def put(self, request, node_id):
|
||||
"""Set the RAID configuration for a specified node.
|
||||
|
||||
:param request: HTTP request.
|
||||
:param node_id: Node name or node uuid
|
||||
:return: None
|
||||
"""
|
||||
return ironic.node_set_raid_config(
|
||||
request,
|
||||
node_id,
|
||||
request.DATA.get('target_raid_config'))
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
nodeSetMaintenance: nodeSetMaintenance,
|
||||
nodeSetBootDevice: nodeSetBootDevice,
|
||||
nodeSetPowerState: nodeSetPowerState,
|
||||
nodeSetRaidConfig: nodeSetRaidConfig,
|
||||
setNodeProvisionState: setNodeProvisionState,
|
||||
updateNode: updateNode,
|
||||
updatePort: updatePort,
|
||||
|
@ -288,6 +289,31 @@
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Set the target raid configuration of a node
|
||||
*
|
||||
* http://developer.openstack.org/api-ref/baremetal/#set-target-raid-config
|
||||
*
|
||||
* @param {string} nodeId – UUID or logical name of a node.
|
||||
* @param {string} raidConfig - Target raid configuration.
|
||||
* @return {promise} Promise
|
||||
*/
|
||||
function nodeSetRaidConfig(nodeId, raidConfig) {
|
||||
return apiService.put('/api/ironic/nodes/' + nodeId + '/states/raid',
|
||||
{target_raid_config: raidConfig})
|
||||
.then(function() {
|
||||
toastService.add('success',
|
||||
gettext('Refresh page.'));
|
||||
})
|
||||
.catch(function(response) {
|
||||
var msg = interpolate(gettext('Unable to set raid config: %s'),
|
||||
[response.data],
|
||||
false);
|
||||
toastService.add('error', msg);
|
||||
return $q.reject(msg);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Set the target provision state of the node.
|
||||
*
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
'nodeSetBootDevice',
|
||||
'nodeSetConsoleMode',
|
||||
'nodeSetPowerState',
|
||||
'nodeSetRaidConfig',
|
||||
'nodeSetMaintenance',
|
||||
'setNodeProvisionState',
|
||||
'updateNode',
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
'horizon.dashboard.admin.ironic.edit-portgroup.service',
|
||||
'horizon.dashboard.admin.ironic.maintenance.service',
|
||||
'horizon.dashboard.admin.ironic.bootdevice.service',
|
||||
'horizon.dashboard.admin.ironic.raidconfig.service',
|
||||
'horizon.dashboard.admin.ironic.node-state-transition.service',
|
||||
'horizon.dashboard.admin.ironic.validUuidPattern'
|
||||
];
|
||||
|
@ -53,6 +54,7 @@
|
|||
editPortgroupService,
|
||||
maintenanceService,
|
||||
bootDeviceService,
|
||||
raidConfigService,
|
||||
nodeStateTransitionService,
|
||||
validUuidPattern) {
|
||||
var ctrl = this;
|
||||
|
@ -64,6 +66,7 @@
|
|||
ctrl.actions = actions;
|
||||
ctrl.maintenanceService = maintenanceService;
|
||||
ctrl.bootDeviceService = bootDeviceService;
|
||||
ctrl.raidConfigService = raidConfigService;
|
||||
|
||||
ctrl.sections = [
|
||||
{
|
||||
|
|
|
@ -45,6 +45,14 @@
|
|||
<span>{$ "Set boot device" | translate $}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a role="menuitem"
|
||||
ng-click="ctrl.raidConfigService.setRaidConfig(ctrl.node);
|
||||
$event.stopPropagation();
|
||||
$event.preventDefault()">
|
||||
<span>{$ "Set RAID configuration" | translate $}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation"
|
||||
ng-repeat="transition in ctrl.nodeStateTransitions">
|
||||
<a role="menuitem"
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright 2017 Intel Corporation
|
||||
*
|
||||
* 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';
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name horizon.dashboard.admin.ironic:RaidConfigController
|
||||
* @ngController
|
||||
*
|
||||
* @description
|
||||
* Controller used to prompt the user for information associated with
|
||||
* setting the target raid configuration of a node
|
||||
*/
|
||||
angular
|
||||
.module('horizon.dashboard.admin.ironic')
|
||||
.controller('RaidConfigController', RaidConfigController);
|
||||
|
||||
RaidConfigController.$inject = [
|
||||
'$uibModalInstance',
|
||||
'horizon.dashboard.admin.ironic.form-field.service',
|
||||
'horizon.app.core.openstack-service-api.ironic',
|
||||
'node'
|
||||
];
|
||||
|
||||
function RaidConfigController($uibModalInstance,
|
||||
formFieldService,
|
||||
ironic,
|
||||
node) {
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.modalTitle = gettext("Set RAID Configuration");
|
||||
|
||||
ctrl.target_raid_config = null;
|
||||
ctrl.logicalDisks = [];
|
||||
ctrl.logicalDisksSrc = [];
|
||||
|
||||
ironic.getNode(node.uuid).then(function() {
|
||||
ctrl.logicalDisksSrc = angular.copy(node.raid_config.logical_disks);
|
||||
});
|
||||
|
||||
ctrl.size_gb = new formFieldService.FormField({
|
||||
id: "size_gb",
|
||||
title: gettext("Size GB"),
|
||||
desc: gettext("Specifies logical disk size in GiB. Required."),
|
||||
pattern: new RegExp('^\\d+$'),
|
||||
value: null,
|
||||
required: true,
|
||||
autoFocus: true
|
||||
});
|
||||
|
||||
ctrl.raid_level = new formFieldService.FormField({
|
||||
type: "radio",
|
||||
id: "raid_level",
|
||||
title: gettext("RAID Level"),
|
||||
desc: gettext("Specifies RAID Level."),
|
||||
options: ['JBOD', '0', '1', '2', '5', '6', '1+0', '5+0', '6+0'],
|
||||
value: '0'});
|
||||
|
||||
ctrl.root_volume = new formFieldService.FormField({
|
||||
type: "radio",
|
||||
id: "root_volume",
|
||||
title: gettext("Root Volume."),
|
||||
desc: gettext(
|
||||
"Specifies whether root volume or not."),
|
||||
options: ['True', 'False'],
|
||||
value: 'False'});
|
||||
|
||||
ctrl.addLogicalDisk = function() {
|
||||
ctrl.logicalDisks.push({raid_level: ctrl.raid_level.value,
|
||||
size_gb: Number(ctrl.size_gb.value),
|
||||
is_root_volume: ctrl.root_volume.value === 'True'});
|
||||
};
|
||||
|
||||
ctrl.deleteLogicalDisk = function(disk) {
|
||||
var index = ctrl.logicalDisks.indexOf(disk);
|
||||
if (index !== -1) {
|
||||
ctrl.logicalDisks.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
ctrl.cancel = function() {
|
||||
$uibModalInstance.dismiss('cancel');
|
||||
};
|
||||
|
||||
ctrl.setTargetRaidConfig = function() {
|
||||
$uibModalInstance.close({target_raid_config: {logical_disks: ctrl.logicalDisks}});
|
||||
};
|
||||
}
|
||||
})();
|
|
@ -0,0 +1,81 @@
|
|||
<div class="modal-header" modal-draggable>
|
||||
<button type="button"
|
||||
class="close"
|
||||
ng-click="$dismiss()"
|
||||
aria-hidden="true"
|
||||
aria-label="Close">
|
||||
<span aria-hidden="true" class="fa fa-times"></span>
|
||||
</button>
|
||||
<h3 class="modal-title">{$ ::ctrl.modalTitle $}</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="SetTargetRaidConfigForm" name="SetTargetRaidConfigForm" class="well well-sm">
|
||||
<!-- raid config -->
|
||||
<form-field field="ctrl.size_gb" form="SetTargetRaidConfigForm"></form-field>
|
||||
<form-field field="ctrl.raid_level" form="SetTargetRaidConfigForm"></form-field>
|
||||
<form-field field="ctrl.root_volume"
|
||||
form="SetTargetRaidConfigForm"></form-field>
|
||||
<button class="btn btn-primary"
|
||||
type="button"
|
||||
ng-click="ctrl.addLogicalDisk()"
|
||||
ng-disabled="SetTargetRaidConfigForm.$invalid || ctrl.size_gb.value < 1"
|
||||
translate>
|
||||
Add Logical Disk
|
||||
</button>
|
||||
</form>
|
||||
<!-- Logical Disks -->
|
||||
<form id="LogicalDisksForm" name="LogicalDisksForm">
|
||||
<div>
|
||||
<table hz-table ng-cloak
|
||||
st-table="ctrl.logicalDisks"
|
||||
st-safe-src="ctrl.logicalDisksSrc"
|
||||
class="table table-rsp table-detail">
|
||||
<thead>
|
||||
<tr>
|
||||
<th translate class="rsp-p1" style="white-space:nowrap">
|
||||
Size GB
|
||||
</th>
|
||||
<th translate class="rsp-p1" style="white-space:nowrap">
|
||||
RAID Level
|
||||
</th>
|
||||
<th translate class="rsp-p1" style="width:100%">
|
||||
Root Volume
|
||||
</th>
|
||||
<th translate class="actions_column">
|
||||
Action
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="disk in ctrl.logicalDisks">
|
||||
<td class="rsp-p1">{$ disk.size_gb $}</td>
|
||||
<td class="rsp-p1">{$ disk.raid_level $}</td>
|
||||
<td class="rsp-p1">{$ disk.is_root_volume $}</td>
|
||||
<td>
|
||||
<a class="btn btn-default"
|
||||
ng-click="ctrl.deleteLogicalDisk(disk)">
|
||||
<span class="fa fa-minus"> </span>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<!--modal footer-->
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-default secondary"
|
||||
type="button"
|
||||
ng-click="ctrl.cancel()"
|
||||
translate>
|
||||
Cancel
|
||||
</button>
|
||||
<button class="btn btn-primary"
|
||||
type="button"
|
||||
ng-click="ctrl.setTargetRaidConfig()"
|
||||
translate>
|
||||
Set Target RAID Config
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright 2017 Intel Corporation
|
||||
*
|
||||
* 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';
|
||||
|
||||
/*
|
||||
* @ngdoc service
|
||||
* @name horizon.dashboard.admin.ironic.raidconfig.service
|
||||
* @description Service for setting the target raid configuration of a node
|
||||
*/
|
||||
angular
|
||||
.module('horizon.dashboard.admin.ironic')
|
||||
.factory('horizon.dashboard.admin.ironic.raidconfig.service',
|
||||
raidConfigService);
|
||||
|
||||
raidConfigService.$inject = [
|
||||
'$uibModal',
|
||||
'horizon.dashboard.admin.ironic.basePath',
|
||||
'horizon.app.core.openstack-service-api.ironic'
|
||||
];
|
||||
|
||||
function raidConfigService($uibModal, basePath, ironic) {
|
||||
var service = {
|
||||
setRaidConfig: setRaidConfig
|
||||
};
|
||||
return service;
|
||||
|
||||
/*
|
||||
* @description Set the target raid configuration of a specified node
|
||||
*
|
||||
* @param {object} node - node object
|
||||
* @return {promise}
|
||||
*/
|
||||
function setRaidConfig(node) {
|
||||
var promise;
|
||||
var options = {
|
||||
controller: "RaidConfigController as ctrl",
|
||||
backdrop: 'static',
|
||||
resolve: {
|
||||
node: function() {
|
||||
return node;
|
||||
}
|
||||
},
|
||||
templateUrl: basePath + '/raidconfig/raidconfig.html'
|
||||
};
|
||||
promise = $uibModal.open(options).result.then(
|
||||
function(result) {
|
||||
return ironic.nodeSetRaidConfig(node.uuid,
|
||||
result.target_raid_config);
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
Loading…
Reference in New Issue