Exemplo n.º 1
0
class SourceStatus:
    """Source Status."""
    def __init__(self, request, source_id):
        """Initialize source id."""
        self.request = request
        self.user = request.user
        self.source_id = source_id
        self.source = Sources.objects.get(source_id=source_id)
        self.sources_client = SourcesHTTPClient(self.source.auth_header,
                                                source_id=source_id)

    @property
    def sources_response(self):
        return self.sources_client.build_source_status(self.status())

    def _set_provider_active_status(self, active_status):
        """Set provider active status."""
        if self.source.koku_uuid:
            try:
                provider = Provider.objects.get(uuid=self.source.koku_uuid)
                provider.active = active_status
                provider.save()
            except Provider.DoesNotExist:
                LOG.info(
                    f"No provider found for Source ID: {self.source.source_id}"
                )

    def determine_status(self, provider_type, source_authentication,
                         source_billing_source):
        """Check cloud configuration status."""
        interface = ProviderAccessor(provider_type)
        error_obj = None
        try:
            interface.cost_usage_source_ready(source_authentication,
                                              source_billing_source)
            self._set_provider_active_status(True)
        except ValidationError as validation_error:
            self._set_provider_active_status(False)
            error_obj = validation_error
        return error_obj

    def status(self):
        """Find the source's availability status."""
        source_billing_source = self.source.billing_source.get(
            "data_source") or {}
        source_authentication = self.source.authentication.get(
            "credentials") or {}
        provider_type = self.source.source_type
        return self.determine_status(provider_type, source_authentication,
                                     source_billing_source)

    def push_status(self):
        """Push status_msg to platform sources."""
        try:
            status_obj = self.status()
            self.sources_client.set_source_status(status_obj)
        except SourcesHTTPClientError as error:
            err_msg = "Unable to push source status. Reason: {}".format(
                str(error))
            LOG.warning(err_msg)
Exemplo n.º 2
0
class SourceStatus:
    """Source Status."""

    def __init__(self, request, source_id):
        """Initialize source id."""
        self.request = request
        self.user = request.user
        self.source_id = source_id
        self.source = Sources.objects.get(source_id=source_id)
        self.sources_client = SourcesHTTPClient(self.source.auth_header, source_id=source_id)

    @property
    def sources_response(self):
        return self.sources_client.build_source_status(self.status())

    def determine_status(self, provider, source_authentication, source_billing_source):
        """Check cloud configuration status."""
        interface = ProviderAccessor(provider)
        error_obj = None
        try:
            interface.cost_usage_source_ready(source_authentication, source_billing_source)
        except ValidationError as validation_error:
            error_obj = validation_error

        return error_obj

    def status(self):
        """Find the source's availability status."""
        # Get the source billing_source, whether it's named bucket
        if self.source.billing_source.get("bucket"):
            source_billing_source = self.source.billing_source.get("bucket")
        elif self.source.billing_source.get("data_source"):
            source_billing_source = self.source.billing_source.get("data_source")
        else:
            source_billing_source = {}
        # Get the source authentication
        if self.source.authentication.get("resource_name"):
            source_authentication = self.source.authentication.get("resource_name")
        elif self.source.authentication.get("credentials"):
            source_authentication = self.source.authentication.get("credentials")
        else:
            source_authentication = {}
        provider = self.source.source_type

        status_obj = self.determine_status(provider, source_authentication, source_billing_source)
        return status_obj

    def push_status(self):
        """Push status_msg to platform sources."""
        try:
            status_obj = self.status()
            self.sources_client.set_source_status(status_obj)
        except SourcesHTTPClientError as error:
            err_msg = "Unable to push source status. Reason: {}".format(str(error))
            LOG.warning(err_msg)
Exemplo n.º 3
0
 def test_build_source_status(self):
     """Test build source status."""
     table = [
         {"error": None, "expected": {"availability_status": "available", "availability_status_error": ""}},
         {
             "error": "my-error",
             "expected": {"availability_status": "unavailable", "availability_status_error": "my-error"},
         },
     ]
     client = SourcesHTTPClient(auth_header=Config.SOURCES_FAKE_HEADER)
     for test in table:
         with self.subTest(test=test):
             result = client.build_source_status(test.get("error"))
             self.assertDictEqual(result, test.get("expected"))
Exemplo n.º 4
0
class SourceStatus:
    """Source Status."""
    def __init__(self, source_id):
        """Initialize source id."""
        self.source_id = source_id
        self.source = Sources.objects.get(source_id=source_id)
        if not source_settings_complete(
                self.source) or self.source.pending_delete:
            raise ObjectDoesNotExist(
                f"Source ID: {self.source_id} not ready for status")
        self.sources_client = SourcesHTTPClient(self.source.auth_header,
                                                source_id=source_id)

    @property
    def sources_response(self):
        return self.sources_client.build_source_status(self.status())

    def _set_provider_active_status(self, active_status):
        """Set provider active status."""
        if self.source.koku_uuid:
            try:
                provider = Provider.objects.get(uuid=self.source.koku_uuid)
                provider.active = active_status
                provider.save()
            except Provider.DoesNotExist:
                LOG.info(
                    f"No provider found for Source ID: {self.source.source_id}"
                )

    def determine_status(self, provider_type, source_authentication,
                         source_billing_source):
        """Check cloud configuration status."""
        interface = ProviderAccessor(provider_type)
        error_obj = None
        try:
            if self.source.account_id not in settings.DEMO_ACCOUNTS:
                interface.cost_usage_source_ready(source_authentication,
                                                  source_billing_source)
            self._set_provider_active_status(True)
        except ValidationError as validation_error:
            self._set_provider_active_status(False)
            error_obj = validation_error
        self.source.refresh_from_db()
        return error_obj

    def status(self):
        """Find the source's availability status."""
        source_billing_source = self.source.billing_source.get(
            "data_source") or {}
        source_authentication = self.source.authentication.get(
            "credentials") or {}
        provider_type = self.source.source_type
        return self.determine_status(provider_type, source_authentication,
                                     source_billing_source)

    @transaction.atomic
    def update_source_name(self):
        """Update source name if it is out of sync with platform."""
        source_details = self.sources_client.get_source_details()
        if source_details.get("name") != self.source.name:
            self.source.name = source_details.get("name")
            self.source.save()
            builder = SourcesProviderCoordinator(self.source_id,
                                                 self.source.auth_header)
            builder.update_account(self.source)

    def push_status(self):
        """Push status_msg to platform sources."""
        try:
            status_obj = self.status()
            if self.source.source_type in (Provider.PROVIDER_GCP,
                                           Provider.PROVIDER_GCP_LOCAL):
                builder = SourcesProviderCoordinator(self.source.source_id,
                                                     self.source.auth_header)
                if not status_obj:
                    if self.source.koku_uuid:
                        builder.update_account(self.source)
                    elif self.source.billing_source.get("data_source",
                                                        {}).get("table_id"):
                        builder.create_account(self.source)
            self.sources_client.set_source_status(status_obj)
            self.update_source_name()
            LOG.info(
                f"Source status for Source ID: {str(self.source_id)}: Status: {str(status_obj)}"
            )
        except SkipStatusPush as error:
            LOG.info(
                f"Platform sources status push skipped. Reason: {str(error)}")
        except SourcesHTTPClientError as error:
            err_msg = "Unable to push source status. Reason: {}".format(
                str(error))
            LOG.warning(err_msg)