c73492c877
Adds support for selecting from the enabled interfaces for the underlying driver while creating nodes. A new tab is added in the enroll node modal. Also enhanced "package.json" and "karma.conf.js" to widen the range of accepted versions and jasmine capabilities. Change-Id: Ie1b24cbf147b849a1d57fcdcbd735429ea7c9e34 Partial-Bug: #1672729
196 lines
6.8 KiB
JavaScript
196 lines
6.8 KiB
JavaScript
/*
|
|
* Copyright 2017 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';
|
|
|
|
/**
|
|
* Controller used to edit an existing Ironic node
|
|
*/
|
|
angular
|
|
.module('horizon.dashboard.admin.ironic')
|
|
.controller('EditNodeController', EditNodeController);
|
|
|
|
EditNodeController.$inject = [
|
|
'$rootScope',
|
|
'$controller',
|
|
'$uibModalInstance',
|
|
'horizon.framework.widgets.toast.service',
|
|
'horizon.app.core.openstack-service-api.ironic',
|
|
'horizon.dashboard.admin.ironic.events',
|
|
'horizon.dashboard.admin.ironic.driverInterfaces',
|
|
'horizon.dashboard.admin.ironic.edit-node.service',
|
|
'horizon.dashboard.admin.ironic.update-patch.service',
|
|
'$log',
|
|
'node'
|
|
];
|
|
|
|
function EditNodeController($rootScope,
|
|
$controller,
|
|
$uibModalInstance,
|
|
toastService,
|
|
ironic,
|
|
ironicEvents,
|
|
driverInterfaces,
|
|
editNodeService,
|
|
updatePatchService,
|
|
$log,
|
|
node) {
|
|
var ctrl = this;
|
|
|
|
$controller('BaseNodeController',
|
|
{ctrl: ctrl,
|
|
$uibModalInstance: $uibModalInstance});
|
|
|
|
ctrl.modalTitle = gettext("Edit Node");
|
|
ctrl.submitButtonTitle = gettext("Update Node");
|
|
|
|
ctrl.baseNode = null;
|
|
|
|
var instanceInfoId = "instance_info";
|
|
ctrl.propertyCollections.push(
|
|
{id: instanceInfoId,
|
|
formId: "instance_info_form",
|
|
title: gettext("Instance Info"),
|
|
addPrompt: gettext("Add Instance Property"),
|
|
placeholder: gettext("Instance Property Name")});
|
|
|
|
ctrl.node[instanceInfoId] = {};
|
|
|
|
init(node);
|
|
|
|
function init(node) {
|
|
ctrl._loadDrivers().then(function() {
|
|
_loadNodeData(node.uuid);
|
|
});
|
|
ctrl._getImages();
|
|
}
|
|
|
|
function _loadNodeData(nodeId) {
|
|
ironic.getNode(nodeId).then(function(node) {
|
|
ctrl.baseNode = angular.copy(node);
|
|
ctrl.node.name = node.name;
|
|
ctrl.node.resource_class = node.resource_class;
|
|
for (var i = 0; i < ctrl.drivers.length; i++) {
|
|
if (ctrl.drivers[i].name === node.driver) {
|
|
ctrl.selectedDriver = ctrl.drivers[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
ctrl.loadDriver(node.driver).then(function() {
|
|
angular.forEach(node.driver_info, function(value, property) {
|
|
if (angular.isDefined(ctrl.driverProperties[property])) {
|
|
ctrl.driverProperties[property].inputValue = value;
|
|
}
|
|
});
|
|
|
|
if (ctrl.driverType === 'classic') {
|
|
ctrl.node.network_interface = node.network_interface;
|
|
ctrl.node.storage_interface = node.storage_interface;
|
|
} else {
|
|
angular.forEach(
|
|
ctrl.driverInterfaceFields,
|
|
function(field, interfaceName) {
|
|
field.value = ctrl.baseNode[interfaceName + '_interface'];
|
|
});
|
|
}
|
|
});
|
|
|
|
ctrl.node.properties = angular.copy(node.properties);
|
|
ctrl.node.extra = angular.copy(node.extra);
|
|
ctrl.node.instance_info = angular.copy(node.instance_info);
|
|
ctrl.node.uuid = node.uuid;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @description Construct a patch that converts source node into
|
|
* target node
|
|
*
|
|
* @param {object} sourceNode - Source node
|
|
* @param {object} targetNode - Target node
|
|
* @return {object[]} Array of patch instructions
|
|
*/
|
|
ctrl.buildPatch = function(sourceNode, targetNode) {
|
|
var patcher = new updatePatchService.UpdatePatch();
|
|
var PatchItem = function PatchItem(id, path) {
|
|
this.id = id;
|
|
this.path = path;
|
|
};
|
|
|
|
angular.forEach([new PatchItem("name", "/name"),
|
|
new PatchItem("resource_class", "/resource_class"),
|
|
new PatchItem("driver", "/driver"),
|
|
new PatchItem("properties", "/properties"),
|
|
new PatchItem("extra", "/extra"),
|
|
new PatchItem("driver_info", "/driver_info"),
|
|
new PatchItem("instance_info", "/instance_info")],
|
|
function(item) {
|
|
patcher.buildPatch(sourceNode[item.id],
|
|
targetNode[item.id],
|
|
item.path);
|
|
});
|
|
|
|
angular.forEach(driverInterfaces, function(interfaceName) {
|
|
var propName = interfaceName + '_interface';
|
|
if (angular.isDefined(sourceNode[propName])) {
|
|
patcher.buildPatch(sourceNode[propName],
|
|
targetNode[propName],
|
|
'/' + propName);
|
|
}
|
|
});
|
|
|
|
return patcher.getPatch();
|
|
};
|
|
|
|
ctrl.submit = function() {
|
|
angular.forEach(ctrl.driverProperties, function(property, name) {
|
|
$log.debug(name +
|
|
", required = " + property.isRequired() +
|
|
", active = " + property.isActive() +
|
|
", input-value = " + property.getInputValue() +
|
|
", default-value = " + property.getDefaultValue());
|
|
if (property.isActive() &&
|
|
property.getInputValue() &&
|
|
property.getInputValue() !== property.getDefaultValue()) {
|
|
$log.debug("Setting driver property " + name + " to " +
|
|
property.inputValue);
|
|
ctrl.node.driver_info[name] = property.inputValue;
|
|
}
|
|
});
|
|
|
|
angular.forEach(ctrl.driverInterfaceFields, function(field, interfaceName) {
|
|
ctrl.node[interfaceName + '_interface'] = field.value;
|
|
});
|
|
|
|
$log.info("Updating node " + JSON.stringify(ctrl.baseNode));
|
|
$log.info("to " + JSON.stringify(ctrl.node));
|
|
|
|
var patch = ctrl.buildPatch(ctrl.baseNode, ctrl.node);
|
|
$log.info("patch = " + JSON.stringify(patch.patch));
|
|
if (patch.status === updatePatchService.UpdatePatch.status.OK) {
|
|
ironic.updateNode(ctrl.baseNode.uuid, patch.patch).then(function(node) {
|
|
$rootScope.$emit(ironicEvents.EDIT_NODE_SUCCESS);
|
|
$uibModalInstance.close(node);
|
|
});
|
|
} else {
|
|
toastService.add('error',
|
|
gettext('Unable to create node update patch.'));
|
|
}
|
|
};
|
|
}
|
|
})();
|