def _get_server_hardware_mac(server_hardware): """Get the MAC address of the first PXE bootable port of an Ethernet port. :param: server_hardware: OneView Server Hardware object. :return: MAC of the first Ethernet and function 'a' port of the Server Hardware object. :raises: OneViewError if there is no Ethernet port on the Server Hardware or if there is no portMap on the Server Hardware requested. """ sh_physical_port = None if server_hardware.get('portMap'): for device in server_hardware.get('portMap', {}).get('deviceSlots', ()): for physical_port in device.get('physicalPorts', ()): if physical_port.get('type') == 'Ethernet': sh_physical_port = physical_port break if sh_physical_port: for virtual_port in sh_physical_port.get('virtualPorts', ()): # NOTE(nicodemos): Ironic oneview drivers needs to use a # port that type is Ethernet and function identifier 'a' for # this FlexNIC to be able to make a deploy using PXE. if virtual_port.get('portFunction') == 'a': return virtual_port.get('mac', ()).lower() raise exception.OneViewError( _("There is no Ethernet port on the Server Hardware: %s") % server_hardware.get('uri')) else: raise exception.OneViewError( _("The Server Hardware: %s doesn't have a list of adapters/slots, " "their ports and attributes. This information is available only " "for blade servers. Is this a rack server?") % server_hardware.get('uri'))
def _get_server_hardware_mac_from_ilo(server_hardware): """Get the MAC of Server Hardware's iLO controller. :param: server_hardware: a server hardware uuid or uri :return: MAC of Server Hardware's iLO controller. :raises: InvalidParameterValue if required iLO credentials are missing. :raises: OneViewError if can't get mac from a server hardware via iLO or if fails to get JSON object with the default path. """ try: ilo_client = get_ilorest_client(server_hardware) ilo_path = "/rest/v1/systems/1" hardware = jsonutils.loads(ilo_client.get(ilo_path).text) hardware_mac = hardware['HostCorrelation']['HostMACAddress'][0] except redfish.JsonDecodingError as exc: LOG.error("Failed in JSON object getting path: %s", ilo_path) raise exception.OneViewError(error=exc) except (ValueError, TypeError, IndexError) as exc: LOG.exception( "Failed to get mac from server hardware %(server_hardware)s " "via iLO. Error: %(message)s", { "server_hardware": server_hardware.get("uri"), "message": exc }) raise exception.OneViewError(error=exc) return hardware_mac
def get_hponeview_client(): """Generate an instance of the hpOneView client. Generates an instance of the hpOneView client using the hpOneView library. :returns: an instance of the OneViewClient :raises: InvalidParameterValue if mandatory information is missing on the node or on invalid input. :raises: OneViewError if try a secure connection without CA certificate. """ manager_url = prepare_manager_url(CONF.oneview.manager_url) insecure = CONF.oneview.allow_insecure_connections ssl_certificate = CONF.oneview.tls_cacert_file if not (insecure or ssl_certificate): msg = _("TLS CA certificate to connect with OneView is missing.") raise exception.OneViewError(error=msg) # NOTE(nicodemos) Ignore the CA certificate if it's an insecure connection if insecure and ssl_certificate: LOG.warning( "Performing an insecure connection with OneView, the CA " "certificate file: %s will be ignored.", ssl_certificate) ssl_certificate = None config = { "ip": manager_url, "credentials": { "userName": CONF.oneview.username, "password": CONF.oneview.password }, "ssl_certificate": ssl_certificate } return hponeview_client.OneViewClient(config)
def _check_applied_server_profile(oneview_client, node, predicate, positive, negative): """Check if node is in use by ironic in OneView. :param oneview_client: an instance of the OneView client :param node: an ironic node object :returns: Boolean value. True if node is in use by ironic, False otherwise. :raises OneViewError: if not possible to get OneView's information for the given node, if not possible to retrieve Server Hardware from OneView. """ oneview_info = common.get_oneview_info(node) try: server_hardware = oneview_client.server_hardware.get( oneview_info.get('server_hardware_uri')) except client_exception.HPOneViewResourceNotFound as e: msg = (_("Error while obtaining Server Hardware from node " "%(node_uuid)s. Error: %(error)s") % { 'node_uuid': node.uuid, 'error': e }) raise exception.OneViewError(error=msg) applied_sp_uri = node.driver_info.get('applied_server_profile_uri') result = predicate(server_hardware, applied_sp_uri) if result: LOG.debug(positive) else: LOG.debug(negative) return result
def has_server_profile(task, oneview_client): """Checks if the node's Server Hardware has a Server Profile associated. Function to check if the Server Profile is applied to the Server Hardware. :param oneview_client: an instance of the OneView client :param task: a TaskManager instance containing the node to act on. """ oneview_info = get_oneview_info(task.node) try: node_has_server_profile = ( oneview_client.get_server_profile_from_hardware(oneview_info) ) except oneview_exceptions.OneViewException as oneview_exc: LOG.error( "Failed to get server profile from OneView appliance for" " node %(node)s. Error: %(message)s", {"node": task.node.uuid, "message": oneview_exc} ) raise exception.OneViewError(error=oneview_exc) if not node_has_server_profile: raise exception.OperationNotPermitted( _("A Server Profile is not associated with node %s.") % task.node.uuid )
def _create_profile_from_template(oneview_client, server_profile_name, server_hardware_uri, server_profile_template): """Create a server profile from a server profile template. :param oneview_client: an HPE OneView Client instance :param server_profile_name: the name of the new server profile :param server_hardware_uri: the server_hardware assigned to server profile :param server_profile_template: the server profile template id or uri :returns: The new server profile generated with the name and server hardware passed on parameters :raises OneViewError: if the communication with OneView fails """ server_profile = oneview_client.server_profile_templates.get_new_profile( server_profile_template) server_profile['name'] = server_profile_name server_profile['serverHardwareUri'] = server_hardware_uri server_profile['serverProfileTemplateUri'] = "" try: return oneview_client.server_profiles.create(server_profile) except client_exception.HPOneViewException as e: msg = (_("Error while creating a Server Profile for Server Hardware: " "%(sh_uri)s. Error: %(error)s") % { 'sh_uri': server_hardware_uri, 'error': e }) raise exception.OneViewError(error=msg)
def validate_oneview_resources_compatibility(task): """Validates if the node configuration is consistent with OneView. This method calls python-oneviewclient functions to validate if the node configuration is consistent with the OneView resources it represents, including server_hardware_uri, server_hardware_type_uri, server_profile_template_uri, enclosure_group_uri and node ports. Also verifies if a Server Profile is applied to the Server Hardware the node represents. If any validation fails, python-oneviewclient will raise an appropriate OneViewException. :param: task: a TaskManager instance containing the node to act on. """ node = task.node node_ports = task.ports try: oneview_client = get_oneview_client() oneview_info = get_oneview_info(node) oneview_client.validate_node_server_hardware( oneview_info, node.properties.get('memory_mb'), node.properties.get('cpus')) oneview_client.validate_node_server_hardware_type(oneview_info) oneview_client.check_server_profile_is_applied(oneview_info) oneview_client.is_node_port_mac_compatible_with_server_profile( oneview_info, node_ports) oneview_client.validate_node_enclosure_group(oneview_info) oneview_client.validate_node_server_profile_template(oneview_info) except oneview_exceptions.OneViewException as oneview_exc: msg = (_("Error validating node resources with OneView: %s") % oneview_exc) LOG.error(msg) raise exception.OneViewError(error=msg)
def get_power_state(self, task): """Gets the current power state. :param task: a TaskManager instance. :returns: one of :mod:`ironic.common.states` POWER_OFF, POWER_ON or ERROR. :raises: OneViewError if fails to retrieve power state of OneView resource """ oneview_client = common.get_hponeview_client() server_hardware = task.node.driver_info.get('server_hardware_uri') try: server_hardware = oneview_client.server_hardware.get( server_hardware) except client_exception.HPOneViewException as exc: LOG.error( "Error getting power state for node %(node)s. Error:" "%(error)s", { 'node': task.node.uuid, 'error': exc }) raise exception.OneViewError(error=exc) else: power_state = server_hardware.get('powerState') return GET_POWER_STATE_MAP.get(power_state)
def test_validate_exception(self, mock_validate, mock_get_ov_client): mock_validate.side_effect = exception.OneViewError('message') with task_manager.acquire(self.context, self.node.uuid) as task: self.assertRaises( exception.InvalidParameterValue, task.driver.power.validate, task)
def set_power_state(self, task, power_state): """Turn the current power state on or off. :param task: a TaskManager instance. :param node: The Node. :param power_state: The desired power state POWER_ON, POWER_OFF or REBOOT from :mod:`ironic.common.states`. :raises: InvalidParameterValue if an invalid power state was specified. :raises: PowerStateFailure if the power couldn't be set to power_state. :raises: OneViewError if OneView fails setting the power state. """ oneview_info = common.get_oneview_info(task.node) oneview_client = common.get_oneview_client() LOG.debug('Setting power state of node %(node_uuid)s to ' '%(power_state)s', {'node_uuid': task.node.uuid, 'power_state': power_state}) try: if power_state == states.POWER_ON: oneview_client.power_on(oneview_info) elif power_state == states.POWER_OFF: oneview_client.power_off(oneview_info) elif power_state == states.REBOOT: oneview_client.power_off(oneview_info) oneview_client.power_on(oneview_info) else: raise exception.InvalidParameterValue( _("set_power_state called with invalid power state %s.") % power_state) except oneview_exceptions.OneViewException as exc: raise exception.OneViewError( _("Error setting power state: %s") % exc )
def set_boot_device(self, task, device, persistent=False): """Sets the boot device for a node. Sets the boot device to use on next reboot of the node. :param task: a task from TaskManager. :param device: the boot device, one of the supported devices listed in :mod:`ironic.common.boot_devices`. :param persistent: Boolean value. True if the boot device will persist to all future boots, False if not. Default: False. :raises: InvalidParameterValue if an invalid boot device is specified. :raises: OperationNotPermitted if the server has no server profile or if the server is already powered on. :raises: OneViewError if the communication with OneView fails """ oneview_info = common.get_oneview_info(task.node) if device not in self.get_supported_boot_devices(task): raise exception.InvalidParameterValue( _("Invalid boot device %s specified.") % device) LOG.debug("Setting boot device to %(device)s for node %(node)s", { "device": device, "node": task.node.uuid }) try: oneview_client = common.get_oneview_client() device_to_oneview = BOOT_DEVICE_MAPPING_TO_OV.get(device) oneview_client.set_boot_device(oneview_info, device_to_oneview) except oneview_exceptions.OneViewException as oneview_exc: msg = (_("Error setting boot device on OneView. Error: %s") % oneview_exc) raise exception.OneViewError(error=msg)
def _deallocate_server_hardware_from_ironic(node): """Deallocate Server Hardware from ironic. :param node: an ironic node object :raises OneViewError: if an error occurs while deallocating the Server Hardware to ironic """ oneview_info = common.get_oneview_info(node) oneview_client = common.get_oneview_client() oneview_client.power_off(oneview_info) applied_sp_uuid = oneview_utils.get_uuid_from_uri( oneview_info.get('applied_server_profile_uri')) try: oneview_client.delete_server_profile(applied_sp_uuid) _del_applied_server_profile_uri_field(node) LOG.info( _LI("Server Profile %(server_profile_uuid)s was successfully" " deleted from node %(node_uuid)s."), { "node_uuid": node.uuid, "server_profile_uuid": applied_sp_uuid }) except oneview_exception.OneViewException as e: msg = (_("Error while deleting applied Server Profile from node " "%(node_uuid)s. Error: %(error)s") % { 'node_uuid': node.uuid, 'error': e }) raise exception.OneViewError(node=node.uuid, reason=msg)
def _validate_server_profile_template_server_hardware_type( server_profile_template, server_hardware): """Validate if the Server Hardware Types are the same. Validate if the Server Profile Template and the Server Hardware have the same Server Hardware Type. :param: server_profile_template: OneView Server Profile Template object. :param: server_hardware: OneView Server Hardware object. :raises: OneViewError if the Server Profile Template and the Server Hardware does not have the same Server Hardware Type. """ spt_server_hardware_type_uri = ( server_profile_template.get('serverHardwareTypeUri')) sh_server_hardware_type_uri = server_hardware.get('serverHardwareTypeUri') if spt_server_hardware_type_uri != sh_server_hardware_type_uri: message = _( "Server profile template %(spt_uri)s serverHardwareTypeUri is " "inconsistent with server hardware %(server_hardware_uri)s " "serverHardwareTypeUri.") % { 'spt_uri': server_profile_template.get('uri'), 'server_hardware_uri': server_hardware.get('uri') } raise exception.OneViewError(message)
def set_boot_device(task): """Sets the boot device for a node. Sets the boot device to use on next reboot of the node. :param task: a task from TaskManager. :raises: InvalidParameterValue if an invalid boot device is specified. :raises: OneViewError if the communication with OneView fails """ oneview_client = common.get_hponeview_client() common.ensure_server_profile(task) driver_internal_info = task.node.driver_internal_info next_boot_device = driver_internal_info.get('next_boot_device') if next_boot_device: boot_device = next_boot_device.get('boot_device') persistent = next_boot_device.get('persistent') if boot_device not in sorted(BOOT_DEVICE_MAP_ONEVIEW): raise exception.InvalidParameterValue( _("Invalid boot device %s specified.") % boot_device) LOG.debug( "Setting boot device to %(boot_device)s and " "persistent to %(persistent)s for node %(node)s", { "boot_device": boot_device, "persistent": persistent, "node": task.node.uuid }) profile = task.node.driver_info.get('applied_server_profile_uri') boot_device = BOOT_DEVICE_MAP_ONEVIEW.get(boot_device) try: server_profile = oneview_client.server_profiles.get(profile) boot = server_profile.get('boot', {}) order = boot.get('order', []) if boot_device in order: order.remove(boot_device) order.insert(0, boot_device) boot['order'] = order server_profile['boot'] = boot oneview_client.server_profiles.update(server_profile, profile) set_onetime_boot(task) driver_internal_info.pop('next_boot_device', None) task.node.driver_internal_info = driver_internal_info task.node.save() except client_exception.HPOneViewException as oneview_exc: msg = (_("Error setting boot device on OneView. Error: %s") % oneview_exc) raise exception.OneViewError(error=msg) else: LOG.debug( "Not going to set boot device because there is no " "'next_boot_device' on driver_internal_info " "for the %(node)s", {"node": task.node.uuid})
def test_validate_fail_node_in_use_by_oneview( self, mock_is_node_in_use_by_oneview, mock_validate, mock_get_ov_client): mock_validate.return_value = True mock_is_node_in_use_by_oneview.side_effect = ( exception.OneViewError('message')) with task_manager.acquire(self.context, self.node.uuid) as task: self.assertRaises(exception.InvalidParameterValue, task.driver.power.validate, task)
def get_boot_device(self, task): """Get the current boot device from the node. Gets the boot device from the node 'next_boot_device on driver_internal_info namespace if exists. Gets through a request to OneView otherwise. :param task: a task from TaskManager. :returns: a dictionary containing: :boot_device: the boot device, one of :mod:`ironic.common.boot_devices` [PXE, DISK, CDROM] :persistent: Whether the boot device will persist to all future boots or not, None if it is unknown. :raises: InvalidParameterValue if the boot device is unknown :raises: OneViewError if the communication with OneView fails """ oneview_client = common.get_hponeview_client() driver_internal_info = task.node.driver_internal_info next_boot_device = driver_internal_info.get('next_boot_device') if next_boot_device: return next_boot_device driver_info = task.node.driver_info server_profile = driver_info.get('applied_server_profile_uri') try: profile = oneview_client.server_profiles.get(server_profile) primary_device = None boot = profile.get('boot', {}) boot_order = boot.get('order', []) if boot_order: primary_device = boot_order[0] except client_exception.HPOneViewException as exc: msg = _("Error on node: %(node)s while getting Server Profile: " "%(profile)s of the from OneView. Error: %(error)s.") % { 'profile': server_profile, 'node': task.node.uuid, 'error': exc } raise exception.OneViewError(msg) if primary_device not in BOOT_DEVICE_MAP_ONEVIEW_REV: raise exception.InvalidParameterValue( _("Unsupported boot device %(device)s for node: %(node)s") % { "device": primary_device, "node": task.node.uuid }) boot_device = { 'boot_device': BOOT_DEVICE_MAP_ONEVIEW_REV.get(primary_device), 'persistent': not _is_onetime_boot(task) } return boot_device
def set_power_state(self, task, power_state, timeout=None): """Set the power state of the task's node. :param task: a TaskManager instance. :param power_state: The desired power state POWER_ON, POWER_OFF or REBOOT from :mod:`ironic.common.states`. :param timeout: timeout (in seconds) positive integer (> 0) for any power state. ``None`` indicates to use default timeout. :raises: InvalidParameterValue if an invalid power state was specified. :raises: PowerStateFailure if the power couldn't be set to power_state. :raises: OneViewError if OneView fails setting the power state. """ client = common.get_hponeview_client() if deploy_utils.is_node_in_use_by_oneview(task.node): raise exception.PowerStateFailure(_( "Cannot set power state '%(power_state)s' to node %(node)s. " "The node is in use by OneView.") % {'power_state': power_state, 'node': task.node.uuid}) if power_state not in SET_POWER_STATE_MAP: raise exception.InvalidParameterValue( _("set_power_state called with invalid power state %s.") % power_state) LOG.debug('Setting power state of node %(node_uuid)s to ' '%(power_state)s', {'node_uuid': task.node.uuid, 'power_state': power_state}) server_hardware = task.node.driver_info.get('server_hardware_uri') timeout = (-1 if timeout is None else timeout) try: if power_state == states.POWER_ON: management.set_boot_device(task) client.server_hardware.update_power_state( SET_POWER_STATE_MAP.get(power_state), server_hardware, timeout=timeout) elif power_state == states.REBOOT: client.server_hardware.update_power_state( SET_POWER_STATE_MAP.get(states.POWER_OFF), server_hardware, timeout=timeout) management.set_boot_device(task) client.server_hardware.update_power_state( SET_POWER_STATE_MAP.get(states.POWER_ON), server_hardware, timeout=timeout) else: client.server_hardware.update_power_state( SET_POWER_STATE_MAP.get(power_state), server_hardware, timeout=timeout) except client_exception.HPOneViewException as exc: raise exception.OneViewError( _("Error setting power state: %s") % exc)
def set_boot_device(task): """Sets the boot device for a node. Sets the boot device to use on next reboot of the node. :param task: a task from TaskManager. :raises: InvalidParameterValue if an invalid boot device is specified. :raises: OperationNotPermitted if the server has no server profile or if the server is already powered on. :raises: OneViewError if the communication with OneView fails """ oneview_client = common.get_oneview_client() common.has_server_profile(task, oneview_client) driver_internal_info = task.node.driver_internal_info next_boot_device = driver_internal_info.get('next_boot_device') if next_boot_device: boot_device = next_boot_device.get('boot_device') persistent = next_boot_device.get('persistent') if boot_device not in sorted(BOOT_DEVICE_MAPPING_TO_OV): raise exception.InvalidParameterValue( _("Invalid boot device %s specified.") % boot_device) LOG.debug( "Setting boot device to %(boot_device)s and " "persistent to %(persistent)s for node %(node)s", { "boot_device": boot_device, "persistent": persistent, "node": task.node.uuid }) try: oneview_info = common.get_oneview_info(task.node) device_to_oneview = BOOT_DEVICE_MAPPING_TO_OV.get(boot_device) oneview_client.set_boot_device(oneview_info, device_to_oneview, onetime=not persistent) driver_internal_info.pop('next_boot_device', None) task.node.driver_internal_info = driver_internal_info task.node.save() except oneview_exceptions.OneViewException as oneview_exc: msg = (_("Error setting boot device on OneView. Error: %s") % oneview_exc) raise exception.OneViewError(error=msg) else: LOG.debug( "Not going to set boot device because there is no " "'next_boot_device' on driver_internal_info " "for the %(node)s", {"node": task.node.uuid})
def _validate_server_profile_template_manage_boot(server_profile_template): """Validate if the Server Profile Template allows to manage the boot order. :param: server_profile_template: OneView Server Profile Template object. :raises: OneViewError if the Server Profile Template does not allows to manage the boot order. """ manage_boot = server_profile_template.get('boot', {}).get('manageBoot') if not manage_boot: message = _("Server Profile Template: %s, does not allow to manage " "boot order.") % server_profile_template.get('uri') raise exception.OneViewError(message)
def _validate_server_profile_template_mac_type(oneview_client, oneview_info): """Validate if the node's Server Profile Template's MAC type is physical. :param: oneview_client: an instance of the HPE OneView client. :param: oneview_info: the OneView related info in an Ironic node. :raises: OneViewError if the node's Server Profile Template's MAC type is not physical. """ server_profile_template = oneview_client.server_profile_templates.get( oneview_info['server_profile_template_uri']) if server_profile_template.get('macType') != 'Physical': message = _("The server profile template %s is not set to use " "physical MAC.") % server_profile_template.get('uri') raise exception.OneViewError(message)
def test_node_stay_manageable_maintenance_when_raise_exception( self, mock_is_node_in_use_by_oneview, mock_node_get): mock_node_get.get.return_value = self.node _setup_node_in_manageable_state(self.node) side_effect = exception.OneViewError('boom') mock_is_node_in_use_by_oneview.side_effect = side_effect self.manager.iter_nodes.return_value = nodes_freed_by_oneview self.deploy._periodic_check_nodes_freed_by_oneview( self.manager, self.context) mock_is_node_in_use_by_oneview.assert_called_once_with(self.node) self.assertFalse(self.manager.update_node.called) self.assertFalse(self.manager.do_provisioning_action.called) self.assertTrue(self.node.maintenance) self.assertEqual(common.NODE_IN_USE_BY_ONEVIEW, self.node.maintenance_reason)
def is_node_in_use_by_oneview(node): """Check if node is in use by OneView user. :param node: an ironic node object :returns: Boolean value. True if node is in use by OneView, False otherwise. :raises OneViewError: if not possible to get OneView's informations for the given node, if not possible to retrieve Server Hardware from OneView. """ oneview_info = common.get_oneview_info(node) oneview_client = common.get_oneview_client() sh_uuid = oneview_utils.get_uuid_from_uri( oneview_info.get("server_hardware_uri")) try: server_hardware = oneview_client.get_server_hardware_by_uuid(sh_uuid) except oneview_exception.OneViewResourceNotFoundError as e: msg = (_("Error while obtaining Server Hardware from node " "%(node_uuid)s. Error: %(error)s") % { 'node_uuid': node.uuid, 'error': e }) raise exception.OneViewError(error=msg) applied_sp_uri = (node.driver_info.get('applied_server_profile_uri')) # Check if Profile exists in Oneview and it is different of the one # applied by ironic if (server_hardware.server_profile_uri not in (None, '') and applied_sp_uri != server_hardware.server_profile_uri): LOG.warning(_LW("Node %s is already in use by OneView."), node.uuid) return True else: LOG.debug( _("Hardware %(hardware_uri)s is free for use by " "ironic on node %(node_uuid)s."), { "hardware_uri": server_hardware.uri, "node_uuid": node.uuid }) return False
def validate_oneview_resources_compatibility(oneview_client, task): """Validates if the node configuration is consistent with OneView. This method calls python-oneviewclient functions to validate if the node configuration is consistent with the OneView resources it represents, including server_hardware_uri, server_hardware_type_uri, server_profile_template_uri, enclosure_group_uri and node ports. Also verifies if a Server Profile is applied to the Server Hardware the node represents when in pre-allocation model. If any validation fails, python-oneviewclient will raise an appropriate OneViewException. :param oneview_client: an instance of the OneView client :param: task: a TaskManager instance containing the node to act on. """ node_ports = task.ports oneview_info = get_oneview_info(task.node) try: spt_uuid = oneview_utils.get_uuid_from_uri( oneview_info.get("server_profile_template_uri")) oneview_client.validate_node_server_profile_template(oneview_info) oneview_client.validate_node_server_hardware_type(oneview_info) oneview_client.validate_node_enclosure_group(oneview_info) oneview_client.validate_node_server_hardware( oneview_info, task.node.properties.get('memory_mb'), task.node.properties.get('cpus')) # NOTE(thiagop): Support to pre-allocation will be dropped in the Pike # release. # NOTE(mrtenio): The Server Profile Template needs to have a physical # MAC when using dynamic_allocation. This will be the default behavior # in the Pike Release. if is_dynamic_allocation_enabled(task.node): oneview_client.is_node_port_mac_compatible_with_server_hardware( oneview_info, node_ports) oneview_client.validate_server_profile_template_mac_type(spt_uuid) else: oneview_client.check_server_profile_is_applied(oneview_info) oneview_client.is_node_port_mac_compatible_with_server_profile( oneview_info, node_ports) except oneview_exceptions.OneViewException as oneview_exc: msg = (_("Error validating node resources with OneView: %s") % oneview_exc) raise exception.OneViewError(error=msg)
def get_boot_device(self, task): """Get the current boot device from the node. Gets the boot device from the node 'next_boot_device on driver_internal_info namespace if exists. Gets through a request to OneView otherwise. :param task: a task from TaskManager. :returns: a dictionary containing: :boot_device: the boot device, one of :mod:`ironic.common.boot_devices` [PXE, DISK, CDROM] :persistent: Whether the boot device will persist to all future boots or not, None if it is unknown. :raises: OperationNotPermitted if no Server Profile is associated with the node :raises: InvalidParameterValue if the boot device is unknown :raises: OneViewError if the communication with OneView fails """ driver_internal_info = task.node.driver_internal_info next_boot_device = driver_internal_info.get('next_boot_device') if next_boot_device: return next_boot_device oneview_info = common.get_oneview_info(task.node) try: boot_order = self.oneview_client.get_boot_order(oneview_info) except oneview_exceptions.OneViewException as oneview_exc: msg = (_("Error getting boot device from OneView. Error: %s") % oneview_exc) raise exception.OneViewError(msg) primary_device = boot_order[0] if primary_device not in BOOT_DEVICE_OV_TO_GENERIC: raise exception.InvalidParameterValue( _("Unsupported boot Device %(device)s for Node: %(node)s") % { "device": primary_device, "node": task.node.uuid }) boot_device = { 'boot_device': BOOT_DEVICE_OV_TO_GENERIC.get(primary_device), 'persistent': True, } return boot_device
def set_power_state(self, task, power_state): """Turn the current power state on or off. :param task: a TaskManager instance. :param power_state: The desired power state POWER_ON, POWER_OFF or REBOOT from :mod:`ironic.common.states`. :raises: InvalidParameterValue if an invalid power state was specified. :raises: PowerStateFailure if the power couldn't be set to power_state. :raises: OneViewError if OneView fails setting the power state. """ if deploy_utils.is_node_in_use_by_oneview(self.oneview_client, task.node): raise exception.PowerStateFailure( _("Cannot set power state '%(power_state)s' to node %(node)s. " "The node is in use by OneView.") % { 'power_state': power_state, 'node': task.node.uuid }) oneview_info = common.get_oneview_info(task.node) LOG.debug( 'Setting power state of node %(node_uuid)s to ' '%(power_state)s', { 'node_uuid': task.node.uuid, 'power_state': power_state }) try: if power_state == states.POWER_ON: management.set_boot_device(task) self.oneview_client.power_on(oneview_info) elif power_state == states.POWER_OFF: self.oneview_client.power_off(oneview_info) elif power_state == states.REBOOT: self.oneview_client.power_off(oneview_info) management.set_boot_device(task) self.oneview_client.power_on(oneview_info) else: raise exception.InvalidParameterValue( _("set_power_state called with invalid power state %s.") % power_state) except oneview_exceptions.OneViewException as exc: raise exception.OneViewError( _("Error setting power state: %s") % exc)
def has_server_profile(task, client): """Checks if the node's Server Hardware has a Server Profile associated. Function to check if the Server Profile is applied to the Server Hardware. :param client: an instance of the OneView client :param task: a TaskManager instance containing the node to act on. """ try: profile = task.node.driver_info.get('applied_server_profile_uri') client.server_profiles.get(profile) except client_exception.HPOneViewException as exc: LOG.error( "Failed to get server profile from OneView appliance for" " node %(node)s. Error: %(message)s", {"node": task.node.uuid, "message": exc} ) raise exception.OneViewError(error=exc)
def _validate_spt_enclosure_group(server_profile_template, server_hardware): """Validate Server Profile Template's Enclosure Group and Server Hardware's. :param: server_profile_template: OneView Server Profile Template object. :param: server_hardware: OneView Server Hardware object. :raises: OneViewError if the Server Profile Template's Enclosure Group does not match the Server Hardware's. """ spt_enclosure_group_uri = server_profile_template.get('enclosureGroupUri') sh_enclosure_group_uri = server_hardware.get('serverGroupUri') if spt_enclosure_group_uri != sh_enclosure_group_uri: message = _("Server profile template %(spt_uri)s enclosureGroupUri is " "inconsistent with server hardware %(sh_uri)s " "serverGroupUri.") % { 'spt_uri': server_profile_template.get('uri'), 'sh_uri': server_hardware.get('uri') } raise exception.OneViewError(message)
def inner(self, *args, **kwargs): oneview_client = self.oneview_client task = args[0] oneview_info = get_oneview_info(task.node) try: node_has_server_profile = ( oneview_client.get_server_profile_from_hardware(oneview_info)) except oneview_exceptions.OneViewException as oneview_exc: LOG.error( _LE("Failed to get server profile from OneView appliance for" " node %(node)s. Error: %(message)s"), { "node": task.node.uuid, "message": oneview_exc }) raise exception.OneViewError(error=oneview_exc) if not node_has_server_profile: raise exception.OperationNotPermitted( _("A Server Profile is not associated with node %s.") % task.node.uuid) return func(self, *args, **kwargs)
def _validate_node_server_hardware_type(oneview_client, oneview_info): """Validate if the node's Server Hardware Type matches Server Hardware's. :param: oneview_client: the HPE OneView Client. :param: oneview_info: the OneView related info in an Ironic node. :raises: OneViewError if the node's Server Hardware Type group doesn't match the Server Hardware's. """ node_server_hardware_type_uri = oneview_info['server_hardware_type_uri'] server_hardware = oneview_client.server_hardware.get( oneview_info['server_hardware_uri']) server_hardware_sht_uri = server_hardware.get('serverHardwareTypeUri') if server_hardware_sht_uri != node_server_hardware_type_uri: message = _("Node server_hardware_type_uri is inconsistent " "with OneView's server hardware %(server_hardware_uri)s " "serverHardwareTypeUri.") % { 'server_hardware_uri': server_hardware.get('uri') } raise exception.OneViewError(message)
def ensure_server_profile(task): """Checks if the node's Server Hardware has a Server Profile associated. Function to check if the Server Profile is applied to the Server Hardware. :param task: a TaskManager instance containing the node to act on. :raises: OneViewError if failed to get server profile from OneView """ oneview_client = get_hponeview_client() try: profile_uri = task.node.driver_info.get('applied_server_profile_uri') oneview_client.server_profiles.get(profile_uri) except client_exception.HPOneViewException as exc: LOG.error( "Failed to get server profile: %(profile)s from OneView appliance " "for node %(node)s. Error: %(message)s", { "profile": profile_uri, "node": task.node.uuid, "message": exc }) raise exception.OneViewError(error=exc)