def _get_azure_client(credentials, billing_source): subscription_id = credentials.get('subscription_id') tenant_id = credentials.get('tenant_id') client_id = credentials.get('client_id') client_secret = credentials.get('client_secret') resource_group_name = billing_source.get('resource_group') storage_account_name = billing_source.get('storage_account') service = AzureService(subscription_id, tenant_id, client_id, client_secret, resource_group_name, storage_account_name) return service
def _get_azure_client(credentials, data_source): subscription_id = credentials.get("subscription_id") tenant_id = credentials.get("tenant_id") client_id = credentials.get("client_id") client_secret = credentials.get("client_secret") resource_group_name = data_source.get("resource_group") storage_account_name = data_source.get("storage_account") service = AzureService(tenant_id, client_id, client_secret, resource_group_name, storage_account_name, subscription_id) return service
def test_describe_cost_management_exports_wrong_account( self, mock_factory): """Test that cost management exports are not returned from incorrect account.""" mock_factory.return_value = MockAzureClientFactory( self.subscription_id, self.container_name, self.current_date_time, self.export_directory, self.resource_group_name, self.storage_account_name) client = AzureService(subscription_id=self.subscription_id, tenant_id=self.tenant_id, client_id=self.client_id, client_secret=self.client_secret, resource_group_name=self.resource_group_name, storage_account_name='wrongaccount') exports = client.describe_cost_management_exports() self.assertEquals(exports, [])
def test_get_latest_cost_export_for_path_exception(self, mock_factory): """Test that function handles a raised exception.""" mock_factory.return_value = Mock( spec=AzureClientFactory, cloud_storage_account=Mock(return_value=Mock( spec=BlobServiceClient, get_container_client=Mock(return_value=Mock( spec=ContainerClient, list_blobs=Mock(side_effect=AdalError("test error")))), )), ) with self.assertRaises(AzureServiceError): service = AzureService(self.tenant_id, self.client_id, self.client_secret, self.resource_group_name, self.storage_account_name) service.get_latest_cost_export_for_path(report_path=FAKE.word(), container_name=FAKE.word())
def get_mock_client(self, blob_list=[], cost_exports=[]): """Generate an AzureService instance with mocked AzureClientFactory. Args: blob_list (list<Mock>) A list of Mock objects. The blob_list Mock objects must have these attributes: - name cost_exports (list<Mock>) A list of Mock objects. The cost_exports Mock objects must have these attributes: - name - delivery_info.destination.container - delivery_info.destination.root_folder_path - delivery_info.destination.resource_id Returns: (AzureService) An instance of AzureService with mocked AzureClientFactory """ fake_data = FAKE.binary(length=1024 * 64) client = None with patch( "masu.external.downloader.azure.azure_service.AzureClientFactory", spec=AzureClientFactory) as mock_factory: mock_factory.return_value = Mock( # AzureClientFactory() spec=AzureClientFactory, cloud_storage_account=Mock( return_value=Mock( # .cloud_storage_account() spec=BlobServiceClient, get_blob_client=Mock( return_value=Mock( # .get_blob_client() spec=BlobClient, # .download_blob().readall() download_blob=Mock(return_value=Mock( readall=Mock(return_value=fake_data))), )), get_container_client=Mock( # .get_container_client().list_blobs() return_value=Mock(spec=ContainerClient, list_blobs=Mock( return_value=blob_list))), )), # .cost_management_client.exports.list().value cost_management_client=Mock(exports=Mock(list=Mock( return_value=Mock(value=cost_exports)))), # .subscription_id subscription_id=self.subscription_id, ) client = AzureService( self.tenant_id, self.client_id, self.client_secret, self.resource_group_name, self.storage_account_name, self.subscription_id, ) return client
def cost_usage_source_is_reachable(self, credentials, data_source): """ Verify that the cost usage report source is reachable by Koku. Implemented by provider specific class. An account validation and connectivity check is to be done. Args: credentials (dict): Azure credentials dict example: {'subscription_id': 'f695f74f-36a4-4112-9fe6-74415fac75a2', 'tenant_id': '319d4d72-7ddc-45d0-9d63-a2db0a36e048', 'client_id': 'ce26bd50-2e5a-4eb7-9504-a05a79568e25', 'client_secret': 'abc123' } data_source (dict): Identifier of the cost usage report source example: { 'resource_group': 'My Resource Group 1', 'storage_account': 'My Storage Account 2' Returns: None Raises: ValidationError: Error string """ key = "azure.error" azure_service = None if not (isinstance(credentials, dict) and isinstance(data_source, dict)): message = "Resource group and/or Storage account must be a dict" raise ValidationError(error_obj(key, message)) resource_group = data_source.get("resource_group") storage_account = data_source.get("storage_account") subscription_id = credentials.get("subscription_id") self._verify_patch_entries(subscription_id, resource_group, storage_account) try: azure_service = AzureService(**credentials, resource_group_name=resource_group, storage_account_name=storage_account) azure_client = AzureClientFactory(**credentials) storage_accounts = azure_client.storage_client.storage_accounts storage_account = storage_accounts.get_properties( resource_group, storage_account) if azure_service and not azure_service.describe_cost_management_exports( ): key = ProviderErrors.AZURE_NO_REPORT_FOUND message = ProviderErrors.AZURE_MISSING_EXPORT_MESSAGE raise ValidationError(error_obj(key, message)) except AzureCostReportNotFound as costreport_err: key = ProviderErrors.AZURE_BILLING_SOURCE_NOT_FOUND raise ValidationError(error_obj(key, str(costreport_err))) except (AdalError, AzureException, AzureServiceError, ClientException, TypeError) as exc: key = ProviderErrors.AZURE_CLIENT_ERROR raise ValidationError(error_obj(key, str(exc))) return True
def cost_usage_source_is_reachable(self, credential_name, storage_resource_name): """ Verify that the cost usage report source is reachable by Koku. Implemented by provider specific class. An account validation and connectivity check is to be done. Args: credential (dict): Azure credentials dict example: {'subscription_id': 'f695f74f-36a4-4112-9fe6-74415fac75a2', 'tenant_id': '319d4d72-7ddc-45d0-9d63-a2db0a36e048', 'client_id': 'ce26bd50-2e5a-4eb7-9504-a05a79568e25', 'client_secret': 'abc123' } source_name (dict): Identifier of the cost usage report source example: { 'resource_group': 'My Resource Group 1', 'storage_account': 'My Storage Account 2' Returns: None Raises: ValidationError: Error string """ key = "billing_source.bucket" azure_service = None if not (isinstance(credential_name, dict) and isinstance(storage_resource_name, dict)): message = f"Resource group and/or Storage account must be a dict" raise ValidationError(error_obj(key, message)) resource_group = storage_resource_name.get("resource_group") storage_account = storage_resource_name.get("storage_account") if not (resource_group and storage_account): message = "resource_group or storage_account is undefined." raise ValidationError(error_obj(key, message)) try: azure_service = AzureService(**credential_name, resource_group_name=resource_group, storage_account_name=storage_account) azure_client = AzureClientFactory(**credential_name) storage_accounts = azure_client.storage_client.storage_accounts storage_account = storage_accounts.get_properties( resource_group, storage_account) except (AdalError, AzureException, AzureServiceError, ClientException, TypeError) as exc: raise ValidationError(error_obj(key, str(exc))) if azure_service and not azure_service.describe_cost_management_exports( ): message = "Cost management export was not found." raise ValidationError(error_obj(key, message)) return True