forked from hashicorp/terraform-provider-azurerm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
builder.go
160 lines (137 loc) · 6.09 KB
/
builder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package clients
import (
"context"
"fmt"
"log"
"strings"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/azure"
"github.com/hashicorp/go-azure-helpers/authentication"
"github.com/hashicorp/go-azure-helpers/resourcemanager/location"
"github.com/hashicorp/go-azure-helpers/sender"
"github.com/kevinklinger/terraform-provider-azurerm/v2/internal/common"
"github.com/kevinklinger/terraform-provider-azurerm/v2/internal/features"
"github.com/kevinklinger/terraform-provider-azurerm/v2/internal/resourceproviders"
)
type ClientBuilder struct {
AuthConfig *authentication.Config
DisableCorrelationRequestID bool
CustomCorrelationRequestID string
DisableTerraformPartnerID bool
PartnerId string
SkipProviderRegistration bool
StorageUseAzureAD bool
TerraformVersion string
Features features.UserFeatures
}
const azureStackEnvironmentError = `
The AzureRM Provider supports the different Azure Public Clouds - including China, Germany,
Public and US Government - however it does not support Azure Stack due to differences in
API and feature availability.
Terraform instead offers a separate "azurestack" provider which supports the functionality
and API's available in Azure Stack via Azure Stack Profiles.
`
func Build(ctx context.Context, builder ClientBuilder) (*Client, error) {
// point folks towards the separate Azure Stack Provider when using Azure Stack
if strings.EqualFold(builder.AuthConfig.Environment, "AZURESTACKCLOUD") {
return nil, fmt.Errorf(azureStackEnvironmentError)
}
isAzureStack, err := authentication.IsEnvironmentAzureStack(ctx, builder.AuthConfig.MetadataHost, builder.AuthConfig.Environment)
if err != nil {
return nil, fmt.Errorf("unable to determine if environment is Azure Stack: %+v", err)
}
if isAzureStack {
return nil, fmt.Errorf(azureStackEnvironmentError)
}
env, err := authentication.AzureEnvironmentByNameFromEndpoint(ctx, builder.AuthConfig.MetadataHost, builder.AuthConfig.Environment)
if err != nil {
return nil, fmt.Errorf("unable to find environment %q from endpoint %q: %+v", builder.AuthConfig.Environment, builder.AuthConfig.MetadataHost, err)
}
// client declarations:
account, err := NewResourceManagerAccount(ctx, *builder.AuthConfig, *env, builder.SkipProviderRegistration)
if err != nil {
return nil, fmt.Errorf("building account: %+v", err)
}
client := Client{
Account: account,
}
oauthConfig, err := builder.AuthConfig.BuildOAuthConfig(env.ActiveDirectoryEndpoint)
if err != nil {
return nil, fmt.Errorf("building OAuth Config: %+v", err)
}
// OAuthConfigForTenant returns a pointer, which can be nil.
if oauthConfig == nil {
return nil, fmt.Errorf("unable to configure OAuthConfig for tenant %s", builder.AuthConfig.TenantID)
}
sender := sender.BuildSender("AzureRM")
// Resource Manager endpoints
endpoint := env.ResourceManagerEndpoint
auth, err := builder.AuthConfig.GetAuthorizationToken(sender, oauthConfig, env.TokenAudience)
if err != nil {
return nil, fmt.Errorf("unable to get authorization token for resource manager: %+v", err)
}
// Graph Endpoints
graphEndpoint := env.GraphEndpoint
graphAuth, err := builder.AuthConfig.GetAuthorizationToken(sender, oauthConfig, graphEndpoint)
if err != nil {
return nil, fmt.Errorf("unable to get authorization token for graph endpoints: %+v", err)
}
// Storage Endpoints
storageAuth, err := builder.AuthConfig.GetAuthorizationToken(sender, oauthConfig, env.ResourceIdentifiers.Storage)
if err != nil {
return nil, fmt.Errorf("unable to get authorization token for storage endpoints: %+v", err)
}
// Synapse Endpoints
var synapseAuth autorest.Authorizer = nil
if env.ResourceIdentifiers.Synapse != azure.NotAvailable {
synapseAuth, err = builder.AuthConfig.GetAuthorizationToken(sender, oauthConfig, env.ResourceIdentifiers.Synapse)
if err != nil {
return nil, fmt.Errorf("unable to get authorization token for synapse endpoints: %+v", err)
}
} else {
log.Printf("[DEBUG] Skipping building the Synapse Authorizer since this is not supported in the current Azure Environment")
}
// Key Vault Endpoints
keyVaultAuth := builder.AuthConfig.BearerAuthorizerCallback(sender, oauthConfig)
// Batch Management Endpoints
batchManagementAuth, err := builder.AuthConfig.GetAuthorizationToken(sender, oauthConfig, env.BatchManagementEndpoint)
if err != nil {
return nil, fmt.Errorf("unable to get authorization token for batch management endpoint: %+v", err)
}
o := &common.ClientOptions{
SubscriptionId: builder.AuthConfig.SubscriptionID,
TenantID: builder.AuthConfig.TenantID,
PartnerId: builder.PartnerId,
TerraformVersion: builder.TerraformVersion,
GraphAuthorizer: graphAuth,
GraphEndpoint: graphEndpoint,
KeyVaultAuthorizer: keyVaultAuth,
ResourceManagerAuthorizer: auth,
ResourceManagerEndpoint: endpoint,
StorageAuthorizer: storageAuth,
SynapseAuthorizer: synapseAuth,
BatchManagementAuthorizer: batchManagementAuth,
SkipProviderReg: builder.SkipProviderRegistration,
DisableCorrelationRequestID: builder.DisableCorrelationRequestID,
CustomCorrelationRequestID: builder.CustomCorrelationRequestID,
DisableTerraformPartnerID: builder.DisableTerraformPartnerID,
Environment: *env,
Features: builder.Features,
StorageUseAzureAD: builder.StorageUseAzureAD,
TokenFunc: func(endpoint string) (autorest.Authorizer, error) {
authorizer, err := builder.AuthConfig.GetAuthorizationToken(sender, oauthConfig, endpoint)
if err != nil {
return nil, fmt.Errorf("getting authorization token for endpoint %s: %+v", endpoint, err)
}
return authorizer, nil
},
}
if err := client.Build(ctx, o); err != nil {
return nil, fmt.Errorf("building Client: %+v", err)
}
if features.EnhancedValidationEnabled() {
location.CacheSupportedLocations(ctx, env.ResourceManagerEndpoint)
resourceproviders.CacheSupportedProviders(ctx, client.Resource.ProvidersClient)
}
return &client, nil
}