github.com/rhenning/terraform@v0.8.0-beta2/builtin/providers/azurerm/config.go (about) 1 package azurerm 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 "net/http" 8 "net/http/httputil" 9 10 "github.com/Azure/azure-sdk-for-go/arm/cdn" 11 "github.com/Azure/azure-sdk-for-go/arm/compute" 12 "github.com/Azure/azure-sdk-for-go/arm/eventhub" 13 "github.com/Azure/azure-sdk-for-go/arm/keyvault" 14 "github.com/Azure/azure-sdk-for-go/arm/network" 15 "github.com/Azure/azure-sdk-for-go/arm/resources/resources" 16 "github.com/Azure/azure-sdk-for-go/arm/scheduler" 17 "github.com/Azure/azure-sdk-for-go/arm/servicebus" 18 "github.com/Azure/azure-sdk-for-go/arm/storage" 19 "github.com/Azure/azure-sdk-for-go/arm/trafficmanager" 20 mainStorage "github.com/Azure/azure-sdk-for-go/storage" 21 "github.com/Azure/go-autorest/autorest" 22 "github.com/Azure/go-autorest/autorest/azure" 23 "github.com/hashicorp/terraform/terraform" 24 riviera "github.com/jen20/riviera/azure" 25 ) 26 27 // ArmClient contains the handles to all the specific Azure Resource Manager 28 // resource classes' respective clients. 29 type ArmClient struct { 30 clientId string 31 tenantId string 32 subscriptionId string 33 34 StopContext context.Context 35 36 rivieraClient *riviera.Client 37 38 availSetClient compute.AvailabilitySetsClient 39 usageOpsClient compute.UsageOperationsClient 40 vmExtensionImageClient compute.VirtualMachineExtensionImagesClient 41 vmExtensionClient compute.VirtualMachineExtensionsClient 42 vmScaleSetClient compute.VirtualMachineScaleSetsClient 43 vmImageClient compute.VirtualMachineImagesClient 44 vmClient compute.VirtualMachinesClient 45 46 appGatewayClient network.ApplicationGatewaysClient 47 ifaceClient network.InterfacesClient 48 loadBalancerClient network.LoadBalancersClient 49 localNetConnClient network.LocalNetworkGatewaysClient 50 publicIPClient network.PublicIPAddressesClient 51 secGroupClient network.SecurityGroupsClient 52 secRuleClient network.SecurityRulesClient 53 subnetClient network.SubnetsClient 54 netUsageClient network.UsagesClient 55 vnetGatewayConnectionsClient network.VirtualNetworkGatewayConnectionsClient 56 vnetGatewayClient network.VirtualNetworkGatewaysClient 57 vnetClient network.VirtualNetworksClient 58 vnetPeeringsClient network.VirtualNetworkPeeringsClient 59 routeTablesClient network.RouteTablesClient 60 routesClient network.RoutesClient 61 62 cdnProfilesClient cdn.ProfilesClient 63 cdnEndpointsClient cdn.EndpointsClient 64 65 eventHubClient eventhub.EventHubsClient 66 eventHubNamespacesClient eventhub.NamespacesClient 67 68 providers resources.ProvidersClient 69 resourceGroupClient resources.GroupsClient 70 tagsClient resources.TagsClient 71 resourceFindClient resources.Client 72 73 jobsClient scheduler.JobsClient 74 jobsCollectionsClient scheduler.JobCollectionsClient 75 76 storageServiceClient storage.AccountsClient 77 storageUsageClient storage.UsageOperationsClient 78 79 deploymentsClient resources.DeploymentsClient 80 81 trafficManagerProfilesClient trafficmanager.ProfilesClient 82 trafficManagerEndpointsClient trafficmanager.EndpointsClient 83 84 serviceBusNamespacesClient servicebus.NamespacesClient 85 serviceBusTopicsClient servicebus.TopicsClient 86 serviceBusSubscriptionsClient servicebus.SubscriptionsClient 87 88 keyVaultClient keyvault.VaultsClient 89 } 90 91 func withRequestLogging() autorest.SendDecorator { 92 return func(s autorest.Sender) autorest.Sender { 93 return autorest.SenderFunc(func(r *http.Request) (*http.Response, error) { 94 // dump request to wire format 95 if dump, err := httputil.DumpRequestOut(r, true); err == nil { 96 log.Printf("[DEBUG] AzureRM Request: \n%s\n", dump) 97 } else { 98 // fallback to basic message 99 log.Printf("[DEBUG] AzureRM Request: %s to %s\n", r.Method, r.URL) 100 } 101 102 resp, err := s.Do(r) 103 if resp != nil { 104 // dump response to wire format 105 if dump, err := httputil.DumpResponse(resp, true); err == nil { 106 log.Printf("[DEBUG] AzureRM Response for %s: \n%s\n", r.URL, dump) 107 } else { 108 // fallback to basic message 109 log.Printf("[DEBUG] AzureRM Response: %s for %s\n", resp.Status, r.URL) 110 } 111 } else { 112 log.Printf("[DEBUG] Request to %s completed with no response", r.URL) 113 } 114 return resp, err 115 }) 116 } 117 } 118 119 func setUserAgent(client *autorest.Client) { 120 version := terraform.VersionString() 121 client.UserAgent = fmt.Sprintf("HashiCorp-Terraform-v%s", version) 122 } 123 124 // getArmClient is a helper method which returns a fully instantiated 125 // *ArmClient based on the Config's current settings. 126 func (c *Config) getArmClient() (*ArmClient, error) { 127 // client declarations: 128 client := ArmClient{ 129 clientId: c.ClientID, 130 tenantId: c.TenantID, 131 subscriptionId: c.SubscriptionID, 132 } 133 134 rivieraClient, err := riviera.NewClient(&riviera.AzureResourceManagerCredentials{ 135 ClientID: c.ClientID, 136 ClientSecret: c.ClientSecret, 137 TenantID: c.TenantID, 138 SubscriptionID: c.SubscriptionID, 139 }) 140 if err != nil { 141 return nil, fmt.Errorf("Error creating Riviera client: %s", err) 142 } 143 144 // validate that the credentials are correct using Riviera. Note that this must be 145 // done _before_ using the Microsoft SDK, because Riviera handles errors. Using a 146 // namespace registration instead of a simple OAuth token refresh guarantees that 147 // service delegation is correct. This has the effect of registering Microsoft.Compute 148 // which is neccessary anyway. 149 if err := registerProviderWithSubscription("Microsoft.Compute", rivieraClient); err != nil { 150 return nil, err 151 } 152 client.rivieraClient = rivieraClient 153 154 oauthConfig, err := azure.PublicCloud.OAuthConfigForTenant(c.TenantID) 155 if err != nil { 156 return nil, err 157 } 158 159 // OAuthConfigForTenant returns a pointer, which can be nil. 160 if oauthConfig == nil { 161 return nil, fmt.Errorf("Unable to configure OAuthConfig for tenant %s", c.TenantID) 162 } 163 164 spt, err := azure.NewServicePrincipalToken(*oauthConfig, c.ClientID, c.ClientSecret, 165 azure.PublicCloud.ResourceManagerEndpoint) 166 if err != nil { 167 return nil, err 168 } 169 170 // NOTE: these declarations should be left separate for clarity should the 171 // clients be wished to be configured with custom Responders/PollingModess etc... 172 asc := compute.NewAvailabilitySetsClient(c.SubscriptionID) 173 setUserAgent(&asc.Client) 174 asc.Authorizer = spt 175 asc.Sender = autorest.CreateSender(withRequestLogging()) 176 client.availSetClient = asc 177 178 uoc := compute.NewUsageOperationsClient(c.SubscriptionID) 179 setUserAgent(&uoc.Client) 180 uoc.Authorizer = spt 181 uoc.Sender = autorest.CreateSender(withRequestLogging()) 182 client.usageOpsClient = uoc 183 184 vmeic := compute.NewVirtualMachineExtensionImagesClient(c.SubscriptionID) 185 setUserAgent(&vmeic.Client) 186 vmeic.Authorizer = spt 187 vmeic.Sender = autorest.CreateSender(withRequestLogging()) 188 client.vmExtensionImageClient = vmeic 189 190 vmec := compute.NewVirtualMachineExtensionsClient(c.SubscriptionID) 191 setUserAgent(&vmec.Client) 192 vmec.Authorizer = spt 193 vmec.Sender = autorest.CreateSender(withRequestLogging()) 194 client.vmExtensionClient = vmec 195 196 vmic := compute.NewVirtualMachineImagesClient(c.SubscriptionID) 197 setUserAgent(&vmic.Client) 198 vmic.Authorizer = spt 199 vmic.Sender = autorest.CreateSender(withRequestLogging()) 200 client.vmImageClient = vmic 201 202 vmssc := compute.NewVirtualMachineScaleSetsClient(c.SubscriptionID) 203 setUserAgent(&vmssc.Client) 204 vmssc.Authorizer = spt 205 vmssc.Sender = autorest.CreateSender(withRequestLogging()) 206 client.vmScaleSetClient = vmssc 207 208 vmc := compute.NewVirtualMachinesClient(c.SubscriptionID) 209 setUserAgent(&vmc.Client) 210 vmc.Authorizer = spt 211 vmc.Sender = autorest.CreateSender(withRequestLogging()) 212 client.vmClient = vmc 213 214 agc := network.NewApplicationGatewaysClient(c.SubscriptionID) 215 setUserAgent(&agc.Client) 216 agc.Authorizer = spt 217 agc.Sender = autorest.CreateSender(withRequestLogging()) 218 client.appGatewayClient = agc 219 220 ehc := eventhub.NewEventHubsClient(c.SubscriptionID) 221 setUserAgent(&ehc.Client) 222 ehc.Authorizer = spt 223 ehc.Sender = autorest.CreateSender(withRequestLogging()) 224 client.eventHubClient = ehc 225 226 ehnc := eventhub.NewNamespacesClient(c.SubscriptionID) 227 setUserAgent(&ehnc.Client) 228 ehnc.Authorizer = spt 229 ehnc.Sender = autorest.CreateSender(withRequestLogging()) 230 client.eventHubNamespacesClient = ehnc 231 232 ifc := network.NewInterfacesClient(c.SubscriptionID) 233 setUserAgent(&ifc.Client) 234 ifc.Authorizer = spt 235 ifc.Sender = autorest.CreateSender(withRequestLogging()) 236 client.ifaceClient = ifc 237 238 lbc := network.NewLoadBalancersClient(c.SubscriptionID) 239 setUserAgent(&lbc.Client) 240 lbc.Authorizer = spt 241 lbc.Sender = autorest.CreateSender(withRequestLogging()) 242 client.loadBalancerClient = lbc 243 244 lgc := network.NewLocalNetworkGatewaysClient(c.SubscriptionID) 245 setUserAgent(&lgc.Client) 246 lgc.Authorizer = spt 247 lgc.Sender = autorest.CreateSender(withRequestLogging()) 248 client.localNetConnClient = lgc 249 250 pipc := network.NewPublicIPAddressesClient(c.SubscriptionID) 251 setUserAgent(&pipc.Client) 252 pipc.Authorizer = spt 253 pipc.Sender = autorest.CreateSender(withRequestLogging()) 254 client.publicIPClient = pipc 255 256 sgc := network.NewSecurityGroupsClient(c.SubscriptionID) 257 setUserAgent(&sgc.Client) 258 sgc.Authorizer = spt 259 sgc.Sender = autorest.CreateSender(withRequestLogging()) 260 client.secGroupClient = sgc 261 262 src := network.NewSecurityRulesClient(c.SubscriptionID) 263 setUserAgent(&src.Client) 264 src.Authorizer = spt 265 src.Sender = autorest.CreateSender(withRequestLogging()) 266 client.secRuleClient = src 267 268 snc := network.NewSubnetsClient(c.SubscriptionID) 269 setUserAgent(&snc.Client) 270 snc.Authorizer = spt 271 snc.Sender = autorest.CreateSender(withRequestLogging()) 272 client.subnetClient = snc 273 274 vgcc := network.NewVirtualNetworkGatewayConnectionsClient(c.SubscriptionID) 275 setUserAgent(&vgcc.Client) 276 vgcc.Authorizer = spt 277 vgcc.Sender = autorest.CreateSender(withRequestLogging()) 278 client.vnetGatewayConnectionsClient = vgcc 279 280 vgc := network.NewVirtualNetworkGatewaysClient(c.SubscriptionID) 281 setUserAgent(&vgc.Client) 282 vgc.Authorizer = spt 283 vgc.Sender = autorest.CreateSender(withRequestLogging()) 284 client.vnetGatewayClient = vgc 285 286 vnc := network.NewVirtualNetworksClient(c.SubscriptionID) 287 setUserAgent(&vnc.Client) 288 vnc.Authorizer = spt 289 vnc.Sender = autorest.CreateSender(withRequestLogging()) 290 client.vnetClient = vnc 291 292 vnpc := network.NewVirtualNetworkPeeringsClient(c.SubscriptionID) 293 setUserAgent(&vnpc.Client) 294 vnpc.Authorizer = spt 295 vnpc.Sender = autorest.CreateSender(withRequestLogging()) 296 client.vnetPeeringsClient = vnpc 297 298 rtc := network.NewRouteTablesClient(c.SubscriptionID) 299 setUserAgent(&rtc.Client) 300 rtc.Authorizer = spt 301 rtc.Sender = autorest.CreateSender(withRequestLogging()) 302 client.routeTablesClient = rtc 303 304 rc := network.NewRoutesClient(c.SubscriptionID) 305 setUserAgent(&rc.Client) 306 rc.Authorizer = spt 307 rc.Sender = autorest.CreateSender(withRequestLogging()) 308 client.routesClient = rc 309 310 rgc := resources.NewGroupsClient(c.SubscriptionID) 311 setUserAgent(&rgc.Client) 312 rgc.Authorizer = spt 313 rgc.Sender = autorest.CreateSender(withRequestLogging()) 314 client.resourceGroupClient = rgc 315 316 pc := resources.NewProvidersClient(c.SubscriptionID) 317 setUserAgent(&pc.Client) 318 pc.Authorizer = spt 319 pc.Sender = autorest.CreateSender(withRequestLogging()) 320 client.providers = pc 321 322 tc := resources.NewTagsClient(c.SubscriptionID) 323 setUserAgent(&tc.Client) 324 tc.Authorizer = spt 325 tc.Sender = autorest.CreateSender(withRequestLogging()) 326 client.tagsClient = tc 327 328 rf := resources.NewClient(c.SubscriptionID) 329 setUserAgent(&rf.Client) 330 rf.Authorizer = spt 331 rf.Sender = autorest.CreateSender(withRequestLogging()) 332 client.resourceFindClient = rf 333 334 jc := scheduler.NewJobsClient(c.SubscriptionID) 335 setUserAgent(&jc.Client) 336 jc.Authorizer = spt 337 jc.Sender = autorest.CreateSender(withRequestLogging()) 338 client.jobsClient = jc 339 340 jcc := scheduler.NewJobCollectionsClient(c.SubscriptionID) 341 setUserAgent(&jcc.Client) 342 jcc.Authorizer = spt 343 jcc.Sender = autorest.CreateSender(withRequestLogging()) 344 client.jobsCollectionsClient = jcc 345 346 ssc := storage.NewAccountsClient(c.SubscriptionID) 347 setUserAgent(&ssc.Client) 348 ssc.Authorizer = spt 349 ssc.Sender = autorest.CreateSender(withRequestLogging()) 350 client.storageServiceClient = ssc 351 352 suc := storage.NewUsageOperationsClient(c.SubscriptionID) 353 setUserAgent(&suc.Client) 354 suc.Authorizer = spt 355 suc.Sender = autorest.CreateSender(withRequestLogging()) 356 client.storageUsageClient = suc 357 358 cpc := cdn.NewProfilesClient(c.SubscriptionID) 359 setUserAgent(&cpc.Client) 360 cpc.Authorizer = spt 361 cpc.Sender = autorest.CreateSender(withRequestLogging()) 362 client.cdnProfilesClient = cpc 363 364 cec := cdn.NewEndpointsClient(c.SubscriptionID) 365 setUserAgent(&cec.Client) 366 cec.Authorizer = spt 367 cec.Sender = autorest.CreateSender(withRequestLogging()) 368 client.cdnEndpointsClient = cec 369 370 dc := resources.NewDeploymentsClient(c.SubscriptionID) 371 setUserAgent(&dc.Client) 372 dc.Authorizer = spt 373 dc.Sender = autorest.CreateSender(withRequestLogging()) 374 client.deploymentsClient = dc 375 376 tmpc := trafficmanager.NewProfilesClient(c.SubscriptionID) 377 setUserAgent(&tmpc.Client) 378 tmpc.Authorizer = spt 379 tmpc.Sender = autorest.CreateSender(withRequestLogging()) 380 client.trafficManagerProfilesClient = tmpc 381 382 tmec := trafficmanager.NewEndpointsClient(c.SubscriptionID) 383 setUserAgent(&tmec.Client) 384 tmec.Authorizer = spt 385 tmec.Sender = autorest.CreateSender(withRequestLogging()) 386 client.trafficManagerEndpointsClient = tmec 387 388 sbnc := servicebus.NewNamespacesClient(c.SubscriptionID) 389 setUserAgent(&sbnc.Client) 390 sbnc.Authorizer = spt 391 sbnc.Sender = autorest.CreateSender(withRequestLogging()) 392 client.serviceBusNamespacesClient = sbnc 393 394 sbtc := servicebus.NewTopicsClient(c.SubscriptionID) 395 setUserAgent(&sbtc.Client) 396 sbtc.Authorizer = spt 397 sbtc.Sender = autorest.CreateSender(withRequestLogging()) 398 client.serviceBusTopicsClient = sbtc 399 400 sbsc := servicebus.NewSubscriptionsClient(c.SubscriptionID) 401 setUserAgent(&sbsc.Client) 402 sbsc.Authorizer = spt 403 sbsc.Sender = autorest.CreateSender(withRequestLogging()) 404 client.serviceBusSubscriptionsClient = sbsc 405 406 kvc := keyvault.NewVaultsClient(c.SubscriptionID) 407 setUserAgent(&kvc.Client) 408 kvc.Authorizer = spt 409 kvc.Sender = autorest.CreateSender(withRequestLogging()) 410 client.keyVaultClient = kvc 411 412 return &client, nil 413 } 414 415 func (armClient *ArmClient) getKeyForStorageAccount(resourceGroupName, storageAccountName string) (string, bool, error) { 416 accountKeys, err := armClient.storageServiceClient.ListKeys(resourceGroupName, storageAccountName) 417 if accountKeys.StatusCode == http.StatusNotFound { 418 return "", false, nil 419 } 420 if err != nil { 421 // We assume this is a transient error rather than a 404 (which is caught above), so assume the 422 // account still exists. 423 return "", true, fmt.Errorf("Error retrieving keys for storage account %q: %s", storageAccountName, err) 424 } 425 426 if accountKeys.Keys == nil { 427 return "", false, fmt.Errorf("Nil key returned for storage account %q", storageAccountName) 428 } 429 430 keys := *accountKeys.Keys 431 return *keys[0].Value, true, nil 432 } 433 434 func (armClient *ArmClient) getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName string) (*mainStorage.BlobStorageClient, bool, error) { 435 key, accountExists, err := armClient.getKeyForStorageAccount(resourceGroupName, storageAccountName) 436 if err != nil { 437 return nil, accountExists, err 438 } 439 if accountExists == false { 440 return nil, false, nil 441 } 442 443 storageClient, err := mainStorage.NewBasicClient(storageAccountName, key) 444 if err != nil { 445 return nil, true, fmt.Errorf("Error creating storage client for storage account %q: %s", storageAccountName, err) 446 } 447 448 blobClient := storageClient.GetBlobService() 449 return &blobClient, true, nil 450 } 451 452 func (armClient *ArmClient) getFileServiceClientForStorageAccount(resourceGroupName, storageAccountName string) (*mainStorage.FileServiceClient, bool, error) { 453 key, accountExists, err := armClient.getKeyForStorageAccount(resourceGroupName, storageAccountName) 454 if err != nil { 455 return nil, accountExists, err 456 } 457 if accountExists == false { 458 return nil, false, nil 459 } 460 461 storageClient, err := mainStorage.NewBasicClient(storageAccountName, key) 462 if err != nil { 463 return nil, true, fmt.Errorf("Error creating storage client for storage account %q: %s", storageAccountName, err) 464 } 465 466 fileClient := storageClient.GetFileService() 467 return &fileClient, true, nil 468 } 469 470 func (armClient *ArmClient) getTableServiceClientForStorageAccount(resourceGroupName, storageAccountName string) (*mainStorage.TableServiceClient, bool, error) { 471 key, accountExists, err := armClient.getKeyForStorageAccount(resourceGroupName, storageAccountName) 472 if err != nil { 473 return nil, accountExists, err 474 } 475 if accountExists == false { 476 return nil, false, nil 477 } 478 479 storageClient, err := mainStorage.NewBasicClient(storageAccountName, key) 480 if err != nil { 481 return nil, true, fmt.Errorf("Error creating storage client for storage account %q: %s", storageAccountName, err) 482 } 483 484 tableClient := storageClient.GetTableService() 485 return &tableClient, true, nil 486 } 487 488 func (armClient *ArmClient) getQueueServiceClientForStorageAccount(resourceGroupName, storageAccountName string) (*mainStorage.QueueServiceClient, bool, error) { 489 key, accountExists, err := armClient.getKeyForStorageAccount(resourceGroupName, storageAccountName) 490 if err != nil { 491 return nil, accountExists, err 492 } 493 if accountExists == false { 494 return nil, false, nil 495 } 496 497 storageClient, err := mainStorage.NewBasicClient(storageAccountName, key) 498 if err != nil { 499 return nil, true, fmt.Errorf("Error creating storage client for storage account %q: %s", storageAccountName, err) 500 } 501 502 queueClient := storageClient.GetQueueService() 503 return &queueClient, true, nil 504 }