Exemplo n.º 1
0
    def hypervisorHeartbeat(self, config, options=None):
        """
        Send heart beat to candlepin server
        :param config: reference on configuration
        :param options: other options
        """
        if options:
            named_options = NamedOptions()
            for key, value in options['global'].items():
                setattr(named_options, key, value)
        else:
            named_options = None

        try:
            connection = self._connect(config)
            result = connection.hypervisorHeartbeat(config['owner'], named_options)
        except BadStatusLine:
            raise ManagerError("Communication with subscription manager interrupted")
        except rhsm_connection.RateLimitExceededException as e:
            raise ManagerThrottleError(e.retry_after)
        except rhsm_connection.GoneException:
            raise ManagerError("Communication with subscription manager failed: consumer no longer exists")
        except rhsm_connection.ConnectionException as e:
            if hasattr(e, 'code'):
                raise ManagerError("Communication with subscription manager failed with code %d: %s" % (e.code, str(e)))
            raise ManagerError("Communication with subscription manager failed: %s" % str(e))

        return result
Exemplo n.º 2
0
    def hypervisorCheckIn(self, report, options=None):
        """ Send hosts to guests mapping to subscription manager. """
        connection = self._connect(report.config)

        is_async = self._is_rhsm_server_async(report, connection)
        serialized_mapping = self._hypervisor_mapping(report, is_async,
                                                      connection)
        self.logger.debug(
            "Host-to-guest mapping being sent to '{owner}': {mapping}".format(
                owner=report.config['owner'],
                mapping=json.dumps(serialized_mapping, indent=4)))

        # All subclasses of ConfigSection use dictionary like notation,
        # but RHSM uses attribute like notation
        if options:
            named_options = NamedOptions()
            for key, value in options['global'].items():
                setattr(named_options, key, value)
        else:
            named_options = None

        try:
            try:
                result = self.connection.hypervisorCheckIn(
                    report.config['owner'],
                    report.config['env'],
                    serialized_mapping,
                    options=named_options)  # pylint:disable=unexpected-keyword-arg
            except TypeError:
                # This is temporary workaround until the options parameter gets implemented
                # in python-rhsm
                self.logger.debug(
                    "hypervisorCheckIn method in python-rhsm doesn't understand options parameter, ignoring"
                )
                result = self.connection.hypervisorCheckIn(
                    report.config['owner'], report.config['env'],
                    serialized_mapping)
        except BadStatusLine:
            raise ManagerError(
                "Communication with subscription manager interrupted")
        except rhsm_connection.RateLimitExceededException as e:
            raise ManagerThrottleError(e.retry_after)
        except rhsm_connection.GoneException:
            raise ManagerError(
                "Communication with subscription manager failed: consumer no longer exists"
            )
        except rhsm_connection.ConnectionException as e:
            if hasattr(e, 'code'):
                raise ManagerError(
                    "Communication with subscription manager failed with code %d: %s"
                    % (e.code, str(e)))
            raise ManagerError(
                "Communication with subscription manager failed: %s" % str(e))

        if is_async is True:
            report.state = AbstractVirtReport.STATE_PROCESSING
            report.job_id = result['id']
        else:
            report.state = AbstractVirtReport.STATE_FINISHED
        return result
Exemplo n.º 3
0
 def check_report_state(self, report):
     # BZ 1554228
     job_id = str(report.job_id)
     self._connect(report.config)
     self.logger.debug('Checking status of job %s', job_id)
     try:
         result = self.connection.getJob(job_id)
     except BadStatusLine:
         raise ManagerError("Communication with subscription manager interrupted")
     except rhsm_connection.RateLimitExceededException as e:
         raise ManagerThrottleError(e.retry_after)
     except rhsm_connection.ConnectionException as e:
         if hasattr(e, 'code'):
             raise ManagerError("Communication with subscription manager failed with code %d: %s" % (e.code, str(e)))
         raise ManagerError("Communication with subscription manager failed: %s" % str(e))
     state = STATE_MAPPING.get(result['state'], AbstractVirtReport.STATE_FAILED)
     report.state = state
     if state not in (AbstractVirtReport.STATE_FINISHED,
                      AbstractVirtReport.STATE_CANCELED,
                      AbstractVirtReport.STATE_FAILED):
         self.logger.debug('Job %s not finished', job_id)
     else:
         # log completed job status
         result_data = result.get('resultData', {})
         if not result_data:
             self.logger.warning("Job status report without resultData: %s", result)
             return
         if isinstance(result_data, string_types):
             self.logger.warning("Job status report encountered the following error: %s", result_data)
             return
         for fail in result_data.get('failedUpdate', []):
             self.logger.error("Error during update list of guests: %s", str(fail))
         self.logger.debug("Number of mappings unchanged: %d", len(result_data.get('unchanged', [])))
         self.logger.info("Mapping for config \"%s\" updated", report.config.name)
