Beispiel #1
0
    def get_boot_device(self, task):
        """Get the current boot device for the task's node.

        Provides the current boot device of the node.

        :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
        """
        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
Beispiel #2
0
    def validate(self, task):
        """Checks required info on 'driver_info' and validates node with OneView

        Validates whether the 'driver_info' property of the supplied
        task's node contains the required info such as server_hardware_uri,
        server_hardware_type, server_profile_template_uri and
        enclosure_group_uri. Also, checks if the server profile of the node is
        applied, if NICs are valid for the server profile of the node, and if
        the server hardware attributes (ram, memory, vcpus count) are
        consistent with OneView.

        :param task: a task from TaskManager.
        :raises: InvalidParameterValue if parameters set are inconsistent with
                 resources in OneView
        """

        common.verify_node_info(task.node)

        try:
            common.validate_oneview_resources_compatibility(task)
        except exception.OneViewError as oneview_exc:
            raise exception.InvalidParameterValue(oneview_exc)
    def set_boot_device(self, task, device, persistent=False):
        """Set the boot device for a node.

        Set 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: MissingParameterValue if a required parameter is missing.
        :raises: IloOperationError on an error from IloClient library.
        """

        try:
            boot_device = BOOT_DEVICE_MAPPING_TO_ILO[device]
        except KeyError:
            raise exception.InvalidParameterValue(
                _("Invalid boot device %s specified.") % device)
        try:
            ilo_object = ilo_common.get_ilo_object(task.node)

            if not persistent:
                ilo_object.set_one_time_boot(boot_device)
            else:
                ilo_object.update_persistent_boot([boot_device])

        except ilo_error.IloError as ilo_exception:
            operation = _("Setting %s as boot device") % device
            raise exception.IloOperationError(operation=operation,
                                              error=ilo_exception)

        LOG.debug("Node %(uuid)s set to boot from %(device)s.", {
            'uuid': task.node.uuid,
            'device': device
        })
Beispiel #4
0
    def test_node_power_action_failed_getting_state(self):
        """Test for exception when we can't get the current power state."""
        node = obj_utils.create_test_node(self.context,
                                          uuid=uuidutils.generate_uuid(),
                                          driver='fake',
                                          power_state=states.POWER_ON)
        task = task_manager.TaskManager(self.context, node.uuid)

        with mock.patch.object(self.driver.power,
                               'get_power_state') as get_power_state_mock:
            get_power_state_mock.side_effect = (
                exception.InvalidParameterValue('failed getting power state'))

            self.assertRaises(exception.InvalidParameterValue,
                              conductor_utils.node_power_action, task,
                              states.POWER_ON)

            node.refresh()
            get_power_state_mock.assert_called_once_with(mock.ANY)
            self.assertEqual(states.POWER_ON, node['power_state'])
            self.assertIsNone(node['target_power_state'])
            self.assertIsNotNone(node['last_error'])
Beispiel #5
0
def node_set_boot_mode(task, mode):
    """Set the boot mode for a node.

    Sets the boot mode for a node if the node's driver interface
    contains a 'management' interface.

    If the node that the boot mode change is being requested for
    is in ADOPTING state, the boot mode will not be set as that
    change could potentially result in the future running state of
    an adopted node being modified erroneously.

    :param task: a TaskManager instance.
    :param mode: Boot mode. Values are one of
        :mod:`ironic.common.boot_modes`
    :raises: InvalidParameterValue if the validation of the
             ManagementInterface fails.
    :raises: DriverOperationError or its derivative in case
             of driver runtime error.
    :raises: UnsupportedDriverExtension if current driver does not have
             vendor interface or method is unsupported.
    """
    if task.node.provision_state == states.ADOPTING:
        return

    task.driver.management.validate(task)

    boot_modes = task.driver.management.get_supported_boot_modes(task)

    if mode not in boot_modes:
        msg = _("Unsupported boot mode %(mode)s specified for "
                "node %(node_id)s. Supported boot modes are: "
                "%(modes)s") % {
                    'mode': mode,
                    'modes': ', '.join(boot_modes),
                    'node_id': task.node.uuid
                }
        raise exception.InvalidParameterValue(msg)

    task.driver.management.set_boot_mode(task, mode=mode)
