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