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