예제 #1
0
    def list_jobs(self, only_unfinished=False):
        """Returns a list of jobs from the job queue

        :param only_unfinished: indicates whether only unfinished jobs should
                                be returned
        :returns: a list of Job objects
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        """

        filter_query = None
        if only_unfinished:
            filter_query = ('select * from DCIM_LifecycleJob '
                            'where Name != "CLEARALL" and '
                            'JobStatus != "Reboot Completed" and '
                            'JobStatus != "Completed" and '
                            'JobStatus != "Completed with Errors" and '
                            'JobStatus != "Failed"')

        doc = self.client.enumerate(uris.DCIM_LifecycleJob,
                                    filter_query=filter_query)

        drac_jobs = utils.find_xml(doc, 'DCIM_LifecycleJob',
                                   uris.DCIM_LifecycleJob, find_all=True)

        return [self._parse_drac_job(drac_job) for drac_job in drac_jobs]
예제 #2
0
    def parse(cls, bios_attr_xml):
        """Parses XML and creates BIOSEnumerableAttribute object"""

        bios_attr = BIOSAttribute.parse(cls.namespace, bios_attr_xml)
        possible_values = [attr.text for attr
                           in utils.find_xml(bios_attr_xml, 'PossibleValues',
                                             cls.namespace, find_all=True)]

        return cls(bios_attr.name, bios_attr.current_value,
                   bios_attr.pending_value, bios_attr.read_only,
                   possible_values)
예제 #3
0
    def test_get_wsman_resource_attr(self):
        doc = etree.fromstring(
            test_utils.InventoryEnumerations[uris.DCIM_CPUView]['ok'])
        cpus = utils.find_xml(doc, 'DCIM_CPUView', uris.DCIM_CPUView,
                              find_all=True)

        val = utils.get_wsman_resource_attr(
            cpus[0], uris.DCIM_CPUView, 'HyperThreadingEnabled',
            allow_missing=False)

        self.assertEqual('1', val)
예제 #4
0
    def invoke(self, resource_uri, method, selectors=None, properties=None,
               expected_return_value=None):
        """Invokes a remote WS-Man method

        :param resource_uri: URI of the resource
        :param method: name of the method to invoke
        :param selectors: dictionary of selectors
        :param properties: dictionary of properties
        :param expected_return_value: expected return value reported back by
            the DRAC card. For return value codes check the profile
            documentation of the resource used in the method call. If not set,
            return value checking is skipped.
        :returns: an lxml.etree.Element object of the response received
        :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
        """
        if selectors is None:
            selectors = {}

        if properties is None:
            properties = {}

        resp = super(WSManClient, self).invoke(resource_uri, method, selectors,
                                               properties)

        return_value = utils.find_xml(resp, 'ReturnValue', resource_uri).text
        if return_value == utils.RET_ERROR:
            message_elems = utils.find_xml(resp, 'Message', resource_uri, True)
            messages = [message_elem.text for message_elem in message_elems]
            raise exceptions.DRACOperationFailed(drac_messages=messages)

        if (expected_return_value is not None and
                return_value != expected_return_value):
            raise exceptions.DRACUnexpectedReturnValue(
                expected_return_value=expected_return_value,
                actual_return_value=return_value)

        return resp
예제 #5
0
    def test_get_wsman_resource_attr_missing_text(self):
        expected_message = ("Attribute 'HyperThreadingEnabled' is not nullable"
                            ", but no value received")
        doc = etree.fromstring(
            test_utils.InventoryEnumerations[
                uris.DCIM_CPUView]['empty_flag'])
        cpus = utils.find_xml(doc, 'DCIM_CPUView', uris.DCIM_CPUView,
                              find_all=True)

        self.assertRaisesRegexp(
            exceptions.DRACEmptyResponseField, re.escape(expected_message),
            utils.get_wsman_resource_attr, cpus[0], uris.DCIM_CPUView,
            'HyperThreadingEnabled', allow_missing=False)
