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