Ejemplo n.º 1
0
    def get_version(self):
        """
        Gets the major version from the Rhevm server
        """
        try:
            headers = dict()
            headers['Version'] = '3'
            response = requests.get(urlparse.urljoin(self.url, 'api'),
                                    auth=self.auth,
                                    headers=headers,
                                    verify=False)
            if response.status_code == 404 and 'ovirt-engine' not in self.url:
                response = requests.get(urlparse.urljoin(
                    self.url, 'ovirt-engine/api'),
                                        auth=self.auth,
                                        headers=headers,
                                        verify=False)
            response.raise_for_status()
        except requests.RequestException as e:
            raise virt.VirtError("Unable to connect to RHEV-M server: %s" %
                                 str(e))

        try:
            api = ElementTree.fromstring(response.content)
        except Exception as e:
            self.logger.debug("Invalid xml file: %s" % response)
            raise virt.VirtError("Invalid XML file returned from RHEV-M: %s" %
                                 str(e))
        version = api.find('.//version')
        if version is not None:
            major = version.attrib['major']
            self.major_version = major
        else:
            self.logger.info("Could not determine version")
Ejemplo n.º 2
0
    def createFilter(self):
        oSpec = self.objectSpec()
        oSpec.obj = self.sc.rootFolder
        oSpec.selectSet = self.buildFullTraversal()

        pfs = self.propertyFilterSpec()
        pfs.objectSet = [oSpec]
        pfs.propSet = [
            self.createPropertySpec("VirtualMachine",
                                    ["config.uuid", "runtime.powerState"]),
            self.createPropertySpec("ClusterComputeResource", ["name"]),
            self.createPropertySpec("HostSystem", [
                "name", "vm", "hardware.systemInfo.uuid",
                "hardware.cpuInfo.numCpuPackages", "parent",
                "config.product.name", "config.product.version",
                "config.network.dnsConfig.hostName",
                "config.network.dnsConfig.domainName"
            ])
        ]

        try:
            return self.client.service.CreateFilter(
                _this=self.sc.propertyCollector, spec=pfs, partialUpdates=0)
        except requests.RequestException as e:
            raise virt.VirtError(str(e))
Ejemplo n.º 3
0
    def login(self):
        """
        Log into ESX
        """

        kwargs = {'transport': RequestsTransport()}
        # Connect to the vCenter server
        if self.config['simplified_vim']:
            wsdl = 'file://%s/vimServiceMinimal.wsdl' % os.path.dirname(
                os.path.abspath(__file__))
            kwargs['cache'] = None
        else:
            wsdl = self.url + '/sdk/vimService.wsdl'
        try:
            self.client = suds.client.Client(wsdl,
                                             location="%s/sdk" % self.url,
                                             **kwargs)
        except requests.RequestException as e:
            raise virt.VirtError(str(e))

        self.client.set_options(timeout=self.MAX_WAIT_TIME)

        # Get Meta Object Reference to ServiceInstance which is the root object of the inventory
        self.moRef = suds.sudsobject.Property('ServiceInstance')
        self.moRef._type = 'ServiceInstance'  # pylint: disable=W0212

        # Service Content object defines properties of the ServiceInstance object
        try:
            self.sc = self.client.service.RetrieveServiceContent(
                _this=self.moRef)
        except requests.RequestException as e:
            raise virt.VirtError(str(e))

        # Login to server using given credentials
        try:
            # Don't log message containing password
            logging.getLogger('suds.client').setLevel(logging.CRITICAL)
            self.client.service.Login(_this=self.sc.sessionManager,
                                      userName=self.username,
                                      password=self.password)
            logging.getLogger('suds.client').setLevel(logging.ERROR)
        except requests.RequestException as e:
            raise virt.VirtError(str(e))
        except suds.WebFault as e:
            self.logger.exception("Unable to login to ESX")
            raise virt.VirtError(str(e))