Beispiel #6
0
def _parse_config_option():
    """Parse config file options.

    This method checks config file options validity.

    :raises: InvalidParameterValue, if config option has invalid value.
    """
    error_msgs = []
    if not os.path.isdir(CONF.irmc.remote_image_share_root):
        error_msgs.append(
            _("Value '%s' for remote_image_share_root isn't a directory "
              "or doesn't exist.") %
            CONF.irmc.remote_image_share_root)
    if CONF.irmc.remote_image_share_type.lower() not in ('nfs', 'cifs'):
        error_msgs.append(
            _("Value '%s' for remote_image_share_type is not supported "
              "value either 'NFS' or 'CIFS'.") %
            CONF.irmc.remote_image_share_type)
    if error_msgs:
        msg = (_("The following errors were encountered while parsing "
                 "config file:%s") % error_msgs)
        raise exception.InvalidParameterValue(msg)
Beispiel #7
0
def validate_boot_option_for_uefi(node):
    """In uefi boot mode, validate if the boot option is compatible.

    This method raises exception if whole disk image being deployed
    in UEFI boot mode without 'boot_option' being set to 'local'.

    :param node: a single Node.
    :raises: InvalidParameterValue
    """

    boot_mode = deploy_utils.get_boot_mode_for_deploy(node)
    boot_option = iscsi_deploy.get_boot_option(node)
    if (boot_mode == 'uefi'
            and node.driver_internal_info.get('is_whole_disk_image')
            and boot_option != 'local'):
        LOG.error(
            _LE("Whole disk image with netboot is not supported in UEFI "
                "boot mode."))
        raise exception.InvalidParameterValue(
            _("Conflict: Whole disk image being used for deploy, but "
              "cannot be used with node %(node_uuid)s configured to use "
              "UEFI boot with netboot option") % {'node_uuid': node.uuid})
Beispiel #8
0
    def set_power_state(self, task, pstate):
        """Turn the power on or off.

        :param task: a TaskManager instance containing the node to act on.
        :param pstate: a power state that will be set on the task's node.
        :raises: IPMIFailure when the native ipmi call fails.
        :raises: InvalidParameterValue when an invalid power state
                 is specified or required ipmi credentials are missing.
        :raises: PowerStateFailure when invalid power state is returned
                 from ipmi.
        """

        driver_info = _parse_driver_info(task.node)

        if pstate == states.POWER_ON:
            _power_on(driver_info)
        elif pstate == states.POWER_OFF:
            _power_off(driver_info)
        else:
            raise exception.InvalidParameterValue(
                _("set_power_state called with an invalid power state: %s.") %
                pstate)
Beispiel #9
0
    def set_power_state(self, task, pstate):
        """Turn the power on or off.

        Set the power state of a node.

        :param task: a TaskManager instance containing the node to act on.
        :param pstate: Either POWER_ON or POWER_OFF from :class:
            `ironic.common.states`.
        :raises: InvalidParameterValue if an invalid power state was specified.
        :raises: PowerStateFailure if the desired power state couldn't be set.
        """

        if pstate == states.POWER_ON:
            state = _power_on(task.node)
        elif pstate == states.POWER_OFF:
            state = _power_off(task.node)
        else:
            raise exception.InvalidParameterValue(
                _("set_power_state called with invalid power state."))

        if state != pstate:
            raise exception.PowerStateFailure(pstate=pstate)
    def validate(self, task, method, http_method, **kwargs):
        """Validates the vendor method's parameters.

        This method validates whether the supplied data contains the required
        information for the driver.

        :param task: a TaskManager instance.
        :param method: name of vendor method.
        :param http_method: HTTP method.
        :param kwargs: data passed to vendor's method.
        :raises: InvalidParameterValue if supplied data is not valid.
        :raises: MissingParameterValue if parameters missing in supplied data.
        """
        try:
            if 'statistics' in method:
                self._validate_statistics_methods(method, **kwargs)
            else:
                self._validate_policy_methods(method, **kwargs)
        except json_schema_exc.ValidationError as e:
            raise exception.InvalidParameterValue(
                _('Input data validation '
                  'error: %s') % e)
