github.com/paybyphone/terraform@v0.9.5-0.20170613192930-9706042ddd51/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 containerReference := azureClient.blobClient.GetContainerReference(azureClient.containerName) 71 blobReference := containerReference.GetBlobReference(azureClient.keyName) 72 73 // put empty blob so we can acquire lease against it 74 options := &mainStorage.PutBlobOptions{} 75 err = blobReference.CreateBlockBlob(options) 76 if err != nil { 77 t.Fatalf("Error creating blob for leasing: %v", err) 78 } 79 80 leaseOptions := &mainStorage.LeaseOptions{} 81 _, err = blobReference.AcquireLease(-1, leaseID, leaseOptions) 82 if err != nil { 83 t.Fatalf("Error acquiring lease: %v", err) 84 } 85 86 // no need to release lease as blob is deleted in testing 87 testClient(t, client) 88 } 89 90 func getAzureConfig(t *testing.T) map[string]string { 91 config := map[string]string{ 92 "arm_subscription_id": os.Getenv("ARM_SUBSCRIPTION_ID"), 93 "arm_client_id": os.Getenv("ARM_CLIENT_ID"), 94 "arm_client_secret": os.Getenv("ARM_CLIENT_SECRET"), 95 "arm_tenant_id": os.Getenv("ARM_TENANT_ID"), 96 "environment": os.Getenv("ARM_ENVIRONMENT"), 97 } 98 99 for k, v := range config { 100 if v == "" { 101 t.Skipf("skipping; %s must be set", strings.ToUpper(k)) 102 } 103 } 104 105 rs := acctest.RandString(8) 106 107 config["resource_group_name"] = fmt.Sprintf("terraform-%s", rs) 108 config["storage_account_name"] = fmt.Sprintf("terraform%s", rs) 109 config["container_name"] = "terraform" 110 config["key"] = "test.tfstate" 111 112 return config 113 } 114 115 func setup(t *testing.T, conf map[string]string) { 116 env, err := getAzureEnvironmentFromConf(conf) 117 if err != nil { 118 t.Fatalf("Error getting Azure environment from conf: %v", err) 119 } 120 creds, err := getCredentialsFromConf(conf, env) 121 if err != nil { 122 t.Fatalf("Error getting credentials from conf: %v", err) 123 } 124 rivieraClient, err := getRivieraClient(creds) 125 if err != nil { 126 t.Fatalf("Error instantiating the riviera client: %v", err) 127 } 128 129 // Create resource group 130 r := rivieraClient.NewRequest() 131 r.Command = riviera.CreateResourceGroup{ 132 Name: conf["resource_group_name"], 133 Location: riviera.WestUS, 134 } 135 response, err := r.Execute() 136 if err != nil { 137 t.Fatalf("Error creating a resource group: %v", err) 138 } 139 if !response.IsSuccessful() { 140 t.Fatalf("Error creating a resource group: %v", response.Error.Error()) 141 } 142 143 // Create storage account 144 r = rivieraClient.NewRequest() 145 r.Command = storage.CreateStorageAccount{ 146 ResourceGroupName: conf["resource_group_name"], 147 Name: conf["storage_account_name"], 148 AccountType: riviera.String("Standard_LRS"), 149 Location: riviera.WestUS, 150 } 151 response, err = r.Execute() 152 if err != nil { 153 t.Fatalf("Error creating a storage account: %v", err) 154 } 155 if !response.IsSuccessful() { 156 t.Fatalf("Error creating a storage account: %v", response.Error.Error()) 157 } 158 159 // Create container 160 accessKey, err := getStorageAccountAccessKey(conf, conf["resource_group_name"], conf["storage_account_name"], env) 161 if err != nil { 162 t.Fatalf("Error creating a storage account: %v", err) 163 } 164 storageClient, err := mainStorage.NewClient(conf["storage_account_name"], accessKey, env.StorageEndpointSuffix, 165 mainStorage.DefaultAPIVersion, true) 166 if err != nil { 167 t.Fatalf("Error creating storage client for storage account %q: %s", conf["storage_account_name"], err) 168 } 169 blobClient := storageClient.GetBlobService() 170 containerName := conf["container_name"] 171 containerReference := blobClient.GetContainerReference(containerName) 172 options := &mainStorage.CreateContainerOptions{ 173 Access: mainStorage.ContainerAccessTypePrivate, 174 } 175 _, err = containerReference.CreateIfNotExists(options) 176 if err != nil { 177 t.Fatalf("Couldn't create container with name %s: %s.", conf["container_name"], err) 178 } 179 } 180 181 func teardown(t *testing.T, conf map[string]string) { 182 env, err := getAzureEnvironmentFromConf(conf) 183 if err != nil { 184 t.Fatalf("Error getting Azure environment from conf: %v", err) 185 } 186 creds, err := getCredentialsFromConf(conf, env) 187 if err != nil { 188 t.Fatalf("Error getting credentials from conf: %v", err) 189 } 190 rivieraClient, err := getRivieraClient(creds) 191 if err != nil { 192 t.Fatalf("Error instantiating the riviera client: %v", err) 193 } 194 195 r := rivieraClient.NewRequest() 196 r.Command = riviera.DeleteResourceGroup{ 197 Name: conf["resource_group_name"], 198 } 199 response, err := r.Execute() 200 if err != nil { 201 t.Fatalf("Error deleting the resource group: %v", err) 202 } 203 if !response.IsSuccessful() { 204 t.Fatalf("Error deleting the resource group: %v", err) 205 } 206 } 207 208 func getRivieraClient(credentials *riviera.AzureResourceManagerCredentials) (*riviera.Client, error) { 209 rivieraClient, err := riviera.NewClient(credentials) 210 if err != nil { 211 return nil, fmt.Errorf("Error creating Riviera client: %s", err) 212 } 213 214 request := rivieraClient.NewRequest() 215 request.Command = riviera.RegisterResourceProvider{ 216 Namespace: "Microsoft.Storage", 217 } 218 219 response, err := request.Execute() 220 if err != nil { 221 return nil, fmt.Errorf("Cannot request provider registration for Azure Resource Manager: %s.", err) 222 } 223 224 if !response.IsSuccessful() { 225 return nil, fmt.Errorf("Credentials for acessing the Azure Resource Manager API are likely " + 226 "to be incorrect, or\n the service principal does not have permission to use " + 227 "the Azure Service Management\n API.") 228 } 229 230 return rivieraClient, nil 231 }