github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/provider/azure/utils.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package azure
     5  
     6  import (
     7  	azurecloud "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
     8  	"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
     9  	"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
    10  	"github.com/juju/errors"
    11  
    12  	"github.com/juju/juju/environs/context"
    13  	"github.com/juju/juju/provider/azure/internal/errorutils"
    14  )
    15  
    16  // collectAPIVersions returns a map of the latest API version for each
    17  // possible resource type. This is needed to use the Azure Resource
    18  // Management API, because the API version requested must match the
    19  // type of the resource being manipulated through the API, rather than
    20  // the API version specified statically in the resource client code.
    21  func collectAPIVersions(ctx context.ProviderCallContext, client *armresources.ProvidersClient) (map[string]string, error) {
    22  	result := make(map[string]string)
    23  
    24  	res := client.NewListPager(nil)
    25  	for res.More() {
    26  		p, err := res.NextPage(ctx)
    27  		if err != nil {
    28  			return map[string]string{}, errorutils.HandleCredentialError(errors.Trace(err), ctx)
    29  		}
    30  
    31  		providers := p.ProviderListResult
    32  		for _, provider := range providers.Value {
    33  			for _, resourceType := range provider.ResourceTypes {
    34  				key := toValue(provider.Namespace) + "/" + toValue(resourceType.ResourceType)
    35  				if len(resourceType.APIVersions) == 0 {
    36  					continue
    37  				}
    38  				// The versions are newest-first.
    39  				result[key] = toValue(resourceType.APIVersions[0])
    40  			}
    41  		}
    42  	}
    43  	return result, nil
    44  }
    45  
    46  func azureCloud(cloudName, apiEndpoint, identityEndpoint string) azurecloud.Configuration {
    47  	// Use well known cloud definitions from the SDk if possible.
    48  	switch cloudName {
    49  	case "azure":
    50  		return azurecloud.AzurePublic
    51  	case "azure-china":
    52  		return azurecloud.AzureChina
    53  	case "azure-gov":
    54  		return azurecloud.AzureGovernment
    55  	}
    56  	return azurecloud.Configuration{
    57  		ActiveDirectoryAuthorityHost: identityEndpoint,
    58  		Services: map[azurecloud.ServiceName]azurecloud.ServiceConfiguration{
    59  			azurecloud.ResourceManager: {
    60  				Audience: "https://management.core.windows.net/",
    61  				Endpoint: apiEndpoint,
    62  			},
    63  		},
    64  	}
    65  }
    66  
    67  func toValue[T any](v *T) T {
    68  	if v == nil {
    69  		return *new(T)
    70  	}
    71  	return *v
    72  }
    73  
    74  func toMap(in map[string]*string) map[string]string {
    75  	result := make(map[string]string)
    76  	for k, v := range in {
    77  		result[k] = toValue(v)
    78  	}
    79  	return result
    80  }
    81  
    82  func toMapPtr(in map[string]string) map[string]*string {
    83  	result := make(map[string]*string)
    84  	for k, v := range in {
    85  		result[k] = to.Ptr(v)
    86  	}
    87  	return result
    88  }