Example #1
0
    def convert_physical_disks(self, physical_disks, raid_enable):
        """Converts a list of physical disks into or out of RAID mode.

        Disks can be enabled or disabled for RAID mode.

        :param physical_disks: list of FQDD ID strings of the physical disks
               to update
        :param raid_enable: boolean flag, set to True if the disk is to
               become part of the RAID.  The same flag is applied to all
               listed disks
        :returns: a dictionary containing the commit_needed key with a boolean
                  value indicating whether a config job must be created for the
                  values to be applied.
        """
        invocation = 'ConvertToRAID' if raid_enable else 'ConvertToNonRAID'

        selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
                     'CreationClassName': 'DCIM_RAIDService',
                     'SystemName': 'DCIM:ComputerSystem',
                     'Name': 'DCIM:RAIDService'}

        properties = {'PDArray': physical_disks}

        doc = self.client.invoke(uris.DCIM_RAIDService, invocation,
                                 selectors, properties,
                                 expected_return_value=utils.RET_SUCCESS)

        return {'commit_required':
                utils.is_reboot_required(doc, uris.DCIM_RAIDService)}
Example #2
0
    def delete_virtual_disk(self, virtual_disk):
        """Deletes a virtual disk

        The deleted virtual disk will be in pending state. For the changes to
        be applied, a config job must be created and the node must be rebooted.

        :param virtual_disk: id of the virtual disk
        :returns: a dictionary containing the commit_needed key with a boolean
                  value indicating whether a config job must be created for the
                  values to be applied.
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        :raises: DRACUnexpectedReturnValue on return value mismatch
        """

        selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
                     'CreationClassName': 'DCIM_RAIDService',
                     'SystemName': 'DCIM:ComputerSystem',
                     'Name': 'DCIM:RAIDService'}
        properties = {'Target': virtual_disk}

        doc = self.client.invoke(uris.DCIM_RAIDService, 'DeleteVirtualDisk',
                                 selectors, properties,
                                 expected_return_value=utils.RET_SUCCESS)

        return {'commit_required': utils.is_reboot_required(
            doc, uris.DCIM_RAIDService)}
Example #3
0
    def delete_virtual_disk(self, virtual_disk):
        """Deletes a virtual disk

        The deleted virtual disk will be in pending state. For the changes to
        be applied, a config job must be created and the node must be rebooted.

        :param virtual_disk: id of the virtual disk
        :returns: a dictionary containing the commit_needed key with a boolean
                  value indicating whether a config job must be created for the
                  values to be applied.
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        :raises: DRACUnexpectedReturnValue on return value mismatch
        """

        selectors = {
            'SystemCreationClassName': 'DCIM_ComputerSystem',
            'CreationClassName': 'DCIM_RAIDService',
            'SystemName': 'DCIM:ComputerSystem',
            'Name': 'DCIM:RAIDService'
        }
        properties = {'Target': virtual_disk}

        doc = self.client.invoke(uris.DCIM_RAIDService,
                                 'DeleteVirtualDisk',
                                 selectors,
                                 properties,
                                 expected_return_value=utils.RET_SUCCESS)

        return {
            'commit_required':
            utils.is_reboot_required(doc, uris.DCIM_RAIDService)
        }
Example #4
0
    def convert_physical_disks(self, physical_disks, raid_enable):
        """Converts a list of physical disks into or out of RAID mode.

        Disks can be enabled or disabled for RAID mode.

        :param physical_disks: list of FQDD ID strings of the physical disks
               to update
        :param raid_enable: boolean flag, set to True if the disk is to
               become part of the RAID.  The same flag is applied to all
               listed disks
        :returns: a dictionary containing the commit_needed key with a boolean
                  value indicating whether a config job must be created for the
                  values to be applied.
        """
        invocation = 'ConvertToRAID' if raid_enable else 'ConvertToNonRAID'

        selectors = {
            'SystemCreationClassName': 'DCIM_ComputerSystem',
            'CreationClassName': 'DCIM_RAIDService',
            'SystemName': 'DCIM:ComputerSystem',
            'Name': 'DCIM:RAIDService'
        }

        properties = {'PDArray': physical_disks}

        doc = self.client.invoke(uris.DCIM_RAIDService,
                                 invocation,
                                 selectors,
                                 properties,
                                 expected_return_value=utils.RET_SUCCESS)

        return {
            'commit_required':
            utils.is_reboot_required(doc, uris.DCIM_RAIDService)
        }