Beispiel #11
0
    def validate(self, task):
        """Check that the node's 'driver_info' is valid.

        Check that the node's 'driver_info' contains the requisite fields
        and that an SSH connection to the node can be established.

        :param task: a TaskManager instance containing the node to act on.
        :raises: InvalidParameterValue if any connection parameters are
            incorrect or if ssh failed to connect to the node.
        :raises: MissingParameterValue if no ports are enrolled for the given
                 node.
        """
        if not driver_utils.get_node_mac_addresses(task):
            raise exception.MissingParameterValue(
                _("Node %s does not have any port associated with it.") %
                task.node.uuid)
        try:
            _get_connection(task.node)
        except exception.SSHConnectFailed as e:
            raise exception.InvalidParameterValue(
                _("SSH connection cannot"
                  " be established: %s") % e)
Beispiel #12
0
    def validate(self, task):
        """Validate the driver-specific Node deployment info."""
        task.driver.boot.validate(task)

        node = task.node
        iwdi = node.driver_internal_info.get('is_whole_disk_image')
        if not iwdi and deploy_utils.get_boot_option(node) == "netboot":
            raise exception.InvalidParameterValue(
                _("Node %(node)s is configured to use the %(driver)s driver "
                  "which does not support netboot.") % {
                      'node': node.uuid,
                      'driver': node.driver
                  })

        params = {}
        image_source = node.instance_info.get('image_source')
        params['instance_info.image_source'] = image_source
        error_msg = _('Node %s failed to validate deploy image info. Some '
                      'parameters were missing') % node.uuid
        deploy_utils.check_for_missing_params(params, error_msg)
        # validate root device hints, proper exceptions are raised from there
        _parse_root_device_hints(node)
Beispiel #13
0
    def activate_license(self, task, **kwargs):
        """Activates iLO Advanced license.

        :param task: a TaskManager object.
        :raises: InvalidParameterValue, if any of the arguments are invalid.
        :raises: NodeCleaningFailure, on failure to execute of clean step.
        """
        ilo_license_key = kwargs.get('ilo_license_key')
        node = task.node

        if not isinstance(ilo_license_key, str):
            msg = (_("Value of 'ilo_license_key' must be a string instead of "
                     "'%(value)s'. Step 'activate_license' is not executed "
                     "for %(node)s.")
                   % {'value': ilo_license_key, 'node': node.uuid})
            LOG.error(msg)
            raise exception.InvalidParameterValue(msg)

        LOG.debug("Activating iLO license for node %(node)s ...",
                  {'node': node.uuid})
        _execute_ilo_step(node, 'activate_license', ilo_license_key)
        LOG.info("iLO license activated for node %s.", node.uuid)
Beispiel #14
0
    def _get_chassis_collection(self, marker, limit, sort_key, sort_dir,
                                resource_url=None, fields=None):
        limit = api_utils.validate_limit(limit)
        sort_dir = api_utils.validate_sort_dir(sort_dir)
        marker_obj = None
        if marker:
            marker_obj = objects.Chassis.get_by_uuid(pecan.request.context,
                                                     marker)

        if sort_key in self.invalid_sort_key_list:
            raise exception.InvalidParameterValue(
                _("The sort_key value %(key)s is an invalid field for sorting")
                % {'key': sort_key})

        chassis = objects.Chassis.list(pecan.request.context, limit,
                                       marker_obj, sort_key=sort_key,
                                       sort_dir=sort_dir)
        return ChassisCollection.convert_with_links(chassis, limit,
                                                    url=resource_url,
                                                    fields=fields,
                                                    sort_key=sort_key,
                                                    sort_dir=sort_dir)