Ejemplo n.º 4
0
    def get_version(self):
        """
        Gets the major version from the Rhevm server
        """
        try:
            # If we are talking to a Rhev4 system, we need to specifically request
            # the Rhev 3 version of the api.  To minimize code impact, we do this
            # by setting a 'Version' header, as outlined in Rhev 4's "Version 3
            # REST API Guide"
            headers = dict()
            headers['Version'] = '3'
            # We will store the api_base that seems to work and use that for future requests
            response = requests.get(urllib.parse.urljoin(
                self.url, self.api_base),
                                    auth=self.auth,
                                    headers=headers,
                                    verify=False)
            if response.status_code == 404:
                # this would happen if the api_base is not correct. early version 3 API.
                self.api_base = 'api'
                response = requests.get(urllib.parse.urljoin(
                    self.url, self.api_base),
                                        auth=self.auth,
                                        headers=headers,
                                        verify=False)
            response.raise_for_status()
        except requests.RequestException as e:
            raise virt.VirtError("Unable to connect to RHEV-M server: %s" %
                                 str(e))

        try:
            api = ElementTree.fromstring(response.content)
        except Exception as e:
            self.logger.debug("Invalid xml file: %s" % response)
            raise virt.VirtError("Invalid XML file returned from RHEV-M: %s" %
                                 str(e))
        version = api.find('.//version')
        if version is not None:
            major = version.attrib['major']
            self.major_version = major
        else:
            self.logger.info("Could not determine version")
Ejemplo n.º 5
0
 def get_xml(self, url):
     """
     Call RHEV-M server, retrieve XML and parse it.
     """
     response = self.get(url)
     try:
         return ElementTree.fromstring(response)
     except Exception as e:
         self.logger.debug("Invalid xml file: %s" % response)
         raise virt.VirtError("Invalid XML file returned from RHEV-M: %s" %
                              str(e))
Ejemplo n.º 6
0
 def get(self, url):
     """
     Call RHEV-M server and retrieve what's on given url.
     """
     try:
         response = requests.get(url, auth=self.auth, verify=False)
         response.raise_for_status()
     except requests.RequestException as e:
         raise virt.VirtError("Unable to connect to RHEV-M server: %s" %
                              str(e))
     # FIXME: other errors
     return response.content
Ejemplo n.º 7
0
 def login(self, url=None):
     """ Login to server using given credentials. """
     url = url or self.url
     try:
         # Don't log message containing password
         self.session = XenAPI.Session(
             url, transport=RequestsXmlrpcTransport(url))
         self.session.xenapi.login_with_password(self.username,
                                                 self.password)
         self.logger.debug("XEN pool login successful with user %s" %
                           self.username)
     except NewMaster as nm:
         url = nm.new_master()
         if "://" not in url:
             url = '%s://%s' % (self.url.partition(":")[0], url)
         self.logger.debug("Switching to new master: %s", url)
         return self.login(url)
     except requests.ConnectionError as e:
         raise virt.VirtError(str(e))
     except Exception as e:
         self.logger.exception("Unable to login to XENserver %s" % self.url)
         raise virt.VirtError(str(e))
Ejemplo n.º 8
0
 def get(self, url):
     """
     Call RHEV-M server and retrieve what's on given url.
     """
     headers = dict()
     try:
         if self.major_version == '4':
             headers['Version'] = '3'
         response = requests.get(url,
                                 auth=self.auth,
                                 verify=False,
                                 headers=headers)
         response.raise_for_status()
     except requests.RequestException as e:
         raise virt.VirtError("Unable to connect to RHEV-M server: %s" %
                              str(e))
     # FIXME: other errors
     return response.content
Ejemplo n.º 9
0
 def get(self, url):
     """
     Call RHEV-M server and retrieve what's on given url.
     """
     try:
         if self.major_version == '4':
             # If we are talking to a Rhev4 system, we need to specifically request
             # the Rhev 3 version of the api.  To minimize code impact, we do this
             # by setting a 'Version' header, as outlined in Rhev 4's "Version 3
             # REST API Guide"
             headers = dict()
             headers['Version'] = '3'
             response = requests.get(url,
                                     auth=self.auth,
                                     verify=False,
                                     headers=headers)
         else:
             response = requests.get(url, auth=self.auth, verify=False)
         response.raise_for_status()
     except requests.RequestException as e:
         raise virt.VirtError("Unable to connect to RHEV-M server: %s" %
                              str(e))
     # FIXME: other errors
     return response.content
