github.com/sathish1597/hashicorp-terraform@v0.11.12-beta1/backend/remote-state/azure/backend_test.go (about)

     1  package azure
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"testing"
     7  
     8  	"github.com/Azure/azure-sdk-for-go/arm/resources/resources"
     9  	armStorage "github.com/Azure/azure-sdk-for-go/arm/storage"
    10  	"github.com/Azure/azure-sdk-for-go/storage"
    11  	"github.com/Azure/go-autorest/autorest"
    12  	"github.com/Azure/go-autorest/autorest/adal"
    13  	"github.com/Azure/go-autorest/autorest/azure"
    14  	"github.com/hashicorp/terraform/backend"
    15  	"github.com/hashicorp/terraform/helper/acctest"
    16  )
    17  
    18  // verify that we are doing ACC tests or the Azure tests specifically
    19  func testACC(t *testing.T) {
    20  	skip := os.Getenv("TF_ACC") == "" && os.Getenv("TF_AZURE_TEST") == ""
    21  	if skip {
    22  		t.Log("azure backend tests require setting TF_ACC or TF_AZURE_TEST")
    23  		t.Skip()
    24  	}
    25  }
    26  
    27  func TestBackend_impl(t *testing.T) {
    28  	var _ backend.Backend = new(Backend)
    29  }
    30  
    31  func TestBackendConfig(t *testing.T) {
    32  	// This test just instantiates the client. Shouldn't make any actual
    33  	// requests nor incur any costs.
    34  
    35  	config := map[string]interface{}{
    36  		"storage_account_name": "tfaccount",
    37  		"container_name":       "tfcontainer",
    38  		"key":                  "state",
    39  		// Access Key must be Base64
    40  		"access_key": "QUNDRVNTX0tFWQ0K",
    41  	}
    42  
    43  	b := backend.TestBackendConfig(t, New(), config).(*Backend)
    44  
    45  	if b.containerName != "tfcontainer" {
    46  		t.Fatalf("Incorrect bucketName was populated")
    47  	}
    48  	if b.keyName != "state" {
    49  		t.Fatalf("Incorrect keyName was populated")
    50  	}
    51  }
    52  
    53  func TestBackend(t *testing.T) {
    54  	testACC(t)
    55  
    56  	keyName := "testState"
    57  	res := setupResources(t, keyName)
    58  	defer destroyResources(t, res.resourceGroupName)
    59  
    60  	b := backend.TestBackendConfig(t, New(), map[string]interface{}{
    61  		"storage_account_name": res.storageAccountName,
    62  		"container_name":       res.containerName,
    63  		"key":                  keyName,
    64  		"access_key":           res.accessKey,
    65  	}).(*Backend)
    66  
    67  	backend.TestBackendStates(t, b)
    68  }
    69  
    70  func TestBackendLocked(t *testing.T) {
    71  	testACC(t)
    72  
    73  	keyName := "testState"
    74  	res := setupResources(t, keyName)
    75  	defer destroyResources(t, res.resourceGroupName)
    76  
    77  	b1 := backend.TestBackendConfig(t, New(), map[string]interface{}{
    78  		"storage_account_name": res.storageAccountName,
    79  		"container_name":       res.containerName,
    80  		"key":                  keyName,
    81  		"access_key":           res.accessKey,
    82  	}).(*Backend)
    83  
    84  	b2 := backend.TestBackendConfig(t, New(), map[string]interface{}{
    85  		"storage_account_name": res.storageAccountName,
    86  		"container_name":       res.containerName,
    87  		"key":                  keyName,
    88  		"access_key":           res.accessKey,
    89  	}).(*Backend)
    90  
    91  	backend.TestBackendStateLocks(t, b1, b2)
    92  	backend.TestBackendStateForceUnlock(t, b1, b2)
    93  }
    94  
    95  type testResources struct {
    96  	resourceGroupName  string
    97  	storageAccountName string
    98  	containerName      string
    99  	keyName            string
   100  	accessKey          string
   101  }
   102  
   103  func setupResources(t *testing.T, keyName string) testResources {
   104  	clients := getTestClient(t)
   105  
   106  	ri := acctest.RandInt()
   107  	rs := acctest.RandString(4)
   108  	res := testResources{
   109  		resourceGroupName:  fmt.Sprintf("terraform-backend-testing-%d", ri),
   110  		storageAccountName: fmt.Sprintf("tfbackendtesting%s", rs),
   111  		containerName:      "terraform",
   112  		keyName:            keyName,
   113  	}
   114  
   115  	location := os.Getenv("ARM_LOCATION")
   116  	if location == "" {
   117  		location = "westus"
   118  	}
   119  
   120  	t.Logf("creating resource group %s", res.resourceGroupName)
   121  	_, err := clients.groupsClient.CreateOrUpdate(res.resourceGroupName, resources.Group{Location: &location})
   122  	if err != nil {
   123  		t.Fatalf("failed to create test resource group: %s", err)
   124  	}
   125  
   126  	t.Logf("creating storage account %s", res.storageAccountName)
   127  	_, createError := clients.storageAccountsClient.Create(res.resourceGroupName, res.storageAccountName, armStorage.AccountCreateParameters{
   128  		Sku: &armStorage.Sku{
   129  			Name: armStorage.StandardLRS,
   130  			Tier: armStorage.Standard,
   131  		},
   132  		Location: &location,
   133  	}, make(chan struct{}))
   134  	createErr := <-createError
   135  	if createErr != nil {
   136  		destroyResources(t, res.resourceGroupName)
   137  		t.Fatalf("failed to create test storage account: %s", err)
   138  	}
   139  
   140  	t.Log("fetching access key for storage account")
   141  	resp, err := clients.storageAccountsClient.ListKeys(res.resourceGroupName, res.storageAccountName)
   142  	if err != nil {
   143  		destroyResources(t, res.resourceGroupName)
   144  		t.Fatalf("failed to list storage account keys %s:", err)
   145  	}
   146  
   147  	keys := *resp.Keys
   148  	res.accessKey = *keys[0].Value
   149  
   150  	storageClient, err := storage.NewClient(res.storageAccountName, res.accessKey,
   151  		clients.environment.StorageEndpointSuffix, storage.DefaultAPIVersion, true)
   152  	if err != nil {
   153  		destroyResources(t, res.resourceGroupName)
   154  		t.Fatalf("failed to list storage account keys %s:", err)
   155  	}
   156  
   157  	t.Logf("creating container %s", res.containerName)
   158  	blobService := storageClient.GetBlobService()
   159  	container := blobService.GetContainerReference(res.containerName)
   160  	err = container.Create(&storage.CreateContainerOptions{})
   161  	if err != nil {
   162  		destroyResources(t, res.resourceGroupName)
   163  		t.Fatalf("failed to create storage container: %s", err)
   164  	}
   165  
   166  	return res
   167  }
   168  
   169  func destroyResources(t *testing.T, resourceGroupName string) {
   170  	warning := "WARNING: Failed to delete the test Azure resources. They may incur charges. (error was %s)"
   171  
   172  	clients := getTestClient(t)
   173  
   174  	t.Log("destroying created resources")
   175  
   176  	// destroying is simple as deleting the resource group will destroy everything else
   177  	_, deleteErr := clients.groupsClient.Delete(resourceGroupName, make(chan struct{}))
   178  	err := <-deleteErr
   179  	if err != nil {
   180  		t.Logf(warning, err)
   181  		return
   182  	}
   183  
   184  	t.Log("Azure resources destroyed")
   185  }
   186  
   187  type testClient struct {
   188  	subscriptionID        string
   189  	tenantID              string
   190  	clientID              string
   191  	clientSecret          string
   192  	environment           azure.Environment
   193  	groupsClient          resources.GroupsClient
   194  	storageAccountsClient armStorage.AccountsClient
   195  }
   196  
   197  func getTestClient(t *testing.T) testClient {
   198  	client := testClient{
   199  		subscriptionID: os.Getenv("ARM_SUBSCRIPTION_ID"),
   200  		tenantID:       os.Getenv("ARM_TENANT_ID"),
   201  		clientID:       os.Getenv("ARM_CLIENT_ID"),
   202  		clientSecret:   os.Getenv("ARM_CLIENT_SECRET"),
   203  	}
   204  
   205  	if client.subscriptionID == "" || client.tenantID == "" || client.clientID == "" || client.clientSecret == "" {
   206  		t.Fatal("Azure credentials missing or incomplete")
   207  	}
   208  
   209  	env, err := getAzureEnvironment(os.Getenv("ARM_ENVIRONMENT"))
   210  	if err != nil {
   211  		t.Fatalf("Failed to detect Azure environment from ARM_ENVIRONMENT value: %s", os.Getenv("ARM_ENVIRONMENT"))
   212  	}
   213  	client.environment = env
   214  
   215  	oauthConfig, err := adal.NewOAuthConfig(env.ActiveDirectoryEndpoint, client.tenantID)
   216  	if err != nil {
   217  		t.Fatalf("Failed to get OAuth config: %s", err)
   218  	}
   219  
   220  	spt, err := adal.NewServicePrincipalToken(*oauthConfig, client.clientID, client.clientSecret, env.ResourceManagerEndpoint)
   221  	if err != nil {
   222  		t.Fatalf("Failed to create Service Principal Token: %s", err)
   223  	}
   224  
   225  	client.groupsClient = resources.NewGroupsClientWithBaseURI(env.ResourceManagerEndpoint, client.subscriptionID)
   226  	client.groupsClient.Authorizer = autorest.NewBearerAuthorizer(spt)
   227  
   228  	client.storageAccountsClient = armStorage.NewAccountsClientWithBaseURI(env.ResourceManagerEndpoint, client.subscriptionID)
   229  	client.storageAccountsClient.Authorizer = autorest.NewBearerAuthorizer(spt)
   230  
   231  	return client
   232  }