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