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