예제 #6
0
    def test_get_wsman_resource_attr_missing_attr(self):
        expected_message = ("Attribute 'HyperThreadingEnabled' is missing "
                            "from the response")
        doc = etree.fromstring(
            test_utils.InventoryEnumerations[
                uris.DCIM_CPUView]['missing_flags'])
        cpus = utils.find_xml(doc, 'DCIM_CPUView', uris.DCIM_CPUView,
                              find_all=True)

        self.assertRaisesRegexp(
            exceptions.DRACMissingResponseField, re.escape(expected_message),
            utils.get_wsman_resource_attr, cpus[0], uris.DCIM_CPUView,
            'HyperThreadingEnabled', allow_missing=False)
예제 #7
0
    def list_boot_modes(self):
        """Returns the list of boot modes

        :returns: list of BootMode objects
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        """

        doc = self.client.enumerate(uris.DCIM_BootConfigSetting)

        drac_boot_modes = utils.find_xml(doc, "DCIM_BootConfigSetting", uris.DCIM_BootConfigSetting, find_all=True)

        return [self._parse_drac_boot_mode(drac_boot_mode) for drac_boot_mode in drac_boot_modes]
예제 #8
0
    def get_power_state(self):
        """Returns the current power state of the node

        :returns: power state of the node, one of 'POWER_ON', 'POWER_OFF' or
                  'REBOOT'
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        """

        filter_query = "select EnabledState from " 'DCIM_ComputerSystem where Name="srv:system"'
        doc = self.client.enumerate(uris.DCIM_ComputerSystem, filter_query=filter_query)
        enabled_state = utils.find_xml(doc, "EnabledState", uris.DCIM_ComputerSystem)

        return POWER_STATES[enabled_state.text]
예제 #9
0
    def list_cpus(self):
        """Returns the list of CPUs

        :returns: a list of CPU objects
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
        """

        doc = self.client.enumerate(uris.DCIM_CPUView)

        cpus = utils.find_xml(doc, 'DCIM_CPUView',
                              uris.DCIM_CPUView,
                              find_all=True)

        return [self._parse_cpus(cpu) for cpu in cpus]
예제 #10
0
    def list_memory(self):
        """Returns the list of installed memory

        :returns: a list of Memory objects
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
        """

        doc = self.client.enumerate(uris.DCIM_MemoryView)

        installed_memory = utils.find_xml(doc, 'DCIM_MemoryView',
                                          uris.DCIM_MemoryView,
                                          find_all=True)

        return [self._parse_memory(memory) for memory in installed_memory]
예제 #11
0
    def list_boot_devices(self):
        """Returns the list of boot devices

        :returns: a dictionary with the boot modes and the list of associated
                  BootDevice objects, ordered by the pending_assigned_sequence
                  property
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        """

        doc = self.client.enumerate(uris.DCIM_BootSourceSetting)

        drac_boot_devices = utils.find_xml(doc, 'DCIM_BootSourceSetting',
                                           uris.DCIM_BootSourceSetting,
                                           find_all=True)
        try:
            boot_devices = [self._parse_drac_boot_device(drac_boot_device)
                            for drac_boot_device in drac_boot_devices]
        except AttributeError:
            # DRAC 11g doesn't have the BootSourceType attribute on the
            # DCIM_BootSourceSetting resource
            controller_version = (
                lifecycle_controller.LifecycleControllerManagement(
                    self.client).get_version())

            if controller_version < LC_CONTROLLER_VERSION_12G:
                boot_devices = [
                    self._parse_drac_boot_device_11g(drac_boot_device)
                    for drac_boot_device in drac_boot_devices]
            else:
                raise

        # group devices by boot mode
        boot_devices_per_mode = {device.boot_mode: []
                                 for device in boot_devices}
        for device in boot_devices:
            boot_devices_per_mode[device.boot_mode].append(device)

        # sort the device list by pending assigned seqeuence
        for mode in boot_devices_per_mode.keys():
            boot_devices_per_mode[mode].sort(
                key=lambda device: device.pending_assigned_sequence)

        return boot_devices_per_mode
예제 #12
0
    def list_cpus(self):
        """Returns the list of CPUs

        :returns: a list of CPU objects
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
        """

        doc = self.client.enumerate(uris.DCIM_CPUView)

        cpus = utils.find_xml(doc,
                              'DCIM_CPUView',
                              uris.DCIM_CPUView,
                              find_all=True)

        return [self._parse_cpus(cpu) for cpu in cpus]
