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