Exemplo n.º 4
0
    def sendVirtGuests(self, report, options=None):
        """
        Update consumer facts with info about virtual guests.

        `guests` is a list of `Guest` instances (or it children).
        """
        guests = report.guests
        self._connect(report.config)

        # Sort the list
        guests.sort(key=lambda item: item.uuid)

        serialized_guests = [guest.toDict() for guest in guests]
        self.logger.info('Sending update in guests lists for config '
                         '"%s": %d guests found',
                         report.config.name, len(guests))
        self.logger.debug("Domain info: %s", json.dumps(serialized_guests, indent=4))

        # Send list of guest uuids to the server
        try:
            self.connection.updateConsumer(self.uuid(), guest_uuids=serialized_guests, hypervisor_id=report.hypervisor_id)
        except rhsm_connection.GoneException:
            raise ManagerError("Communication with subscription manager failed: consumer no longer exists")
        except rhsm_connection.RateLimitExceededException as e:
            raise ManagerThrottleError(e.retry_after)
        report.state = AbstractVirtReport.STATE_FINISHED
Exemplo n.º 5
0
 def check_report_state(self, report):
     job_id = report.job_id
     self._connect(report.config)
     self.logger.debug('Checking status of job %s', job_id)
     try:
         result = self.connection.getJob(job_id)
     except BadStatusLine:
         raise ManagerError(
             "Communication with subscription manager interrupted")
     except rhsm_connection.ConnectionException as e:
         if hasattr(e, 'code'):
             raise ManagerError(
                 "Communication with subscription manager failed with code %d: %s"
                 % (e.code, str(e)))
         raise ManagerError(
             "Communication with subscription manager failed: %s" % str(e))
     state = STATE_MAPPING.get(result['state'],
                               AbstractVirtReport.STATE_FAILED)
     report.state = state
     if state not in (AbstractVirtReport.STATE_FINISHED,
                      AbstractVirtReport.STATE_CANCELED,
                      AbstractVirtReport.STATE_FAILED):
         self.logger.debug('Job %s not finished', job_id)
     else:
         # log completed job status
         resultData = result.get('resultData', {})
         if not resultData:
             self.logger.warning("Job status report without resultData: %s",
                                 result)
             return
         for fail in resultData.get('failedUpdate', []):
             self.logger.error("Error during update list of guests: %s",
                               str(fail))
         for updated in resultData.get('updated', []):
             guests = [x['guestId'] for x in updated['guestIds']]
             self.logger.debug("Updated host %s with guests: [%s]",
                               updated['uuid'], ", ".join(guests))
         for created in resultData.get('created', []):
             guests = [x['guestId'] for x in created['guestIds']]
             self.logger.debug("Created host: %s with guests: [%s]",
                               created['uuid'], ", ".join(guests))
         self.logger.debug("Number of mappings unchanged: %d",
                           len(resultData.get('unchanged', [])))
         self.logger.info("Mapping for config \"%s\" updated",
                          report.config.name)
Exemplo n.º 6
0
    def _check_owner_lib(self, kwargs, config):
        """
        Try to check values of env and owner. These values has to be
        equal to values obtained from Satellite server.
        :param kwargs: dictionary possibly containing valid username and
                       password used for connection to rhsm
        :param config: Configuration of virt-who
        :return: None
        """

        if config is None:
            return

        # Check 'owner' and 'env' only in situation, when these values
        # are set and rhsm_username and rhsm_password are not set
        if 'username' not in kwargs and 'password' not in kwargs and \
                'owner' in config.keys() and 'env' in config.keys():
            pass
        else:
            return

        uuid = self.uuid()
        consumer = self.connection.getConsumer(uuid)

        if 'environment' in consumer:
            environment = consumer['environment']
        else:
            return

        if environment:
            environment_name = environment['name']
            owner = self.connection.getOwner(uuid)
            owner_id = owner['key']

            if config['owner'] != owner_id:
                raise ManagerError(
                    "Cannot send data to: %s, because owner from configuration: %s is different" %
                    (owner_id, config['owner'])
                )

            if config['env'] != environment_name:
                raise ManagerError(
                    "Cannot send data to: %s, because Satellite env: %s differs from configuration: %s" %
                    (owner_id, environment_name, config['env'])
                )