Example #5
0
    def set_bios_settings(self, new_settings):
        """Sets the BIOS configuration

        To be more precise, it sets the pending_value parameter for each of the
        attributes passed in. For the values to be applied, a config job must
        be created and the node must be rebooted.

        :param new_settings: a dictionary containing the proposed values, with
                             each key being the name of attribute and the
                             value being the proposed value.
        :returns: a dictionary containing the commit_needed key with a boolean
                  value indicating whether a config job must be created for the
                  values to be applied.
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        :raises: DRACUnexpectedReturnValue on return value mismatch
        :raises: InvalidParameterValue on invalid BIOS attribute
        """

        current_settings = self.list_bios_settings()
        unknown_keys = set(new_settings) - set(current_settings)
        if unknown_keys:
            msg = ('Unknown BIOS attributes found: %(unknown_keys)r' %
                   {'unknown_keys': unknown_keys})
            raise exceptions.InvalidParameterValue(reason=msg)

        read_only_keys = []
        unchanged_attribs = []
        invalid_attribs_msgs = []
        attrib_names = []
        candidates = set(new_settings)

        for attr in candidates:
            if str(new_settings[attr]) == str(
                    current_settings[attr].current_value):
                unchanged_attribs.append(attr)
            elif current_settings[attr].read_only:
                read_only_keys.append(attr)
            else:
                validation_msg = current_settings[attr].validate(
                    new_settings[attr])
                if validation_msg is None:
                    attrib_names.append(attr)
                else:
                    invalid_attribs_msgs.append(validation_msg)

        if unchanged_attribs:
            LOG.warning('Ignoring unchanged BIOS attributes: %r',
                        unchanged_attribs)

        if invalid_attribs_msgs or read_only_keys:
            if read_only_keys:
                read_only_msg = ['Cannot set read-only BIOS attributes: %r.'
                                 % read_only_keys]
            else:
                read_only_msg = []

            drac_messages = '\n'.join(invalid_attribs_msgs + read_only_msg)
            raise exceptions.DRACOperationFailed(
                drac_messages=drac_messages)

        if not attrib_names:
            return {'commit_required': False}

        selectors = {'CreationClassName': 'DCIM_BIOSService',
                     'Name': 'DCIM:BIOSService',
                     'SystemCreationClassName': 'DCIM_ComputerSystem',
                     'SystemName': 'DCIM:ComputerSystem'}
        properties = {'Target': 'BIOS.Setup.1-1',
                      'AttributeName': attrib_names,
                      'AttributeValue': [new_settings[attr] for attr
                                         in attrib_names]}
        doc = self.client.invoke(uris.DCIM_BIOSService, 'SetAttributes',
                                 selectors, properties)

        return {'commit_required': utils.is_reboot_required(
            doc, uris.DCIM_BIOSService)}
Example #6
0
def set_settings(client, list_settings, new_settings, resource_uri,
                 cim_creation_class_name, cim_name, target):
    current_settings = list_settings()

    unknown_keys = set(new_settings) - set(current_settings)
    if unknown_keys:
        msg = ('Unknown attributes found: %(unknown_keys)r' % {
            'unknown_keys': unknown_keys
        })
        raise exceptions.InvalidParameterValue(reason=msg)

    read_only_keys = []
    unchanged_attribs = []
    invalid_attribs_msgs = []
    attrib_names = []
    candidates = set(new_settings)

    for attr in candidates:
        if str(new_settings[attr]) == str(
                current_settings[attr].current_value):
            unchanged_attribs.append(attr)
        elif current_settings[attr].read_only:
            read_only_keys.append(attr)
        else:
            validation_msg = current_settings[attr].validate(
                new_settings[attr])
            if validation_msg:
                invalid_attribs_msgs.append(validation_msg)
            else:
                attrib_names.append(attr)

    if unchanged_attribs:
        LOG.debug('Ignoring unchanged attributes: %r', unchanged_attribs)

    if invalid_attribs_msgs or read_only_keys:
        if read_only_keys:
            read_only_msg = [
                'Cannot set read-only attributes: %r.' % read_only_keys
            ]
        else:
            read_only_msg = []

        drac_messages = '\n'.join(invalid_attribs_msgs + read_only_msg)
        raise exceptions.DRACOperationFailed(drac_messages=drac_messages)

    if not attrib_names:
        return {'commit_required': False, 'reboot_required': False}

    selectors = {
        'CreationClassName': cim_creation_class_name,
        'Name': cim_name,
        'SystemCreationClassName': 'DCIM_ComputerSystem',
        'SystemName': 'DCIM:ComputerSystem'
    }
    properties = {
        'Target': target,
        'AttributeName': attrib_names,
        'AttributeValue': [new_settings[attr] for attr in attrib_names]
    }
    doc = client.invoke(resource_uri, 'SetAttributes', selectors, properties)

    return {
        'commit_required': is_commit_required(doc, resource_uri),
        'reboot_required': utils.is_reboot_required(doc, resource_uri)
    }
