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