From 68da0390b7943ae86f38b55d14e000bf8bbc8946 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Thu, 17 Aug 2017 12:57:53 -0400 Subject: [PATCH] remove legacy azure remote state code The implementation has been moved to a backend. --- state/remote/azure.go | 235 ------------------------------------- state/remote/azure_test.go | 231 ------------------------------------ 2 files changed, 466 deletions(-) delete mode 100644 state/remote/azure.go delete mode 100644 state/remote/azure_test.go diff --git a/state/remote/azure.go b/state/remote/azure.go deleted file mode 100644 index ee30eb007..000000000 --- a/state/remote/azure.go +++ /dev/null @@ -1,235 +0,0 @@ -package remote - -import ( - "bytes" - "fmt" - "io/ioutil" - "os" - - "github.com/Azure/azure-sdk-for-go/arm/storage" - mainStorage "github.com/Azure/azure-sdk-for-go/storage" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/adal" - "github.com/Azure/go-autorest/autorest/azure" - riviera "github.com/jen20/riviera/azure" -) - -func azureFactory(conf map[string]string) (Client, error) { - storageAccountName, ok := conf["storage_account_name"] - if !ok { - return nil, fmt.Errorf("missing 'storage_account_name' configuration") - } - containerName, ok := conf["container_name"] - if !ok { - return nil, fmt.Errorf("missing 'container_name' configuration") - } - keyName, ok := conf["key"] - if !ok { - return nil, fmt.Errorf("missing 'key' configuration") - } - - env, err := getAzureEnvironmentFromConf(conf) - if err != nil { - return nil, err - } - - accessKey, ok := confOrEnv(conf, "access_key", "ARM_ACCESS_KEY") - if !ok { - resourceGroupName, ok := conf["resource_group_name"] - if !ok { - return nil, fmt.Errorf("missing 'resource_group_name' configuration") - } - - var err error - accessKey, err = getStorageAccountAccessKey(conf, resourceGroupName, storageAccountName, env) - if err != nil { - return nil, fmt.Errorf("Couldn't read access key from storage account: %s.", err) - } - } - - storageClient, err := mainStorage.NewClient(storageAccountName, accessKey, env.StorageEndpointSuffix, - mainStorage.DefaultAPIVersion, true) - if err != nil { - return nil, fmt.Errorf("Error creating storage client for storage account %q: %s", storageAccountName, err) - } - - blobClient := storageClient.GetBlobService() - leaseID, _ := confOrEnv(conf, "lease_id", "ARM_LEASE_ID") - - return &AzureClient{ - blobClient: &blobClient, - containerName: containerName, - keyName: keyName, - leaseID: leaseID, - }, nil -} - -func getStorageAccountAccessKey(conf map[string]string, resourceGroupName, storageAccountName string, env azure.Environment) (string, error) { - creds, err := getCredentialsFromConf(conf, env) - if err != nil { - return "", err - } - - oauthConfig, err := adal.NewOAuthConfig(env.ActiveDirectoryEndpoint, creds.TenantID) - if err != nil { - return "", err - } - if oauthConfig == nil { - return "", fmt.Errorf("Unable to configure OAuthConfig for tenant %s", creds.TenantID) - } - - spt, err := adal.NewServicePrincipalToken(*oauthConfig, creds.ClientID, creds.ClientSecret, env.ResourceManagerEndpoint) - if err != nil { - return "", err - } - - accountsClient := storage.NewAccountsClientWithBaseURI(env.ResourceManagerEndpoint, creds.SubscriptionID) - accountsClient.Authorizer = autorest.NewBearerAuthorizer(spt) - - keys, err := accountsClient.ListKeys(resourceGroupName, storageAccountName) - if err != nil { - return "", fmt.Errorf("Error retrieving keys for storage account %q: %s", storageAccountName, err) - } - - if keys.Keys == nil { - return "", fmt.Errorf("Nil key returned for storage account %q", storageAccountName) - } - - accessKeys := *keys.Keys - return *accessKeys[0].Value, nil -} - -func getCredentialsFromConf(conf map[string]string, env azure.Environment) (*riviera.AzureResourceManagerCredentials, error) { - subscriptionID, ok := confOrEnv(conf, "arm_subscription_id", "ARM_SUBSCRIPTION_ID") - if !ok { - return nil, fmt.Errorf("missing 'arm_subscription_id' configuration") - } - clientID, ok := confOrEnv(conf, "arm_client_id", "ARM_CLIENT_ID") - if !ok { - return nil, fmt.Errorf("missing 'arm_client_id' configuration") - } - clientSecret, ok := confOrEnv(conf, "arm_client_secret", "ARM_CLIENT_SECRET") - if !ok { - return nil, fmt.Errorf("missing 'arm_client_secret' configuration") - } - tenantID, ok := confOrEnv(conf, "arm_tenant_id", "ARM_TENANT_ID") - if !ok { - return nil, fmt.Errorf("missing 'arm_tenant_id' configuration") - } - - return &riviera.AzureResourceManagerCredentials{ - SubscriptionID: subscriptionID, - ClientID: clientID, - ClientSecret: clientSecret, - TenantID: tenantID, - ActiveDirectoryEndpoint: env.ActiveDirectoryEndpoint, - ResourceManagerEndpoint: env.ResourceManagerEndpoint, - }, nil -} - -func getAzureEnvironmentFromConf(conf map[string]string) (azure.Environment, error) { - envName, ok := confOrEnv(conf, "environment", "ARM_ENVIRONMENT") - if !ok { - return azure.PublicCloud, nil - } - - env, err := azure.EnvironmentFromName(envName) - if err != nil { - // try again with wrapped value to support readable values like german instead of AZUREGERMANCLOUD - var innerErr error - env, innerErr = azure.EnvironmentFromName(fmt.Sprintf("AZURE%sCLOUD", envName)) - if innerErr != nil { - return env, fmt.Errorf("invalid 'environment' configuration: %s", err) - } - } - - return env, nil -} - -func confOrEnv(conf map[string]string, confKey, envVar string) (string, bool) { - value, ok := conf[confKey] - if ok { - return value, true - } - - value = os.Getenv(envVar) - - return value, value != "" -} - -type AzureClient struct { - blobClient *mainStorage.BlobStorageClient - containerName string - keyName string - leaseID string -} - -func (c *AzureClient) Get() (*Payload, error) { - containerReference := c.blobClient.GetContainerReference(c.containerName) - blobReference := containerReference.GetBlobReference(c.keyName) - options := &mainStorage.GetBlobOptions{} - blob, err := blobReference.Get(options) - if err != nil { - if storErr, ok := err.(mainStorage.AzureStorageServiceError); ok { - if storErr.Code == "BlobNotFound" { - return nil, nil - } - } - return nil, err - } - - defer blob.Close() - - data, err := ioutil.ReadAll(blob) - if err != nil { - return nil, err - } - - payload := &Payload{ - Data: data, - } - - // If there was no data, then return nil - if len(payload.Data) == 0 { - return nil, nil - } - - return payload, nil -} - -func (c *AzureClient) Put(data []byte) error { - setOptions := &mainStorage.SetBlobPropertiesOptions{} - putOptions := &mainStorage.PutBlobOptions{} - - containerReference := c.blobClient.GetContainerReference(c.containerName) - blobReference := containerReference.GetBlobReference(c.keyName) - - blobReference.Properties.ContentType = "application/json" - blobReference.Properties.ContentLength = int64(len(data)) - - if c.leaseID != "" { - setOptions.LeaseID = c.leaseID - putOptions.LeaseID = c.leaseID - } - - reader := bytes.NewReader(data) - - err := blobReference.CreateBlockBlobFromReader(reader, putOptions) - if err != nil { - return err - } - - return blobReference.SetProperties(setOptions) -} - -func (c *AzureClient) Delete() error { - containerReference := c.blobClient.GetContainerReference(c.containerName) - blobReference := containerReference.GetBlobReference(c.keyName) - options := &mainStorage.DeleteBlobOptions{} - - if c.leaseID != "" { - options.LeaseID = c.leaseID - } - - return blobReference.Delete(options) -} diff --git a/state/remote/azure_test.go b/state/remote/azure_test.go deleted file mode 100644 index 599f090c3..000000000 --- a/state/remote/azure_test.go +++ /dev/null @@ -1,231 +0,0 @@ -package remote - -import ( - "fmt" - "os" - "strings" - "testing" - - mainStorage "github.com/Azure/azure-sdk-for-go/storage" - "github.com/hashicorp/terraform/helper/acctest" - riviera "github.com/jen20/riviera/azure" - "github.com/jen20/riviera/storage" - "github.com/satori/uuid" -) - -func TestAzureClient_impl(t *testing.T) { - var _ Client = new(AzureClient) -} - -// This test creates a bucket in Azure and populates it. -// It may incur costs, so it will only run if Azure credential environment -// variables are present. -func TestAzureClient(t *testing.T) { - config := getAzureConfig(t) - - setup(t, config) - defer teardown(t, config) - - client, err := azureFactory(config) - if err != nil { - t.Fatalf("Error for valid config: %v", err) - } - - testClient(t, client) -} - -// This test is the same as TestAzureClient with the addition of passing an -// empty string in the lease_id, we expect the client to pass tests -func TestAzureClientEmptyLease(t *testing.T) { - config := getAzureConfig(t) - config["lease_id"] = "" - - setup(t, config) - defer teardown(t, config) - - client, err := azureFactory(config) - if err != nil { - t.Fatalf("Error for valid config: %v", err) - } - - testClient(t, client) -} - -// This test is the same as TestAzureClient with the addition of using the -// lease_id config option -func TestAzureClientLease(t *testing.T) { - leaseID := uuid.NewV4().String() - config := getAzureConfig(t) - config["lease_id"] = leaseID - - setup(t, config) - defer teardown(t, config) - - client, err := azureFactory(config) - if err != nil { - t.Fatalf("Error for valid config: %v", err) - } - azureClient := client.(*AzureClient) - - containerReference := azureClient.blobClient.GetContainerReference(azureClient.containerName) - blobReference := containerReference.GetBlobReference(azureClient.keyName) - - // put empty blob so we can acquire lease against it - options := &mainStorage.PutBlobOptions{} - err = blobReference.CreateBlockBlob(options) - if err != nil { - t.Fatalf("Error creating blob for leasing: %v", err) - } - - leaseOptions := &mainStorage.LeaseOptions{} - _, err = blobReference.AcquireLease(-1, leaseID, leaseOptions) - if err != nil { - t.Fatalf("Error acquiring lease: %v", err) - } - - // no need to release lease as blob is deleted in testing - testClient(t, client) -} - -func getAzureConfig(t *testing.T) map[string]string { - config := map[string]string{ - "arm_subscription_id": os.Getenv("ARM_SUBSCRIPTION_ID"), - "arm_client_id": os.Getenv("ARM_CLIENT_ID"), - "arm_client_secret": os.Getenv("ARM_CLIENT_SECRET"), - "arm_tenant_id": os.Getenv("ARM_TENANT_ID"), - "environment": os.Getenv("ARM_ENVIRONMENT"), - } - - for k, v := range config { - if v == "" { - t.Skipf("skipping; %s must be set", strings.ToUpper(k)) - } - } - - rs := acctest.RandString(8) - - config["resource_group_name"] = fmt.Sprintf("terraform-%s", rs) - config["storage_account_name"] = fmt.Sprintf("terraform%s", rs) - config["container_name"] = "terraform" - config["key"] = "test.tfstate" - - return config -} - -func setup(t *testing.T, conf map[string]string) { - env, err := getAzureEnvironmentFromConf(conf) - if err != nil { - t.Fatalf("Error getting Azure environment from conf: %v", err) - } - creds, err := getCredentialsFromConf(conf, env) - if err != nil { - t.Fatalf("Error getting credentials from conf: %v", err) - } - rivieraClient, err := getRivieraClient(creds) - if err != nil { - t.Fatalf("Error instantiating the riviera client: %v", err) - } - - // Create resource group - r := rivieraClient.NewRequest() - r.Command = riviera.CreateResourceGroup{ - Name: conf["resource_group_name"], - Location: riviera.WestUS, - } - response, err := r.Execute() - if err != nil { - t.Fatalf("Error creating a resource group: %v", err) - } - if !response.IsSuccessful() { - t.Fatalf("Error creating a resource group: %v", response.Error.Error()) - } - - // Create storage account - r = rivieraClient.NewRequest() - r.Command = storage.CreateStorageAccount{ - ResourceGroupName: conf["resource_group_name"], - Name: conf["storage_account_name"], - AccountType: riviera.String("Standard_LRS"), - Location: riviera.WestUS, - } - response, err = r.Execute() - if err != nil { - t.Fatalf("Error creating a storage account: %v", err) - } - if !response.IsSuccessful() { - t.Fatalf("Error creating a storage account: %v", response.Error.Error()) - } - - // Create container - accessKey, err := getStorageAccountAccessKey(conf, conf["resource_group_name"], conf["storage_account_name"], env) - if err != nil { - t.Fatalf("Error creating a storage account: %v", err) - } - storageClient, err := mainStorage.NewClient(conf["storage_account_name"], accessKey, env.StorageEndpointSuffix, - mainStorage.DefaultAPIVersion, true) - if err != nil { - t.Fatalf("Error creating storage client for storage account %q: %s", conf["storage_account_name"], err) - } - blobClient := storageClient.GetBlobService() - containerName := conf["container_name"] - containerReference := blobClient.GetContainerReference(containerName) - options := &mainStorage.CreateContainerOptions{ - Access: mainStorage.ContainerAccessTypePrivate, - } - _, err = containerReference.CreateIfNotExists(options) - if err != nil { - t.Fatalf("Couldn't create container with name %s: %s.", conf["container_name"], err) - } -} - -func teardown(t *testing.T, conf map[string]string) { - env, err := getAzureEnvironmentFromConf(conf) - if err != nil { - t.Fatalf("Error getting Azure environment from conf: %v", err) - } - creds, err := getCredentialsFromConf(conf, env) - if err != nil { - t.Fatalf("Error getting credentials from conf: %v", err) - } - rivieraClient, err := getRivieraClient(creds) - if err != nil { - t.Fatalf("Error instantiating the riviera client: %v", err) - } - - r := rivieraClient.NewRequest() - r.Command = riviera.DeleteResourceGroup{ - Name: conf["resource_group_name"], - } - response, err := r.Execute() - if err != nil { - t.Fatalf("Error deleting the resource group: %v", err) - } - if !response.IsSuccessful() { - t.Fatalf("Error deleting the resource group: %v", err) - } -} - -func getRivieraClient(credentials *riviera.AzureResourceManagerCredentials) (*riviera.Client, error) { - rivieraClient, err := riviera.NewClient(credentials) - if err != nil { - return nil, fmt.Errorf("Error creating Riviera client: %s", err) - } - - request := rivieraClient.NewRequest() - request.Command = riviera.RegisterResourceProvider{ - Namespace: "Microsoft.Storage", - } - - response, err := request.Execute() - if err != nil { - return nil, fmt.Errorf("Cannot request provider registration for Azure Resource Manager: %s.", err) - } - - if !response.IsSuccessful() { - return nil, fmt.Errorf("Credentials for acessing the Azure Resource Manager API are likely " + - "to be incorrect, or\n the service principal does not have permission to use " + - "the Azure Service Management\n API.") - } - - return rivieraClient, nil -}