Example #7
0
    def create_virtual_disk(self, raid_controller, physical_disks, raid_level,
                            size_mb, disk_name=None, span_length=None,
                            span_depth=None):
        """Creates a virtual disk

        The created virtual disk will be in pending state. For the changes to
        be applied, a config job must be created and the node must be rebooted.

        :param raid_controller: id of the RAID controller
        :param physical_disks: ids of the physical disks
        :param raid_level: RAID level of the virtual disk
        :param size_mb: size of the virtual disk in megabytes
        :param disk_name: name of the virtual disk (optional)
        :param span_length: number of disks per span (optional)
        :param span_depth: number of spans in virtual disk (optional)
        :returns: a dictionary containing the commit_needed key with a boolean
                  value indicating whether a config job must be created for the
                  values to be applied.
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        :raises: DRACUnexpectedReturnValue on return value mismatch
        :raises: InvalidParameterValue on invalid input parameter
        """

        virtual_disk_prop_names = []
        virtual_disk_prop_values = []
        error_msgs = []

        # RAID controller validation
        if not raid_controller:
            error_msgs.append("'raid_controller' is not supplied")

        # physical disks validation
        if not physical_disks:
            error_msgs.append("'physical_disks' is not supplied")

        # size validation
        if not size_mb:
            error_msgs.append("'size_mb' is not supplied")
        else:
            utils.validate_integer_value(size_mb, 'size_mb', error_msgs)

        virtual_disk_prop_names.append('Size')
        virtual_disk_prop_values.append(str(size_mb))

        # RAID level validation
        virtual_disk_prop_names.append('RAIDLevel')
        try:
            virtual_disk_prop_values.append(RAID_LEVELS[str(raid_level)])
        except KeyError:
            error_msgs.append("'raid_level' is invalid")

        if disk_name is not None:
            virtual_disk_prop_names.append('VirtualDiskName')
            virtual_disk_prop_values.append(disk_name)

        if span_depth is not None:
            utils.validate_integer_value(span_depth, 'span_depth', error_msgs)

            virtual_disk_prop_names.append('SpanDepth')
            virtual_disk_prop_values.append(str(span_depth))

        if span_length is not None:
            utils.validate_integer_value(span_length, 'span_length',
                                         error_msgs)

            virtual_disk_prop_names.append('SpanLength')
            virtual_disk_prop_values.append(str(span_length))

        if error_msgs:
            msg = ('The following errors were encountered while parsing '
                   'the provided parameters: %r') % ','.join(error_msgs)
            raise exceptions.InvalidParameterValue(reason=msg)

        selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
                     'CreationClassName': 'DCIM_RAIDService',
                     'SystemName': 'DCIM:ComputerSystem',
                     'Name': 'DCIM:RAIDService'}
        properties = {'Target': raid_controller,
                      'PDArray': physical_disks,
                      'VDPropNameArray': virtual_disk_prop_names,
                      'VDPropValueArray': virtual_disk_prop_values}
        doc = self.client.invoke(uris.DCIM_RAIDService, 'CreateVirtualDisk',
                                 selectors, properties,
                                 expected_return_value=utils.RET_SUCCESS)

        return {'commit_required': utils.is_reboot_required(
            doc, uris.DCIM_RAIDService)}
