azure-sdk-for-python icon indicating copy to clipboard operation
azure-sdk-for-python copied to clipboard

The resource type 'alerts' could not be found in the namespace 'Microsoft.CostManagement' for api version '2019-11-01'

Open guhuajun opened this issue 3 years ago • 5 comments

  • Package Name: azure-mgmt-costmanagement
  • Package Version: 3.0.0
  • Operating System: Windows 10 21H2 (OS Build 19044.2130)
  • Python Version: 3.10.8

Describe the bug Failed to call CostManagementClient().alerts.list(scope=scope)

I am playing with azure-mgmt-* packages for checking the readiness of these python packages. ConsumptionManagementClient().usage_details.list() is working for me. But it looks like I need to migrate to Cost Management APIs. https://learn.microsoft.com/en-us/azure/cost-management-billing/automate/migrate-ea-reporting-arm-apis-overview

But here are the error messages:

azure.core.exceptions.ResourceNotFoundError: (InvalidResourceType) The resource type 'alerts' could not be found in the namespace 'Microsoft.CostManagement' for api version '2019-11-01'. The supported api-versions are '2018-08-01-preview,2019-10-01,2021-10-01,2022-10-01'.
Code: InvalidResourceType
Message: The resource type 'alerts' could not be found in the namespace 'Microsoft.CostManagement' for api version '2019-11-01'. The supported api-versions are '2018-08-01-preview,2019-10-01,2021-10-01,2022-10-01'. 

To Reproduce Steps to reproduce the behavior:

  1. Create a python click project and define some commands. Not mandatory
  2. Define a mixin to handle the authentication
import os
from pathlib import Path

from azure.identity import ClientSecretCredential, CertificateCredential
from azure.mgmt.billing import BillingManagementClient
from azure.mgmt.consumption import ConsumptionManagementClient
from azure.mgmt.costmanagement import CostManagementClient
from loguru import logger

from .envs import *


class ClientMixin:

    def __init__(self, **kwargs):
        cred_kwargs = {
            'tenant_id': AAD_GLOBAL_TENANT_ID,
            'client_id': AAD_GLOBAL_CLIENT_ID,
        }
        if AAD_GLOBAL_CLIENT_SECRET:
            cred_kwargs['client_secret'] = AAD_GLOBAL_CLIENT_SECRET
            credential = ClientSecretCredential(**cred_kwargs)
        else:
            cert_path = os.path.join(
                Path(__file__).parent.parent.parent.parent, 'certs/a_cert.pfx')
            cred_kwargs['certificate_path'] = cert_path
            cred_kwargs['password'] = AAD_GLOBAL_CERT_PASSWORD
            credential = CertificateCredential(**cred_kwargs)

        super().__init__(credential=credential, subscription_id=AAD_GLOBAL_SUBSCRIPTION_ID)


class AzureGlobalBillingClient(ClientMixin, BillingManagementClient):
    pass


class AzureGlobalConsumptionClient(ClientMixin, ConsumptionManagementClient):
    pass


class AzureGlobalCostManagementClient(ClientMixin, CostManagementClient):
    pass
  1. Call the api
    with AzureGlobalCostManagementClient() as client:
        scope = f'/providers/Microsoft.Billing/billingAccounts/{AAD_GLOBAL_BILLING_ACCOUNT_ID}'
        results = client.alerts.list(scope=scope)
        click.secho(results)

Expected behavior A successful call to CostManagementClient().[whatever].list(scope=scope)

ConsumptionManagementClient().usage_details.list(scope=scope) is working.

    with AzureGlobalConsumptionClient() as client:
        # for billing account id, go to Azure Portal, Search Cost Management + Billing, click Settings > Properties
        scope = f'/providers/Microsoft.Billing/billingAccounts/{AAD_GLOBAL_BILLING_ACCOUNT_ID}'
        details = [x.as_dict() for x in list(client.usage_details.list(scope=scope))]
        df = pd.DataFrame.from_records(details)
        click.secho(df.tail())
D:\repos\[a python project]\src (main -> origin) 
(env) $ python main.py azure get
                                                    id  ... cost_allocation_rule_name
351  /providers/Microsoft.Billing/billingAccounts/5...  ...
352  /providers/Microsoft.Billing/billingAccounts/5...  ...
353  /providers/Microsoft.Billing/billingAccounts/5...  ...
354  /providers/Microsoft.Billing/billingAccounts/5...  ...
355  /providers/Microsoft.Billing/billingAccounts/5...  ...

[5 rows x 76 columns]

Screenshots not needed

Additional context Will the API version not be hardcoded in future version? Just like the change in this pull request? https://github.com/Azure/azure-sdk-for-python/pull/23167

Exceptions

  File "D:\repos\[A python project]\src\commands\clouds\azure.py", line 49, in get
    results = client.alerts.list(scope=scope)
  File "D:\repos\[A python project]\env\lib\site-packages\azure\mgmt\costmanagement\operations\_alerts_operations.py", line 105, in list
    map_error(status_code=response.status_code, response=response, error_map=error_map)
  File "D:\repos\[A python project]\env\lib\site-packages\azure\core\exceptions.py", line 107, in map_error      
    raise error