Exemplo n.º 7
0
    def test_send_check_status_heartbeat_call_failure(self):
        # This tests that reports of the right type are batched into one
        # and that the hypervisorCheckIn method of the destination is called
        # with the right parameters
        config1, d1 = self.create_fake_config('source1',
                                              **self.default_config_args)
        config2, d2 = self.create_fake_config('source2',
                                              **self.default_config_args)
        virt1 = Mock()
        virt1.CONFIG_TYPE = 'esx'
        virt2 = Mock()
        virt2.CONFIG_TYPE = 'esx'
        report1 = StatusReport(config1)
        report2 = StatusReport(config2)

        data_to_send = {'source1': report1, 'source2': report2}

        source_keys = ['source1', 'source2']
        report1 = Mock()
        report2 = Mock()
        report1.hash = "report1_hash"
        report2.hash = "report2_hash"
        datastore = {'source1': report1, 'source2': report2}

        manager = Mock()
        options = Mock()
        options.print_ = False

        manager.hypervisorHeartbeat = Mock(
            side_effect=ManagerError("cannot connect to destination"))
        manager.hypervisorCheckIn = Mock()
        logger = Mock()
        config, d = self.create_fake_config('test', **self.default_config_args)
        config.owner = 'test_owner'
        terminate_event = Mock()
        interval = 10  # Arbitrary for this test
        destination_thread = DestinationThread(logger,
                                               config,
                                               source_keys=source_keys,
                                               source=datastore,
                                               dest=manager,
                                               interval=interval,
                                               terminate_event=terminate_event,
                                               oneshot=True,
                                               status=True,
                                               options=self.options)
        destination_thread._send_data(data_to_send)
        for source_key, report in data_to_send.items():
            self.assertEqual(
                report.data['destination']['message'],
                "Error during status connection: cannot connect to destination."
            )
Exemplo n.º 8
0
    def _connect(self, config=None):
        """ Connect to the subscription-manager. """

        kwargs = {
            'host': self.rhsm_config.get('server', 'hostname'),
            'ssl_port': int(self.rhsm_config.get('server', 'port')),
            'handler': self.rhsm_config.get('server', 'prefix'),
            'proxy_hostname': self.rhsm_config.get('server', 'proxy_hostname'),
            'proxy_port': self.rhsm_config.get('server', 'proxy_port'),
            'proxy_user': self.rhsm_config.get('server', 'proxy_user'),
            'proxy_password': self.rhsm_config.get('server', 'proxy_password'),
            'no_proxy': self.rhsm_config.get('server', 'no_proxy'),
            'insecure': self.rhsm_config.get('server', 'insecure')
        }
        kwargs_to_config = {
            'host': 'rhsm_hostname',
            'ssl_port': 'rhsm_port',
            'handler': 'rhsm_prefix',
            'proxy_hostname': 'rhsm_proxy_hostname',
            'proxy_port': 'rhsm_proxy_port',
            'proxy_user': '******',
            'proxy_password': '******',
            'no_proxy': 'rhsm_no_proxy',
            'insecure': 'rhsm_insecure'
        }

        rhsm_username = None
        rhsm_password = None

        if config:
            try:
                rhsm_username = config['rhsm_username']
                rhsm_password = config['rhsm_password']
            except KeyError:
                pass

            if rhsm_username == NotSetSentinel:
                rhsm_username = None
            if rhsm_password == NotSetSentinel:
                rhsm_password = None

            # Testing for None is necessary, it might be an empty string
            for key, value in kwargs.items():
                try:
                    from_config = config[kwargs_to_config[key]]
                    if from_config != NotSetSentinel and from_config is \
                            not None:
                        if key == 'ssl_port':
                            from_config = int(from_config)
                        kwargs[key] = from_config
                except KeyError:
                    continue

        if rhsm_username and rhsm_password:
            self.logger.debug("Authenticating with RHSM username %s", rhsm_username)
            kwargs['username'] = rhsm_username
            kwargs['password'] = rhsm_password
        else:
            self.logger.debug("Authenticating with certificate: %s", self.cert_file)
            if not os.access(self.cert_file, os.R_OK):
                raise SubscriptionManagerUnregisteredError(
                    "Unable to read certificate, system is not registered or you are not root")
            kwargs['cert_file'] = self.cert_file
            kwargs['key_file'] = self.key_file

        self.logger.info("X-Correlation-ID: %s", self.correlation_id)
        if self.correlation_id:
            kwargs['correlation_id'] = self.correlation_id

        self.connection = rhsm_connection.UEPConnection(**kwargs)
        # add version to user_agent header on connection BZ 1844506
        self.connection.conn.user_agent += " " + parser.get_version().replace(" ", "/")
        try:
            if not self.connection.ping()['result']:
                raise SubscriptionManagerError(
                    "Unable to obtain status from server, UEPConnection is likely not usable."
                )
        except rhsm_connection.RateLimitExceededException as e:
            raise ManagerThrottleError(e.retry_after)
        except BadStatusLine:
            raise ManagerError("Communication with subscription manager interrupted")

        return self.connection