Beispiel #15
0
def validate_boot_parameters_for_trusted_boot(node):
    """Check if boot parameters are valid for trusted boot."""
    boot_mode = boot_mode_utils.get_boot_mode(node)
    boot_option = deploy_utils.get_boot_option(node)
    is_whole_disk_image = node.driver_internal_info.get('is_whole_disk_image')
    # 'is_whole_disk_image' is not supported by trusted boot, because there is
    # no Kernel/Ramdisk to measure at all.
    if (boot_mode != 'bios' or is_whole_disk_image
            or boot_option != 'netboot'):
        msg = (_("Trusted boot is only supported in BIOS boot mode with "
                 "netboot and without whole_disk_image, but Node "
                 "%(node_uuid)s was configured with boot_mode: %(boot_mode)s, "
                 "boot_option: %(boot_option)s, is_whole_disk_image: "
                 "%(is_whole_disk_image)s: at least one of them is wrong, and "
                 "this can be caused by enable secure boot.") % {
                     'node_uuid': node.uuid,
                     'boot_mode': boot_mode,
                     'boot_option': boot_option,
                     'is_whole_disk_image': is_whole_disk_image
                 })
        LOG.error(msg)
        raise exception.InvalidParameterValue(msg)
Beispiel #16
0
def validate_configuration(raid_config, raid_config_schema):
    """Validates the RAID configuration passed using JSON schema.

    This method validates a RAID configuration against a RAID configuration
    schema.

    :param raid_config: A dictionary containing RAID configuration information
    :param raid_config_schema: A dictionary which is the schema to be used for
        validation.
    :raises: InvalidParameterValue, if validation of the RAID configuration
        fails.
    """
    try:
        jsonschema.validate(raid_config, raid_config_schema)
    except json_schema_exc.ValidationError as e:
        # NOTE: Even though e.message is deprecated in general, it is said
        # in jsonschema documentation to use this still.
        msg = _("RAID config validation error: %s") % e.message
        raise exception.InvalidParameterValue(msg)

    # Check if there are multiple root volumes specified.
    _check_and_return_root_volumes(raid_config)
Beispiel #17
0
    def update_volume_connector(self, ident, connector_info):
        if 'uuid' in connector_info:
            msg = _("Cannot overwrite UUID for an existing Volume Connector.")
            raise exception.InvalidParameterValue(err=msg)

        try:
            with _session_for_write() as session:
                query = model_query(models.VolumeConnector)
                query = add_identity_filter(query, ident)
                ref = query.one()
                orig_type = ref['type']
                orig_connector_id = ref['connector_id']
                ref.update(connector_info)
                session.flush()
        except db_exc.DBDuplicateEntry:
            raise exception.VolumeConnectorTypeAndIdAlreadyExists(
                type=connector_info.get('type', orig_type),
                connector_id=connector_info.get('connector_id',
                                                orig_connector_id))
        except NoResultFound:
            raise exception.VolumeConnectorNotFound(connector=ident)
        return ref
Beispiel #18
0
    def _get_conductors_collection(self,
                                   marker,
                                   limit,
                                   sort_key,
                                   sort_dir,
                                   resource_url=None,
                                   fields=None,
                                   detail=None):

        limit = api_utils.validate_limit(limit)
        sort_dir = api_utils.validate_sort_dir(sort_dir)

        if sort_key in self.invalid_sort_key_list:
            raise exception.InvalidParameterValue(
                _("The sort_key value %(key)s is an invalid field for "
                  "sorting") % {'key': sort_key})

        marker_obj = None
        if marker:
            marker_obj = objects.Conductor.get_by_hostname(api.request.context,
                                                           marker,
                                                           online=None)

        conductors = objects.Conductor.list(api.request.context,
                                            limit=limit,
                                            marker=marker_obj,
                                            sort_key=sort_key,
                                            sort_dir=sort_dir)

        parameters = {'sort_key': sort_key, 'sort_dir': sort_dir}

        if detail is not None:
            parameters['detail'] = detail

        return ConductorCollection.convert_with_links(conductors,
                                                      limit,
                                                      url=resource_url,
                                                      fields=fields,
                                                      **parameters)