Example #8
0
    def create_virtual_disk(self,
                            raid_controller,
                            physical_disks,
                            raid_level,
                            size_mb,
                            disk_name=None,
                            span_length=None,
                            span_depth=None):
        """Creates a virtual disk

        The created virtual disk will be in pending state. For the changes to
        be applied, a config job must be created and the node must be rebooted.

        :param raid_controller: id of the RAID controller
        :param physical_disks: ids of the physical disks
        :param raid_level: RAID level of the virtual disk
        :param size_mb: size of the virtual disk in megabytes
        :param disk_name: name of the virtual disk (optional)
        :param span_length: number of disks per span (optional)
        :param span_depth: number of spans in virtual disk (optional)
        :returns: a dictionary containing the commit_needed key with a boolean
                  value indicating whether a config job must be created for the
                  values to be applied.
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        :raises: DRACUnexpectedReturnValue on return value mismatch
        :raises: InvalidParameterValue on invalid input parameter
        """

        virtual_disk_prop_names = []
        virtual_disk_prop_values = []
        error_msgs = []

        # RAID controller validation
        if not raid_controller:
            error_msgs.append("'raid_controller' is not supplied")

        # physical disks validation
        if not physical_disks:
            error_msgs.append("'physical_disks' is not supplied")

        # size validation
        if not size_mb:
            error_msgs.append("'size_mb' is not supplied")
        else:
            utils.validate_integer_value(size_mb, 'size_mb', error_msgs)

        virtual_disk_prop_names.append('Size')
        virtual_disk_prop_values.append(str(size_mb))

        # RAID level validation
        virtual_disk_prop_names.append('RAIDLevel')
        try:
            virtual_disk_prop_values.append(RAID_LEVELS[str(raid_level)])
        except KeyError:
            error_msgs.append("'raid_level' is invalid")

        if disk_name is not None:
            virtual_disk_prop_names.append('VirtualDiskName')
            virtual_disk_prop_values.append(disk_name)

        if span_depth is not None:
            utils.validate_integer_value(span_depth, 'span_depth', error_msgs)

            virtual_disk_prop_names.append('SpanDepth')
            virtual_disk_prop_values.append(str(span_depth))

        if span_length is not None:
            utils.validate_integer_value(span_length, 'span_length',
                                         error_msgs)

            virtual_disk_prop_names.append('SpanLength')
            virtual_disk_prop_values.append(str(span_length))

        if error_msgs:
            msg = ('The following errors were encountered while parsing '
                   'the provided parameters: %r') % ','.join(error_msgs)
            raise exceptions.InvalidParameterValue(reason=msg)

        selectors = {
            'SystemCreationClassName': 'DCIM_ComputerSystem',
            'CreationClassName': 'DCIM_RAIDService',
            'SystemName': 'DCIM:ComputerSystem',
            'Name': 'DCIM:RAIDService'
        }
        properties = {
            'Target': raid_controller,
            'PDArray': physical_disks,
            'VDPropNameArray': virtual_disk_prop_names,
            'VDPropValueArray': virtual_disk_prop_values
        }
        doc = self.client.invoke(uris.DCIM_RAIDService,
                                 'CreateVirtualDisk',
                                 selectors,
                                 properties,
                                 expected_return_value=utils.RET_SUCCESS)

        return {
            'commit_required':
            utils.is_reboot_required(doc, uris.DCIM_RAIDService)
        }
Example #9
0
    def set_nic_settings(self, nic_id, settings):
        """Modify one or more settings of a NIC.

        If successful, the pending values of the attributes are set. For
        the new values to be applied, a configuration job must be
        created and the node must be rebooted.

        :param nic_id: id of the network interface controller (NIC)
        :param settings: dictionary containing the proposed values, with
                         each key being the name of an attribute and the
                         value being the proposed value
        :returns: dictionary containing a 'commit_required' key with a
                  boolean value indicating whether a configuration job
                  must be created for the new settings to be applied and
                  also containing a 'reboot_required' key with a boolean
                  value indicating whether or not a reboot is required
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the iDRAC
                 interface
        :raises: InvalidParameterValue on invalid NIC attribute
        """
        current_settings = self.list_nic_settings(nic_id)
        unknown_keys = set(settings) - set(current_settings)

        if unknown_keys:
            msg = ('Unknown NIC attributes found: %(unknown_keys)r' % {
                'unknown_keys': unknown_keys
            })
            raise ironic_exceptions.InvalidParameterValue(reason=msg)

        read_only_keys = []
        unchanged_attribs = []
        invalid_attribs_msgs = []
        attrib_names = []
        candidates = set(settings)

        for attr in candidates:
            if str(settings[attr]) == str(
                    current_settings[attr].current_value):
                unchanged_attribs.append(attr)
            elif current_settings[attr].read_only:
                read_only_keys.append(attr)
            else:
                validation_msg = current_settings[attr].validate(
                    settings[attr])

                if validation_msg is None:
                    attrib_names.append(attr)
                else:
                    invalid_attribs_msgs.append(validation_msg)

        if unchanged_attribs:
            LOG.warning('Ignoring unchanged NIC attributes: %r' %
                        unchanged_attribs)

        if invalid_attribs_msgs or read_only_keys:
            if read_only_keys:
                read_only_msg = [
                    'Cannot set read-only NIC attributes: %r.' % read_only_keys
                ]
            else:
                read_only_msg = []

            drac_messages = '\n'.join(invalid_attribs_msgs + read_only_msg)
            raise ironic_exceptions.DRACOperationFailed(
                drac_messages=drac_messages)

        if not attrib_names:
            return {'commit_required': False}

        selectors = {
            'CreationClassName': 'DCIM_NICService',
            'Name': 'DCIM:NICService',
            'SystemCreationClassName': 'DCIM_ComputerSystem',
            'SystemName': 'DCIM:ComputerSystem'
        }
        properties = {
            'Target': nic_id,
            'AttributeName': attrib_names,
            'AttributeValue': [settings[attr] for attr in attrib_names]
        }
        doc = self.client.invoke(uris.DCIM_NICService, 'SetAttributes',
                                 selectors, properties)

        return {
            'reboot_required':
            utils.is_reboot_required(doc, uris.DCIM_NICService),
            'commit_required':
            utils_additional.is_commit_required(doc, uris.DCIM_NICService)
        }