예제 #13
0
    def test_get_wsman_resource_attr_missing_attr(self):
        expected_message = ("Attribute 'HyperThreadingEnabled' is missing "
                            "from the response")
        doc = etree.fromstring(test_utils.InventoryEnumerations[
            uris.DCIM_CPUView]['missing_flags'])
        cpus = utils.find_xml(doc,
                              'DCIM_CPUView',
                              uris.DCIM_CPUView,
                              find_all=True)

        self.assertRaisesRegexp(exceptions.DRACMissingResponseField,
                                re.escape(expected_message),
                                utils.get_wsman_resource_attr,
                                cpus[0],
                                uris.DCIM_CPUView,
                                'HyperThreadingEnabled',
                                allow_missing=False)
예제 #14
0
    def test_get_all_wsman_resource_attrs(self):
        doc = etree.fromstring(
            test_utils.RAIDEnumerations[uris.DCIM_VirtualDiskView]['ok'])
        vdisks = utils.find_xml(doc,
                                'DCIM_VirtualDiskView',
                                uris.DCIM_VirtualDiskView,
                                find_all=True)

        vals = utils.get_all_wsman_resource_attrs(vdisks[0],
                                                  uris.DCIM_VirtualDiskView,
                                                  'PhysicalDiskIDs')

        expected_pdisks = [
            'Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1',
            'Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1'
        ]
        self.assertListEqual(expected_pdisks, vals)
예제 #15
0
    def test_get_wsman_resource_attr_missing_text(self):
        expected_message = ("Attribute 'HyperThreadingEnabled' is not nullable"
                            ", but no value received")
        doc = etree.fromstring(
            test_utils.InventoryEnumerations[uris.DCIM_CPUView]['empty_flag'])
        cpus = utils.find_xml(doc,
                              'DCIM_CPUView',
                              uris.DCIM_CPUView,
                              find_all=True)

        self.assertRaisesRegexp(exceptions.DRACEmptyResponseField,
                                re.escape(expected_message),
                                utils.get_wsman_resource_attr,
                                cpus[0],
                                uris.DCIM_CPUView,
                                'HyperThreadingEnabled',
                                allow_missing=False)
예제 #16
0
    def parse(cls, nic_attr_xml):
        """Parse XML and create a NICEnumerationAttribute object."""

        nic_attr = NICAttribute.parse(cls.namespace, nic_attr_xml)
        possible_values = [attr.text for attr
                           in utils.find_xml(nic_attr_xml,
                                             'PossibleValues',
                                             cls.namespace,
                                             find_all=True)]

        return cls(nic_attr.name,
                   nic_attr.instance_id,
                   nic_attr.current_value,
                   nic_attr.pending_value,
                   nic_attr.read_only,
                   nic_attr.fqdd,
                   possible_values)
예제 #17
0
    def list_nics(self):
        """Returns the list of NICs

        :returns: a list of NIC objects
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        """

        doc = self.client.enumerate(uris.DCIM_NICView)
        drac_nics = utils.find_xml(doc,
                                   'DCIM_NICView',
                                   uris.DCIM_NICView,
                                   find_all=True)

        return [self._parse_drac_nic(nic) for nic in drac_nics]
예제 #18
0
    def list_system_inventory(self):
        """Returns the system inventory

        :returns: a list of Memory objects
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
        """

        doc = self.client.enumerate(uris.DCIM_SystemView)

        inventory = utils.find_xml(doc,
                                   'DCIM_SystemView',
                                   uris.DCIM_SystemView,
                                   find_all=True)

        return [self._parse_system_inventory(item) for item in inventory]
    def get_version(self):
        """Returns the Lifecycle controller version

        :returns: Lifecycle controller version as a tuple of integers
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        """

        filter_query = ('select LifecycleControllerVersion '
                        'from DCIM_SystemView')
        doc = self.client.enumerate(uris.DCIM_SystemView,
                                    filter_query=filter_query)
        lc_version_str = utils.find_xml(doc, 'LifecycleControllerVersion',
                                        uris.DCIM_SystemView).text

        return tuple(map(int, (lc_version_str.split('.'))))