Beispiel #19
0
    def post(self, node_ident, callback_url, agent_version=None):
        """Process a heartbeat from the deploy ramdisk.

        :param node_ident: the UUID or logical name of a node.
        :param callback_url: the URL to reach back to the ramdisk.
        :param agent_version: The version of the agent that is heartbeating.
            ``None`` indicates that the agent that is heartbeating is a version
            before sending agent_version was introduced so agent v3.0.0 (the
            last release before sending agent_version was introduced) will be
            assumed.
        :raises: NodeNotFound if node with provided UUID or name was not found.
        :raises: InvalidUuidOrName if node_ident is not valid name or UUID.
        :raises: NoValidHost if RPC topic for node could not be retrieved.
        :raises: NotFound if requested API version does not allow this
            endpoint.
        """
        if not api_utils.allow_ramdisk_endpoints():
            raise exception.NotFound()

        if agent_version and not api_utils.allow_agent_version_in_heartbeat():
            raise exception.InvalidParameterValue(
                _('Field "agent_version" not recognised'))

        cdict = pecan.request.context.to_policy_values()
        policy.authorize('baremetal:node:ipa_heartbeat', cdict, cdict)

        rpc_node = api_utils.get_rpc_node_with_suffix(node_ident)

        try:
            topic = pecan.request.rpcapi.get_topic_for(rpc_node)
        except exception.NoValidHost as e:
            e.code = http_client.BAD_REQUEST
            raise

        pecan.request.rpcapi.heartbeat(pecan.request.context,
                                       rpc_node.uuid,
                                       callback_url,
                                       agent_version,
                                       topic=topic)
Beispiel #20
0
def get_deploy_info(node, **kwargs):
    """Returns the information required for doing iSCSI deploy in a dictionary.

    :param node: ironic node object
    :param kwargs: the keyword args passed from the conductor node.
    :raises: MissingParameterValue, if some required parameters were not
        passed.
    :raises: InvalidParameterValue, if any of the parameters have invalid
        value.
    """

    deploy_key = kwargs.get('key')
    i_info = parse_instance_info(node)
    if i_info['deploy_key'] != deploy_key:
        raise exception.InvalidParameterValue(_("Deploy key does not match"))

    params = {'address': kwargs.get('address'),
              'port': kwargs.get('port', '3260'),
              'iqn': kwargs.get('iqn'),
              'lun': kwargs.get('lun', '1'),
              'image_path': _get_image_file_path(node.uuid),
              'root_mb': 1024 * int(i_info['root_gb']),
              'swap_mb': int(i_info['swap_mb']),
              'ephemeral_mb': 1024 * int(i_info['ephemeral_gb']),
              'preserve_ephemeral': i_info['preserve_ephemeral'],
              'node_uuid': node.uuid,
             }

    missing = [key for key in params if params[key] is None]
    if missing:
        raise exception.MissingParameterValue(_(
                "Parameters %s were not passed to ironic"
                " for deploy.") % missing)

    # configdrive and ephemeral_format are nullable
    params['ephemeral_format'] = i_info.get('ephemeral_format')
    params['configdrive'] = i_info.get('configdrive')

    return params
Beispiel #21
0
    def set_power_state(self, task, pstate):
        """Turn the power on or off.

        :param task: a TaskManager instance containing the node to act on.
        :param pstate: The desired power state, one of ironic.common.states
            POWER_ON, POWER_OFF.
        :raises: InvalidParameterValue if required ipmi parameters are missing
            or if an invalid power state was specified.
        :raises: PowerStateFailure if the power couldn't be set to pstate.

        """
        driver_info = _parse_driver_info(task.node)

        if pstate == states.POWER_ON:
            state = _power_on(driver_info)
        elif pstate == states.POWER_OFF:
            state = _power_off(driver_info)
        else:
            raise exception.InvalidParameterValue(_("set_power_state called "
                    "with invalid power state %s.") % pstate)
        if state != pstate:
            raise exception.PowerStateFailure(pstate=pstate)