Ejemplo n.º 10
0
    def getHostGuestMapping(self):
        guests = []
        connection = self.connect()
        hypervsoap = HyperVSoap(self.url, connection, self.logger)
        uuid = None
        if not self.useNewApi:
            try:
                # SettingType == 3 means current setting, 5 is snapshot - we don't want snapshots
                uuid = hypervsoap.Enumerate(
                    "select BIOSGUID, ElementName "
                    "from Msvm_VirtualSystemSettingData "
                    "where SettingType = 3", "root/virtualization")
            except HyperVCallFailed:
                self.logger.debug(
                    "Unable to enumerate using root/virtualization namespace, "
                    "trying root/virtualization/v2 namespace")
                self.useNewApi = True

        if self.useNewApi:
            # Filter out Planned VMs and snapshots, see
            # http://msdn.microsoft.com/en-us/library/hh850257%28v=vs.85%29.aspx
            uuid = hypervsoap.Enumerate(
                "select BIOSGUID, ElementName "
                "from Msvm_VirtualSystemSettingData "
                "where VirtualSystemType = 'Microsoft:Hyper-V:System:Realized'",
                "root/virtualization/v2")

        # Get guest states
        guest_states = hypervsoap.Invoke_GetSummaryInformation(
            "root/virtualization/v2" if self.
            useNewApi else "root/virtualization")
        vmmsVersion = self.getVmmsVersion(hypervsoap)
        for instance in hypervsoap.Pull(uuid):
            try:
                uuid = instance["BIOSGUID"]
            except KeyError:
                self.logger.warning("Guest without BIOSGUID found, ignoring")
                continue

            try:
                elementName = instance["ElementName"]
            except KeyError:
                self.logger.warning("Guest %s is missing ElementName", uuid)
                continue

            try:
                state = guest_states[elementName]
            except KeyError:
                self.logger.warning("Unknown state for guest %s", elementName)
                state = virt.Guest.STATE_UNKNOWN

            guests.append(virt.Guest(HyperV.decodeWinUUID(uuid), self, state))
        # Get the hostname
        hostname = None
        socket_count = None
        data = hypervsoap.Enumerate(
            "select DNSHostName, NumberOfProcessors from Win32_ComputerSystem",
            "root/cimv2")
        for instance in hypervsoap.Pull(data, "root/cimv2"):
            hostname = instance["DNSHostName"]
            socket_count = instance["NumberOfProcessors"]

        if self.config.hypervisor_id == 'uuid':
            uuid = hypervsoap.Enumerate(
                "select UUID from Win32_ComputerSystemProduct", "root/cimv2")
            host = None
            for instance in hypervsoap.Pull(uuid, "root/cimv2"):
                host = HyperV.decodeWinUUID(instance["UUID"])
        elif self.config.hypervisor_id == 'hostname':
            host = hostname
        else:
            raise virt.VirtError(
                'Invalid option %s for hypervisor_id, use one of: uuid, or hostname'
                % self.config.hypervisor_id)
        facts = {
            virt.Hypervisor.CPU_SOCKET_FACT: str(socket_count),
            virt.Hypervisor.HYPERVISOR_TYPE_FACT: 'hyperv',
            virt.Hypervisor.HYPERVISOR_VERSION_FACT: vmmsVersion,
        }
        hypervisor = virt.Hypervisor(hypervisorId=host,
                                     name=hostname,
                                     guestIds=guests,
                                     facts=facts)
        return {'hypervisors': [hypervisor]}