예제 #20
0
    def list_physical_disks(self):
        """Returns the list of physical disks

        :returns: a list of PhysicalDisk objects
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        """

        doc = self.client.enumerate(uris.DCIM_PhysicalDiskView)

        drac_physical_disks = utils.find_xml(doc, 'DCIM_PhysicalDiskView',
                                             uris.DCIM_PhysicalDiskView,
                                             find_all=True)

        return [self._parse_drac_physical_disk(disk)
                for disk in drac_physical_disks]
예제 #21
0
    def list_raid_controllers(self):
        """Returns the list of RAID controllers

        :returns: a list of RAIDController objects
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        """

        doc = self.client.enumerate(uris.DCIM_ControllerView)

        drac_raid_controllers = utils.find_xml(doc, 'DCIM_ControllerView',
                                               uris.DCIM_ControllerView,
                                               find_all=True)

        return [self._parse_drac_raid_controller(controller)
                for controller in drac_raid_controllers]
예제 #22
0
    def get_power_state(self):
        """Returns the current power state of the node

        :returns: power state of the node, one of 'POWER_ON', 'POWER_OFF' or
                  'REBOOT'
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        """

        filter_query = ('select EnabledState from DCIM_ComputerSystem')
        doc = self.client.enumerate(uris.DCIM_ComputerSystem,
                                    filter_query=filter_query)
        enabled_state = utils.find_xml(doc, 'EnabledState',
                                       uris.DCIM_ComputerSystem)

        return POWER_STATES[enabled_state.text]
예제 #23
0
    def get_version(self):
        """Returns the Lifecycle controller version

        :returns: Lifecycle controller version as a tuple of integers
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        """

        filter_query = ('select LifecycleControllerVersion '
                        'from DCIM_SystemView')
        doc = self.client.enumerate(uris.DCIM_SystemView,
                                    filter_query=filter_query)
        lc_version_str = utils.find_xml(doc, 'LifecycleControllerVersion',
                                        uris.DCIM_SystemView).text

        return tuple(map(int, (lc_version_str.split('.'))))
예제 #24
0
    def list_boot_modes(self):
        """Returns the list of boot modes

        :returns: list of BootMode objects
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        """

        doc = self.client.enumerate(uris.DCIM_BootConfigSetting)

        drac_boot_modes = utils.find_xml(doc, 'DCIM_BootConfigSetting',
                                         uris.DCIM_BootConfigSetting,
                                         find_all=True)

        return [self._parse_drac_boot_mode(drac_boot_mode)
                for drac_boot_mode in drac_boot_modes]
예제 #25
0
    def list_raid_controllers(self):
        """Returns the list of RAID controllers

        :returns: a list of RAIDController objects
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        """

        doc = self.client.enumerate(uris.DCIM_ControllerView)

        drac_raid_controllers = utils.find_xml(doc, 'DCIM_ControllerView',
                                               uris.DCIM_ControllerView,
                                               find_all=True)

        return [self._parse_drac_raid_controller(controller)
                for controller in drac_raid_controllers]
예제 #26
0
    def list_virtual_disks(self):
        """Returns the list of virtual disks

        :returns: a list of VirtualDisk objects
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        """

        doc = self.client.enumerate(uris.DCIM_VirtualDiskView)

        drac_virtual_disks = utils.find_xml(doc, 'DCIM_VirtualDiskView',
                                            uris.DCIM_VirtualDiskView,
                                            find_all=True)

        return [self._parse_drac_virtual_disk(disk)
                for disk in drac_virtual_disks]