Beispiel #22
0
def check_image_size(task, image_source):
    """Check if the requested image is larger than the ram size.

    :param task: a TaskManager instance containing the node to act on.
    :param image_source: href of the image.
    :raises: InvalidParameterValue if size of the image is greater than
        the available ram size.
    """
    node = task.node
    properties = node.properties
    # skip check if 'memory_mb' is not defined
    if 'memory_mb' not in properties:
        LOG.warning(
            'Skip the image size check as memory_mb is not '
            'defined in properties on node %s.', node.uuid)
        return

    image_show = images.image_show(task.context, image_source)
    if CONF.agent.stream_raw_images and image_show.get('disk_format') == 'raw':
        LOG.debug(
            'Skip the image size check since the image is going to be '
            'streamed directly onto the disk for node %s', node.uuid)
        return

    memory_size = int(properties.get('memory_mb'))
    image_size = int(image_show['size'])
    reserved_size = CONF.agent.memory_consumed_by_agent
    if (image_size + (reserved_size * units.Mi)) > (memory_size * units.Mi):
        msg = (_('Memory size is too small for requested image, if it is '
                 'less than (image size + reserved RAM size), will break '
                 'the IPA deployments. Image size: %(image_size)d MiB, '
                 'Memory size: %(memory_size)d MiB, Reserved size: '
                 '%(reserved_size)d MiB.') % {
                     'image_size': image_size / units.Mi,
                     'memory_size': memory_size,
                     'reserved_size': reserved_size
                 })
        raise exception.InvalidParameterValue(msg)
Beispiel #23
0
    def _get_volume_targets_collection(self, node_ident, marker, limit,
                                       sort_key, sort_dir, resource_url=None,
                                       fields=None, detail=None):
        limit = api_utils.validate_limit(limit)
        sort_dir = api_utils.validate_sort_dir(sort_dir)

        marker_obj = None
        if marker:
            marker_obj = objects.VolumeTarget.get_by_uuid(
                pecan.request.context, marker)

        if sort_key in self.invalid_sort_key_list:
            raise exception.InvalidParameterValue(
                _("The sort_key value %(key)s is an invalid field for "
                  "sorting") % {'key': sort_key})

        node_ident = self.parent_node_ident or node_ident

        if node_ident:
            # FIXME(comstud): Since all we need is the node ID, we can
            #                 make this more efficient by only querying
            #                 for that column. This will get cleaned up
            #                 as we move to the object interface.
            node = api_utils.get_rpc_node(node_ident)
            targets = objects.VolumeTarget.list_by_node_id(
                pecan.request.context, node.id, limit, marker_obj,
                sort_key=sort_key, sort_dir=sort_dir)
        else:
            targets = objects.VolumeTarget.list(pecan.request.context,
                                                limit, marker_obj,
                                                sort_key=sort_key,
                                                sort_dir=sort_dir)
        return VolumeTargetCollection.convert_with_links(targets, limit,
                                                         url=resource_url,
                                                         fields=fields,
                                                         sort_key=sort_key,
                                                         sort_dir=sort_dir,
                                                         detail=detail)
Beispiel #24
0
    def set_boot_device(self, task, device, persistent=False):
        """Set the boot device for a node.

        Set the boot device to use on next reboot of the node.

        :param task: a TaskManager instance containing the node to act on.
        :param device: the boot device, one of
                       :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.
        """
        node = task.node

        if device not in _BOOT_DEVICES_MAP:
            raise exception.InvalidParameterValue(
                _("set_boot_device called with invalid device '%(device)s' "
                  "for node %(node_id)s.") % {
                      'device': device,
                      'node_id': node.uuid
                  })

        # NOTE(ifarkas): DRAC interface doesn't allow changing the boot device
        #                multiple times in a row without a reboot. This is
        #                because a change need to be committed via a
        #                configuration job, and further configuration jobs
        #                cannot be created until the previous one is processed
        #                at the next boot. As a workaround, saving it to
        #                driver_internal_info and committing the change during
        #                power state change.
        driver_internal_info = node.driver_internal_info
        driver_internal_info['drac_boot_device'] = {
            'boot_device': device,
            'persistent': persistent
        }
        node.driver_internal_info = driver_internal_info
        node.save()
