def invoke(self,
               resource_uri,
               method,
               selectors=None,
               properties=None,
               expected_return_value=None,
               wait_for_idrac=True,
               check_return_value=True):
        """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.
        :param wait_for_idrac: indicates whether or not to wait for the
            iDRAC to be ready to accept commands before issuing the
            command
        :param check_return_value: indicates if the ReturnValue should be
            checked and an exception thrown on an unexpected value
        :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 wait_for_idrac:
            self.wait_until_idrac_is_ready()

        if selectors is None:
            selectors = {}

        if properties is None:
            properties = {}

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

        if check_return_value:
            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
    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)
        physical_disks = [
            self._parse_drac_physical_disk(disk)
            for disk in drac_physical_disks
        ]

        drac_pcie_disks = utils.find_xml(doc,
                                         'DCIM_PCIeSSDView',
                                         uris.DCIM_PCIeSSDView,
                                         find_all=True)
        pcie_disks = [
            self._parse_drac_physical_disk(disk, uris.DCIM_PCIeSSDView)
            for disk in drac_pcie_disks
        ]

        return physical_disks + pcie_disks
Пример #3
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 != "Reboot Failed" 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]
    def is_idrac_ready(self):
        """Indicates if the iDRAC is ready to accept commands

           Returns a boolean indicating if the iDRAC is ready to accept
           commands.

        :returns: Boolean indicating iDRAC readiness
        :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',
            'SystemName': 'DCIM:ComputerSystem',
            'CreationClassName': 'DCIM_LCService',
            'Name': 'DCIM:LCService'
        }

        result = self.invoke(uris.DCIM_LCService,
                             'GetRemoteServicesAPIStatus',
                             selectors, {},
                             expected_return_value=utils.RET_SUCCESS,
                             wait_for_idrac=False)

        message_id = utils.find_xml(result, 'MessageID',
                                    uris.DCIM_LCService).text

        return message_id == IDRAC_IS_READY
    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.instance_id,
                   bios_attr.current_value, bios_attr.pending_value,
                   bios_attr.read_only, possible_values)
    def parse(cls, idrac_attr_xml):
        """Parses XML and creates iDRACCardEnumerableAttribute object"""

        idrac_attr = iDRACCardAttribute.parse(cls.namespace, idrac_attr_xml)
        possible_values = [attr.text for attr
                           in utils.find_xml(idrac_attr_xml, 'PossibleValues',
                                             cls.namespace, find_all=True)]

        return cls(idrac_attr.name, idrac_attr.instance_id,
                   idrac_attr.current_value, idrac_attr.pending_value,
                   idrac_attr.read_only, idrac_attr.fqdd, idrac_attr.group_id,
                   possible_values)
Пример #7
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)
    def parse(cls, system_attr_xml):
        """Parses XML and creates SystemEnumerableAttribute object"""

        system_attr = SystemAttribute.parse(
            cls.namespace, system_attr_xml)
        possible_values = [attr.text for attr
                           in utils.find_xml(system_attr_xml, 'PossibleValues',
                                             cls.namespace, find_all=True)]

        return cls(system_attr.name, system_attr.instance_id,
                   system_attr.current_value, system_attr.pending_value,
                   system_attr.read_only, system_attr.fqdd,
                   system_attr.group_id, possible_values)
    def get_system(self):
        """Returns a System object

            :returns: a System object
            :raises: WSManRequestFailure on request failures
            :raises: WSManInvalidRespons when receiving invalid response
        """
        doc = self.client.enumerate(uris.DCIM_SystemView)
        drac_system = utils.find_xml(doc,
                                     'DCIM_SystemView',
                                     uris.DCIM_SystemView,
                                     find_all=False)

        return self._parse_drac_system(drac_system)
Пример #10
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
        """

        doc = self.client.enumerate(uris.DCIM_SystemView, wait_for_idrac=False)
        lc_version_str = utils.find_xml(doc, 'LifecycleControllerVersion',
                                        uris.DCIM_SystemView).text

        return tuple(map(int, (lc_version_str.split('.'))))
    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]
    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]
    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
    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]
    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]
    def list_nics(self, sort=False):
        """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)
        nics = [self._parse_drac_nic(nic) for nic in drac_nics]
        if sort:
            nics.sort(key=lambda nic: nic.id)

        return nics
    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
        ]
Пример #18
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)