Exemplo n.º 9
0
    def _connect(self, config=None):
        """ Connect to the subscription-manager. """

        kwargs = {
            'host': self.rhsm_config.get('server', 'hostname'),
            'ssl_port': int(self.rhsm_config.get('server', 'port')),
            'handler': self.rhsm_config.get('server', 'prefix'),
            'proxy_hostname': self.rhsm_config.get('server', 'proxy_hostname'),
            'proxy_port': self.rhsm_config.get('server', 'proxy_port'),
            'proxy_user': self.rhsm_config.get('server', 'proxy_user'),
            'proxy_password': self.rhsm_config.get('server', 'proxy_password'),
            'insecure': self.rhsm_config.get('server', 'insecure')
        }

        rhsm_username = None
        rhsm_password = None

        if config:
            rhsm_username = config.rhsm_username
            rhsm_password = config.rhsm_password

            # Testing for None is necessary, it might be an empty string

            if config.rhsm_hostname is not None:
                kwargs['host'] = config.rhsm_hostname

            if config.rhsm_port is not None:
                kwargs['ssl_port'] = int(config.rhsm_port)

            if config.rhsm_prefix is not None:
                kwargs['handler'] = config.rhsm_prefix

            if config.rhsm_proxy_hostname is not None:
                kwargs['proxy_hostname'] = config.rhsm_proxy_hostname

            if config.rhsm_proxy_port is not None:
                kwargs['proxy_port'] = config.rhsm_proxy_port

            if config.rhsm_proxy_user is not None:
                kwargs['proxy_user'] = config.rhsm_proxy_user

            if config.rhsm_proxy_password is not None:
                kwargs['proxy_password'] = config.rhsm_proxy_password

            if config.rhsm_insecure is not None:
                kwargs['insecure'] = config.rhsm_insecure

        if rhsm_username and rhsm_password:
            self.logger.debug("Authenticating with RHSM username %s",
                              rhsm_username)
            kwargs['username'] = rhsm_username
            kwargs['password'] = rhsm_password
        else:
            self.logger.debug("Authenticating with certificate: %s",
                              self.cert_file)
            if not os.access(self.cert_file, os.R_OK):
                raise SubscriptionManagerUnregisteredError(
                    "Unable to read certificate, system is not registered or you are not root"
                )
            kwargs['cert_file'] = self.cert_file
            kwargs['key_file'] = self.key_file

        self.connection = rhsm_connection.UEPConnection(**kwargs)
        try:
            if not self.connection.ping()['result']:
                raise SubscriptionManagerError(
                    "Unable to obtain status from server, UEPConnection is likely not usable."
                )
        except BadStatusLine:
            raise ManagerError(
                "Communication with subscription manager interrupted")