Beispiel #25
0
def parse_driver_info(node):
    """Parses and creates AMT driver info

    :param node: an Ironic node object.
    :returns: AMT driver info.
    :raises: MissingParameterValue if any required parameters are missing.
    :raises: InvalidParameterValue if any parameters have invalid values.
    """

    info = node.driver_info or {}
    d_info = {}
    missing_info = []

    for param in REQUIRED_PROPERTIES:
        value = info.get(param)
        if value:
            if not isinstance(value, six.binary_type):
                value = value.encode()
            d_info[param[4:]] = value
        else:
            missing_info.append(param)

    if missing_info:
        raise exception.MissingParameterValue(
            _("AMT driver requires the following to be set in "
              "node's driver_info: %s.") % missing_info)

    d_info['uuid'] = node.uuid
    param = 'amt_protocol'
    protocol = info.get(param, CONF.amt.get(param[4:]))
    if protocol not in AMT_PROTOCOL_PORT_MAP:
        raise exception.InvalidParameterValue(
            _("Invalid protocol %s.") % protocol)
    if not isinstance(value, six.binary_type):
        protocol = protocol.encode()
    d_info[param[4:]] = protocol

    return d_info
Beispiel #26
0
def _get_certificate_file_list(cert_file_list):
    """Get the list of certificates to use.

    :param cert_file_list: certificates file list.
    :returns: cert_file_list if it's not empty. If empty or None,
        returns the list of path configured for "webserver_verify_ca"
        configuration option if the path exists. If the path does not
        exist, returns empty list.
    :raises: InvalidParameterValue if argument provided is other than
        a list.
    """

    cfl = cert_file_list

    if not cfl:
        try:
            verify = strutils.bool_from_string(CONF.webserver_verify_ca,
                                               strict=True)
        except ValueError:
            verify = CONF.webserver_verify_ca

        if isinstance(verify, bool):
            return []

        if not os.path.exists(verify):
            LOG.error(
                "Path to the certificate file %(path)s "
                "does not exist.", {'path': verify})
            return []

        cfl = [verify]

    if not isinstance(cfl, list):
        raise exception.InvalidParameterValue(
            _('List of files is expected whereas "%(atype)s" type '
              'is provided.') % {'atype': type(cfl)})

    return cfl
