示例#1
0
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'))
示例#2
0
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
示例#3
0
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)
示例#4
0
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
示例#5
0
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
        )
示例#6
0
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)
示例#7
0
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)
示例#8
0
    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)
示例#9
0
 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)
示例#10
0
    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
            )
示例#11
0
    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)
示例#12
0
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)
示例#13
0
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)
示例#14
0
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})
示例#15
0
 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)
示例#16
0
    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
示例#17
0
    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)
示例#18
0
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})
示例#19
0
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)
示例#20
0
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)
示例#21
0
 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)
示例#22
0
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
示例#23
0
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)
示例#24
0
    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
示例#25
0
    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)
示例#26
0
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)
示例#27
0
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)
示例#28
0
 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)
示例#29
0
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)
示例#30
0
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)