def destroy_account(self, koku_uuid, retry_count=None): """Call to destroy provider.""" try: self._provider_builder.destroy_provider(koku_uuid, retry_count=retry_count) destroy_source_event(self._source_id) except ProviderBuilderError as provider_err: LOG.error(f"Failed to remove provider. Error: {str(provider_err)}")
def delete_source_and_provider(source_id, source_uuid, auth_header): try: Provider.objects.get(uuid=source_uuid) source_mgr = KafkaSourceManager(auth_header) source_mgr.destroy_provider(source_uuid) except Provider.DoesNotExist: LOG.info( f"delete_source_and_provider: Provider UUID: {source_uuid} does not exist" ) except Exception as err: LOG.info(f"Koku Provider removal failed. Error: {err}.") # An error has occurred while removing the Provider. Return now so that the # Source will remain linked with the Provider return try: source_instance = Sources.objects.get(source_id=source_id) destroy_source_event(source_instance.source_id) except Sources.DoesNotExist: LOG.info( f"delete_source_and_provider: Source ID: {source_id} does not exist" ) except (InterfaceError, OperationalError) as error: # The source is marked as pending_delete=True at this point. # In the event of a database error, the sourcewill be cleaned up on next # boot of the sources client. LOG.error(f"Koku Source removal failed. Error: {error}.")
def test_destroy_source_event(self): """Tests that a source can be destroyed.""" test_uuid = faker.uuid4() self.assertIsNotNone(self.test_obj) storage.add_provider_koku_uuid(self.test_source_id, test_uuid) response = storage.destroy_source_event(self.test_source_id) self.assertFalse(Sources.objects.filter(source_id=self.test_source_id).exists()) self.assertEqual(response, test_uuid)
def test_destroy_source_event_db_down(self): """Tests when destroying a source when DB is down.""" with patch("sources.storage.Sources.objects") as mock_objects: mock_objects.get.side_effect = InterfaceError("Test exception") with self.assertRaises(InterfaceError): storage.destroy_source_event(self.test_source_id)
def test_destroy_source_event_not_found(self): """Tests when destroying a non-existent source.""" response = storage.destroy_source_event(self.test_source_id + 1) self.assertIsNone(response)
def execute_koku_provider_op(msg, cost_management_type_id): """ Execute the 'create' or 'destroy Koku-Provider operations. 'create' operations: Koku POST /providers is executed along with updating the Sources database table with the Koku Provider uuid. 'destroy' operations: Koku DELETE /providers is executed along with removing the Sources database entry. Two types of exceptions are handled for Koku HTTP operations. Recoverable client and Non-Recoverable client errors. If the error is recoverable the calling function (synchronize_sources) will re-queue the operation. Args: msg (Asyncio msg): Dictionary messages containing operation, provider and offset. example: {'operation': 'create', 'provider': SourcesModelObj, 'offset': 3} cost_management_type_id (Integer): Cost Management Type Identifier Returns: None """ provider = msg.get("provider") operation = msg.get("operation") koku_client = KokuHTTPClient(provider.auth_header) sources_client = SourcesHTTPClient(provider.auth_header, provider.source_id) try: if operation == "create": LOG.info( f"Creating Koku Provider for Source ID: {str(provider.source_id)}" ) koku_details = koku_client.create_provider( provider.name, provider.source_type, provider.authentication, provider.billing_source, provider.source_uuid, ) LOG.info( f'Koku Provider UUID {koku_details.get("uuid")} assigned to Source ID {str(provider.source_id)}.' ) storage.add_provider_koku_uuid(provider.source_id, koku_details.get("uuid")) elif operation == "destroy": if provider.koku_uuid: try: response = koku_client.destroy_provider(provider.koku_uuid) LOG.info( f"Koku Provider UUID ({provider.koku_uuid}) Removal Status Code: {str(response.status_code)}" ) except KokuHTTPClientNonRecoverableError: LOG.info( f"Koku Provider already removed. Remove Source ID: {str(provider.source_id)}." ) storage.destroy_source_event(provider.source_id) elif operation == "update": koku_details = koku_client.update_provider( provider.koku_uuid, provider.name, provider.source_type, provider.authentication, provider.billing_source, ) storage.clear_update_flag(provider.source_id) LOG.info( f'Koku Provider UUID {koku_details.get("uuid")} with Source ID {str(provider.source_id)} updated.' ) sources_client.set_source_status(None, cost_management_type_id) except KokuHTTPClientError as koku_error: raise SourcesIntegrationError("Koku provider error: ", str(koku_error)) except KokuHTTPClientNonRecoverableError as koku_error: err_msg = f"Unable to {operation} provider for Source ID: {str(provider.source_id)}. Reason: {str(koku_error)}" LOG.error(err_msg) sources_client.set_source_status(str(koku_error), cost_management_type_id)