Beispiel #27
0
    def get_all(self, node=None, marker=None, limit=None, sort_key='id',
                sort_dir='asc', fields=None, detail=None, project=None):
        """Retrieve a list of volume connectors.

        :param node: UUID or name of a node, to get only volume connectors
                     for that node.
        :param marker: pagination marker for large data sets.
        :param limit: maximum number of resources to return in a single result.
                      This value cannot be larger than the value of max_limit
                      in the [api] section of the ironic configuration, or only
                      max_limit resources will be returned.
        :param sort_key: column to sort results by. Default: id.
        :param sort_dir: direction to sort. "asc" or "desc". Default: "asc".
        :param fields: Optional, a list with a specified set of fields
                       of the resource to be returned.
        :param detail: Optional, whether to retrieve with detail.

        :returns: a list of volume connectors, or an empty list if no volume
                  connector is found.

        :raises: InvalidParameterValue if sort_key does not exist
        :raises: InvalidParameterValue if sort key is invalid for sorting.
        :raises: InvalidParameterValue if both fields and detail are specified.
        """
        project = api_utils.check_volume_list_policy(
            parent_node=self.parent_node_ident)

        if fields is None and not detail:
            fields = _DEFAULT_RETURN_FIELDS

        if fields and detail:
            raise exception.InvalidParameterValue(
                _("Can't fetch a subset of fields with 'detail' set"))

        resource_url = 'volume/connectors'
        return self._get_volume_connectors_collection(
            node, marker, limit, sort_key, sort_dir, resource_url=resource_url,
            fields=fields, detail=detail, project=project)
    def set_power_state(self, task, target_state, timeout=None):
        """Turn the current power state on or off.

        :param task: a TaskManager instance.
        :param target_state: The desired power state POWER_ON, POWER_OFF or
            REBOOT from :mod:`ironic.common.states`.
        :raises: MissingParameterValue, if some required parameter(s) are
            missing in the node's driver_info.
        :raises: InvalidParameterValue, if some parameter(s) have invalid
            value(s) in the node's driver_info OR if an invalid power state
            was specified.
        """
        driver_info = _parse_driver_info(task.node)
        vm_name = driver_info['ovirt_vm_name']
        vm = _getvm(driver_info)
        try:
            if target_state == states.POWER_OFF:
                vm.stop()
            elif target_state == states.POWER_ON:
                vm.start()
            elif target_state == states.REBOOT:
                status = vm.get().status.value
                if status == 'down':
                    vm.start()
                else:
                    vm.reboot()
            else:
                msg = _("'set_power_state' called with invalid power "
                        "state '%s'") % target_state
                raise exception.InvalidParameterValue(msg)
        except sdk.Error as e:
            LOG.error(
                "Could not change status of VM vm %(name)s "
                "got error: %(error)s", {
                    'name': vm_name,
                    'error': e
                })
            raise staging_exception.OVirtError(err=e)
Beispiel #29
0
    def set_boot_device(self, task, device, persistent=False):
        """Set the boot device for the task's node.

        Set the boot device to use on next reboot of the node.

        :param task: a task from TaskManager.
        :param device: the boot device, one of
                       :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. Ignored by this driver.
        :raises: InvalidParameterValue if an invalid boot device is
                 specified or if any connection parameters are incorrect.
        :raises: MissingParameterValue if a required parameter is missing
        :raises: SSHConnectFailed if ssh failed to connect to the node.
        :raises: SSHCommandFailed on an error from ssh.
        :raises: NotImplementedError if the virt_type does not support
            setting the boot device.

        """
        node = task.node
        driver_info = _parse_driver_info(node)
        if device not in self.get_supported_boot_devices(task):
            raise exception.InvalidParameterValue(_(
                "Invalid boot device %s specified.") % device)
        driver_info['macs'] = driver_utils.get_node_mac_addresses(task)
        ssh_obj = _get_connection(node)

        boot_device_map = _get_boot_device_map(driver_info['virt_type'])
        try:
            _set_boot_device(ssh_obj, driver_info, boot_device_map[device])
        except NotImplementedError:
            with excutils.save_and_reraise_exception():
                LOG.error(_LE("Failed to set boot device for node %(node)s, "
                              "virt_type %(vtype)s does not support this "
                              "operation"),
                          {'node': node.uuid,
                           'vtype': driver_info['virt_type']})
Beispiel #30
0
    def add_cleaning_network(self, task):
        """Add the cleaning network to a node.

        :param task: A TaskManager instance.
        :returns: a dictionary in the form {port.uuid: neutron_port['id']}
        :raises: NetworkError, InvalidParameterValue
        """
        if not uuidutils.is_uuid_like(CONF.neutron.cleaning_network_uuid):
            raise exception.InvalidParameterValue(_(
                'You must provide a valid cleaning network UUID in '
                '[neutron]cleaning_network_uuid configuration option.'))
        # If we have left over ports from a previous cleaning, remove them
        neutron.rollback_ports(task, CONF.neutron.cleaning_network_uuid)
        LOG.info(_LI('Adding cleaning network to node %s'), task.node.uuid)
        vifs = neutron.add_ports_to_network(
            task, CONF.neutron.cleaning_network_uuid, is_flat=True)
        for port in task.ports:
            if port.uuid in vifs:
                internal_info = port.internal_info
                internal_info['cleaning_vif_port_id'] = vifs[port.uuid]
                port.internal_info = internal_info
                port.save()
        return vifs