Ejemplo n.º 11
0
    def getHostGuestMapping(self):
        """
        Returns dictionary containing a list of virt.Hypervisors
        Each virt.Hypervisor contains the hypervisor ID as well as a list of
        virt.Guest

        {'hypervisors': [Hypervisor1, ...]
        }
        """
        mapping = {}
        hosts = {}
        clusters = set()

        clusters_xml = self.get_xml(self.clusters_url)
        hosts_xml = self.get_xml(self.hosts_url)
        vms_xml = self.get_xml(self.vms_url)

        # Save ids of clusters that are "virt_service"
        for cluster in clusters_xml.findall('cluster'):
            cluster_id = cluster.get('id')
            virt_service = cluster.find('virt_service').text
            if virt_service.lower() == 'true':
                clusters.add(cluster_id)

        for host in hosts_xml.findall('host'):
            id = host.get('id')

            # Check if host is in cluster that is "virt_service"
            host_cluster = host.find('cluster')
            host_cluster_id = host_cluster.get('id')
            if host_cluster_id not in clusters:
                # Skip the host if it's cluster is not "virt_service"
                self.logger.debug(
                    'Cluster of host %s is not virt_service, skipped', id)
                continue

            if self.config.hypervisor_id == 'uuid':
                host_id = id
            elif self.config.hypervisor_id == 'hwuuid':
                try:
                    host_id = host.find('hardware_information').find(
                        'uuid').text
                except AttributeError:
                    self.logger.warn("Host %s doesn't have hardware uuid", id)
                    continue
            elif self.config.hypervisor_id == 'hostname':
                host_id = host.find('name').text
            else:
                raise virt.VirtError(
                    'Invalid option %s for hypervisor_id, use one of: uuid, hwuuid, or hostname'
                    % self.config.hypervisor_id)

            sockets = host.find('cpu').find('topology').get('sockets')
            if not sockets:
                sockets = host.find('cpu').find('topology').find(
                    'sockets').text

            facts = {
                virt.Hypervisor.CPU_SOCKET_FACT: sockets,
                virt.Hypervisor.HYPERVISOR_TYPE_FACT: 'qemu',
            }
            try:
                version = host.find('version').get('full_version')
                if version:
                    facts[virt.Hypervisor.HYPERVISOR_VERSION_FACT] = version
            except AttributeError:
                pass

            hosts[id] = virt.Hypervisor(hypervisorId=host_id,
                                        name=host.find('name').text,
                                        facts=facts)
            mapping[id] = []
        for vm in vms_xml.findall('vm'):
            guest_id = vm.get('id')
            host = vm.find('host')
            if host is None:
                # Guest don't have any host
                continue

            host_id = host.get('id')
            if host_id not in mapping.keys():
                self.logger.warning(
                    "Guest %s claims that it belongs to host %s which doesn't exist",
                    guest_id, host_id)
                continue

            try:
                status = vm.find('status')
                try:
                    state_text = status.find('state').text.lower()
                except AttributeError:
                    # RHEVM 4.0 reports the state differently
                    state_text = status.text.lower()
                state = RHEVM_STATE_TO_GUEST_STATE.get(
                    state_text, virt.Guest.STATE_UNKNOWN)
            except AttributeError:
                self.logger.warning("Guest %s doesn't report any status",
                                    guest_id)
                state = virt.Guest.STATE_UNKNOWN

            hosts[host_id].guestIds.append(virt.Guest(guest_id, self, state))

        return {'hypervisors': hosts.values()}
