github.com/nathanielks/terraform@v0.6.1-0.20170509030759-13e1a62319dc/state/remote/azure_test.go (about)

     1  package remote
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strings"
     7  	"testing"
     8  
     9  	mainStorage "github.com/Azure/azure-sdk-for-go/storage"
    10  	"github.com/hashicorp/terraform/helper/acctest"
    11  	riviera "github.com/jen20/riviera/azure"
    12  	"github.com/jen20/riviera/storage"
    13  	"github.com/satori/uuid"
    14  )
    15  
    16  func TestAzureClient_impl(t *testing.T) {
    17  	var _ Client = new(AzureClient)
    18  }
    19  
    20  // This test creates a bucket in Azure and populates it.
    21  // It may incur costs, so it will only run if Azure credential environment
    22  // variables are present.
    23  func TestAzureClient(t *testing.T) {
    24  	config := getAzureConfig(t)
    25  
    26  	setup(t, config)
    27  	defer teardown(t, config)
    28  
    29  	client, err := azureFactory(config)
    30  	if err != nil {
    31  		t.Fatalf("Error for valid config: %v", err)
    32  	}
    33  
    34  	testClient(t, client)
    35  }
    36  
    37  // This test is the same as TestAzureClient with the addition of passing an
    38  // empty string in the lease_id, we expect the client to pass tests
    39  func TestAzureClientEmptyLease(t *testing.T) {
    40  	config := getAzureConfig(t)
    41  	config["lease_id"] = ""
    42  
    43  	setup(t, config)
    44  	defer teardown(t, config)
    45  
    46  	client, err := azureFactory(config)
    47  	if err != nil {
    48  		t.Fatalf("Error for valid config: %v", err)
    49  	}
    50  
    51  	testClient(t, client)
    52  }
    53  
    54  // This test is the same as TestAzureClient with the addition of using the
    55  // lease_id config option
    56  func TestAzureClientLease(t *testing.T) {
    57  	leaseID := uuid.NewV4().String()
    58  	config := getAzureConfig(t)
    59  	config["lease_id"] = leaseID
    60  
    61  	setup(t, config)
    62  	defer teardown(t, config)
    63  
    64  	client, err := azureFactory(config)
    65  	if err != nil {
    66  		t.Fatalf("Error for valid config: %v", err)
    67  	}
    68  	azureClient := client.(*AzureClient)
    69  
    70  	// put empty blob so we can acquire lease against it
    71  	err = azureClient.blobClient.CreateBlockBlob(azureClient.containerName, azureClient.keyName)
    72  	if err != nil {
    73  		t.Fatalf("Error creating blob for leasing: %v", err)
    74  	}
    75  
    76  	_, err = azureClient.blobClient.AcquireLease(azureClient.containerName, azureClient.keyName, -1, leaseID)
    77  	if err != nil {
    78  		t.Fatalf("Error acquiring lease: %v", err)
    79  	}
    80  
    81  	// no need to release lease as blob is deleted in testing
    82  	testClient(t, client)
    83  }
    84  
    85  func getAzureConfig(t *testing.T) map[string]string {
    86  	config := map[string]string{
    87  		"arm_subscription_id": os.Getenv("ARM_SUBSCRIPTION_ID"),
    88  		"arm_client_id":       os.Getenv("ARM_CLIENT_ID"),
    89  		"arm_client_secret":   os.Getenv("ARM_CLIENT_SECRET"),
    90  		"arm_tenant_id":       os.Getenv("ARM_TENANT_ID"),
    91  		"environment":         os.Getenv("ARM_ENVIRONMENT"),
    92  	}
    93  
    94  	for k, v := range config {
    95  		if v == "" {
    96  			t.Skipf("skipping; %s must be set", strings.ToUpper(k))
    97  		}
    98  	}
    99  
   100  	rs := acctest.RandString(8)
   101  
   102  	config["resource_group_name"] = fmt.Sprintf("terraform-%s", rs)
   103  	config["storage_account_name"] = fmt.Sprintf("terraform%s", rs)
   104  	config["container_name"] = "terraform"
   105  	config["key"] = "test.tfstate"
   106  
   107  	return config
   108  }
   109  
   110  func setup(t *testing.T, conf map[string]string) {
   111  	env, err := getAzureEnvironmentFromConf(conf)
   112  	if err != nil {
   113  		t.Fatalf("Error getting Azure environment from conf: %v", err)
   114  	}
   115  	creds, err := getCredentialsFromConf(conf, env)
   116  	if err != nil {
   117  		t.Fatalf("Error getting credentials from conf: %v", err)
   118  	}
   119  	rivieraClient, err := getRivieraClient(creds)
   120  	if err != nil {
   121  		t.Fatalf("Error instantiating the riviera client: %v", err)
   122  	}
   123  
   124  	// Create resource group
   125  	r := rivieraClient.NewRequest()
   126  	r.Command = riviera.CreateResourceGroup{
   127  		Name:     conf["resource_group_name"],
   128  		Location: riviera.WestUS,
   129  	}
   130  	response, err := r.Execute()
   131  	if err != nil {
   132  		t.Fatalf("Error creating a resource group: %v", err)
   133  	}
   134  	if !response.IsSuccessful() {
   135  		t.Fatalf("Error creating a resource group: %v", response.Error.Error())
   136  	}
   137  
   138  	// Create storage account
   139  	r = rivieraClient.NewRequest()
   140  	r.Command = storage.CreateStorageAccount{
   141  		ResourceGroupName: conf["resource_group_name"],
   142  		Name:              conf["storage_account_name"],
   143  		AccountType:       riviera.String("Standard_LRS"),
   144  		Location:          riviera.WestUS,
   145  	}
   146  	response, err = r.Execute()
   147  	if err != nil {
   148  		t.Fatalf("Error creating a storage account: %v", err)
   149  	}
   150  	if !response.IsSuccessful() {
   151  		t.Fatalf("Error creating a storage account: %v", response.Error.Error())
   152  	}
   153  
   154  	// Create container
   155  	accessKey, err := getStorageAccountAccessKey(conf, conf["resource_group_name"], conf["storage_account_name"], env)
   156  	if err != nil {
   157  		t.Fatalf("Error creating a storage account: %v", err)
   158  	}
   159  	storageClient, err := mainStorage.NewClient(conf["storage_account_name"], accessKey, env.StorageEndpointSuffix,
   160  		mainStorage.DefaultAPIVersion, true)
   161  	if err != nil {
   162  		t.Fatalf("Error creating storage client for storage account %q: %s", conf["storage_account_name"], err)
   163  	}
   164  	blobClient := storageClient.GetBlobService()
   165  	_, err = blobClient.CreateContainerIfNotExists(conf["container_name"], mainStorage.ContainerAccessTypePrivate)
   166  	if err != nil {
   167  		t.Fatalf("Couldn't create container with name %s: %s.", conf["container_name"], err)
   168  	}
   169  }
   170  
   171  func teardown(t *testing.T, conf map[string]string) {
   172  	env, err := getAzureEnvironmentFromConf(conf)
   173  	if err != nil {
   174  		t.Fatalf("Error getting Azure environment from conf: %v", err)
   175  	}
   176  	creds, err := getCredentialsFromConf(conf, env)
   177  	if err != nil {
   178  		t.Fatalf("Error getting credentials from conf: %v", err)
   179  	}
   180  	rivieraClient, err := getRivieraClient(creds)
   181  	if err != nil {
   182  		t.Fatalf("Error instantiating the riviera client: %v", err)
   183  	}
   184  
   185  	r := rivieraClient.NewRequest()
   186  	r.Command = riviera.DeleteResourceGroup{
   187  		Name: conf["resource_group_name"],
   188  	}
   189  	response, err := r.Execute()
   190  	if err != nil {
   191  		t.Fatalf("Error deleting the resource group: %v", err)
   192  	}
   193  	if !response.IsSuccessful() {
   194  		t.Fatalf("Error deleting the resource group: %v", err)
   195  	}
   196  }
   197  
   198  func getRivieraClient(credentials *riviera.AzureResourceManagerCredentials) (*riviera.Client, error) {
   199  	rivieraClient, err := riviera.NewClient(credentials)
   200  	if err != nil {
   201  		return nil, fmt.Errorf("Error creating Riviera client: %s", err)
   202  	}
   203  
   204  	request := rivieraClient.NewRequest()
   205  	request.Command = riviera.RegisterResourceProvider{
   206  		Namespace: "Microsoft.Storage",
   207  	}
   208  
   209  	response, err := request.Execute()
   210  	if err != nil {
   211  		return nil, fmt.Errorf("Cannot request provider registration for Azure Resource Manager: %s.", err)
   212  	}
   213  
   214  	if !response.IsSuccessful() {
   215  		return nil, fmt.Errorf("Credentials for acessing the Azure Resource Manager API are likely " +
   216  			"to be incorrect, or\n  the service principal does not have permission to use " +
   217  			"the Azure Service Management\n  API.")
   218  	}
   219  
   220  	return rivieraClient, nil
   221  }