How to get network usages/quotas using Azure SDK for Golang?

143 Views Asked by At

I'm trying to get information about network usages and quota using Azure SDK for Golang and receive the same result as executing the following CLI command:

% az network list-usages  --location centralus --out table
Name                                                               CurrentValue    Limit
-----------------------------------------------------------------  --------------  ----------
Virtual Networks                                                   3               1000
(...)

My implementation (I also tried to use NewListPager instead of Get method, but the result is similar):

import "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/quota/armquota" 
// (...)

    subscriptionID := "<MY_SUBSCRIPTION_ID>"
    factory, err := armquota.NewClientFactory(creds, nil)
    if err != nil {
        return err
    }

    quotaSvc, err := factory.NewClient()
    usagesSvc, err := factory.NewUsagesClient()


    quotaResult, err := quotaSvc.Get(ctx, "VirtualNetworks", "subscriptions/"+subscriptionID+"/providers/Microsoft.Network/locations/centralus", nil)
    if err == nil {
        quotaJson, err := quotaResult.MarshalJSON()
        if err == nil {
            fmt.Println("Quota result=", string(quotaJson), ", name=", *quotaResult.Name)
        } else {
            fmt.Println("Cannot marshal quota json")
        }
    } else {
        fmt.Println("Cannot get quota")
    }

    usageResult, err := usagesSvc.Get(ctx, "VirtualNetworks", "subscriptions/"+subscriptionID+"/providers/Microsoft.Network/locations/centralus", nil)
    if err == nil {
        usagesJson, err := usageResult.MarshalJSON()
        if err == nil {
            fmt.Println("Usages result=", string(usagesJson), ", name=", *usageResult.Name)
        } else {
            fmt.Println("Cannot marshal usages json")
        }
    } else {
        fmt.Println("Cannot get usages")
    }

Output:

Quota result:

{
   "id":"/subscriptions/<MY_SUBSCRIPTION_ID>/providers/Microsoft.Network/locations/centralus/providers/Microsoft.Quota/quotas/VirtualNetworks",
   "name":"VirtualNetworks",
   "properties":{
      "isQuotaApplicable":false,
      "limit":{
         "limitObjectType":"LimitValue",
         "limitType":"Independent",
         "value":1000
      },
      "name":{
         "localizedValue":"Virtual Networks",
         "value":"VirtualNetworks"
      },
      "properties":{
         
      },
      "unit":"Count"
   },
   "type":"Microsoft.Quota/Quotas"
}

Usages result:

{
   "id":"/subscriptions/<MY_SUBSCRIPTION_ID>/providers/Microsoft.Network/locations/centralus/providers/Microsoft.Quota/usages/VirtualNetworks",
   "name":"VirtualNetworks",
   "properties":{
      "isQuotaApplicable":false,
      "name":{
         "localizedValue":"Virtual Networks",
         "value":"VirtualNetworks"
      },
      "properties":{
         
      },
      "unit":"Count",
      "usages":{
         
      }
   },
   "type":"Microsoft.Quota/Usages"
}

What's the correct way to get the usages value 3 exactly like when getting limits via Azure CLI?

2

There are 2 best solutions below

0
On BEST ANSWER

How to get network usages/quotas using Azure SDK for Golang?

In my environment, Using the Azure CLI command I can get the usage result like the below:

enter image description here

To get the current value you need to use github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 package using Go lang.

Code:

package main

import (
    "context"
    "log"

    "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
    "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4"
)

func main() {
    cred, err := azidentity.NewDefaultAzureCredential(nil)
    if err != nil {
        log.Fatalf("failed to obtain a credential: %v", err)
    }
    ctx := context.Background()
    clientFactory, err := armnetwork.NewClientFactory("your-subscription-id", cred, nil)
    if err != nil {
        log.Fatalf("failed to create client: %v", err)
    }
    pager := clientFactory.NewUsagesClient().NewListPager("centralus", nil)
    for pager.More() {
        page, err := pager.NextPage(ctx)
        if err != nil {
            log.Fatalf("failed to advance page: %v", err)
        }

                    for _, usage := range page.UsagesListResult.Value {
            if usage.Name.LocalizedValue != nil && *usage.Name.LocalizedValue == "Virtual Networks" {
                log.Printf("Usage Name: %s, Current Value: %d, Limit: %d, Unit: %s",
                    *usage.Name.LocalizedValue, *usage.CurrentValue, *usage.Limit, *usage.Unit)
            }
        }
    }
}

Output:

2023/10/11 13:07:54 Usage Name: Virtual Networks, Current Value: 14, Limit: 1000, Unit: Count

enter image description here

Reference:

Usages - List - REST API (Azure Virtual Networks) | Microsoft Learn

0
On

Thank you very much, @Venkatesan! Your approach has definitely resolved my issue, although it's quite interesting that the Query Service Client isn't functioning correctly in the Golang SDK.

I conducted some debugging and examined how other SDKs handle this. I was surprised to see where the quota value is located in the response when fetched using the SDK for Python.

This indicates that there might be a bug related to the Quota Service somewhere. I submitted a pull request with a quick fix proposal, which was subsequently replaced by a bug report in the azure-rest-api-specs. So I'm hopeful that my initial approach (utilizing armquota.Client) will also function properly in the near future.