From 562cbe3862ee601e2b0da0165e8f6892c41c0958 Mon Sep 17 00:00:00 2001 From: Eliise S Date: Wed, 17 Jun 2020 15:31:50 +0100 Subject: [PATCH 01/18] Use new workspace_url format + fix azure test Co-authored-by: Lawrence.Gripper@microsoft.com --- .devcontainer/devcontainer.json | 21 ++--- Makefile | 2 +- databricks/azure_auth.go | 52 +++--------- databricks/provider.go | 15 ++++ ...e_databricks_azure_adls_gen2_mount_test.go | 26 ++---- ...source_databricks_azure_blob_mount_test.go | 28 +------ .../resource_databricks_job_aws_test.go | 80 +++++++++---------- .../resource_databricks_job_azure_test.go | 48 +++++------ examples/simple-azure-tf-deployment/main.tf | 1 + integration-environment-azure/prereqs.tf | 8 +- integration-environment-azure/run.sh | 15 ++-- website/content/Provider/_index.md | 7 ++ 12 files changed, 134 insertions(+), 169 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 4d1b2ae293..f9aff16b68 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,6 +3,14 @@ { "name": "databricks-terraform", "dockerFile": "Dockerfile", + "mounts": [ + // Mount go mod cache + "source=databricks-terraform-gomodcache,target=/go/pkg,type=volume", + // Keep command history + "source=databricks-terraform-bashhistory,target=/commandhistory,type=volume", + // Mount docker socket for docker builds + "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind", + ], "runArgs": [ // Uncomment the next line to use a non-root user. On Linux, this will prevent // new files getting created as root, but you may need to update the USER_UID @@ -12,14 +20,8 @@ "--security-opt", "seccomp=unconfined", "--privileged", - - "--name", "databricks-terraform-devcontainer", - // Mount go mod cache - "-v", "databricks-terraform-gomodcache:/go/pkg", - // Keep command history - "-v", "databricks-terraform-bashhistory:/root/commandhistory", - // Mount docker socket for docker builds - "-v", "/var/run/docker.sock:/var/run/docker.sock", + "--name", + "databricks-terraform-devcontainer", // Use host network "--network=host", ], @@ -51,8 +53,9 @@ // "postCreateCommand": "go version", // Add the IDs of extensions you want installed when the container is created in the array below. "extensions": [ - "ms-vscode.go", + "golang.go", "mauve.terraform", + "hashicorp.terraform", "ms-vsliveshare.vsliveshare" ] } \ No newline at end of file diff --git a/Makefile b/Makefile index 9ae41145b0..0ca8a4a313 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ vendor: # INTEGRATION TESTING WITH AZURE terraform-acc-azure: fmt @echo "==> Running Terraform Acceptance Tests for Azure..." - @CLOUD_ENV="azure" TF_ACC=1 gotestsum --format short-verbose --raw-command go test -v -json -tags=azure -short -coverprofile=coverage.out ./... + @/bin/bash integration-environment-azure/run.sh # INTEGRATION TESTING WITH AWS terraform-acc-aws: fmt diff --git a/databricks/azure_auth.go b/databricks/azure_auth.go index 4b8685f716..a933ab7c55 100644 --- a/databricks/azure_auth.go +++ b/databricks/azure_auth.go @@ -3,12 +3,12 @@ package databricks import ( "encoding/json" "fmt" + "log" + "net/http" + "github.com/Azure/go-autorest/autorest/adal" "github.com/Azure/go-autorest/autorest/azure" "github.com/databrickslabs/databricks-terraform/client/service" - "log" - "net/http" - urlParse "net/url" ) // List of management information @@ -23,6 +23,7 @@ type AzureAuth struct { AdbWorkspaceResourceID string AdbAccessToken string AdbPlatformToken string + AdbWorkspaceUrl string } // TokenPayload contains all the auth information for azure sp authentication @@ -73,38 +74,6 @@ func (a *AzureAuth) getManagementToken(config *service.DBApiClientConfig) error return nil } -func (a *AzureAuth) getWorkspaceID(config *service.DBApiClientConfig) error { - log.Println("[DEBUG] Getting Workspace ID via management token.") - // Escape all the ids - url := fmt.Sprintf("https://management.azure.com/subscriptions/%s/resourceGroups/%s"+ - "/providers/Microsoft.Databricks/workspaces/%s", - urlParse.PathEscape(a.TokenPayload.SubscriptionID), - urlParse.PathEscape(a.TokenPayload.ResourceGroup), - urlParse.PathEscape(a.TokenPayload.WorkspaceName)) - headers := map[string]string{ - "Content-Type": "application/json", - "cache-control": "no-cache", - "Authorization": "Bearer " + a.ManagementToken, - } - type apiVersion struct { - ApiVersion string `url:"api-version"` - } - uriPayload := apiVersion{ - ApiVersion: "2018-04-01", - } - var responseMap map[string]interface{} - resp, err := service.PerformQuery(config, http.MethodGet, url, "2.0", headers, false, true, uriPayload, nil) - if err != nil { - return err - } - err = json.Unmarshal(resp, &responseMap) - if err != nil { - return err - } - a.AdbWorkspaceResourceID = responseMap["id"].(string) - return err -} - func (a *AzureAuth) getADBPlatformToken(clientConfig *service.DBApiClientConfig) error { log.Println("[DEBUG] Creating Azure Databricks management OAuth token.") platformTokenOAuthCfg, err := adal.NewOAuthConfigWithAPIVersion(azure.PublicCloud.ActiveDirectoryEndpoint, @@ -177,11 +146,11 @@ func (a *AzureAuth) initWorkspaceAndGetClient(config *service.DBApiClientConfig) return err } - // Get workspace access token - err = a.getWorkspaceID(config) - if err != nil { - return err - } + a.AdbWorkspaceResourceID = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s"+ + "/providers/Microsoft.Databricks/workspaces/%s", + a.TokenPayload.SubscriptionID, + a.TokenPayload.ResourceGroup, + a.TokenPayload.WorkspaceName) // Get platform token err = a.getADBPlatformToken(config) @@ -195,8 +164,7 @@ func (a *AzureAuth) initWorkspaceAndGetClient(config *service.DBApiClientConfig) return err } - //// TODO: Eventually change this to include new Databricks domain names. May have to add new vars and/or deprecate existing args. - config.Host = "https://" + a.TokenPayload.AzureRegion + ".azuredatabricks.net" + config.Host = a.AdbWorkspaceUrl config.Token = a.AdbAccessToken return nil diff --git a/databricks/provider.go b/databricks/provider.go index 1d1680bd1c..11a63c8a14 100644 --- a/databricks/provider.go +++ b/databricks/provider.go @@ -119,6 +119,11 @@ func Provider(version string) terraform.ResourceProvider { Required: true, DefaultFunc: schema.EnvDefaultFunc("DATABRICKS_AZURE_WORKSPACE_NAME", nil), }, + "workspace_url": { + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("DATABRICKS_AZURE_WORKSPACE_URL", nil), + }, "resource_group": { Type: schema.TypeString, Required: true, @@ -169,6 +174,8 @@ func providerConfigureAzureClient(d *schema.ResourceData, providerVersion string azureAuthMap := azureAuth.(map[string]interface{}) //azureAuth AzureAuth{} tokenPayload := TokenPayload{} + adbWorkspaceURL := "" + // The if else is required for the reason that "azure_auth" schema object is not a block but a map // Maps do not inherently auto populate defaults from environment variables unless we explicitly assign values // This makes it very difficult to test @@ -192,6 +199,12 @@ func providerConfigureAzureClient(d *schema.ResourceData, providerVersion string } else if os.Getenv("DATABRICKS_AZURE_WORKSPACE_NAME") != "" { tokenPayload.WorkspaceName = os.Getenv("DATABRICKS_AZURE_WORKSPACE_NAME") } + // TODO: Can required field not be set? + if workspaceURL, ok := azureAuthMap["workspace_url"].(string); ok { + adbWorkspaceURL = workspaceURL + } else if os.Getenv("DATABRICKS_AZURE_WORKSPACE_URL") != "" { + adbWorkspaceURL = os.Getenv("DATABRICKS_AZURE_WORKSPACE_URL") + } // This provider takes DATABRICKS_AZURE_* for client ID etc // The azurerm provider uses ARM_* for the same values @@ -228,12 +241,14 @@ func providerConfigureAzureClient(d *schema.ResourceData, providerVersion string tokenPayload.TenantID = os.Getenv("ARM_TENANT_ID") } + adbWorkspaceURL = "https://" + adbWorkspaceURL azureAuthSetup := AzureAuth{ TokenPayload: &tokenPayload, ManagementToken: "", AdbWorkspaceResourceID: "", AdbAccessToken: "", AdbPlatformToken: "", + AdbWorkspaceUrl: adbWorkspaceURL, } // Setup the CustomAuthorizer Function to be called at API invoke rather than client invoke diff --git a/databricks/resource_databricks_azure_adls_gen2_mount_test.go b/databricks/resource_databricks_azure_adls_gen2_mount_test.go index 964b267021..05bb8e0c7e 100644 --- a/databricks/resource_databricks_azure_adls_gen2_mount_test.go +++ b/databricks/resource_databricks_azure_adls_gen2_mount_test.go @@ -42,34 +42,18 @@ func testAccAzureAdlsGen2Mount_correctly_mounts() string { clientID := os.Getenv("ARM_CLIENT_ID") clientSecret := os.Getenv("ARM_CLIENT_SECRET") tenantID := os.Getenv("ARM_TENANT_ID") - subscriptionID := os.Getenv("ARM_SUBSCRIPTION_ID") - workspaceName := os.Getenv("TEST_WORKSPACE_NAME") - resourceGroupName := os.Getenv("TEST_RESOURCE_GROUP") - managedResourceGroupName := os.Getenv("TEST_MANAGED_RESOURCE_GROUP") - location := os.Getenv("TEST_LOCATION") gen2AdalName := os.Getenv("TEST_GEN2_ADAL_NAME") definition := fmt.Sprintf(` - provider "databricks" { - azure_auth = { - client_id = "%[1]s" - client_secret = "%[2]s" - tenant_id = "%[3]s" - subscription_id = "%[4]s" - - workspace_name = "%[5]s" - resource_group = "%[6]s" - managed_resource_group = "%[7]s" - azure_region = "%[8]s" - } - } - resource "databricks_cluster" "cluster" { num_workers = 1 spark_version = "6.4.x-scala2.11" node_type_id = "Standard_D3_v2" # Don't spend too much, turn off cluster after 15mins autotermination_minutes = 15 + spark_conf = { + "spark.databricks.delta.preview.enabled": "false" + } } resource "databricks_secret_scope" "terraform" { @@ -88,7 +72,7 @@ func testAccAzureAdlsGen2Mount_correctly_mounts() string { resource "databricks_azure_adls_gen2_mount" "mount" { cluster_id = databricks_cluster.cluster.id container_name = "dev" # Created by prereqs.tf - storage_account_name = "%[9]s" + storage_account_name = "%[4]s" directory = "" mount_name = "localdir${databricks_cluster.cluster.cluster_id}" tenant_id = "%[3]s" @@ -98,7 +82,7 @@ func testAccAzureAdlsGen2Mount_correctly_mounts() string { initialize_file_system = true } -`, clientID, clientSecret, tenantID, subscriptionID, workspaceName, resourceGroupName, managedResourceGroupName, location, gen2AdalName) +`, clientID, clientSecret, tenantID, gen2AdalName) return definition } diff --git a/databricks/resource_databricks_azure_blob_mount_test.go b/databricks/resource_databricks_azure_blob_mount_test.go index afcf66389c..fc714d9fcc 100644 --- a/databricks/resource_databricks_azure_blob_mount_test.go +++ b/databricks/resource_databricks_azure_blob_mount_test.go @@ -97,32 +97,10 @@ func testAccAzureBlobMount_mount_exists(n string, azureBlobMount *AzureBlobMount } func testAccAzureBlobMount_correctly_mounts() string { - clientID := os.Getenv("ARM_CLIENT_ID") - clientSecret := os.Getenv("ARM_CLIENT_SECRET") - tenantID := os.Getenv("ARM_TENANT_ID") - subscriptionID := os.Getenv("ARM_SUBSCRIPTION_ID") - workspaceName := os.Getenv("TEST_WORKSPACE_NAME") - resourceGroupName := os.Getenv("TEST_RESOURCE_GROUP") - managedResourceGroupName := os.Getenv("TEST_MANAGED_RESOURCE_GROUP") - location := os.Getenv("TEST_LOCATION") blobAccountKey := os.Getenv("TEST_STORAGE_ACCOUNT_KEY") blobAccountName := os.Getenv("TEST_STORAGE_ACCOUNT_NAME") definition := fmt.Sprintf(` - provider "databricks" { - azure_auth = { - client_id = "%[1]s" - client_secret = "%[2]s" - tenant_id = "%[3]s" - subscription_id = "%[4]s" - - workspace_name = "%[5]s" - resource_group = "%[6]s" - managed_resource_group = "%[7]s" - azure_region = "%[8]s" - } - } - resource "databricks_cluster" "cluster" { num_workers = 1 spark_version = "6.4.x-scala2.11" @@ -140,20 +118,20 @@ func testAccAzureBlobMount_correctly_mounts() string { resource "databricks_secret" "storage_key" { key = "blob_storage_key" - string_value = "%[10]s" + string_value = "%[1]s" scope = databricks_secret_scope.terraform.name } resource "databricks_azure_blob_mount" "mount" { cluster_id = databricks_cluster.cluster.id container_name = "dev" # Created by prereqs.tf - storage_account_name = "%[9]s" + storage_account_name = "%[2]s" mount_name = "dev" auth_type = "ACCESS_KEY" token_secret_scope = databricks_secret_scope.terraform.name token_secret_key = databricks_secret.storage_key.key } -`, clientID, clientSecret, tenantID, subscriptionID, workspaceName, resourceGroupName, managedResourceGroupName, location, blobAccountName, blobAccountKey) +`, blobAccountKey, blobAccountName) return definition } diff --git a/databricks/resource_databricks_job_aws_test.go b/databricks/resource_databricks_job_aws_test.go index 011b89db7d..01f35467de 100644 --- a/databricks/resource_databricks_job_aws_test.go +++ b/databricks/resource_databricks_job_aws_test.go @@ -95,49 +95,49 @@ func testAwsJobValuesNewCluster(t *testing.T, job *model.Job) resource.TestCheck assert.NotNil(t, job.Settings.NotebookTask) assert.Equal(t, 2, int(job.Settings.NewCluster.Autoscale.MinWorkers)) assert.Equal(t, 3, int(job.Settings.NewCluster.Autoscale.MaxWorkers)) - assert.Equal(t, "6.4.x-scala2.11", job.Settings.NewCluster.SparkVersion) - assert.Equal(t, model.AwsAvailability(model.AwsAvailabilitySpot), job.Settings.NewCluster.AwsAttributes.Availability) - assert.Equal(t, "us-east-1a", job.Settings.NewCluster.AwsAttributes.ZoneID) - assert.Equal(t, 100, int(job.Settings.NewCluster.AwsAttributes.SpotBidPricePercent)) - assert.Equal(t, 1, int(job.Settings.NewCluster.AwsAttributes.FirstOnDemand)) - assert.Equal(t, model.EbsVolumeType(model.EbsVolumeTypeGeneralPurposeSsd), job.Settings.NewCluster.AwsAttributes.EbsVolumeType) - assert.Equal(t, 1, int(job.Settings.NewCluster.AwsAttributes.EbsVolumeCount)) - assert.Equal(t, 32, int(job.Settings.NewCluster.AwsAttributes.EbsVolumeSize)) - assert.Equal(t, "r3.xlarge", job.Settings.NewCluster.NodeTypeID) - assert.Equal(t, "/Users/jane.doe@databricks.com/my-demo-notebook", job.Settings.NotebookTask.NotebookPath) - assert.Equal(t, "my-demo-notebook", job.Settings.Name) - assert.Equal(t, 3600, int(job.Settings.TimeoutSeconds)) - assert.Equal(t, 1, int(job.Settings.MaxRetries)) - assert.Equal(t, 1, int(job.Settings.MaxConcurrentRuns)) + assert.Equal(t, "6.4.x-scala2.11", job.Settings.NewCluster.SparkVersion) + assert.Equal(t, model.AwsAvailability(model.AwsAvailabilitySpot), job.Settings.NewCluster.AwsAttributes.Availability) + assert.Equal(t, "us-east-1a", job.Settings.NewCluster.AwsAttributes.ZoneID) + assert.Equal(t, 100, int(job.Settings.NewCluster.AwsAttributes.SpotBidPricePercent)) + assert.Equal(t, 1, int(job.Settings.NewCluster.AwsAttributes.FirstOnDemand)) + assert.Equal(t, model.EbsVolumeType(model.EbsVolumeTypeGeneralPurposeSsd), job.Settings.NewCluster.AwsAttributes.EbsVolumeType) + assert.Equal(t, 1, int(job.Settings.NewCluster.AwsAttributes.EbsVolumeCount)) + assert.Equal(t, 32, int(job.Settings.NewCluster.AwsAttributes.EbsVolumeSize)) + assert.Equal(t, "r3.xlarge", job.Settings.NewCluster.NodeTypeID) + assert.Equal(t, "/Users/jane.doe@databricks.com/my-demo-notebook", job.Settings.NotebookTask.NotebookPath) + assert.Equal(t, "my-demo-notebook", job.Settings.Name) + assert.Equal(t, 3600, int(job.Settings.TimeoutSeconds)) + assert.Equal(t, 1, int(job.Settings.MaxRetries)) + assert.Equal(t, 1, int(job.Settings.MaxConcurrentRuns)) return nil } } func testAwsJobResourceNewCluster() string { - return fmt.Sprintf(` - resource "databricks_job" "my_job" { - new_cluster { - autoscale { - min_workers = 2 - max_workers = 3 - } - spark_version = "6.4.x-scala2.11" - aws_attributes { - availability = "SPOT" - zone_id = "us-east-1a" - spot_bid_price_percent = "100" - first_on_demand = 1 - ebs_volume_type = "GENERAL_PURPOSE_SSD" - ebs_volume_count = 1 - ebs_volume_size = 32 - } - node_type_id = "r3.xlarge" - } - notebook_path = "/Users/jane.doe@databricks.com/my-demo-notebook" - name = "my-demo-notebook" - timeout_seconds = 3600 - max_retries = 1 - max_concurrent_runs = 1 - } - `) + return ` + resource "databricks_job" "my_job" { + new_cluster { + autoscale { + min_workers = 2 + max_workers = 3 + } + spark_version = "6.4.x-scala2.11" + aws_attributes { + availability = "SPOT" + zone_id = "us-east-1a" + spot_bid_price_percent = "100" + first_on_demand = 1 + ebs_volume_type = "GENERAL_PURPOSE_SSD" + ebs_volume_count = 1 + ebs_volume_size = 32 + } + node_type_id = "r3.xlarge" + } + notebook_path = "/Users/jane.doe@databricks.com/my-demo-notebook" + name = "my-demo-notebook" + timeout_seconds = 3600 + max_retries = 1 + max_concurrent_runs = 1 + } + ` } diff --git a/databricks/resource_databricks_job_azure_test.go b/databricks/resource_databricks_job_azure_test.go index 5347063fd4..07ed4ced4c 100644 --- a/databricks/resource_databricks_job_azure_test.go +++ b/databricks/resource_databricks_job_azure_test.go @@ -94,33 +94,33 @@ func testAzureJobValuesNewCluster(t *testing.T, job *model.Job) resource.TestChe assert.NotNil(t, job.Settings.NotebookTask) assert.Equal(t, 2, int(job.Settings.NewCluster.Autoscale.MinWorkers)) assert.Equal(t, 3, int(job.Settings.NewCluster.Autoscale.MaxWorkers)) - assert.Equal(t, "6.4.x-scala2.11", job.Settings.NewCluster.SparkVersion) - assert.Equal(t, "Standard_DS3_v2", job.Settings.NewCluster.NodeTypeID) - assert.Equal(t, "/Users/jane.doe@databricks.com/my-demo-notebook", job.Settings.NotebookTask.NotebookPath) - assert.Equal(t, "my-demo-notebook", job.Settings.Name) - assert.Equal(t, 3600, int(job.Settings.TimeoutSeconds)) - assert.Equal(t, 1, int(job.Settings.MaxRetries)) - assert.Equal(t, 1, int(job.Settings.MaxConcurrentRuns)) + assert.Equal(t, "6.4.x-scala2.11", job.Settings.NewCluster.SparkVersion) + assert.Equal(t, "Standard_DS3_v2", job.Settings.NewCluster.NodeTypeID) + assert.Equal(t, "/Users/jane.doe@databricks.com/my-demo-notebook", job.Settings.NotebookTask.NotebookPath) + assert.Equal(t, "my-demo-notebook", job.Settings.Name) + assert.Equal(t, 3600, int(job.Settings.TimeoutSeconds)) + assert.Equal(t, 1, int(job.Settings.MaxRetries)) + assert.Equal(t, 1, int(job.Settings.MaxConcurrentRuns)) return nil } } func testAzureJobResourceNewCluster() string { - return fmt.Sprintf(` - resource "databricks_job" "my_job" { - new_cluster { - autoscale { - min_workers = 2 - max_workers = 3 - } - spark_version = "6.4.x-scala2.11" - node_type_id = "Standard_DS3_v2" - } - notebook_path = "/Users/jane.doe@databricks.com/my-demo-notebook" - name = "my-demo-notebook" - timeout_seconds = 3600 - max_retries = 1 - max_concurrent_runs = 1 - } - `) + return ` + resource "databricks_job" "my_job" { + new_cluster { + autoscale { + min_workers = 2 + max_workers = 3 + } + spark_version = "6.4.x-scala2.11" + node_type_id = "Standard_DS3_v2" + } + notebook_path = "/Users/jane.doe@databricks.com/my-demo-notebook" + name = "my-demo-notebook" + timeout_seconds = 3600 + max_retries = 1 + max_concurrent_runs = 1 + } + ` } diff --git a/examples/simple-azure-tf-deployment/main.tf b/examples/simple-azure-tf-deployment/main.tf index b6b8ef4bbf..4b313f9f5a 100644 --- a/examples/simple-azure-tf-deployment/main.tf +++ b/examples/simple-azure-tf-deployment/main.tf @@ -46,6 +46,7 @@ provider "databricks" { azure_region = azurerm_databricks_workspace.demo_test_workspace.location workspace_name = azurerm_databricks_workspace.demo_test_workspace.name resource_group = azurerm_databricks_workspace.demo_test_workspace.resource_group_name + workspace_url = azurerm_databricks_workspace.demo_test_workspace.workspace_url client_id = var.client_id client_secret = var.client_secret tenant_id = var.tenant_id diff --git a/integration-environment-azure/prereqs.tf b/integration-environment-azure/prereqs.tf index 18a9823007..0ca027c511 100644 --- a/integration-environment-azure/prereqs.tf +++ b/integration-environment-azure/prereqs.tf @@ -1,5 +1,5 @@ provider "azurerm" { - version = "~> 2.3" + version = "~> 2.14" features {} } @@ -22,7 +22,7 @@ resource "azurerm_databricks_workspace" "example" { name = "workspace${random_string.naming.result}" resource_group_name = azurerm_resource_group.example.name location = azurerm_resource_group.example.location - sku = "standard" + sku = "premium" managed_resource_group_name = "workspace${random_string.naming.result}" } @@ -77,6 +77,10 @@ output "workspace_name" { value = azurerm_databricks_workspace.example.name } +output "workspace_url" { + value = azurerm_databricks_workspace.example.workspace_url +} + output "gen2_adal_name" { value = azurerm_storage_account.adlsaccount.name } diff --git a/integration-environment-azure/run.sh b/integration-environment-azure/run.sh index adc9d5e6ac..714d11a049 100755 --- a/integration-environment-azure/run.sh +++ b/integration-environment-azure/run.sh @@ -32,16 +32,21 @@ fi terraform init terraform apply -auto-approve -export TEST_RESOURCE_GROUP=$(terraform output rg_name) -export TEST_WORKSPACE_NAME=$(terraform output workspace_name) +export CLOUD_ENV="azure" export TEST_GEN2_ADAL_NAME=$(terraform output gen2_adal_name) -export TEST_MANAGED_RESOURCE_GROUP=$(terraform output workspace_managed_rg_name) -export TEST_LOCATION=$(terraform output location) export TEST_STORAGE_ACCOUNT_KEY=$(terraform output blob_storage_key) export TEST_STORAGE_ACCOUNT_NAME=$(terraform output blob_storage_name) +export DATABRICKS_AZURE_WORKSPACE_NAME=$(terraform output workspace_name) +export DATABRICKS_AZURE_RESOURCE_GROUP=$(terraform output rg_name) +export DATABRICKS_AZURE_WORKSPACE_URL=$(terraform output workspace_url) +export AZURE_REGION=$(terraform output location) +export DATABRICKS_AZURE_MANAGED_RESOURCE_GROUP=$(terraform output workspace_managed_rg_name) + echo -e "----> Running Azure Acceptance Tests \n\n" # Output debug log to file while tests run export TF_LOG_PATH=$PWD/tf.log # Run all Azure integration tests -TF_LOG=debug TF_ACC=1 gotestsum --format short-verbose --raw-command go test -v -json -short -coverprofile=coverage.out -test.timeout 35m -run 'TestAccAzure' ./../... \ No newline at end of file +TF_LOG=debug TF_ACC=1 gotestsum --format short-verbose --raw-command \ + go test -v -json -short -coverprofile=coverage.out \ + -test.timeout 35m -run 'TestAccAzure' ./../... \ No newline at end of file diff --git a/website/content/Provider/_index.md b/website/content/Provider/_index.md index c57622e31e..5ff6b8522f 100644 --- a/website/content/Provider/_index.md +++ b/website/content/Provider/_index.md @@ -78,6 +78,7 @@ provider "databricks" { managed_resource_group = azurerm_databricks_workspace.demo_test_workspace.managed_resource_group_name azure_region = azurerm_databricks_workspace.demo_test_workspace.location workspace_name = azurerm_databricks_workspace.demo_test_workspace.name + workspace_url = azurerm_databricks_workspace.demo_test_workspace.workspace_url resource_group = azurerm_databricks_workspace.demo_test_workspace.resource_group_name client_id = var.client_id client_secret = var.client_secret @@ -137,6 +138,7 @@ provider "databricks" { managed_resource_group = "${azurerm_databricks_workspace.sri_test_workspace.managed_resource_group_name}" azure_region = "${azurerm_databricks_workspace.sri_test_workspace.location}" workspace_name = "${azurerm_databricks_workspace.sri_test_workspace.name}" + workspace_url = "${azurerm_databricks_workspace.sri_test_workspace.workspace_url}" resource_group = "${azurerm_databricks_workspace.sri_test_workspace.resource_group_name}" client_id = "${var.client_id}" client_secret = "${var.client_secret}" @@ -158,6 +160,7 @@ The following variables can be passed via environment variables: * `managed_resource_group` → `DATABRICKS_AZURE_MANAGED_RESOURCE_GROUP` * `azure_region` → `AZURE_REGION` * `workspace_name` → `DATABRICKS_AZURE_WORKSPACE_NAME` +* `workspace_url` → `DATABRICKS_AZURE_WORKSPACE_URL` * `resource_group` → `DATABRICKS_AZURE_RESOURCE_GROUP` * `subscription_id` → `DATABRICKS_AZURE_SUBSCRIPTION_ID` or `ARM_SUBSCRIPTION_ID` * `client_secret` → `DATABRICKS_AZURE_CLIENT_SECRET` or `ARM_CLIENT_SECRET` @@ -228,6 +231,7 @@ Alternatively you can provide this value as an environment variable `DATABRICKS_ > azure_region = "centralus" > managed_resource_group = "my-databricks-managed-rg" > workspace_name = "test-managed-workspace" +> workspace_url = "adb-somenumber.19.azuredatabricks.net" > resource_group = "1-test-rg" > client_id = var.client_id > client_secret = var.client_secret @@ -248,6 +252,9 @@ Alternatively you can provide this value as an environment variable `AZURE_REGIO * `workspace_name` - This is the name of your Azure Databricks Workspace. Alternatively you can provide this value as an environment variable `DATABRICKS_AZURE_WORKSPACE_NAME`. +* `workspace_url` - This is the URL of the Azure Databricks Workspace API. +Alternatively you can provide this value as an environment variable `DATABRICKS_AZURE_WORKSPACE_URL`. + * `resource_group` - This is the resource group in which your Azure Databricks Workspace resides in. Alternatively you can provide this value as an environment variable `DATABRICKS_AZURE_RESOURCE_GROUP`. From 1667062089c997ccc764b96ccef9b19d2791e553 Mon Sep 17 00:00:00 2001 From: Eliise S Date: Wed, 17 Jun 2020 16:48:14 +0100 Subject: [PATCH 02/18] Fix tests --- databricks/azure_auth.go | 7 +++---- databricks/resource_databricks_azure_blob_mount_test.go | 3 +++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/databricks/azure_auth.go b/databricks/azure_auth.go index a933ab7c55..3f202e56af 100644 --- a/databricks/azure_auth.go +++ b/databricks/azure_auth.go @@ -101,9 +101,9 @@ func (a *AzureAuth) getADBPlatformToken(clientConfig *service.DBApiClientConfig) func (a *AzureAuth) getWorkspaceAccessToken(config *service.DBApiClientConfig) error { log.Println("[DEBUG] Creating workspace token") - apiLifeTimeInSeconds := int32(600) + apiLifeTimeInSeconds := int32(3600) comment := "Secret made via SP" - url := "https://" + a.TokenPayload.AzureRegion + ".azuredatabricks.net/api/2.0/token/create" + url := a.AdbWorkspaceUrl + "/api/2.0/token/create" payload := struct { LifetimeSeconds int32 `json:"lifetime_seconds,omitempty"` Comment string `json:"comment,omitempty"` @@ -146,8 +146,7 @@ func (a *AzureAuth) initWorkspaceAndGetClient(config *service.DBApiClientConfig) return err } - a.AdbWorkspaceResourceID = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s"+ - "/providers/Microsoft.Databricks/workspaces/%s", + a.AdbWorkspaceResourceID = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Databricks/workspaces/%s", a.TokenPayload.SubscriptionID, a.TokenPayload.ResourceGroup, a.TokenPayload.WorkspaceName) diff --git a/databricks/resource_databricks_azure_blob_mount_test.go b/databricks/resource_databricks_azure_blob_mount_test.go index fc714d9fcc..7bcb792a06 100644 --- a/databricks/resource_databricks_azure_blob_mount_test.go +++ b/databricks/resource_databricks_azure_blob_mount_test.go @@ -107,6 +107,9 @@ func testAccAzureBlobMount_correctly_mounts() string { node_type_id = "Standard_D3_v2" # Don't spend too much, turn off cluster after 15mins autotermination_minutes = 15 + spark_conf = { + "spark.databricks.delta.preview.enabled": "false" + } } resource "databricks_secret_scope" "terraform" { From 0b1132e59cbc912cab523f2a6217008acbb6bc34 Mon Sep 17 00:00:00 2001 From: Eliise S Date: Wed, 17 Jun 2020 17:22:50 +0100 Subject: [PATCH 03/18] Make logging optional --- integration-environment-azure/run.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/integration-environment-azure/run.sh b/integration-environment-azure/run.sh index 714d11a049..9290da395b 100755 --- a/integration-environment-azure/run.sh +++ b/integration-environment-azure/run.sh @@ -29,6 +29,13 @@ then rm -f *.tfstate fi +if [ -n "$TEST_LOG_LEVEL" ] +then + export TF_LOG=$TEST_LOG_LEVEL + # Output debug log to file while tests run + export TF_LOG_PATH=$PWD/tf.log +fi + terraform init terraform apply -auto-approve @@ -44,9 +51,8 @@ export AZURE_REGION=$(terraform output location) export DATABRICKS_AZURE_MANAGED_RESOURCE_GROUP=$(terraform output workspace_managed_rg_name) echo -e "----> Running Azure Acceptance Tests \n\n" -# Output debug log to file while tests run -export TF_LOG_PATH=$PWD/tf.log + # Run all Azure integration tests -TF_LOG=debug TF_ACC=1 gotestsum --format short-verbose --raw-command \ +TF_ACC=1 gotestsum --format short-verbose --raw-command \ go test -v -json -short -coverprofile=coverage.out \ -test.timeout 35m -run 'TestAccAzure' ./../... \ No newline at end of file From 88537ca8e4ba569246f4aa033d9421916040081b Mon Sep 17 00:00:00 2001 From: Eliise S Date: Wed, 17 Jun 2020 17:27:30 +0100 Subject: [PATCH 04/18] Remove comment --- databricks/provider.go | 1 - 1 file changed, 1 deletion(-) diff --git a/databricks/provider.go b/databricks/provider.go index 11a63c8a14..51be205972 100644 --- a/databricks/provider.go +++ b/databricks/provider.go @@ -199,7 +199,6 @@ func providerConfigureAzureClient(d *schema.ResourceData, providerVersion string } else if os.Getenv("DATABRICKS_AZURE_WORKSPACE_NAME") != "" { tokenPayload.WorkspaceName = os.Getenv("DATABRICKS_AZURE_WORKSPACE_NAME") } - // TODO: Can required field not be set? if workspaceURL, ok := azureAuthMap["workspace_url"].(string); ok { adbWorkspaceURL = workspaceURL } else if os.Getenv("DATABRICKS_AZURE_WORKSPACE_URL") != "" { From 1dd56328ba3c15fb8ba0ccb6a4b4b0b778e888b1 Mon Sep 17 00:00:00 2001 From: Eliise S Date: Wed, 17 Jun 2020 17:28:11 +0100 Subject: [PATCH 05/18] Add spaces Like a maniac --- databricks/provider.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/databricks/provider.go b/databricks/provider.go index 51be205972..76c29d9240 100644 --- a/databricks/provider.go +++ b/databricks/provider.go @@ -184,21 +184,25 @@ func providerConfigureAzureClient(d *schema.ResourceData, providerVersion string } else if os.Getenv("DATABRICKS_AZURE_MANAGED_RESOURCE_GROUP") != "" { tokenPayload.ManagedResourceGroup = os.Getenv("DATABRICKS_AZURE_MANAGED_RESOURCE_GROUP") } + if azureRegion, ok := azureAuthMap["azure_region"].(string); ok { tokenPayload.AzureRegion = azureRegion } else if os.Getenv("AZURE_REGION") != "" { tokenPayload.AzureRegion = os.Getenv("AZURE_REGION") } + if resourceGroup, ok := azureAuthMap["resource_group"].(string); ok { tokenPayload.ResourceGroup = resourceGroup } else if os.Getenv("DATABRICKS_AZURE_RESOURCE_GROUP") != "" { tokenPayload.ResourceGroup = os.Getenv("DATABRICKS_AZURE_RESOURCE_GROUP") } + if workspaceName, ok := azureAuthMap["workspace_name"].(string); ok { tokenPayload.WorkspaceName = workspaceName } else if os.Getenv("DATABRICKS_AZURE_WORKSPACE_NAME") != "" { tokenPayload.WorkspaceName = os.Getenv("DATABRICKS_AZURE_WORKSPACE_NAME") } + if workspaceURL, ok := azureAuthMap["workspace_url"].(string); ok { adbWorkspaceURL = workspaceURL } else if os.Getenv("DATABRICKS_AZURE_WORKSPACE_URL") != "" { @@ -218,6 +222,7 @@ func providerConfigureAzureClient(d *schema.ResourceData, providerVersion string } else if os.Getenv("ARM_SUBSCRIPTION_ID") != "" { tokenPayload.SubscriptionID = os.Getenv("ARM_SUBSCRIPTION_ID") } + if clientSecret, ok := azureAuthMap["client_secret"].(string); ok { tokenPayload.ClientSecret = clientSecret } else if os.Getenv("DATABRICKS_AZURE_CLIENT_SECRET") != "" { @@ -225,6 +230,7 @@ func providerConfigureAzureClient(d *schema.ResourceData, providerVersion string } else if os.Getenv("ARM_CLIENT_SECRET") != "" { tokenPayload.ClientSecret = os.Getenv("ARM_CLIENT_SECRET") } + if clientID, ok := azureAuthMap["client_id"].(string); ok { tokenPayload.ClientID = clientID } else if os.Getenv("DATABRICKS_AZURE_CLIENT_ID") != "" { @@ -232,6 +238,7 @@ func providerConfigureAzureClient(d *schema.ResourceData, providerVersion string } else if os.Getenv("ARM_CLIENT_ID") != "" { tokenPayload.ClientID = os.Getenv("ARM_CLIENT_ID") } + if tenantID, ok := azureAuthMap["tenant_id"].(string); ok { tokenPayload.TenantID = tenantID } else if os.Getenv("DATABRICKS_AZURE_TENANT_ID") != "" { From 422ba1b6b7bba0a3f42f77f679599ad5e4efdfbb Mon Sep 17 00:00:00 2001 From: Eliise S Date: Wed, 17 Jun 2020 18:45:30 +0100 Subject: [PATCH 06/18] Fix fmt and fmt code --- .devcontainer/Dockerfile | 4 +++- databricks/azure_auth.go | 1 - databricks/provider.go | 8 ++++---- go.sum | 1 + 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 84d8a374af..e3ef342463 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -37,7 +37,9 @@ RUN \ # --> Delve for debugging go get github.com/go-delve/delve/cmd/dlv@v1.3.2 \ # --> Go language server - && go get golang.org/x/tools/gopls@v0.2.1 \ + && go get golang.org/x/tools/gopls@v0.4.1 \ + # --> Goimports + && go get golang.org/x/tools/cmd/goimports \ # --> Gotestsum && go get gotest.tools/gotestsum@v0.4.2 \ # --> Go symbols and outline for go to symbol support and test support diff --git a/databricks/azure_auth.go b/databricks/azure_auth.go index 86dc4844e9..dfa05e712b 100644 --- a/databricks/azure_auth.go +++ b/databricks/azure_auth.go @@ -5,7 +5,6 @@ import ( "fmt" "log" "net/http" - urlParse "net/url" "github.com/Azure/go-autorest/autorest/adal" "github.com/Azure/go-autorest/autorest/azure" diff --git a/databricks/provider.go b/databricks/provider.go index ef304e2969..8cea4cb5e2 100644 --- a/databricks/provider.go +++ b/databricks/provider.go @@ -188,25 +188,25 @@ func providerConfigureAzureClient(d *schema.ResourceData, config *service.DBApiC } else if os.Getenv("DATABRICKS_AZURE_MANAGED_RESOURCE_GROUP") != "" { tokenPayload.ManagedResourceGroup = os.Getenv("DATABRICKS_AZURE_MANAGED_RESOURCE_GROUP") } - + if azureRegion, ok := azureAuthMap["azure_region"].(string); ok { tokenPayload.AzureRegion = azureRegion } else if os.Getenv("AZURE_REGION") != "" { tokenPayload.AzureRegion = os.Getenv("AZURE_REGION") } - + if resourceGroup, ok := azureAuthMap["resource_group"].(string); ok { tokenPayload.ResourceGroup = resourceGroup } else if os.Getenv("DATABRICKS_AZURE_RESOURCE_GROUP") != "" { tokenPayload.ResourceGroup = os.Getenv("DATABRICKS_AZURE_RESOURCE_GROUP") } - + if workspaceName, ok := azureAuthMap["workspace_name"].(string); ok { tokenPayload.WorkspaceName = workspaceName } else if os.Getenv("DATABRICKS_AZURE_WORKSPACE_NAME") != "" { tokenPayload.WorkspaceName = os.Getenv("DATABRICKS_AZURE_WORKSPACE_NAME") } - + if workspaceURL, ok := azureAuthMap["workspace_url"].(string); ok { adbWorkspaceURL = workspaceURL } else if os.Getenv("DATABRICKS_AZURE_WORKSPACE_URL") != "" { diff --git a/go.sum b/go.sum index 9c2ba2e717..db15d0be11 100644 --- a/go.sum +++ b/go.sum @@ -328,6 +328,7 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= From 944cf904ba40ea47c4811b46ecb81dca40722274 Mon Sep 17 00:00:00 2001 From: Eliise S Date: Thu, 18 Jun 2020 10:33:58 +0000 Subject: [PATCH 07/18] Add local install make command --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index d3f8e30a3f..9a8bf75a1b 100644 --- a/Makefile +++ b/Makefile @@ -48,6 +48,9 @@ vendor: @echo "==> Filling vendor folder with library code..." @go mod vendor +local-install: + @/bin/bash godownloader-databricks-provider.sh -b $HOME/.terraform.d/plugins + # INTEGRATION TESTING WITH AZURE terraform-acc-azure: lint @echo "==> Running Terraform Acceptance Tests for Azure..." From 7a4129e7785f822c0d6aeb8bda2a270d6f889e9d Mon Sep 17 00:00:00 2001 From: Eliise S Date: Thu, 18 Jun 2020 11:44:43 +0000 Subject: [PATCH 08/18] Make local install use repo build Co-authored-by: Lawrence Gripper --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 9a8bf75a1b..1965ba6d0d 100644 --- a/Makefile +++ b/Makefile @@ -48,8 +48,8 @@ vendor: @echo "==> Filling vendor folder with library code..." @go mod vendor -local-install: - @/bin/bash godownloader-databricks-provider.sh -b $HOME/.terraform.d/plugins +local-install: build + mv terraform-provider-databricks $(HOME)/.terraform.d/plugins/terraform-provider-databricks_v0.2.0 # INTEGRATION TESTING WITH AZURE terraform-acc-azure: lint From a34fd1b85898ef4b0d91b08ed6668f9d011c12f1 Mon Sep 17 00:00:00 2001 From: Eliise S Date: Mon, 22 Jun 2020 16:34:31 +0000 Subject: [PATCH 09/18] Remove redudant azure_auth --- ...esource_databricks_azure_adls_gen2_mount_test.go | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/databricks/resource_databricks_azure_adls_gen2_mount_test.go b/databricks/resource_databricks_azure_adls_gen2_mount_test.go index 6a08bea2b4..d212863556 100644 --- a/databricks/resource_databricks_azure_adls_gen2_mount_test.go +++ b/databricks/resource_databricks_azure_adls_gen2_mount_test.go @@ -125,19 +125,6 @@ func testAccAzureAdlsGen2MountCaptureError() string { gen2AdalName := os.Getenv("TEST_GEN2_ADAL_NAME") definition := fmt.Sprintf(` - provider "databricks" { - azure_auth = { - client_id = "%[1]s" - client_secret = "%[2]s" - tenant_id = "%[3]s" - subscription_id = "%[4]s" - - workspace_name = "%[5]s" - resource_group = "%[6]s" - managed_resource_group = "%[7]s" - azure_region = "%[8]s" - } - } resource "databricks_cluster" "cluster" { num_workers = 1 From 5eee662d04ea106583ae260ea015e2826f13acb0 Mon Sep 17 00:00:00 2001 From: Eliise S Date: Tue, 23 Jun 2020 11:12:52 +0000 Subject: [PATCH 10/18] Get workspace url from azure managment api --- databricks/azure_auth.go | 155 +++++++++++++++++++++++----------- databricks/azure_auth_test.go | 27 +++--- databricks/provider.go | 25 +----- 3 files changed, 119 insertions(+), 88 deletions(-) diff --git a/databricks/azure_auth.go b/databricks/azure_auth.go index dfa05e712b..7e3135fe4c 100644 --- a/databricks/azure_auth.go +++ b/databricks/azure_auth.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "net/http" + "time" "github.com/Azure/go-autorest/autorest/adal" "github.com/Azure/go-autorest/autorest/azure" @@ -16,16 +17,6 @@ const ( ADBResourceID string = "2ff814a6-3304-4ab8-85cb-cd0e6f879c1d" ) -// AzureAuth is a struct that contains information about the azure sp authentication -type AzureAuth struct { - TokenPayload *TokenPayload - ManagementToken string - AdbWorkspaceResourceID string - AdbAccessToken string - AdbPlatformToken string - AdbWorkspaceUrl string -} - // TokenPayload contains all the auth information for azure sp authentication type TokenPayload struct { ManagedResourceGroup string @@ -38,6 +29,39 @@ type TokenPayload struct { TenantID string } +type Workspace struct { + Name string `json:"name"` + ID string `json:"id"` + Type string `json:"type"` + Sku struct { + Name string `json:"name"` + } `json:"sku"` + Location string `json:"location"` + Properties struct { + ManagedResourceGroupID string `json:"managedResourceGroupId"` + Parameters interface{} `json:"parameters"` + ProvisioningState string `json:"provisioningState"` + UIDefinitionURI string `json:"uiDefinitionUri"` + Authorizations []struct { + PrincipalID string `json:"principalId"` + RoleDefinitionID string `json:"roleDefinitionId"` + } `json:"authorizations"` + CreatedBy struct { + Oid string `json:"oid"` + Puid string `json:"puid"` + ApplicationID string `json:"applicationId"` + } `json:"createdBy"` + UpdatedBy struct { + Oid string `json:"oid"` + Puid string `json:"puid"` + ApplicationID string `json:"applicationId"` + } `json:"updatedBy"` + CreatedDateTime time.Time `json:"createdDateTime"` + WorkspaceID string `json:"workspaceId"` + WorkspaceURL string `json:"workspaceUrl"` + } `json:"properties"` +} + // WsProps contains information about the workspace properties type WsProps struct { ManagedResourceGroupID string `json:"managedResourceGroupId"` @@ -50,60 +74,91 @@ type WorkspaceRequest struct { Location string `json:"location"` } -func (a *AzureAuth) getManagementToken() error { +func (t *TokenPayload) getManagementToken() (*string, error) { log.Println("[DEBUG] Creating Azure Databricks management OAuth token.") mgmtTokenOAuthCfg, err := adal.NewOAuthConfigWithAPIVersion(azure.PublicCloud.ActiveDirectoryEndpoint, - a.TokenPayload.TenantID, + t.TenantID, nil) if err != nil { - return err + return nil, err } mgmtToken, err := adal.NewServicePrincipalToken( *mgmtTokenOAuthCfg, - a.TokenPayload.ClientID, - a.TokenPayload.ClientSecret, + t.ClientID, + t.ClientSecret, azure.PublicCloud.ServiceManagementEndpoint) if err != nil { - return err + return nil, err } err = mgmtToken.Refresh() if err != nil { - return err + return nil, err } - a.ManagementToken = mgmtToken.OAuthToken() - return nil + token := mgmtToken.OAuthToken() + + return &token, nil } -func (a *AzureAuth) getADBPlatformToken() error { +func (t *TokenPayload) getWorkspace(config *service.DBApiClientConfig, managementToken *string) (*Workspace, error) { + log.Println("[DEBUG] Getting Workspace ID via management token.") + url := fmt.Sprintf("https://management.azure.com/subscriptions/%s/resourceGroups/%s"+ + "/providers/Microsoft.Databricks/workspaces/%s", + t.SubscriptionID, + t.ResourceGroup, + t.WorkspaceName) + headers := map[string]string{ + "Content-Type": "application/json", + "cache-control": "no-cache", + "Authorization": "Bearer " + *managementToken, + } + type apiVersion struct { + APIVersion string `url:"api-version"` + } + uriPayload := apiVersion{ + APIVersion: "2018-04-01", + } + resp, err := service.PerformQuery(config, http.MethodGet, url, "2.0", headers, false, true, uriPayload, nil) + if err != nil { + return nil, err + } + + var workspace Workspace + err = json.Unmarshal(resp, &workspace) + if err != nil { + return nil, err + } + return &workspace, err +} + +func (t *TokenPayload) getADBPlatformToken() (*string, error) { log.Println("[DEBUG] Creating Azure Databricks management OAuth token.") platformTokenOAuthCfg, err := adal.NewOAuthConfigWithAPIVersion(azure.PublicCloud.ActiveDirectoryEndpoint, - a.TokenPayload.TenantID, + t.TenantID, nil) if err != nil { - return err + return nil, err } platformToken, err := adal.NewServicePrincipalToken( *platformTokenOAuthCfg, - a.TokenPayload.ClientID, - a.TokenPayload.ClientSecret, + t.ClientID, + t.ClientSecret, ADBResourceID) if err != nil { - return err + return nil, err } err = platformToken.Refresh() if err != nil { - return err + return nil, err } - a.AdbPlatformToken = platformToken.OAuthToken() - return nil + adbPlatformToken := platformToken.OAuthToken() + return &adbPlatformToken, nil } -func (a *AzureAuth) getWorkspaceAccessToken(config *service.DBApiClientConfig) error { +func getWorkspaceAccessToken(config *service.DBApiClientConfig, managementToken, adbWorkspaceUrl, adbWorkspaceResourceID, adbPlatformToken *string) (*string, error) { log.Println("[DEBUG] Creating workspace token") apiLifeTimeInSeconds := int32(3600) comment := "Secret made via SP" - url := a.AdbWorkspaceUrl + "/api/2.0/token/create" payload := struct { LifetimeSeconds int32 `json:"lifetime_seconds,omitempty"` Comment string `json:"comment,omitempty"` @@ -113,23 +168,25 @@ func (a *AzureAuth) getWorkspaceAccessToken(config *service.DBApiClientConfig) e } headers := map[string]string{ "Content-Type": "application/x-www-form-urlencoded", - "X-Databricks-Azure-Workspace-Resource-Id": a.AdbWorkspaceResourceID, - "X-Databricks-Azure-SP-Management-Token": a.ManagementToken, + "X-Databricks-Azure-Workspace-Resource-Id": *adbWorkspaceResourceID, + "X-Databricks-Azure-SP-Management-Token": *managementToken, "cache-control": "no-cache", - "Authorization": "Bearer " + a.AdbPlatformToken, + "Authorization": "Bearer " + *adbPlatformToken, } - var responseMap map[string]interface{} + url := *adbWorkspaceUrl + "/api/2.0/token/create" resp, err := service.PerformQuery(config, http.MethodPost, url, "2.0", headers, true, true, payload, nil) if err != nil { - return err + return nil, err } + + var responseMap map[string]interface{} err = json.Unmarshal(resp, &responseMap) if err != nil { - return err + return nil, err } - a.AdbAccessToken = responseMap["token_value"].(string) - return nil + adbAccessToken := responseMap["token_value"].(string) + return &adbAccessToken, nil } // Main function call that gets made and it follows 4 steps at the moment: @@ -137,34 +194,36 @@ func (a *AzureAuth) getWorkspaceAccessToken(config *service.DBApiClientConfig) e // 2. Get Workspace ID // 3. Get Azure Databricks Platform OAuth Token using Databricks resource id // 4. Get Azure Databricks Workspace Personal Access Token for the SP (60 min duration) -func (a *AzureAuth) initWorkspaceAndGetClient(config *service.DBApiClientConfig) error { +func (t *TokenPayload) initWorkspaceAndGetClient(config *service.DBApiClientConfig) error { //var dbClient service.DBApiClient // Get management token - err := a.getManagementToken() + managementToken, err := t.getManagementToken() if err != nil { return err } - a.AdbWorkspaceResourceID = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Databricks/workspaces/%s", - a.TokenPayload.SubscriptionID, - a.TokenPayload.ResourceGroup, - a.TokenPayload.WorkspaceName) + // Get workspace access token + adbWorkspace, err := t.getWorkspace(config, managementToken) + if err != nil { + return err + } + adbWorkspaceUrl := "https://" + adbWorkspace.Properties.WorkspaceURL // Get platform token - err = a.getADBPlatformToken() + adbPlatformToken, err := t.getADBPlatformToken() if err != nil { return err } // Get workspace personal access token - err = a.getWorkspaceAccessToken(config) + workspaceAccessToken, err := getWorkspaceAccessToken(config, managementToken, &adbWorkspaceUrl, &adbWorkspace.ID, adbPlatformToken) if err != nil { return err } - config.Host = a.AdbWorkspaceUrl - config.Token = a.AdbAccessToken + config.Host = adbWorkspaceUrl + config.Token = *workspaceAccessToken return nil } diff --git a/databricks/azure_auth_test.go b/databricks/azure_auth_test.go index 11858b668a..1d64336d9f 100644 --- a/databricks/azure_auth_test.go +++ b/databricks/azure_auth_test.go @@ -20,24 +20,19 @@ func TestAzureAuthCreateApiToken(t *testing.T) { t.Skip("skipping integration test in short mode.") } - azureAuth := AzureAuth{ - TokenPayload: &TokenPayload{ - ManagedResourceGroup: os.Getenv("DATABRICKS_AZURE_MANAGED_RESOURCE_GROUP"), - AzureRegion: os.Getenv("AZURE_REGION"), - WorkspaceName: os.Getenv("DATABRICKS_AZURE_WORKSPACE_NAME"), - ResourceGroup: os.Getenv("DATABRICKS_AZURE_RESOURCE_GROUP"), - }, - ManagementToken: "", - AdbWorkspaceResourceID: "", - AdbAccessToken: "", - AdbPlatformToken: "", + tokenPayload := TokenPayload{ + ManagedResourceGroup: os.Getenv("DATABRICKS_AZURE_MANAGED_RESOURCE_GROUP"), + AzureRegion: os.Getenv("AZURE_REGION"), + WorkspaceName: os.Getenv("DATABRICKS_AZURE_WORKSPACE_NAME"), + ResourceGroup: os.Getenv("DATABRICKS_AZURE_RESOURCE_GROUP"), + SubscriptionID: os.Getenv("DATABRICKS_AZURE_SUBSCRIPTION_ID"), + TenantID: os.Getenv("DATABRICKS_AZURE_TENANT_ID"), + ClientID: os.Getenv("DATABRICKS_AZURE_CLIENT_ID"), + ClientSecret: os.Getenv("DATABRICKS_AZURE_CLIENT_SECRET"), } - azureAuth.TokenPayload.SubscriptionID = os.Getenv("DATABRICKS_AZURE_SUBSCRIPTION_ID") - azureAuth.TokenPayload.TenantID = os.Getenv("DATABRICKS_AZURE_TENANT_ID") - azureAuth.TokenPayload.ClientID = os.Getenv("DATABRICKS_AZURE_CLIENT_ID") - azureAuth.TokenPayload.ClientSecret = os.Getenv("DATABRICKS_AZURE_CLIENT_SECRET") + config := GetIntegrationDBClientOptions() - err := azureAuth.initWorkspaceAndGetClient(config) + err := tokenPayload.initWorkspaceAndGetClient(config) assert.NoError(t, err, err) api := service.DBApiClient{} api.SetConfig(config) diff --git a/databricks/provider.go b/databricks/provider.go index 8cea4cb5e2..6a2701c96e 100644 --- a/databricks/provider.go +++ b/databricks/provider.go @@ -123,11 +123,6 @@ func Provider(version string) terraform.ResourceProvider { Required: true, DefaultFunc: schema.EnvDefaultFunc("DATABRICKS_AZURE_WORKSPACE_NAME", nil), }, - "workspace_url": { - Type: schema.TypeString, - Required: true, - DefaultFunc: schema.EnvDefaultFunc("DATABRICKS_AZURE_WORKSPACE_URL", nil), - }, "resource_group": { Type: schema.TypeString, Required: true, @@ -176,9 +171,7 @@ func providerConfigureAzureClient(d *schema.ResourceData, config *service.DBApiC log.Println("Creating db client via azure auth!") azureAuth, _ := d.GetOk("azure_auth") azureAuthMap := azureAuth.(map[string]interface{}) - //azureAuth AzureAuth{} tokenPayload := TokenPayload{} - adbWorkspaceURL := "" // The if else is required for the reason that "azure_auth" schema object is not a block but a map // Maps do not inherently auto populate defaults from environment variables unless we explicitly assign values @@ -207,12 +200,6 @@ func providerConfigureAzureClient(d *schema.ResourceData, config *service.DBApiC tokenPayload.WorkspaceName = os.Getenv("DATABRICKS_AZURE_WORKSPACE_NAME") } - if workspaceURL, ok := azureAuthMap["workspace_url"].(string); ok { - adbWorkspaceURL = workspaceURL - } else if os.Getenv("DATABRICKS_AZURE_WORKSPACE_URL") != "" { - adbWorkspaceURL = os.Getenv("DATABRICKS_AZURE_WORKSPACE_URL") - } - // This provider takes DATABRICKS_AZURE_* for client ID etc // The azurerm provider uses ARM_* for the same values // To make it easier to use the two providers together we use the following sources in order: @@ -260,18 +247,8 @@ func providerConfigureAzureClient(d *schema.ResourceData, config *service.DBApiC tokenPayload.TenantID = os.Getenv("ARM_TENANT_ID") } - adbWorkspaceURL = "https://" + adbWorkspaceURL - azureAuthSetup := AzureAuth{ - TokenPayload: &tokenPayload, - ManagementToken: "", - AdbWorkspaceResourceID: "", - AdbAccessToken: "", - AdbPlatformToken: "", - AdbWorkspaceUrl: adbWorkspaceURL, - } - // Setup the CustomAuthorizer Function to be called at API invoke rather than client invoke - config.CustomAuthorizer = azureAuthSetup.initWorkspaceAndGetClient + config.CustomAuthorizer = tokenPayload.initWorkspaceAndGetClient var dbClient service.DBApiClient dbClient.SetConfig(config) return &dbClient, nil From ec6b2cb90f84a293e5033bcce62492be44e7a843 Mon Sep 17 00:00:00 2001 From: Eliise S Date: Tue, 23 Jun 2020 13:26:32 +0000 Subject: [PATCH 11/18] Update comment --- databricks/azure_auth.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/databricks/azure_auth.go b/databricks/azure_auth.go index 7e3135fe4c..16665bd111 100644 --- a/databricks/azure_auth.go +++ b/databricks/azure_auth.go @@ -191,11 +191,10 @@ func getWorkspaceAccessToken(config *service.DBApiClientConfig, managementToken, // Main function call that gets made and it follows 4 steps at the moment: // 1. Get Management OAuth Token using management endpoint -// 2. Get Workspace ID +// 2. Get Workspace ID and URL // 3. Get Azure Databricks Platform OAuth Token using Databricks resource id // 4. Get Azure Databricks Workspace Personal Access Token for the SP (60 min duration) func (t *TokenPayload) initWorkspaceAndGetClient(config *service.DBApiClientConfig) error { - //var dbClient service.DBApiClient // Get management token managementToken, err := t.getManagementToken() From 8027cc100c7735e2ff360718b19aba45dcffa165 Mon Sep 17 00:00:00 2001 From: Eliise S Date: Tue, 23 Jun 2020 13:47:30 +0000 Subject: [PATCH 12/18] Change from pointers Co-authored-by: Stuart Leeks --- databricks/azure_auth.go | 49 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/databricks/azure_auth.go b/databricks/azure_auth.go index 16665bd111..a30a3a8198 100644 --- a/databricks/azure_auth.go +++ b/databricks/azure_auth.go @@ -74,13 +74,13 @@ type WorkspaceRequest struct { Location string `json:"location"` } -func (t *TokenPayload) getManagementToken() (*string, error) { +func (t *TokenPayload) getManagementToken() (string, error) { log.Println("[DEBUG] Creating Azure Databricks management OAuth token.") mgmtTokenOAuthCfg, err := adal.NewOAuthConfigWithAPIVersion(azure.PublicCloud.ActiveDirectoryEndpoint, t.TenantID, nil) if err != nil { - return nil, err + return "", err } mgmtToken, err := adal.NewServicePrincipalToken( *mgmtTokenOAuthCfg, @@ -88,18 +88,17 @@ func (t *TokenPayload) getManagementToken() (*string, error) { t.ClientSecret, azure.PublicCloud.ServiceManagementEndpoint) if err != nil { - return nil, err + return "", err } err = mgmtToken.Refresh() if err != nil { - return nil, err + return "", err } - token := mgmtToken.OAuthToken() - return &token, nil + return mgmtToken.OAuthToken(), nil } -func (t *TokenPayload) getWorkspace(config *service.DBApiClientConfig, managementToken *string) (*Workspace, error) { +func (t *TokenPayload) getWorkspace(config *service.DBApiClientConfig, managementToken string) (*Workspace, error) { log.Println("[DEBUG] Getting Workspace ID via management token.") url := fmt.Sprintf("https://management.azure.com/subscriptions/%s/resourceGroups/%s"+ "/providers/Microsoft.Databricks/workspaces/%s", @@ -109,7 +108,7 @@ func (t *TokenPayload) getWorkspace(config *service.DBApiClientConfig, managemen headers := map[string]string{ "Content-Type": "application/json", "cache-control": "no-cache", - "Authorization": "Bearer " + *managementToken, + "Authorization": "Bearer " + managementToken, } type apiVersion struct { APIVersion string `url:"api-version"` @@ -130,13 +129,13 @@ func (t *TokenPayload) getWorkspace(config *service.DBApiClientConfig, managemen return &workspace, err } -func (t *TokenPayload) getADBPlatformToken() (*string, error) { +func (t *TokenPayload) getADBPlatformToken() (string, error) { log.Println("[DEBUG] Creating Azure Databricks management OAuth token.") platformTokenOAuthCfg, err := adal.NewOAuthConfigWithAPIVersion(azure.PublicCloud.ActiveDirectoryEndpoint, t.TenantID, nil) if err != nil { - return nil, err + return "", err } platformToken, err := adal.NewServicePrincipalToken( *platformTokenOAuthCfg, @@ -144,18 +143,18 @@ func (t *TokenPayload) getADBPlatformToken() (*string, error) { t.ClientSecret, ADBResourceID) if err != nil { - return nil, err + return "", err } err = platformToken.Refresh() if err != nil { - return nil, err + return "", err } - adbPlatformToken := platformToken.OAuthToken() - return &adbPlatformToken, nil + + return platformToken.OAuthToken(), nil } -func getWorkspaceAccessToken(config *service.DBApiClientConfig, managementToken, adbWorkspaceUrl, adbWorkspaceResourceID, adbPlatformToken *string) (*string, error) { +func getWorkspaceAccessToken(config *service.DBApiClientConfig, managementToken, adbWorkspaceUrl, adbWorkspaceResourceID, adbPlatformToken string) (string, error) { log.Println("[DEBUG] Creating workspace token") apiLifeTimeInSeconds := int32(3600) comment := "Secret made via SP" @@ -168,25 +167,25 @@ func getWorkspaceAccessToken(config *service.DBApiClientConfig, managementToken, } headers := map[string]string{ "Content-Type": "application/x-www-form-urlencoded", - "X-Databricks-Azure-Workspace-Resource-Id": *adbWorkspaceResourceID, - "X-Databricks-Azure-SP-Management-Token": *managementToken, + "X-Databricks-Azure-Workspace-Resource-Id": adbWorkspaceResourceID, + "X-Databricks-Azure-SP-Management-Token": managementToken, "cache-control": "no-cache", - "Authorization": "Bearer " + *adbPlatformToken, + "Authorization": "Bearer " + adbPlatformToken, } - url := *adbWorkspaceUrl + "/api/2.0/token/create" + url := adbWorkspaceUrl + "/api/2.0/token/create" resp, err := service.PerformQuery(config, http.MethodPost, url, "2.0", headers, true, true, payload, nil) if err != nil { - return nil, err + return "", err } var responseMap map[string]interface{} err = json.Unmarshal(resp, &responseMap) if err != nil { - return nil, err + return "", err } - adbAccessToken := responseMap["token_value"].(string) - return &adbAccessToken, nil + + return responseMap["token_value"].(string), nil } // Main function call that gets made and it follows 4 steps at the moment: @@ -216,13 +215,13 @@ func (t *TokenPayload) initWorkspaceAndGetClient(config *service.DBApiClientConf } // Get workspace personal access token - workspaceAccessToken, err := getWorkspaceAccessToken(config, managementToken, &adbWorkspaceUrl, &adbWorkspace.ID, adbPlatformToken) + workspaceAccessToken, err := getWorkspaceAccessToken(config, managementToken, adbWorkspaceUrl, adbWorkspace.ID, adbPlatformToken) if err != nil { return err } config.Host = adbWorkspaceUrl - config.Token = *workspaceAccessToken + config.Token = workspaceAccessToken return nil } From 6509d69cd8f23ad9b45bfc69a98593beafe73ae4 Mon Sep 17 00:00:00 2001 From: Eliise S Date: Tue, 23 Jun 2020 14:05:21 +0000 Subject: [PATCH 13/18] Update docs --- databricks/azure_auth.go | 1 - examples/simple-azure-tf-deployment/main.tf | 73 ++++++++++----------- integration-environment-azure/prereqs.tf | 4 -- integration-environment-azure/run.sh | 1 - website/content/Provider/_index.md | 7 -- website/content/Resources/mws_workspaces.md | 2 +- 6 files changed, 37 insertions(+), 51 deletions(-) diff --git a/databricks/azure_auth.go b/databricks/azure_auth.go index a30a3a8198..d1c1af1742 100644 --- a/databricks/azure_auth.go +++ b/databricks/azure_auth.go @@ -194,7 +194,6 @@ func getWorkspaceAccessToken(config *service.DBApiClientConfig, managementToken, // 3. Get Azure Databricks Platform OAuth Token using Databricks resource id // 4. Get Azure Databricks Workspace Personal Access Token for the SP (60 min duration) func (t *TokenPayload) initWorkspaceAndGetClient(config *service.DBApiClientConfig) error { - // Get management token managementToken, err := t.getManagementToken() if err != nil { diff --git a/examples/simple-azure-tf-deployment/main.tf b/examples/simple-azure-tf-deployment/main.tf index 4b313f9f5a..1a3d7537d5 100644 --- a/examples/simple-azure-tf-deployment/main.tf +++ b/examples/simple-azure-tf-deployment/main.tf @@ -24,18 +24,18 @@ variable "managed_resource_group_name" { } provider "azurerm" { - client_id = var.client_id - client_secret = var.client_secret - tenant_id = var.tenant_id + client_id = var.client_id + client_secret = var.client_secret + tenant_id = var.tenant_id subscription_id = var.subscription_id } resource "azurerm_databricks_workspace" "demo_test_workspace" { - location = "centralus" - name = "terraform-test-ws-6" - resource_group_name = var.resource_group + location = "centralus" + name = "terraform-test-ws-6" + resource_group_name = var.resource_group managed_resource_group_name = var.managed_resource_group_name - sku = "premium" + sku = "premium" } @@ -43,22 +43,21 @@ resource "azurerm_databricks_workspace" "demo_test_workspace" { provider "databricks" { azure_auth = { managed_resource_group = azurerm_databricks_workspace.demo_test_workspace.managed_resource_group_name - azure_region = azurerm_databricks_workspace.demo_test_workspace.location - workspace_name = azurerm_databricks_workspace.demo_test_workspace.name - resource_group = azurerm_databricks_workspace.demo_test_workspace.resource_group_name - workspace_url = azurerm_databricks_workspace.demo_test_workspace.workspace_url - client_id = var.client_id - client_secret = var.client_secret - tenant_id = var.tenant_id - subscription_id = var.subscription_id + azure_region = azurerm_databricks_workspace.demo_test_workspace.location + workspace_name = azurerm_databricks_workspace.demo_test_workspace.name + resource_group = azurerm_databricks_workspace.demo_test_workspace.resource_group_name + client_id = var.client_id + client_secret = var.client_secret + tenant_id = var.tenant_id + subscription_id = var.subscription_id } } // resource "databricks_scim_user" "my-user" { - count = 2 - user_name = join("", ["demo-test-user", "+",count.index,"@databricks.com"]) + count = 2 + user_name = join("", ["demo-test-user", "+", count.index, "@databricks.com"]) display_name = "demo Test User" entitlements = [ "allow-cluster-create", @@ -67,56 +66,56 @@ resource "databricks_scim_user" "my-user" { resource "databricks_scim_group" "my-group" { display_name = "demo Test Group" - members = [databricks_scim_user.my-user[0].id] + members = [databricks_scim_user.my-user[0].id] } resource "databricks_secret_scope" "my-scope" { name = "terraform-demo-scope2" } resource "databricks_secret" "test_secret" { - key = "demo-test-secret-1" + key = "demo-test-secret-1" string_value = "hello world 123" - scope = databricks_secret_scope.my-scope.name + scope = databricks_secret_scope.my-scope.name } resource "databricks_secret_acl" "my-acl" { - principal = "USERS" + principal = "USERS" permission = "READ" - scope = databricks_secret_scope.my-scope.name + scope = databricks_secret_scope.my-scope.name } resource "databricks_instance_pool" "my-pool" { - instance_pool_name = "demo-terraform-pool" - min_idle_instances = 0 - max_capacity = 5 - node_type_id = "Standard_DS3_v2" + instance_pool_name = "demo-terraform-pool" + min_idle_instances = 0 + max_capacity = 5 + node_type_id = "Standard_DS3_v2" idle_instance_autotermination_minutes = 10 disk_spec = { azure_disk_volume_type = "PREMIUM_LRS" - disk_size = 80 - disk_count = 1 + disk_size = 80 + disk_count = 1 } custom_tags = { - "creator": "demo user" - "testChange": "demo user" + "creator" : "demo user" + "testChange" : "demo user" } } resource "databricks_token" "my-token" { lifetime_seconds = 6000 - comment = "Testing terraform v2" + comment = "Testing terraform v2" } resource "databricks_notebook" "my-dbc-base" { - content = filebase64("${path.module}/demo-terraform.dbc") - path = "/terraform-test-folder/folder1/folder2/terraformsamplecode" + content = filebase64("${path.module}/demo-terraform.dbc") + path = "/terraform-test-folder/folder1/folder2/terraformsamplecode" overwrite = false - mkdirs = true - format = "DBC" + mkdirs = true + format = "DBC" } data "databricks_notebook" "my-notebook" { - path = "/terraform-test-folder/folder1/folder2/terraformsamplecode" + path = "/terraform-test-folder/folder1/folder2/terraformsamplecode" format = "DBC" } @@ -131,4 +130,4 @@ output "databricks_scope" { output "notebook-content" { value = data.databricks_notebook.my-notebook.content -} \ No newline at end of file +} diff --git a/integration-environment-azure/prereqs.tf b/integration-environment-azure/prereqs.tf index 0ca027c511..8dc6049357 100644 --- a/integration-environment-azure/prereqs.tf +++ b/integration-environment-azure/prereqs.tf @@ -77,10 +77,6 @@ output "workspace_name" { value = azurerm_databricks_workspace.example.name } -output "workspace_url" { - value = azurerm_databricks_workspace.example.workspace_url -} - output "gen2_adal_name" { value = azurerm_storage_account.adlsaccount.name } diff --git a/integration-environment-azure/run.sh b/integration-environment-azure/run.sh index 9290da395b..5c425a3ff6 100755 --- a/integration-environment-azure/run.sh +++ b/integration-environment-azure/run.sh @@ -46,7 +46,6 @@ export TEST_STORAGE_ACCOUNT_NAME=$(terraform output blob_storage_name) export DATABRICKS_AZURE_WORKSPACE_NAME=$(terraform output workspace_name) export DATABRICKS_AZURE_RESOURCE_GROUP=$(terraform output rg_name) -export DATABRICKS_AZURE_WORKSPACE_URL=$(terraform output workspace_url) export AZURE_REGION=$(terraform output location) export DATABRICKS_AZURE_MANAGED_RESOURCE_GROUP=$(terraform output workspace_managed_rg_name) diff --git a/website/content/Provider/_index.md b/website/content/Provider/_index.md index 5ff6b8522f..c57622e31e 100644 --- a/website/content/Provider/_index.md +++ b/website/content/Provider/_index.md @@ -78,7 +78,6 @@ provider "databricks" { managed_resource_group = azurerm_databricks_workspace.demo_test_workspace.managed_resource_group_name azure_region = azurerm_databricks_workspace.demo_test_workspace.location workspace_name = azurerm_databricks_workspace.demo_test_workspace.name - workspace_url = azurerm_databricks_workspace.demo_test_workspace.workspace_url resource_group = azurerm_databricks_workspace.demo_test_workspace.resource_group_name client_id = var.client_id client_secret = var.client_secret @@ -138,7 +137,6 @@ provider "databricks" { managed_resource_group = "${azurerm_databricks_workspace.sri_test_workspace.managed_resource_group_name}" azure_region = "${azurerm_databricks_workspace.sri_test_workspace.location}" workspace_name = "${azurerm_databricks_workspace.sri_test_workspace.name}" - workspace_url = "${azurerm_databricks_workspace.sri_test_workspace.workspace_url}" resource_group = "${azurerm_databricks_workspace.sri_test_workspace.resource_group_name}" client_id = "${var.client_id}" client_secret = "${var.client_secret}" @@ -160,7 +158,6 @@ The following variables can be passed via environment variables: * `managed_resource_group` → `DATABRICKS_AZURE_MANAGED_RESOURCE_GROUP` * `azure_region` → `AZURE_REGION` * `workspace_name` → `DATABRICKS_AZURE_WORKSPACE_NAME` -* `workspace_url` → `DATABRICKS_AZURE_WORKSPACE_URL` * `resource_group` → `DATABRICKS_AZURE_RESOURCE_GROUP` * `subscription_id` → `DATABRICKS_AZURE_SUBSCRIPTION_ID` or `ARM_SUBSCRIPTION_ID` * `client_secret` → `DATABRICKS_AZURE_CLIENT_SECRET` or `ARM_CLIENT_SECRET` @@ -231,7 +228,6 @@ Alternatively you can provide this value as an environment variable `DATABRICKS_ > azure_region = "centralus" > managed_resource_group = "my-databricks-managed-rg" > workspace_name = "test-managed-workspace" -> workspace_url = "adb-somenumber.19.azuredatabricks.net" > resource_group = "1-test-rg" > client_id = var.client_id > client_secret = var.client_secret @@ -252,9 +248,6 @@ Alternatively you can provide this value as an environment variable `AZURE_REGIO * `workspace_name` - This is the name of your Azure Databricks Workspace. Alternatively you can provide this value as an environment variable `DATABRICKS_AZURE_WORKSPACE_NAME`. -* `workspace_url` - This is the URL of the Azure Databricks Workspace API. -Alternatively you can provide this value as an environment variable `DATABRICKS_AZURE_WORKSPACE_URL`. - * `resource_group` - This is the resource group in which your Azure Databricks Workspace resides in. Alternatively you can provide this value as an environment variable `DATABRICKS_AZURE_RESOURCE_GROUP`. diff --git a/website/content/Resources/mws_workspaces.md b/website/content/Resources/mws_workspaces.md index 6c67b6b64e..e297ae02a6 100644 --- a/website/content/Resources/mws_workspaces.md +++ b/website/content/Resources/mws_workspaces.md @@ -134,7 +134,7 @@ In addition to all arguments above, the following attributes are exported: #### - `network_error_messages`: > Array of error messages about the network configuration. -> Contains the following objects: +> Contains the following objects: > error_type: The AWS resource associated with this error: credentials, VPC, subnet, security group, or network ACL. > error_message: Details of the error. From 67f6b60972be47f13f92ad8b8c1179faa12dad28 Mon Sep 17 00:00:00 2001 From: Eliise S Date: Tue, 23 Jun 2020 14:16:32 +0000 Subject: [PATCH 14/18] Assert env var is set --- databricks/azure_auth_test.go | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/databricks/azure_auth_test.go b/databricks/azure_auth_test.go index 1d64336d9f..84c7795fb8 100644 --- a/databricks/azure_auth_test.go +++ b/databricks/azure_auth_test.go @@ -1,6 +1,7 @@ package databricks import ( + "fmt" "os" "testing" @@ -21,14 +22,14 @@ func TestAzureAuthCreateApiToken(t *testing.T) { } tokenPayload := TokenPayload{ - ManagedResourceGroup: os.Getenv("DATABRICKS_AZURE_MANAGED_RESOURCE_GROUP"), - AzureRegion: os.Getenv("AZURE_REGION"), - WorkspaceName: os.Getenv("DATABRICKS_AZURE_WORKSPACE_NAME"), - ResourceGroup: os.Getenv("DATABRICKS_AZURE_RESOURCE_GROUP"), - SubscriptionID: os.Getenv("DATABRICKS_AZURE_SUBSCRIPTION_ID"), - TenantID: os.Getenv("DATABRICKS_AZURE_TENANT_ID"), - ClientID: os.Getenv("DATABRICKS_AZURE_CLIENT_ID"), - ClientSecret: os.Getenv("DATABRICKS_AZURE_CLIENT_SECRET"), + ManagedResourceGroup: getAndAssertEnv(t, "DATABRICKS_AZURE_MANAGED_RESOURCE_GROUP"), + AzureRegion: getAndAssertEnv(t, "AZURE_REGION"), + WorkspaceName: getAndAssertEnv(t, "DATABRICKS_AZURE_WORKSPACE_NAME"), + ResourceGroup: getAndAssertEnv(t, "DATABRICKS_AZURE_RESOURCE_GROUP"), + SubscriptionID: getAndAssertEnv(t, "DATABRICKS_AZURE_SUBSCRIPTION_ID"), + TenantID: getAndAssertEnv(t, "DATABRICKS_AZURE_TENANT_ID"), + ClientID: getAndAssertEnv(t, "DATABRICKS_AZURE_CLIENT_ID"), + ClientSecret: getAndAssertEnv(t, "DATABRICKS_AZURE_CLIENT_SECRET"), } config := GetIntegrationDBClientOptions() @@ -53,3 +54,10 @@ func TestAzureAuthCreateApiToken(t *testing.T) { assert.NoError(t, instancePoolErr, instancePoolErr) } + +// getAndAssertEnv fetches the env for testing and also asserts that the env value is not Zero i.e "" +func getAndAssertEnv(t *testing.T, key string) string { + value, present := os.LookupEnv("a") + assert.False(t, present, fmt.Sprintf("Env variable %s is not set", key)) + return value +} From 031fbf517f7432c2c00a9b879d301661ea1be83c Mon Sep 17 00:00:00 2001 From: Eliise S Date: Tue, 23 Jun 2020 14:16:41 +0000 Subject: [PATCH 15/18] Reverse bool --- databricks/provider.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/databricks/provider.go b/databricks/provider.go index 669ce68592..7835741c97 100644 --- a/databricks/provider.go +++ b/databricks/provider.go @@ -298,7 +298,11 @@ func providerConfigure(d *schema.ResourceData, providerVersion string) (interfac //version information from go-releaser using -ldflags to tell the golang linker to send semver info config.UserAgent = fmt.Sprintf("databricks-tf-provider/%s", providerVersion) - if _, ok := d.GetOk("azure_auth"); !ok { + if _, ok := d.GetOk("azure_auth"); ok { + // Abstracted logic to another function that returns a interface{}, error to inject directly + // for the providers during cloud integration testing + return providerConfigureAzureClient(d, &config) + } else { if host, ok := d.GetOk("host"); ok { config.Host = host.(string) } @@ -323,10 +327,6 @@ func providerConfigure(d *schema.ResourceData, providerVersion string) (interfac return nil, fmt.Errorf("failed to get credentials from config file; error msg: %w", err) } } - } else { - // Abstracted logic to another function that returns a interface{}, error to inject directly - // for the providers during cloud integration testing - return providerConfigureAzureClient(d, &config) } var dbClient service.DBApiClient From 7f123ccae7d5c1460edfb7963ea9d1d1818f559c Mon Sep 17 00:00:00 2001 From: Eliise S Date: Tue, 23 Jun 2020 16:44:20 +0000 Subject: [PATCH 16/18] Use correct operator --- databricks/azure_auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/databricks/azure_auth_test.go b/databricks/azure_auth_test.go index 84c7795fb8..1e7754e856 100644 --- a/databricks/azure_auth_test.go +++ b/databricks/azure_auth_test.go @@ -58,6 +58,6 @@ func TestAzureAuthCreateApiToken(t *testing.T) { // getAndAssertEnv fetches the env for testing and also asserts that the env value is not Zero i.e "" func getAndAssertEnv(t *testing.T, key string) string { value, present := os.LookupEnv("a") - assert.False(t, present, fmt.Sprintf("Env variable %s is not set", key)) + assert.True(t, present, fmt.Sprintf("Env variable %s is not set", key)) return value } From f617d2db80f486703bb6da5f73bd702fe2a78051 Mon Sep 17 00:00:00 2001 From: Eliise S Date: Wed, 24 Jun 2020 13:42:34 +0000 Subject: [PATCH 17/18] Run all integration tests --- integration-environment-azure/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-environment-azure/run.sh b/integration-environment-azure/run.sh index 5c425a3ff6..c6a223633f 100755 --- a/integration-environment-azure/run.sh +++ b/integration-environment-azure/run.sh @@ -53,5 +53,5 @@ echo -e "----> Running Azure Acceptance Tests \n\n" # Run all Azure integration tests TF_ACC=1 gotestsum --format short-verbose --raw-command \ - go test -v -json -short -coverprofile=coverage.out \ + go test -v -json -coverprofile=coverage.out \ -test.timeout 35m -run 'TestAccAzure' ./../... \ No newline at end of file From 62164f011ec58ddc8f2fac16f095fcbe5161c0e3 Mon Sep 17 00:00:00 2001 From: Eliise S Date: Wed, 24 Jun 2020 13:42:44 +0000 Subject: [PATCH 18/18] Use KEY --- databricks/azure_auth_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/databricks/azure_auth_test.go b/databricks/azure_auth_test.go index 1e7754e856..7253bad34b 100644 --- a/databricks/azure_auth_test.go +++ b/databricks/azure_auth_test.go @@ -57,7 +57,7 @@ func TestAzureAuthCreateApiToken(t *testing.T) { // getAndAssertEnv fetches the env for testing and also asserts that the env value is not Zero i.e "" func getAndAssertEnv(t *testing.T, key string) string { - value, present := os.LookupEnv("a") + value, present := os.LookupEnv(key) assert.True(t, present, fmt.Sprintf("Env variable %s is not set", key)) return value }