pkg/armhelpers/tenantid.go (41 lines of code) (raw):

// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. package armhelpers import ( "context" "net/http" "regexp" subscriptions "github.com/Azure/azure-sdk-for-go/profile/p20200901/resourcemanager/resources/armsubscriptions" "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" "github.com/Azure/azure-sdk-for-go/sdk/azcore/fake" "github.com/pkg/errors" log "github.com/sirupsen/logrus" ) // GetTenantID figures out the AAD tenant ID of the subscription by making an // unauthenticated request to the Get Subscription Details endpoint and parses // the value from WWW-Authenticate header. func GetTenantID(subscriptionID string, cloud cloud.Configuration) (string, error) { const hdrKey = "WWW-Authenticate" log.Debugf("Resolving tenantID for subscriptionID: %s", subscriptionID) c, _ := subscriptions.NewClient(&fake.TokenCredential{}, &arm.ClientOptions{ ClientOptions: azcore.ClientOptions{ Cloud: cloud, }, }) // we expect this request to fail (err != nil), but we are only interested // in headers, so surface the error if the Response is not present (i.e. // network error etc) _, err := c.Get(context.Background(), subscriptionID, nil) var responseErr *azcore.ResponseError errors.As(err, &responseErr) if responseErr.RawResponse == nil { return "", errors.Wrap(err, "Request failed") } // Expecting 401 StatusUnauthorized here, just read the header if responseErr.StatusCode != http.StatusUnauthorized { return "", errors.Errorf("Unexpected response from Get Subscription: %v", responseErr.StatusCode) } hdr := responseErr.RawResponse.Header.Get(hdrKey) if hdr == "" { return "", errors.Errorf("Header %v not found in Get Subscription response", hdrKey) } // Example value for hdr: // Bearer authorization_uri="https://login.windows.net/996fe9d1-6171-40aa-945b-4c64b63bf655", error="invalid_token", error_description="The authentication failed because of missing 'Authorization' header." r := regexp.MustCompile(`authorization_uri=".*/([0-9a-f\-]+)"`) m := r.FindStringSubmatch(hdr) if m == nil { return "", errors.Errorf("Could not find the tenant ID in header: %s %q", hdrKey, hdr) } return m[1], nil }