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)}
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)}
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) }
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) }
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)}
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) }
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)}
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) }
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) }