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