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