예제 #27
0
    def parse(cls, namespace, raid_attr_xml):
        """Parses XML and creates RAIDAttribute object"""

        name = utils.get_wsman_resource_attr(
            raid_attr_xml, namespace, 'AttributeName')
        instance_id = utils.get_wsman_resource_attr(
            raid_attr_xml, namespace, 'InstanceID')
        current_value = [attr.text for attr in
                         utils.find_xml(raid_attr_xml, 'CurrentValue',
                                        namespace, find_all=True)]
        pending_value = utils.get_wsman_resource_attr(
            raid_attr_xml, namespace, 'PendingValue', nullable=True)
        read_only = utils.get_wsman_resource_attr(
            raid_attr_xml, namespace, 'IsReadOnly')
        fqdd = utils.get_wsman_resource_attr(
            raid_attr_xml, namespace, 'FQDD')

        return cls(name, instance_id, current_value, pending_value,
                   (read_only == 'true'), fqdd)
예제 #28
0
    def get_job(self, job_id):
        """Returns a job from the job queue

        :param job_id: id of the job
        :returns: a Job object on successful query, None otherwise
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        """

        filter_query = 'select * from DCIM_LifecycleJob where InstanceID="%s"' % job_id

        doc = self.client.enumerate(uris.DCIM_LifecycleJob, filter_query=filter_query)

        drac_job = utils.find_xml(doc, "DCIM_LifecycleJob", uris.DCIM_LifecycleJob)

        if drac_job:
            return self._parse_drac_job(drac_job)
예제 #29
0
    def list_firmware_components(self):
        """Returns the list of RAID controllers

        :returns: a list of RAIDController objects
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        """

        doc = self.client.enumerate(uris.DCIM_SoftwareIdentity)

        software_components = utils.find_xml(doc,
                                             'DCIM_SoftwareIdentity',
                                             uris.DCIM_SoftwareIdentity,
                                             find_all=True)

        return [
            self._parse_software_components(component)
            for component in software_components
        ]
예제 #30
0
    def get_job(self, job_id):
        """Returns a job from the job queue

        :param job_id: id of the job
        :returns: a Job object on successful query, None otherwise
        :raises: WSManRequestFailure on request failures
        :raises: WSManInvalidResponse when receiving invalid response
        :raises: DRACOperationFailed on error reported back by the DRAC
                 interface
        """

        filter_query = (
            'select * from DCIM_LifecycleJob where InstanceID="%s"' % job_id)

        doc = self.client.enumerate(uris.DCIM_LifecycleJob,
                                    filter_query=filter_query)

        drac_job = utils.find_xml(doc, 'DCIM_LifecycleJob',
                                  uris.DCIM_LifecycleJob)

        if drac_job is not None:
            return self._parse_drac_job(drac_job)
예제 #31
0
    def clear_foreign_config(self, raid_controller):
        """Free up foreign drives

        The job to clear foreign config will be in pending state.
        For the changes to be applied, a config job must be created.

        :param raid_controller: id of the RAID controller
        :returns: a dictionary containing:
                 - The is_commit_required key with the value always set to
                   True indicating that a config job must be created to
                   clear foreign configuration.
                 - The is_reboot_required key with a RebootRequired enumerated
                   value indicating whether the server must be rebooted to
                   clear foreign configuration.
        :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': raid_controller}

        doc = self.client.invoke(uris.DCIM_RAIDService,
                                 'ClearForeignConfig',
                                 selectors,
                                 properties,
                                 check_return_value=False)

        is_commit_required_value = True
        is_reboot_required_value = None

        ret_value = utils.find_xml(doc, 'ReturnValue',
                                   uris.DCIM_RAIDService).text

        if ret_value == utils.RET_ERROR:
            message_id = utils.find_xml(doc, 'MessageID',
                                        uris.DCIM_RAIDService).text

            # A MessageID 'STOR018'/'STOR058' indicates no foreign drive was
            # detected. Return a value which informs the caller nothing
            # further needs to be done.
            no_foreign_drives_detected = any(stor_id == message_id
                                             for stor_id in NO_FOREIGN_DRIVES)
            if no_foreign_drives_detected:
                is_commit_required_value = False
                is_reboot_required_value = constants.RebootRequired.false
            else:
                message = utils.find_xml(doc, 'Message',
                                         uris.DCIM_RAIDService).text
                raise exceptions.DRACOperationFailed(drac_messages=message)

        return utils.build_return_dict(
            doc,
            uris.DCIM_RAIDService,
            is_commit_required_value=is_commit_required_value,
            is_reboot_required_value=is_reboot_required_value)