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