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