azure.core.exceptions.ResourceNotFoundError: (InvalidResourceType) The resource type 'alerts' could not be found in the namespace 'Microsoft.CostManagement' for api version '2019-11-01'. The supported api-versions are '2018-08-01-preview,2019-10-01,2021-10-01,2022-10-01'.
Code: InvalidResourceType
Message: The resource type 'alerts' could not be found in the namespace 'Microsoft.CostManagement' for api version '2019-11-01'. The supported api-versions are '2018-08-01-preview,2019-10-01,2021-10-01,2022-10-01'. 

Line 81 - 83 in [A python project]\env\Lib\site-packages\azure\mgmt\costmanagement\operations_alerts_operations.py

error_map.update(kwargs.pop('error_map', {}))
api_version = "2019-11-01"
accept = "application/json"

guhuajun avatar Nov 07 '22 06:11 guhuajun

Label prediction was below confidence level 0.6 for Model:ServiceLabels: 'API Management:0.057374503,KeyVault:0.050402462,ARM:0.044054143'

azure-sdk avatar Nov 07 '22 06:11 azure-sdk

Thanks for the feedback, we’ll investigate asap.

xiangyan99 avatar Nov 07 '22 17:11 xiangyan99

Greetings,

I can confirm that I have a successful call to the cost management rest API endpoint directly. Personally speaking, it will not be a block issue for me to complete some data visualization work items later without using azure-mgmt-costmangement package.

    # a self-defined client
    client = AzureRestAPIClient()

    # https://learn.microsoft.com/en-us/rest/api/cost-management/query/usage?tabs=HTTP#queryfilter
    data = {
        'type': 'Usage',
        'timeframe': 'TheLastMonth',
        'dataset': {
            'granularity': 'None',
            'aggregation': {
                'totalCost': {
                    'name': 'PreTaxCost',
                    'function': 'Sum'
                }
            },
            'grouping': [
                {
                    'type': 'Dimension',
                    'name': 'ResourceGroup'
                }
            ]
        }
    }
    response = client.post(url=AZ_GLOBAL_COST_MANAGEMENT, json=data, prettify=True)
    click.secho(response)
(env) $ python main.py azure cost get
{
  "id": "providers/Microsoft.Billing/billingAccounts/{AAD_GLOBAL_BILLING_ACCOUNT_ID}/providers/Microsoft.CostManagement/query/request_id",     
  "name": "request_id",
  "type": "Microsoft.CostManagement/query",
  "location": null,
  "sku": null,
  "eTag": null,
  "properties": {
    "nextLink": null,
    "columns": [
      {
        "name": "PreTaxCost",
        "type": "Number"
      },
      {
        "name": "ResourceGroup",
        "type": "String"
      },
      {
        "name": "Currency",
        "type": "String"
      }
    ],
    "rows": [
      [
        0.29000000000000004,
        "cloud-shell-storage-southeastasia",
        "USD"
      ],
      [
        0.0,
        "default-storage-eastasia",
        "USD"
      ],
      [
        0.0,
        "default-storage-japanwest",
        "USD"
      ],
      [
        0.0,
        "default-storage-southcentralus",
        "USD"
      ],
      [
        0.0,
        "default-storage-southeastasia",
        "USD"
      ],
      [
        2.0399994456481068,
        "[pii]-jaeast-resgroup",
        "USD"
      ],
      [
        0.0,
        "[pii]-seasia-resgroup",
        "USD"
      ],
      [
        0.0,
        "[pii]-se-asia-resgroup",
        "USD"
      ],
      [
        0.0,
        "[pii]-uswest-resgroup",
        "USD"
      ],
      [
        0.0,
        "[pii]-westus-resgroup",
        "USD"
      ],
      [
        12.030000554351894,
        "[a resource group name]",
        "USD"
      ],
      [
        0.0,
        "[pii]-rg",
        "USD"
      ],
      [
        0.0,
        "[pii]-rg",
        "USD"
      ]
    ]
  }
}

guhuajun avatar Nov 08 '22 03:11 guhuajun

Hi @guhuajun

We have updated the version about azure-mgmt-costmanagement, please update the package version to 4.0.0b1, and try to run the code again. https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/costmanagement/azure-mgmt-costmanagement/azure/mgmt/costmanagement/operations/_alerts_operations.py#L173-L242

Wzb123456789 avatar Nov 09 '22 06:11 Wzb123456789

Hello @Wzb123456789,

I can confirm the 4.0.0b1 package is working, thanks for updating the package. Let me keep on playing with the azure-mgmt-costmanagement package.

D:\repos\[a python project]\src (main -> origin) 
(env) $ pip list | grep azure-mgmt-costmanagement
azure-mgmt-costmanagement  4.0.0b1

D:\repos\[a python project]\src (main -> origin) 
(env) $ python main.py azure cost get
{'additional_properties': {}, 'value': [], 'next_link': None}

guhuajun avatar Nov 09 '22 07:11 guhuajun

Greetings,

Close this issue due to the new release of azure-mgmt-costmanagement. I am busy with other topics, and further tests are delayed.

guhuajun avatar Nov 16 '22 05:11 guhuajun