Ejemplo n.º 12
0
    def getHostGuestMapping(self):
        mapping = {'hypervisors': []}
        for host_id, host in self.hosts.items():
            parent = host['parent'].value
            if self.config.exclude_host_parents is not None and parent in self.config.exclude_host_parents:
                self.logger.debug(
                    "Skipping host '%s' because its parent '%s' is excluded",
                    host_id, parent)
                continue
            if self.config.filter_host_parents is not None and parent not in self.config.filter_host_parents:
                self.logger.debug(
                    "Skipping host '%s' because its parent '%s' is not included",
                    host_id, parent)
                continue
            guests = []

            try:
                if self.config.hypervisor_id == 'uuid':
                    uuid = host['hardware.systemInfo.uuid']
                elif self.config.hypervisor_id == 'hwuuid':
                    uuid = host_id
                elif self.config.hypervisor_id == 'hostname':
                    uuid = host['config.network.dnsConfig.hostName']
                    domain_name = host['config.network.dnsConfig.domainName']
                    if domain_name:
                        uuid = '{0}.{1}'.format(uuid, domain_name)
                else:
                    raise virt.VirtError(
                        'Invalid option %s for hypervisor_id, use one of: uuid, hwuuid, or hostname'
                        % self.config.hypervisor_id)
            except KeyError:
                self.logger.debug(
                    "Host '%s' doesn't have hypervisor_id property", host_id)
                continue
            if host['vm']:
                for vm_id in host['vm'].ManagedObjectReference:
                    if vm_id.value not in self.vms:
                        self.logger.debug(
                            "Host '%s' references non-existing guest '%s'",
                            host_id, vm_id.value)
                        continue
                    vm = self.vms[vm_id.value]
                    if 'config.uuid' not in vm:
                        self.logger.debug(
                            "Guest '%s' doesn't have 'config.uuid' property",
                            vm_id.value)
                        continue
                    if not vm['config.uuid'].strip():
                        self.logger.debug(
                            "Guest '%s' has empty 'config.uuid' property",
                            vm_id.value)
                        continue
                    state = virt.Guest.STATE_UNKNOWN
                    try:
                        if vm['runtime.powerState'] == 'poweredOn':
                            state = virt.Guest.STATE_RUNNING
                        elif vm['runtime.powerState'] == 'suspended':
                            state = virt.Guest.STATE_PAUSED
                        elif vm['runtime.powerState'] == 'poweredOff':
                            state = virt.Guest.STATE_SHUTOFF
                    except KeyError:
                        self.logger.debug(
                            "Guest '%s' doesn't have 'runtime.powerState' property",
                            vm_id.value)
                    guests.append(virt.Guest(vm['config.uuid'], self, state))
            try:
                name = host['config.network.dnsConfig.hostName']
                domain_name = host['config.network.dnsConfig.domainName']
                if domain_name:
                    name = '{0}.{1}'.format(name, domain_name)
            except KeyError:
                self.logger.debug("Unable to determine hostname for host '%s'",
                                  uuid)
                name = ''

            facts = {
                virt.Hypervisor.CPU_SOCKET_FACT:
                str(host['hardware.cpuInfo.numCpuPackages']),
                virt.Hypervisor.HYPERVISOR_TYPE_FACT:
                host.get('config.product.name', 'vmware'),
            }
            version = host.get('config.product.version', None)
            if version:
                facts[virt.Hypervisor.HYPERVISOR_VERSION_FACT] = version

            mapping['hypervisors'].append(
                virt.Hypervisor(hypervisorId=uuid,
                                guestIds=guests,
                                name=name,
                                facts=facts))
        return mapping