Exemplo n.º 10
0
    def hypervisorCheckIn(self, report, options=None):
        """ Send hosts to guests mapping to subscription manager. """
        mapping = report.association
        serialized_mapping = {}

        self._connect(report.config)
        self.logger.debug(
            "Checking if server has capability 'hypervisor_async'")
        is_async = hasattr(
            self.connection, 'has_capability'
        ) and self.connection.has_capability('hypervisors_async')
        if is_async and os.environ.get('VIRTWHO_DISABLE_ASYNC',
                                       '').lower() in ['1', 'yes', 'true']:
            self.logger.info(
                "Async reports are supported but explicitly disabled")
            is_async = False

        if is_async:
            self.logger.debug("Server has capability 'hypervisors_async'")
            # Transform the mapping into the async version
            serialized_mapping = {
                'hypervisors': [h.toDict() for h in mapping['hypervisors']]
            }

        else:
            self.logger.debug(
                "Server does not have 'hypervisors_async' capability")
            # Reformat the data from the mapping to make it fit with
            # the old api.
            for hypervisor in mapping['hypervisors']:
                guests = [g.toDict() for g in hypervisor.guestIds]
                serialized_mapping[hypervisor.hypervisorId] = guests

        hypervisor_count = len(mapping['hypervisors'])
        guest_count = sum(
            len(hypervisor.guestIds) for hypervisor in mapping['hypervisors'])
        self.logger.info(
            'Sending update in hosts-to-guests mapping for config '
            '"%s": %d hypervisors and %d guests found', report.config.name,
            hypervisor_count, guest_count)
        self.logger.debug("Host-to-guest mapping: %s",
                          json.dumps(serialized_mapping, indent=4))
        try:
            try:
                result = self.connection.hypervisorCheckIn(report.config.owner,
                                                           report.config.env,
                                                           serialized_mapping,
                                                           options=options)  # pylint:disable=unexpected-keyword-arg
            except TypeError:
                # This is temporary workaround until the options parameter gets implemented
                # in python-rhsm
                self.logger.debug(
                    "hypervisorCheckIn method in python-rhsm doesn't understand options parameter, ignoring"
                )
                result = self.connection.hypervisorCheckIn(
                    report.config.owner, report.config.env, serialized_mapping)
        except BadStatusLine:
            raise ManagerError(
                "Communication with subscription manager interrupted")
        except rhsm_connection.RateLimitExceededException as e:
            retry_after = int(
                getattr(e, 'headers', {}).get('Retry-After', '60'))
            raise ManagerThrottleError(retry_after)
        except rhsm_connection.GoneException:
            raise ManagerError(
                "Communication with subscription manager failed: consumer no longer exists"
            )
        except rhsm_connection.ConnectionException as e:
            if hasattr(e, 'code'):
                raise ManagerError(
                    "Communication with subscription manager failed with code %d: %s"
                    % (e.code, str(e)))
            raise ManagerError(
                "Communication with subscription manager failed: %s" % str(e))
        if is_async is True:
            report.state = AbstractVirtReport.STATE_PROCESSING
            report.job_id = result['id']
        else:
            report.state = AbstractVirtReport.STATE_FINISHED
        return result
Exemplo n.º 11
0
    def _connect(self, config=None):
        """ Connect to the subscription-manager. """

        kwargs = {
            'host': self.rhsm_config.get('server', 'hostname'),
            'ssl_port': int(self.rhsm_config.get('server', 'port')),
            'handler': self.rhsm_config.get('server', 'prefix'),
            'proxy_hostname': self.rhsm_config.get('server', 'proxy_hostname'),
            'proxy_port': self.rhsm_config.get('server', 'proxy_port'),
            'proxy_user': self.rhsm_config.get('server', 'proxy_user'),
            'proxy_password': self.rhsm_config.get('server', 'proxy_password'),
            'insecure': self.rhsm_config.get('server', 'insecure')
        }
        kwargs_to_config = {
            'host': 'rhsm_hostname',
            'ssl_port': 'rhsm_port',
            'handler': 'rhsm_prefix',
            'proxy_hostname': 'rhsm_proxy_hostname',
            'proxy_port': 'rhsm_proxy_port',
            'proxy_user': '******',
            'proxy_password': '******',
            'insecure': 'rhsm_insecure'
        }

        rhsm_username = None
        rhsm_password = None

        if config:
            try:
                rhsm_username = config['rhsm_username']
                rhsm_password = config['rhsm_password']
            except KeyError:
                pass

            if rhsm_username == NotSetSentinel:
                rhsm_username = None
            if rhsm_password == NotSetSentinel:
                rhsm_password = None

            # Testing for None is necessary, it might be an empty string
            for key, value in kwargs.iteritems():
                try:
                    from_config = config[kwargs_to_config[key]]
                    if from_config is not NotSetSentinel and from_config is \
                            not None:
                        if key is 'ssl_port':
                            from_config = int(from_config)
                        kwargs[key] = from_config
                except KeyError:
                    continue

        if rhsm_username and rhsm_password:
            self.logger.debug("Authenticating with RHSM username %s",
                              rhsm_username)
            kwargs['username'] = rhsm_username
            kwargs['password'] = rhsm_password
        else:
            self.logger.debug("Authenticating with certificate: %s",
                              self.cert_file)
            if not os.access(self.cert_file, os.R_OK):
                raise SubscriptionManagerUnregisteredError(
                    "Unable to read certificate, system is not registered or you are not root"
                )
            kwargs['cert_file'] = self.cert_file
            kwargs['key_file'] = self.key_file

        self.connection = rhsm_connection.UEPConnection(**kwargs)
        try:
            if not self.connection.ping()['result']:
                raise SubscriptionManagerError(
                    "Unable to obtain status from server, UEPConnection is likely not usable."
                )
        except BadStatusLine:
            raise ManagerError(
                "Communication with subscription manager interrupted")