/* * 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.')); } }; } })();