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