diff --git a/CHANGELOG.md b/CHANGELOG.md index 1da9ec0b..0df0f125 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,13 @@ All notable changes to this project will be documented in this file. -## [Unreleased](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.2.24...HEAD) +## [Unreleased](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.2.25...HEAD) + +## [0.2.25](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.2.24...v0.2.25) + +## Changes + +- Enable OAuth configuration for Databricks connections + update docs accordingly ## [0.2.24](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.2.23...v0.2.24) diff --git a/docs/resources/connection.md b/docs/resources/connection.md index 3017babe..f720c3f6 100644 --- a/docs/resources/connection.md +++ b/docs/resources/connection.md @@ -23,13 +23,16 @@ For BigQuery, due to the list of fields being very different, you can use the `d // legacy names will be removed from 0.3 onwards resource "dbtcloud_connection" "databricks" { - project_id = dbtcloud_project.dbt_project.id - type = "adapter" - name = "Databricks" - database = "" // currenyly need to be empty for databricks - host_name = "my-databricks-host.cloud.databricks.com" - http_path = "/my/path" - catalog = "moo" + project_id = dbtcloud_project.dbt_project.id + type = "adapter" + name = "Databricks" + database = "" // currenyly need to be empty for databricks + host_name = "my-databricks-host.cloud.databricks.com" + http_path = "/my/path" + catalog = "moo" + // add the following for OAuth + oauth_client_id = "yourclientid" + oauth_client_secret = "yourclientsecret" } resource "dbtcloud_connection" "redshift" { @@ -42,13 +45,17 @@ resource "dbtcloud_connection" "redshift" { } resource "dbtcloud_connection" "snowflake" { - project_id = dbtcloud_project.dbt_project.id - type = "snowflake" - name = "My Snowflake warehouse" - account = "my-snowflake-account" - database = "MY_DATABASE" - role = "MY_ROLE" - warehouse = "MY_WAREHOUSE" + project_id = dbtcloud_project.dbt_project.id + type = "snowflake" + name = "My Snowflake warehouse" + account = "my-snowflake-account" + database = "MY_DATABASE" + role = "MY_ROLE" + warehouse = "MY_WAREHOUSE" + // add the following for OAuth + oauth_client_id = "yourclientid" + oauth_client_secret = "yourclientsecret" + allow_sso = true } ``` @@ -64,24 +71,24 @@ resource "dbtcloud_connection" "snowflake" { ### Optional -- `account` (String) Account name for the connection -- `allow_keep_alive` (Boolean) Whether or not the connection should allow client session keep alive -- `allow_sso` (Boolean) Whether or not the connection should allow SSO -- `catalog` (String) Catalog name if Unity Catalog is enabled in your Databricks workspace +- `account` (String) Account name for the connection (for Snowflake) +- `allow_keep_alive` (Boolean) Whether or not the connection should allow client session keep alive (for Snowflake) +- `allow_sso` (Boolean) Whether or not the connection should allow SSO (for Snowflake) +- `catalog` (String) Catalog name if Unity Catalog is enabled in your Databricks workspace (for Databricks) - `host_name` (String) Host name for the connection, including Databricks cluster -- `http_path` (String) The HTTP path of the Databricks cluster or SQL warehouse +- `http_path` (String) The HTTP path of the Databricks cluster or SQL warehouse (for Databricks) - `is_active` (Boolean) Whether the connection is active -- `oauth_client_id` (String) OAuth client identifier -- `oauth_client_secret` (String) OAuth client secret +- `oauth_client_id` (String) OAuth client identifier (for Snowflake and Databricks) +- `oauth_client_secret` (String) OAuth client secret (for Snowflake and Databricks) - `port` (Number) Port number to connect via - `private_link_endpoint_id` (String) The ID of the PrivateLink connection. This ID can be found using the `privatelink_endpoint` data source -- `role` (String) Role name for the connection +- `role` (String) Role name for the connection (for Snowflake) - `tunnel_enabled` (Boolean) Whether or not tunneling should be enabled on your database connection -- `warehouse` (String) Warehouse name for the connection +- `warehouse` (String) Warehouse name for the connection (for Snowflake) ### Read-Only -- `adapter_id` (Number) Adapter id created for the Databricks connection +- `adapter_id` (Number) Adapter id created for the Databricks connection (for Databricks) - `connection_id` (Number) Connection Identifier - `id` (String) The ID of this resource. diff --git a/examples/resources/dbtcloud_connection/resource.tf b/examples/resources/dbtcloud_connection/resource.tf index c97e75ee..2bd1fd3f 100644 --- a/examples/resources/dbtcloud_connection/resource.tf +++ b/examples/resources/dbtcloud_connection/resource.tf @@ -3,13 +3,16 @@ // legacy names will be removed from 0.3 onwards resource "dbtcloud_connection" "databricks" { - project_id = dbtcloud_project.dbt_project.id - type = "adapter" - name = "Databricks" - database = "" // currenyly need to be empty for databricks - host_name = "my-databricks-host.cloud.databricks.com" - http_path = "/my/path" - catalog = "moo" + project_id = dbtcloud_project.dbt_project.id + type = "adapter" + name = "Databricks" + database = "" // currenyly need to be empty for databricks + host_name = "my-databricks-host.cloud.databricks.com" + http_path = "/my/path" + catalog = "moo" + // add the following for OAuth + oauth_client_id = "yourclientid" + oauth_client_secret = "yourclientsecret" } resource "dbtcloud_connection" "redshift" { @@ -22,11 +25,15 @@ resource "dbtcloud_connection" "redshift" { } resource "dbtcloud_connection" "snowflake" { - project_id = dbtcloud_project.dbt_project.id - type = "snowflake" - name = "My Snowflake warehouse" - account = "my-snowflake-account" - database = "MY_DATABASE" - role = "MY_ROLE" - warehouse = "MY_WAREHOUSE" + project_id = dbtcloud_project.dbt_project.id + type = "snowflake" + name = "My Snowflake warehouse" + account = "my-snowflake-account" + database = "MY_DATABASE" + role = "MY_ROLE" + warehouse = "MY_WAREHOUSE" + // add the following for OAuth + oauth_client_id = "yourclientid" + oauth_client_secret = "yourclientsecret" + allow_sso = true } \ No newline at end of file diff --git a/pkg/dbt_cloud/connection.go b/pkg/dbt_cloud/connection.go index 4007277a..8ea97226 100644 --- a/pkg/dbt_cloud/connection.go +++ b/pkg/dbt_cloud/connection.go @@ -122,6 +122,8 @@ func (c *Client) CreateConnection( hostName, httpPath, catalog, + oAuthClientID, + oAuthClientSecret, ) } else { connectionDetails.Account = account @@ -185,7 +187,8 @@ func (c *Client) CreateConnection( return nil, err } - if (oAuthClientID != "") && (oAuthClientSecret != "") { + // those are secrets and not given back by the API + if (oAuthClientID != "") && (oAuthClientSecret != "") && (connectionType != "adapter") { connectionResponse.Data.Details.OAuthClientID = oAuthClientID connectionResponse.Data.Details.OAuthClientSecret = oAuthClientSecret } @@ -277,6 +280,8 @@ func GetDatabricksConnectionDetails( hostName string, httpPath string, catalog string, + clientID string, + clientSecret string, ) *AdapterCredentialDetails { noValidation := AdapterCredentialFieldMetadataValidation{ Required: false, @@ -321,11 +326,39 @@ func GetDatabricksConnectionDetails( Value: httpPath, } - fieldOrder := []string{"type", "host", "http_path"} + clientIDMetadata := AdapterCredentialFieldMetadata{ + Label: "OAuth Client ID", + Description: "Required to enable Databricks OAuth authentication for IDE developers.", + Field_Type: "text", + Encrypt: true, + Overrideable: false, + Validation: noValidation, + } + clientIDField := AdapterCredentialField{ + Metadata: clientIDMetadata, + Value: clientID, + } + + clientSecretMetadata := AdapterCredentialFieldMetadata{ + Label: "OAuth Client Secret", + Description: "Required to enable Databricks OAuth authentication for IDE developers.", + Field_Type: "text", + Encrypt: true, + Overrideable: false, + Validation: noValidation, + } + clientSecretField := AdapterCredentialField{ + Metadata: clientSecretMetadata, + Value: clientSecret, + } + + fieldOrder := []string{"type", "host", "http_path", "client_id", "client_secret"} fields := map[string]AdapterCredentialField{ - "type": typeField, - "host": hostField, - "http_path": httpPathField, + "type": typeField, + "host": hostField, + "http_path": httpPathField, + "client_id": clientIDField, + "client_secret": clientSecretField, } if catalog != "" { diff --git a/pkg/resources/connection.go b/pkg/resources/connection.go index adf8462e..3c647e02 100644 --- a/pkg/resources/connection.go +++ b/pkg/resources/connection.go @@ -75,7 +75,7 @@ func ResourceConnection() *schema.Resource { "account": &schema.Schema{ Type: schema.TypeString, Optional: true, - Description: "Account name for the connection", + Description: "Account name for the connection (for Snowflake)", ConflictsWith: []string{"host_name"}, }, "host_name": &schema.Schema{ @@ -98,37 +98,37 @@ func ResourceConnection() *schema.Resource { "warehouse": &schema.Schema{ Type: schema.TypeString, Optional: true, - Description: "Warehouse name for the connection", + Description: "Warehouse name for the connection (for Snowflake)", }, "role": &schema.Schema{ Type: schema.TypeString, Optional: true, Default: "", - Description: "Role name for the connection", + Description: "Role name for the connection (for Snowflake)", }, "allow_sso": &schema.Schema{ Type: schema.TypeBool, Optional: true, Default: false, - Description: "Whether or not the connection should allow SSO", + Description: "Whether or not the connection should allow SSO (for Snowflake)", }, "allow_keep_alive": &schema.Schema{ Type: schema.TypeBool, Optional: true, Default: false, - Description: "Whether or not the connection should allow client session keep alive", + Description: "Whether or not the connection should allow client session keep alive (for Snowflake)", }, "oauth_client_id": &schema.Schema{ Type: schema.TypeString, Optional: true, Default: "", - Description: "OAuth client identifier", + Description: "OAuth client identifier (for Snowflake and Databricks)", }, "oauth_client_secret": &schema.Schema{ Type: schema.TypeString, Optional: true, Default: "", - Description: "OAuth client secret", + Description: "OAuth client secret (for Snowflake and Databricks)", }, "tunnel_enabled": &schema.Schema{ Type: schema.TypeBool, @@ -139,17 +139,17 @@ func ResourceConnection() *schema.Resource { "http_path": &schema.Schema{ Type: schema.TypeString, Optional: true, - Description: "The HTTP path of the Databricks cluster or SQL warehouse", + Description: "The HTTP path of the Databricks cluster or SQL warehouse (for Databricks)", }, "catalog": &schema.Schema{ Type: schema.TypeString, Optional: true, - Description: "Catalog name if Unity Catalog is enabled in your Databricks workspace", + Description: "Catalog name if Unity Catalog is enabled in your Databricks workspace (for Databricks)", }, "adapter_id": &schema.Schema{ Type: schema.TypeInt, Computed: true, - Description: "Adapter id created for the Databricks connection", + Description: "Adapter id created for the Databricks connection (for Databricks)", }, }, @@ -159,7 +159,11 @@ func ResourceConnection() *schema.Resource { } } -func resourceConnectionCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceConnectionCreate( + ctx context.Context, + d *schema.ResourceData, + m interface{}, +) diag.Diagnostics { c := m.(*dbt_cloud.Client) var diags diag.Diagnostics @@ -183,7 +187,26 @@ func resourceConnectionCreate(ctx context.Context, d *schema.ResourceData, m int httpPath := d.Get("http_path").(string) catalog := d.Get("catalog").(string) - connection, err := c.CreateConnection(projectId, name, connectionType, privatelinkEndpointID, isActive, account, database, warehouse, role, &allowSSO, &allowKeepAlive, oAuthClientID, oAuthClientSecret, hostName, port, &tunnelEnabled, httpPath, catalog) + connection, err := c.CreateConnection( + projectId, + name, + connectionType, + privatelinkEndpointID, + isActive, + account, + database, + warehouse, + role, + &allowSSO, + &allowKeepAlive, + oAuthClientID, + oAuthClientSecret, + hostName, + port, + &tunnelEnabled, + httpPath, + catalog, + ) if err != nil { return diag.FromErr(err) } @@ -195,7 +218,11 @@ func resourceConnectionCreate(ctx context.Context, d *schema.ResourceData, m int return diags } -func resourceConnectionRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceConnectionRead( + ctx context.Context, + d *schema.ResourceData, + m interface{}, +) diag.Diagnostics { c := m.(*dbt_cloud.Client) var diags diag.Diagnostics @@ -257,11 +284,13 @@ func resourceConnectionRead(ctx context.Context, d *schema.ResourceData, m inter if err := d.Set("allow_keep_alive", connection.Details.ClientSessionKeepAlive); err != nil { return diag.FromErr(err) } - if err := d.Set("oauth_client_id", connection.Details.OAuthClientID); err != nil { - return diag.FromErr(err) - } - if err := d.Set("oauth_client_secret", connection.Details.OAuthClientSecret); err != nil { - return diag.FromErr(err) + if d.Get("type") == "snowflake" { + if err := d.Set("oauth_client_id", connection.Details.OAuthClientID); err != nil { + return diag.FromErr(err) + } + if err := d.Set("oauth_client_secret", connection.Details.OAuthClientSecret); err != nil { + return diag.FromErr(err) + } } if err := d.Set("port", connection.Details.Port); err != nil { return diag.FromErr(err) @@ -272,10 +301,14 @@ func resourceConnectionRead(ctx context.Context, d *schema.ResourceData, m inter httpPath := "" catalog := "" hostName := connection.Details.Host + clientID := "" + clientSecret := "" if connection.Details.AdapterDetails != nil { httpPath = connection.Details.AdapterDetails.Fields["http_path"].Value.(string) catalog = connection.Details.AdapterDetails.Fields["catalog"].Value.(string) hostName = connection.Details.AdapterDetails.Fields["host"].Value.(string) + clientID = d.Get("oauth_client_id").(string) + clientSecret = d.Get("oauth_client_secret").(string) } if err := d.Set("host_name", hostName); err != nil { return diag.FromErr(err) @@ -286,6 +319,15 @@ func resourceConnectionRead(ctx context.Context, d *schema.ResourceData, m inter if err := d.Set("catalog", catalog); err != nil { return diag.FromErr(err) } + // we set those just for the adapter as the logic for Snowflake is up in this function + if d.Get("type") == "adapter" { + if err := d.Set("oauth_client_id", clientID); err != nil { + return diag.FromErr(err) + } + if err := d.Set("oauth_client_secret", clientSecret); err != nil { + return diag.FromErr(err) + } + } if err := d.Set("adapter_id", connection.Details.AdapterId); err != nil { return diag.FromErr(err) } @@ -293,7 +335,11 @@ func resourceConnectionRead(ctx context.Context, d *schema.ResourceData, m inter return diags } -func resourceConnectionUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceConnectionUpdate( + ctx context.Context, + d *schema.ResourceData, + m interface{}, +) diag.Diagnostics { c := m.(*dbt_cloud.Client) projectIdString := strings.Split(d.Id(), dbt_cloud.ID_DELIMITER)[0] @@ -369,11 +415,11 @@ func resourceConnectionUpdate(ctx context.Context, d *schema.ResourceData, m int allowKeepAlive := d.Get("allow_keep_alive").(bool) connection.Details.ClientSessionKeepAlive = &allowKeepAlive } - if d.HasChange("oauth_client_id") { + if d.HasChange("oauth_client_id") && d.Get("type") == "snowflake" { oAuthClientID := d.Get("oauth_client_id").(string) connection.Details.OAuthClientID = oAuthClientID } - if d.HasChange("oauth_client_secret") { + if d.HasChange("oauth_client_secret") && d.Get("type") == "snowflake" { oAuthClientSecret := d.Get("oauth_client_secret").(string) connection.Details.OAuthClientSecret = oAuthClientSecret } @@ -381,8 +427,17 @@ func resourceConnectionUpdate(ctx context.Context, d *schema.ResourceData, m int tunnelEnabled := d.Get("tunnel_enabled").(bool) connection.Details.TunnelEnabled = &tunnelEnabled } - if d.HasChange("http_path") || d.HasChange("host_name") || d.HasChange("catalog") { - connection.Details.AdapterDetails = dbt_cloud.GetDatabricksConnectionDetails(d.Get("host_name").(string), d.Get("http_path").(string), d.Get("catalog").(string)) + if d.Get("type") == "adapter" && + (d.HasChange("http_path") || d.HasChange("host_name") || d.HasChange("catalog") || + d.HasChange("oauth_client_id") || + d.HasChange("oauth_client_secret")) { + connection.Details.AdapterDetails = dbt_cloud.GetDatabricksConnectionDetails( + d.Get("host_name").(string), + d.Get("http_path").(string), + d.Get("catalog").(string), + d.Get("oauth_client_id").(string), + d.Get("oauth_client_secret").(string), + ) } if d.HasChange("adapter_id") { adapterId := d.Get("adapter_id").(int) @@ -398,7 +453,11 @@ func resourceConnectionUpdate(ctx context.Context, d *schema.ResourceData, m int return resourceConnectionRead(ctx, d, m) } -func resourceConnectionDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceConnectionDelete( + ctx context.Context, + d *schema.ResourceData, + m interface{}, +) diag.Diagnostics { c := m.(*dbt_cloud.Client) var diags diag.Diagnostics diff --git a/pkg/resources/connection_acceptance_test.go b/pkg/resources/connection_acceptance_test.go index a2038679..645cccb9 100644 --- a/pkg/resources/connection_acceptance_test.go +++ b/pkg/resources/connection_acceptance_test.go @@ -27,18 +27,36 @@ func TestAccDbtCloudConnectionResource(t *testing.T) { CheckDestroy: testAccCheckDbtCloudConnectionDestroy, Steps: []resource.TestStep{ { - Config: testAccDbtCloudConnectionResourceBasicConfig(connectionName, projectName, oAuthClientID, oAuthClientSecret), + Config: testAccDbtCloudConnectionResourceBasicConfig( + connectionName, + projectName, + oAuthClientID, + oAuthClientSecret, + ), Check: resource.ComposeTestCheckFunc( testAccCheckDbtCloudConnectionExists("dbtcloud_connection.test_connection"), - resource.TestCheckResourceAttr("dbtcloud_connection.test_connection", "name", connectionName), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_connection", + "name", + connectionName, + ), ), }, // RENAME { - Config: testAccDbtCloudConnectionResourceBasicConfig(connectionName2, projectName, oAuthClientID, oAuthClientSecret), + Config: testAccDbtCloudConnectionResourceBasicConfig( + connectionName2, + projectName, + oAuthClientID, + oAuthClientSecret, + ), Check: resource.ComposeTestCheckFunc( testAccCheckDbtCloudConnectionExists("dbtcloud_connection.test_connection"), - resource.TestCheckResourceAttr("dbtcloud_connection.test_connection", "name", connectionName2), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_connection", + "name", + connectionName2, + ), ), }, // // MODIFY @@ -73,20 +91,46 @@ func TestAccDbtCloudRedshiftConnectionResource(t *testing.T) { CheckDestroy: testAccCheckDbtCloudConnectionDestroy, Steps: []resource.TestStep{ { - Config: testAccDbtCloudConnectionResourceRedshiftConfig(connectionName, projectName), + Config: testAccDbtCloudConnectionResourceRedshiftConfig( + connectionName, + projectName, + ), Check: resource.ComposeTestCheckFunc( - testAccCheckDbtCloudConnectionExists("dbtcloud_connection.test_redshift_connection"), - resource.TestCheckResourceAttr("dbtcloud_connection.test_redshift_connection", "name", connectionName), - resource.TestCheckResourceAttr("dbtcloud_connection.test_redshift_connection", "database", "db"), - resource.TestCheckResourceAttr("dbtcloud_connection.test_redshift_connection", "port", "5432"), + testAccCheckDbtCloudConnectionExists( + "dbtcloud_connection.test_redshift_connection", + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_redshift_connection", + "name", + connectionName, + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_redshift_connection", + "database", + "db", + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_redshift_connection", + "port", + "5432", + ), ), }, // RENAME { - Config: testAccDbtCloudConnectionResourceRedshiftConfig(connectionName2, projectName), + Config: testAccDbtCloudConnectionResourceRedshiftConfig( + connectionName2, + projectName, + ), Check: resource.ComposeTestCheckFunc( - testAccCheckDbtCloudConnectionExists("dbtcloud_connection.test_redshift_connection"), - resource.TestCheckResourceAttr("dbtcloud_connection.test_redshift_connection", "name", connectionName2), + testAccCheckDbtCloudConnectionExists( + "dbtcloud_connection.test_redshift_connection", + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_redshift_connection", + "name", + connectionName2, + ), ), }, // // MODIFY @@ -121,20 +165,46 @@ func TestAccDbtCloudPostgresConnectionResource(t *testing.T) { CheckDestroy: testAccCheckDbtCloudConnectionDestroy, Steps: []resource.TestStep{ { - Config: testAccDbtCloudConnectionResourcePostgresConfig(connectionName, projectName), + Config: testAccDbtCloudConnectionResourcePostgresConfig( + connectionName, + projectName, + ), Check: resource.ComposeTestCheckFunc( - testAccCheckDbtCloudConnectionExists("dbtcloud_connection.test_postgres_connection"), - resource.TestCheckResourceAttr("dbtcloud_connection.test_postgres_connection", "name", connectionName), - resource.TestCheckResourceAttr("dbtcloud_connection.test_postgres_connection", "database", "db"), - resource.TestCheckResourceAttr("dbtcloud_connection.test_postgres_connection", "port", "5432"), + testAccCheckDbtCloudConnectionExists( + "dbtcloud_connection.test_postgres_connection", + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_postgres_connection", + "name", + connectionName, + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_postgres_connection", + "database", + "db", + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_postgres_connection", + "port", + "5432", + ), ), }, // RENAME { - Config: testAccDbtCloudConnectionResourcePostgresConfig(connectionName2, projectName), + Config: testAccDbtCloudConnectionResourcePostgresConfig( + connectionName2, + projectName, + ), Check: resource.ComposeTestCheckFunc( - testAccCheckDbtCloudConnectionExists("dbtcloud_connection.test_postgres_connection"), - resource.TestCheckResourceAttr("dbtcloud_connection.test_postgres_connection", "name", connectionName2), + testAccCheckDbtCloudConnectionExists( + "dbtcloud_connection.test_postgres_connection", + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_postgres_connection", + "name", + connectionName2, + ), ), }, // // MODIFY @@ -170,32 +240,135 @@ func TestAccDbtCloudDatabricksConnectionResource(t *testing.T) { CheckDestroy: testAccCheckDbtCloudConnectionDestroy, Steps: []resource.TestStep{ { - Config: testAccDbtCloudConnectionResourceDatabricksConfig(connectionName, projectName, databricksHost, "/my/databricks", "moo"), + Config: testAccDbtCloudConnectionResourceDatabricksConfig( + connectionName, + projectName, + databricksHost, + "/my/databricks", + "moo", + false, + ), Check: resource.ComposeTestCheckFunc( - testAccCheckDbtCloudConnectionExists("dbtcloud_connection.test_databricks_connection"), - resource.TestCheckResourceAttr("dbtcloud_connection.test_databricks_connection", "name", connectionName), - resource.TestCheckResourceAttr("dbtcloud_connection.test_databricks_connection", "host_name", databricksHost), - resource.TestCheckResourceAttr("dbtcloud_connection.test_databricks_connection", "http_path", "/my/databricks"), - resource.TestCheckResourceAttr("dbtcloud_connection.test_databricks_connection", "catalog", "moo"), - resource.TestCheckResourceAttrSet("dbtcloud_connection.test_databricks_connection", "adapter_id"), + testAccCheckDbtCloudConnectionExists( + "dbtcloud_connection.test_databricks_connection", + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_databricks_connection", + "name", + connectionName, + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_databricks_connection", + "host_name", + databricksHost, + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_databricks_connection", + "http_path", + "/my/databricks", + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_databricks_connection", + "catalog", + "moo", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_connection.test_databricks_connection", + "adapter_id", + ), ), }, // RENAME { - Config: testAccDbtCloudConnectionResourceDatabricksConfig(connectionName2, projectName, databricksHost, "/my/databricks", "moo"), + Config: testAccDbtCloudConnectionResourceDatabricksConfig( + connectionName2, + projectName, + databricksHost, + "/my/databricks", + "moo", + false, + ), Check: resource.ComposeTestCheckFunc( - testAccCheckDbtCloudConnectionExists("dbtcloud_connection.test_databricks_connection"), - resource.TestCheckResourceAttr("dbtcloud_connection.test_databricks_connection", "name", connectionName2), + testAccCheckDbtCloudConnectionExists( + "dbtcloud_connection.test_databricks_connection", + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_databricks_connection", + "name", + connectionName2, + ), ), }, // MODIFY { - Config: testAccDbtCloudConnectionResourceDatabricksConfig(connectionName2, projectName, databricksHost, "/my/databricks_new", "moo2"), + Config: testAccDbtCloudConnectionResourceDatabricksConfig( + connectionName2, + projectName, + databricksHost, + "/my/databricks_new", + "moo2", + false, + ), Check: resource.ComposeTestCheckFunc( - testAccCheckDbtCloudConnectionExists("dbtcloud_connection.test_databricks_connection"), - resource.TestCheckResourceAttr("dbtcloud_connection.test_databricks_connection", "name", connectionName2), - resource.TestCheckResourceAttr("dbtcloud_connection.test_databricks_connection", "http_path", "/my/databricks_new"), - resource.TestCheckResourceAttr("dbtcloud_connection.test_databricks_connection", "catalog", "moo2"), + testAccCheckDbtCloudConnectionExists( + "dbtcloud_connection.test_databricks_connection", + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_databricks_connection", + "name", + connectionName2, + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_databricks_connection", + "http_path", + "/my/databricks_new", + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_databricks_connection", + "catalog", + "moo2", + ), + ), + }, + // MODIFY TO AUTH + { + Config: testAccDbtCloudConnectionResourceDatabricksConfig( + connectionName2, + projectName, + databricksHost, + "/my/databricks_new", + "moo2", + true, + ), + Check: resource.ComposeTestCheckFunc( + testAccCheckDbtCloudConnectionExists( + "dbtcloud_connection.test_databricks_connection", + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_databricks_connection", + "name", + connectionName2, + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_databricks_connection", + "http_path", + "/my/databricks_new", + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_databricks_connection", + "catalog", + "moo2", + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_databricks_connection", + "oauth_client_id", + "client", + ), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_databricks_connection", + "oauth_client_secret", + "secret", + ), ), }, // IMPORT @@ -203,7 +376,7 @@ func TestAccDbtCloudDatabricksConnectionResource(t *testing.T) { ResourceName: "dbtcloud_connection.test_databricks_connection", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{}, + ImportStateVerifyIgnore: []string{"oauth_client_id", "oauth_client_secret"}, }, }, }) @@ -226,11 +399,23 @@ func TestAccDbtCloudConnectionPrivateLinkResource(t *testing.T) { CheckDestroy: testAccCheckDbtCloudConnectionDestroy, Steps: []resource.TestStep{ { - Config: testAccDbtCloudConnectionResourcePrivateLinkConfig(connectionName, projectName, endpointName, endpointURL), + Config: testAccDbtCloudConnectionResourcePrivateLinkConfig( + connectionName, + projectName, + endpointName, + endpointURL, + ), Check: resource.ComposeTestCheckFunc( testAccCheckDbtCloudConnectionExists("dbtcloud_connection.test_connection"), - resource.TestCheckResourceAttr("dbtcloud_connection.test_connection", "name", connectionName), - resource.TestCheckResourceAttrSet("dbtcloud_connection.test_connection", "private_link_endpoint_id"), + resource.TestCheckResourceAttr( + "dbtcloud_connection.test_connection", + "name", + connectionName, + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_connection.test_connection", + "private_link_endpoint_id", + ), ), }, // IMPORT @@ -244,7 +429,9 @@ func TestAccDbtCloudConnectionPrivateLinkResource(t *testing.T) { } } -func testAccDbtCloudConnectionResourceBasicConfig(connectionName, projectName, oAuthClientID, oAuthClientSecret string) string { +func testAccDbtCloudConnectionResourceBasicConfig( + connectionName, projectName, oAuthClientID, oAuthClientSecret string, +) string { return fmt.Sprintf(` resource "dbtcloud_project" "test_project" { name = "%s" @@ -258,7 +445,7 @@ resource "dbtcloud_connection" "test_connection" { database = "db" warehouse = "wh" role = "user" - allow_sso = false + allow_sso = true allow_keep_alive = false oauth_client_id = "%s" oauth_client_secret = "%s" @@ -302,7 +489,22 @@ resource "dbtcloud_connection" "test_postgres_connection" { `, projectName, connectionName) } -func testAccDbtCloudConnectionResourceDatabricksConfig(connectionName, projectName string, databricksHost string, httpPath string, catalog string) string { +func testAccDbtCloudConnectionResourceDatabricksConfig( + connectionName, projectName string, + databricksHost string, + httpPath string, + catalog string, + oAuth bool, +) string { + + oauthConfig := "" + if oAuth { + oauthConfig = ` + oauth_client_id = "client" + oauth_client_secret = "secret" + ` + } + return fmt.Sprintf(` resource "dbtcloud_project" "test_project" { name = "%s" @@ -316,11 +518,14 @@ resource "dbtcloud_connection" "test_databricks_connection" { host_name = "%s" http_path = "%s" catalog = "%s" + %s } -`, projectName, connectionName, databricksHost, httpPath, catalog) +`, projectName, connectionName, databricksHost, httpPath, catalog, oauthConfig) } -func testAccDbtCloudConnectionResourcePrivateLinkConfig(connectionName, projectName, endpointName, endpointURL string) string { +func testAccDbtCloudConnectionResourcePrivateLinkConfig( + connectionName, projectName, endpointName, endpointURL string, +) string { return fmt.Sprintf(` resource "dbtcloud_project" "test_project" { name = "%s"