Пример #1
0
    def enable(self):
        """
        Mark this CloudAccount as enabled and perform operations to make it so.

        This has the side effect of calling the related content_object (e.g.
        AwsCloudAccount) to make any cloud-specific changes. If any that cloud-specific
        function fails, we rollback our state change and re-raise the exception for the
        caller to handle further.
        """
        logger.info(
            _("'is_enabled' is %(is_enabled)s before enabling %(cloudaccount)s"),
            {"is_enabled": self.is_enabled, "cloudaccount": self},
        )
        if not self.is_enabled:
            self.is_enabled = True
            self.enabled_at = get_now()
            self.save()
        try:
            self.content_object.enable()
            # delete stale ConcurrentUsage when an clount is enabled
            ConcurrentUsage.objects.filter(user=self.user, date=get_today()).delete()
        except Exception as e:
            # All failure notifications should happen during the failure
            logger.info(e)
            transaction.set_rollback(True)
            return False

        sources.notify_application_availability(
            self.user.username, self.platform_application_id, "available"
        )
Пример #2
0
    def disable(self, message="", power_off_instances=True, notify_sources=True):
        """
        Mark this CloudAccount as disabled and perform operations to make it so.

        This has the side effect of finding all related powered-on instances and
        recording a new "power_off" event them. It also calls the related content_object
        (e.g. AwsCloudAccount) to make any cloud-specific changes.

        Args:
            message (string): status message to set on the Sources Application
            power_off_instances (bool): if this is set to false, we do not create
                power_off instance events when disabling the account. This is used on
                account deletion, when we still want to run the rest of the account
                disable logic, but should not be creating power_off instance events.
                Since creating the instance event in the same transaction as deleting
                the account causes Django errors.
            notify_sources (bool): determines if we notify sources about this operation.
                This should always be true except for very special cases.
        """
        logger.info(_("Attempting to disable %(account)s"), {"account": self})
        if self.is_enabled:
            self.is_enabled = False
            self.save()
        if power_off_instances:
            self._power_off_instances(power_off_time=get_now())
        self.content_object.disable()
        if notify_sources:
            sources.notify_application_availability(
                self.user.username, self.platform_application_id, "unavailable", message
            )
        logger.info(_("Finished disabling %(account)s"), {"account": self})
Пример #3
0
    def test_notify_sources_application_availability_kafka_exception(
        self,
        mock_kafka_producer,
    ):
        """Test notify source application availability handling KafkaException."""
        kafka_producer = mock_kafka_producer(self.sources_kafka_config)
        kafka_producer.produce.side_effect = KafkaException(KafkaError(5))

        with override_settings(
            LISTENER_SERVER=self.listener_server,
            LISTENER_PORT=self.listener_port,
            SOURCES_STATUS_TOPIC=self.sources_kafka_topic,
            SOURCES_RESOURCE_TYPE=self.sources_resource_type,
            SOURCES_AVAILABILITY_EVENT_TYPE=self.sources_availability_event_type,
            SOURCES_ENABLE_DATA_MANAGEMENT_FROM_KAFKA=True,
        ):
            with self.assertRaises(KafkaProducerException):
                sources.notify_application_availability(
                    self.account_number,
                    self.application_id,
                    availability_status=self.available_status,
                )

            kafka_producer.produce.assert_called_with(
                topic=self.sources_kafka_topic,
                value=json.dumps(self.kafka_payload),
                headers={
                    "x-rh-identity": self.headers["X-RH-IDENTITY"],
                    "event_type": self.sources_availability_event_type,
                },
                callback=_check_response,
            )
            kafka_producer.flush.assert_not_called()
Пример #4
0
    def test_notify_sources_application_availability_success(
        self,
        mock_kafka_producer,
    ):
        """Test notify sources happy path success."""
        kafka_producer = mock_kafka_producer(self.sources_kafka_config)

        with override_settings(
            LISTENER_SERVER=self.listener_server,
            LISTENER_PORT=self.listener_port,
            SOURCES_STATUS_TOPIC=self.sources_kafka_topic,
            SOURCES_RESOURCE_TYPE=self.sources_resource_type,
            SOURCES_AVAILABILITY_EVENT_TYPE=self.sources_availability_event_type,
            SOURCES_ENABLE_DATA_MANAGEMENT_FROM_KAFKA=True,
            VERBOSE_SOURCES_NOTIFICATION_LOGGING=True,
        ):
            sources.notify_application_availability(
                self.account_number,
                self.application_id,
                availability_status=self.available_status,
            )

        kafka_producer.produce.assert_called_with(
            topic=self.sources_kafka_topic,
            value=json.dumps(self.kafka_payload),
            headers={
                "x-rh-identity": self.headers["X-RH-IDENTITY"],
                "event_type": self.sources_availability_event_type,
            },
            callback=_check_response,
        )
        kafka_producer.flush.assert_called()
Пример #5
0
def notify_application_availability_task(account_number,
                                         application_id,
                                         availability_status,
                                         availability_status_error=""):
    """
    Update Sources application's availability status.

    This is a task wrapper to the sources.notify_application_availability
    method which sends the availability_status Kafka message to Sources.

    Args:
        account_number (str): Account number identifier
        application_id (int): Platform insights application id
        availability_status (string): Availability status to set
        availability_status_error (string): Optional status error
    """
    try:
        sources.notify_application_availability(
            account_number,
            application_id,
            availability_status,
            availability_status_error,
        )
    except KafkaProducerException:
        raise
Пример #6
0
 def notify(self, account_number, application_id, error_message=None):
     """Tell sources an application is not available because of error."""
     if not error_message:
         error_message = self.get_message()
     sources.notify_application_availability(
         account_number,
         application_id,
         availability_status="unavailable",
         availability_status_error=error_message,
     )
Пример #7
0
 def test_notify_sources_application_availability_skip(
     self,
     mock_kafka_producer,
 ):
     """Test notify source application availability skips if not enabled."""
     with override_settings(SOURCES_ENABLE_DATA_MANAGEMENT_FROM_KAFKA=False):
         sources.notify_application_availability(
             self.account_number,
             self.application_id,
             availability_status=self.available_status,
         )
     mock_kafka_producer.assert_not_called()