Ejemplo n.º 13
0
    def _send(self, method, url, **kwargs):
        """This private method acting as proxy for all http methods.
    Args:
      method (str): The http method type.
      url (str): The URL to for the Request
      kwargs (dict): Keyword args to be passed to the requests call.
        retries (int): The retry count in case of HTTP errors.
                       Except the codes in the list NO_RETRY_HTTP_CODES.

    Returns:
      Response (requests.Response): The response object.
    """
        kwargs['verify'] = kwargs.get('verify', False)
        if 'timeout' not in kwargs:
            kwargs['timeout'] = self._timeout
        if 'data' not in kwargs:
            body = {}
            kwargs['data'] = json.dumps(body)
        content_dict = {'content-type': 'application/json'}
        kwargs.setdefault('headers', {})
        kwargs['headers'].update(content_dict)

        func = getattr(self._session, method)
        response = None

        retries = kwargs.pop("retries", None)
        retry_interval = kwargs.pop("retry_interval", self._retry_interval)
        retry_count = retries if retries else self._retries
        for ii in range(retry_count):
            try:
                response = func(url, **kwargs)
                if self._internal_debug:
                    self._logger.debug("%s method The request url sent: %s" %
                                       (method.upper(), response.request.url))
                    self._logger.debug('Response status: %d' %
                                       response.status_code)
                    self._logger.debug('Response: %s' %
                                       json.dumps(response.json(), indent=4))

            except (ConnectionError, ReadTimeout) as e:
                self._logger.warning("Request failed with error: %s" % e)
                if ii != retry_count - 1:
                    time.sleep(retry_interval)
                continue
            finally:
                self._session.close()
            if response.ok:
                return response
            if response.status_code in [401, 403]:
                raise virt.VirtError(
                    'HTTP Auth Failed %s %s. \n res: response: %s' %
                    (method, url, response))
            elif response.status_code == 409:
                raise virt.VirtError(
                    'HTTP conflict with the current state of the '
                    'target resource %s %s. \n res: %s' %
                    (method, url, response))
            elif response.status_code in self.NO_RETRY_HTTP_CODES:
                break
            if ii != retry_count - 1:
                time.sleep(retry_interval)

        if response is not None:
            msg = 'HTTP %s %s failed: ' % (method, url)
            if hasattr(response, "text") and response.text:
                msg = "\n".join([msg, response.text]).encode('utf-8')
                self._logger.error(msg)
        else:
            self._logger.error("Failed to make the HTTP request (%s, %s)" %
                               (method, url))
Ejemplo n.º 14
0
    def getHostGuestMapping(self):
        assert hasattr(self, 'session'), "Login was not called"
        hosts = self.session.xenapi.host.get_all()

        mapping = {
            'hypervisors': [],
        }

        for host in hosts:

            record = self.session.xenapi.host.get_record(host)
            guests = []

            for resident in self.session.xenapi.host.get_resident_VMs(host):
                vm = self.session.xenapi.VM.get_record(resident)
                uuid = vm['uuid']

                if vm.get('is_control_domain', False):
                    if uuid not in self.ignored_guests:
                        self.ignored_guests.add(uuid)
                        self.logger.debug("Control Domain %s is ignored", uuid)
                    continue

                if vm.get('is_a_snapshot', False) or vm.get(
                        'is_a_template', False):
                    if uuid not in self.ignored_guests:
                        self.ignored_guests.add(uuid)
                        self.logger.debug(
                            "Guest %s is snapshot or template, ignoring", uuid)
                    continue

                if vm['power_state'] == 'Running':
                    state = virt.Guest.STATE_RUNNING
                elif vm['power_state'] == 'Suspended':
                    state = virt.Guest.STATE_PAUSED
                elif vm['power_state'] == 'Paused':
                    state = virt.Guest.STATE_PAUSED
                elif vm['power_state'] == 'Halted':
                    state = virt.Guest.STATE_SHUTOFF
                else:
                    state = virt.Guest.STATE_UNKNOWN

                guests.append(virt.Guest(uuid=uuid, virt=self, state=state))

            facts = {}
            sockets = record.get('cpu_info', {}).get('socket_count')
            if sockets is not None:
                facts[virt.Hypervisor.CPU_SOCKET_FACT] = str(sockets)
            brand = record.get('software_version', {}).get('product_brand')
            if brand:
                facts[virt.Hypervisor.HYPERVISOR_TYPE_FACT] = brand
            version = record.get('software_version', {}).get('product_version')
            if version:
                facts[virt.Hypervisor.HYPERVISOR_VERSION_FACT] = version

            if self.config.hypervisor_id == 'uuid':
                uuid = record["uuid"]
            elif self.config.hypervisor_id == 'hwuuid':
                uuid = record["cpu_info"]['features']
            elif self.config.hypervisor_id == 'hostname':
                uuid = record["hostname"]
            else:
                raise virt.VirtError(
                    'Invalid option %s for hypervisor_id, use one of: uuid, hwuuid, or hostname'
                    % self.config.hypervisor_id)

            mapping['hypervisors'].append(
                virt.Hypervisor(hypervisorId=uuid,
                                guestIds=guests,
                                name=record["hostname"],
                                facts=facts))
        return mapping