From 5396981d737076ac03d5a828f1021f6a21b92515 Mon Sep 17 00:00:00 2001 From: Cedric <23346008+840@users.noreply.github.com> Date: Fri, 15 Nov 2024 20:49:57 +0100 Subject: [PATCH] [Feature] Add `databricks_mws_network_connectivity_config` and `databricks_mws_network_connectivity_configs` data source (#3665) ## Changes Add `databricks_mws_network_connectivity_config` & `databricks_mws_network_connectivity_configs` data source Resolves #3614 ## Tests - [x] `make test` run locally - [x] relevant change in `docs/` folder - [x] covered with integration tests in `internal/acceptance` - [ ] relevant acceptance tests are passing - [x] using Go SDK --------- Co-authored-by: Alex Ott Co-authored-by: Alex Ott --- .../mws_network_connectivity_config.md | 67 ++++++++ .../mws_network_connectivity_configs.md | 55 +++++++ ...ta_mws_network_connectivity_config_test.go | 51 +++++++ ...a_mws_network_connectivity_configs_test.go | 45 ++++++ internal/providers/sdkv2/sdkv2.go | 2 + mws/data_mws_network_connectivity_config.go | 33 ++++ ...ta_mws_network_connectivity_config_test.go | 67 ++++++++ mws/data_mws_network_connectivity_configs.go | 43 ++++++ ...a_mws_network_connectivity_configs_test.go | 144 ++++++++++++++++++ 9 files changed, 507 insertions(+) create mode 100755 docs/data-sources/mws_network_connectivity_config.md create mode 100755 docs/data-sources/mws_network_connectivity_configs.md create mode 100755 internal/acceptance/data_mws_network_connectivity_config_test.go create mode 100755 internal/acceptance/data_mws_network_connectivity_configs_test.go create mode 100644 mws/data_mws_network_connectivity_config.go create mode 100644 mws/data_mws_network_connectivity_config_test.go create mode 100644 mws/data_mws_network_connectivity_configs.go create mode 100644 mws/data_mws_network_connectivity_configs_test.go diff --git a/docs/data-sources/mws_network_connectivity_config.md b/docs/data-sources/mws_network_connectivity_config.md new file mode 100755 index 0000000000..c360efa5ea --- /dev/null +++ b/docs/data-sources/mws_network_connectivity_config.md @@ -0,0 +1,67 @@ +--- +subcategory: "Deployment" +--- +# databricks_mws_network_connectivity_config Data Source + +-> **Note** This data source can only be used with an account-level provider! + +Retrieves information about [databricks_mws_network_connectivity_config](../resources/mws_network_connectivity_config.md) in Databricks Account. + +## Example Usage + +Fetching information about a network connectivity configuration in Databricks Account + +```hcl +provider "databricks" { + // other configuration + account_id = "" +} + +data "databricks_mws_network_connectivity_config" "this" { + name = "ncc" +} + +output "config" { + value = data.databricks_mws_network_connectivity_config.this +} +``` + +## Argument Reference + +* `name` - (Required) Name of the network connectivity configuration. + +## Attribute Reference + +* `account_id` - The Databricks account ID associated with this network configuration. +* `creation_time` - Time in epoch milliseconds when the network was created. +* `egress_config` - Array of egress configuration objects. + * `default_rules` - Array of default rules. + * `aws_stable_ip_rule` - The stable AWS IP CIDR blocks. You can use these to configure the firewall of your resources to allow traffic from your Databricks workspace. + * `cidr_blocks` - The list of stable IP CIDR blocks from which Databricks network traffic originates when accessing your resources. + * `azure_service_endpoint_rule` - Array of Azure service endpoint rules. + * `subnets` - Array of strings representing the subnet IDs. + * `target_region` - The target region for the service endpoint. + * `target_services` - Array of target services. + * `target_rules` - Array of target rules. + * `azure_private_endpoint_rules` - Array of private endpoint rule objects. + * `rule_id` - The ID of a private endpoint rule. + * `network_connectivity_config_id` - The ID of a network connectivity configuration, which is the parent resource of this private endpoint rule object. + * `resource_id` - The Azure resource ID of the target resource. + * `group_id` - The sub-resource type (group ID) of the target resource. + * `endpoint_name` - The name of the Azure private endpoint resource. + * `connection_state` - The current status of this private endpoint. + * `deactivated` - Whether this private endpoint is deactivated. + * `deactivated_at` - Time in epoch milliseconds when this object was deactivated. + * `creation_time` - Time in epoch milliseconds when this object was created. + * `updated_time` - Time in epoch milliseconds when this object was updated. +* `name` - The name of the network connectivity configuration. +* `network_connectivity_config_id` - The Databricks network connectivity configuration ID. +* `region` - The region of the network connectivity configuration. +* `updated_time` - Time in epoch milliseconds when the network was updated. + +## Related Resources + +The following resources are used in the same context: + +* [databricks_mws_network_connectivity_configs](./mws_network_connectivity_configs.md) to get names of all network connectivity configurations. +* [databricks_mws_network_connectivity_config](../resources/mws_network_connectivity_config.md) to manage network connectivity configuration. diff --git a/docs/data-sources/mws_network_connectivity_configs.md b/docs/data-sources/mws_network_connectivity_configs.md new file mode 100755 index 0000000000..9d59dfa329 --- /dev/null +++ b/docs/data-sources/mws_network_connectivity_configs.md @@ -0,0 +1,55 @@ +--- +subcategory: "Deployment" +--- +# databricks_mws_network_connectivity_configs Data Source + +-> **Note** This data source can only be used with an account-level provider! + +Lists all [databricks_mws_network_connectivity_config](../resources/mws_network_connectivity_config.md) in Databricks Account. + +## Example Usage + +List all network connectivity configurations in Databricks Account + +```hcl +provider "databricks" { + // other configuration + account_id = "" +} + +data "databricks_mws_network_connectivity_configs" "this" {} + +output "all" { + value = data.databricks_mws_network_connectivity_configs.this +} +``` + +List network connectivity configurations from a specific region in Databricks Account + +```hcl +provider "databricks" { + // other configuration + account_id = "" +} + +data "databricks_mws_network_connectivity_configs" "this" { + region = "us-east-1" +} + +output "filtered" { + value = data.databricks_mws_network_connectivity_configs.this +} +``` + +## Argument Reference + +* `region` - (Optional) Filter network connectivity configurations by region. + +## Attribute Reference + +This data source exports the following attributes: + +* `names` - List of names of [databricks_mws_network_connectivity_config](./databricks_mws_network_connectivity_config.md) + +* [databricks_mws_network_connectivity_config](./mws_network_connectivity_config.md) to get information about a single network connectivity configuration. +* [databricks_mws_network_connectivity_config](../resources/mws_network_connectivity_config.md) to manage network connectivity configuration. diff --git a/internal/acceptance/data_mws_network_connectivity_config_test.go b/internal/acceptance/data_mws_network_connectivity_config_test.go new file mode 100755 index 0000000000..15dc457d62 --- /dev/null +++ b/internal/acceptance/data_mws_network_connectivity_config_test.go @@ -0,0 +1,51 @@ +package acceptance + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/terraform" +) + +func TestAccDataSourceMwsNetworkConnectivityConfigTest(t *testing.T) { + loadWorkspaceEnv(t) + if isGcp(t) { + skipf(t)("GCP not supported") + } + var sourceRegion string + if isAzure(t) { + sourceRegion = "eastus2" + } else if isAws(t) { + sourceRegion = "us-east-2" + } + AccountLevel(t, + Step{ + Template: fmt.Sprintf(` + resource "databricks_mws_network_connectivity_config" "this" { + name = "tf-{var.RANDOM}" + region = "%s" + } + + data "databricks_mws_network_connectivity_config" "this" { + depends_on = [databricks_mws_network_connectivity_config.this] + name = databricks_mws_network_connectivity_config.this.name + }`, sourceRegion), + Check: func(s *terraform.State) error { + r, ok := s.RootModule().Resources["data.databricks_mws_network_connectivity_config.this"] + if !ok { + return fmt.Errorf("data not found in state") + } + name := r.Primary.Attributes["name"] + if name == "" { + return fmt.Errorf("name is empty: %v", r.Primary.Attributes) + } + expect := sourceRegion + region := r.Primary.Attributes["region"] + if region != expect { + return fmt.Errorf("incorrect region. expected: %v, received: %v", + expect, region) + } + return nil + }, + }) +} diff --git a/internal/acceptance/data_mws_network_connectivity_configs_test.go b/internal/acceptance/data_mws_network_connectivity_configs_test.go new file mode 100755 index 0000000000..94647bb4ca --- /dev/null +++ b/internal/acceptance/data_mws_network_connectivity_configs_test.go @@ -0,0 +1,45 @@ +package acceptance + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/terraform" +) + +func TestAccDataSourceMwsNetworkConnectivityConfigsTest(t *testing.T) { + loadWorkspaceEnv(t) + if isGcp(t) { + skipf(t)("GCP not supported") + } + var region string + if isAzure(t) { + region = "eastus2" + } else if isAws(t) { + region = "us-east-2" + } + AccountLevel(t, + Step{ + Template: fmt.Sprintf(` + resource "databricks_mws_network_connectivity_configs" "this" { + name = "tf-{var.RANDOM}" + region = "%s" + } + + data "databricks_mws_network_connectivity_configs" "this" { + depends_on = [databricks_mws_network_connectivity_config.this] + region = databricks_mws_network_connectivity_config.this.region + }`, region), + Check: func(s *terraform.State) error { + r, ok := s.RootModule().Resources["data.databricks_mws_network_connectivity_configs.this"] + if !ok { + return fmt.Errorf("data not found in state") + } + names := r.Primary.Attributes["names"] + if names == "" { + return fmt.Errorf("names is empty: %v", r.Primary.Attributes) + } + return nil + }, + }) +} diff --git a/internal/providers/sdkv2/sdkv2.go b/internal/providers/sdkv2/sdkv2.go index e689b5b693..1426b411c4 100644 --- a/internal/providers/sdkv2/sdkv2.go +++ b/internal/providers/sdkv2/sdkv2.go @@ -103,6 +103,8 @@ func DatabricksProvider(sdkV2Fallbacks ...pluginfw.SdkV2FallbackOption) *schema. "databricks_mlflow_model": mlflow.DataSourceModel().ToResource(), "databricks_mlflow_models": mlflow.DataSourceModels().ToResource(), "databricks_mws_credentials": mws.DataSourceMwsCredentials().ToResource(), + "databricks_mws_network_connectivity_config": mws.DataSourceMwsNetworkConnectivityConfig().ToResource(), + "databricks_mws_network_connectivity_configs": mws.DataSourceMwsNetworkConnectivityConfigs().ToResource(), "databricks_mws_workspaces": mws.DataSourceMwsWorkspaces().ToResource(), "databricks_node_type": clusters.DataSourceNodeType().ToResource(), "databricks_notebook": workspace.DataSourceNotebook().ToResource(), diff --git a/mws/data_mws_network_connectivity_config.go b/mws/data_mws_network_connectivity_config.go new file mode 100644 index 0000000000..ba50160886 --- /dev/null +++ b/mws/data_mws_network_connectivity_config.go @@ -0,0 +1,33 @@ +package mws + +import ( + "context" + + "github.com/databricks/databricks-sdk-go" + "github.com/databricks/databricks-sdk-go/service/settings" + "github.com/databricks/terraform-provider-databricks/common" +) + +func DataSourceMwsNetworkConnectivityConfig() common.Resource { + type mwsNetworkConnectivityConfiguration struct { + settings.NetworkConnectivityConfiguration + } + + type mwsNetworkConnectivityConfigurationParams struct { + Name string `json:"name"` + } + + return common.AccountDataWithParams(func(ctx context.Context, data mwsNetworkConnectivityConfigurationParams, a *databricks.AccountClient) (*mwsNetworkConnectivityConfiguration, error) { + list, err := a.NetworkConnectivity.ListNetworkConnectivityConfigurationsAll(ctx, settings.ListNetworkConnectivityConfigurationsRequest{}) + if err != nil { + return nil, err + } + + for _, ncc := range list { + if data.Name == ncc.Name { + return &mwsNetworkConnectivityConfiguration{NetworkConnectivityConfiguration: ncc}, nil + } + } + return nil, nil + }) +} diff --git a/mws/data_mws_network_connectivity_config_test.go b/mws/data_mws_network_connectivity_config_test.go new file mode 100644 index 0000000000..e3eaa0ee28 --- /dev/null +++ b/mws/data_mws_network_connectivity_config_test.go @@ -0,0 +1,67 @@ +package mws + +import ( + "fmt" + "testing" + + "github.com/databricks/databricks-sdk-go/experimental/mocks" + "github.com/databricks/databricks-sdk-go/service/settings" + "github.com/stretchr/testify/mock" + + "github.com/databricks/terraform-provider-databricks/qa" +) + +func TestDataSourceMwsNetworkConnectivityConfig(t *testing.T) { + var ncc = settings.NetworkConnectivityConfiguration{ + AccountId: "abc", + CreationTime: 0, + EgressConfig: &settings.NccEgressConfig{ + DefaultRules: nil, + TargetRules: nil, + }, + Name: "def", + NetworkConnectivityConfigId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + Region: "us-east-1", + UpdatedTime: 0, + } + + qa.ResourceFixture{ + MockAccountClientFunc: func(a *mocks.MockAccountClient) { + api := a.GetMockNetworkConnectivityAPI().EXPECT() + api.ListNetworkConnectivityConfigurationsAll(mock.Anything, settings.ListNetworkConnectivityConfigurationsRequest{}).Return( + []settings.NetworkConnectivityConfiguration{ncc}, nil, + ) + }, + AccountID: "abc", + Read: true, + NonWritable: true, + Resource: DataSourceMwsNetworkConnectivityConfig(), + ID: "_", + HCL: fmt.Sprintf(` + name = "%s" + `, ncc.Name), + }.ApplyAndExpectData(t, map[string]interface{}{ + "account_id": "abc", + "creation_time": 0, + "egress_config": []interface{}{map[string]interface{}{"default_rules": []interface{}{}, "target_rules": []interface{}{}}}, + "id": "_", + "name": "def", + "network_connectivity_config_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "region": "us-east-1", + "updated_time": 0, + }) +} + +func TestDataSourceMwsNetworkConnectivityConfig_Error(t *testing.T) { + qa.ResourceFixture{ + Fixtures: qa.HTTPFailures, + AccountID: "abc", + Resource: DataSourceMwsNetworkConnectivityConfig(), + Read: true, + NonWritable: true, + ID: "_", + HCL: ` + name = "def" + `, + }.ExpectError(t, "i'm a teapot") +} diff --git a/mws/data_mws_network_connectivity_configs.go b/mws/data_mws_network_connectivity_configs.go new file mode 100644 index 0000000000..870973fe53 --- /dev/null +++ b/mws/data_mws_network_connectivity_configs.go @@ -0,0 +1,43 @@ +package mws + +import ( + "context" + + "github.com/databricks/databricks-sdk-go" + "github.com/databricks/databricks-sdk-go/service/settings" + "github.com/databricks/terraform-provider-databricks/common" +) + +func DataSourceMwsNetworkConnectivityConfigs() common.Resource { + type mwsNetworkConnectivityConfiguration struct { + Names []string `json:"names" tf:"computed,optional"` + } + + type mwsNetworkConnectivityConfigurationParams struct { + Names []string `json:"names" tf:"computed,optional"` + Region string `json:"region" tf:"optional"` + } + + return common.AccountDataWithParams(func(ctx context.Context, data mwsNetworkConnectivityConfigurationParams, a *databricks.AccountClient) (*mwsNetworkConnectivityConfiguration, error) { + list, err := a.NetworkConnectivity.ListNetworkConnectivityConfigurationsAll(ctx, settings.ListNetworkConnectivityConfigurationsRequest{}) + if err != nil { + return nil, err + } + + if data.Region != "" { + filtered := []string{} + for _, ncc := range list { + if data.Region == ncc.Region { + filtered = append(filtered, ncc.Name) + } + } + return &mwsNetworkConnectivityConfiguration{Names: filtered}, nil + } + + names := []string{} + for _, ncc := range list { + names = append(names, ncc.Name) + } + return &mwsNetworkConnectivityConfiguration{Names: names}, nil + }) +} diff --git a/mws/data_mws_network_connectivity_configs_test.go b/mws/data_mws_network_connectivity_configs_test.go new file mode 100644 index 0000000000..71fab07131 --- /dev/null +++ b/mws/data_mws_network_connectivity_configs_test.go @@ -0,0 +1,144 @@ +package mws + +import ( + "fmt" + "testing" + + "github.com/databricks/databricks-sdk-go/experimental/mocks" + "github.com/databricks/databricks-sdk-go/service/settings" + "github.com/stretchr/testify/mock" + + "github.com/databricks/terraform-provider-databricks/qa" +) + +func getTestNccs() []settings.NetworkConnectivityConfiguration { + return []settings.NetworkConnectivityConfiguration{ + { + AccountId: "abc", + CreationTime: 0, + EgressConfig: &settings.NccEgressConfig{ + DefaultRules: nil, + TargetRules: nil, + }, + Name: "def", + NetworkConnectivityConfigId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + Region: "us-east-1", + UpdatedTime: 0, + }, + { + AccountId: "abc", + CreationTime: 0, + EgressConfig: &settings.NccEgressConfig{ + DefaultRules: nil, + TargetRules: nil, + }, + Name: "ghi", + NetworkConnectivityConfigId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + Region: "us-west-1", + UpdatedTime: 0, + }, + } +} + +func TestDataSourceMwsNetworkConnectivityConfigs_All(t *testing.T) { + qa.ResourceFixture{ + MockAccountClientFunc: func(a *mocks.MockAccountClient) { + api := a.GetMockNetworkConnectivityAPI().EXPECT() + api.ListNetworkConnectivityConfigurationsAll(mock.Anything, settings.ListNetworkConnectivityConfigurationsRequest{}).Return( + []settings.NetworkConnectivityConfiguration{ + { + AccountId: "abc", + CreationTime: 0, + EgressConfig: &settings.NccEgressConfig{ + DefaultRules: nil, + TargetRules: nil, + }, + Name: "def", + NetworkConnectivityConfigId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + Region: "us-east-1", + UpdatedTime: 0, + }, + { + AccountId: "abc", + CreationTime: 0, + EgressConfig: &settings.NccEgressConfig{ + DefaultRules: nil, + TargetRules: nil, + }, + Name: "ghi", + NetworkConnectivityConfigId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + Region: "us-west-1", + UpdatedTime: 0, + }, + }, nil, + ) + }, + AccountID: "abc", + Read: true, + NonWritable: true, + Resource: DataSourceMwsNetworkConnectivityConfigs(), + ID: "_", + }.ApplyAndExpectData(t, map[string]any{ + "names": []interface{}{"def", "ghi"}, + }) +} + +func TestDataSourceMwsNetworkConnectivityConfigs_Filter(t *testing.T) { + qa.ResourceFixture{ + MockAccountClientFunc: func(a *mocks.MockAccountClient) { + api := a.GetMockNetworkConnectivityAPI().EXPECT() + api.ListNetworkConnectivityConfigurationsAll(mock.Anything, settings.ListNetworkConnectivityConfigurationsRequest{}).Return( + []settings.NetworkConnectivityConfiguration{ + { + AccountId: "abc", + CreationTime: 0, + EgressConfig: &settings.NccEgressConfig{ + DefaultRules: nil, + TargetRules: nil, + }, + Name: "def", + NetworkConnectivityConfigId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + Region: "us-east-1", + UpdatedTime: 0, + }, + { + AccountId: "abc", + CreationTime: 0, + EgressConfig: &settings.NccEgressConfig{ + DefaultRules: nil, + TargetRules: nil, + }, + Name: "def-3", + NetworkConnectivityConfigId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + Region: "us-west-1", + UpdatedTime: 0, + }, + }, nil, + ) + }, + AccountID: "abc", + Read: true, + NonWritable: true, + Resource: DataSourceMwsNetworkConnectivityConfigs(), + ID: "_", + HCL: fmt.Sprintf(` + region = "%s" + `, getTestNccs()[0].Region), + }.ApplyAndExpectData(t, map[string]any{ + "names": []interface{}{"def"}, + }) +} + +func TestDataSourceMwsNetworkConnectivityConfigs_Error(t *testing.T) { + qa.ResourceFixture{ + Fixtures: qa.HTTPFailures, + AccountID: "abc", + Resource: DataSourceMwsNetworkConnectivityConfigs(), + Read: true, + NonWritable: true, + ID: "_", + HCL: ` + region = "us-east-1" + `, + }.ExpectError(t, "i'm a teapot") +}