diff --git a/.changelog/3610.txt b/.changelog/3610.txt new file mode 100644 index 0000000000..7444f4eb30 --- /dev/null +++ b/.changelog/3610.txt @@ -0,0 +1,11 @@ +```release-note:note +resource/mongodbatlas_stream_connection: Deprecates the `instance_name` attribute `workspace_name`. All configurations using `instance_name` should be updated to use the new `workspace_name` attribute instead + +``` +```release-note:note +data-source/mongodbatlas_stream_connection: Deprecates the `instance_name` attribute `workspace_name`. All configurations using `instance_name` should be updated to use the new `workspace_name` attribute instead +``` + +```release-note:note +data-source/mongodbatlas_stream_connections: Deprecates the `instance_name` attribute `workspace_name`. All configurations using `instance_name` should be updated to use the new `workspace_name` attribute instead +``` \ No newline at end of file diff --git a/docs/data-sources/stream_connection.md b/docs/data-sources/stream_connection.md index 56ebede13a..eb9d1eb837 100644 --- a/docs/data-sources/stream_connection.md +++ b/docs/data-sources/stream_connection.md @@ -11,7 +11,17 @@ subcategory: "Streams" ```terraform data "mongodbatlas_stream_connection" "example" { project_id = "" - instance_name = "" + workspace_name = "" + connection_name = "" +} +``` + +### Example using workspace_name + +```terraform +data "mongodbatlas_stream_connection" "example" { + project_id = "" + workspace_name = "" connection_name = "" } ``` @@ -19,9 +29,12 @@ data "mongodbatlas_stream_connection" "example" { ## Argument Reference * `project_id` - (Required) Unique 24-hexadecimal digit string that identifies your project. -* `instance_name` - (Required) Human-readable label that identifies the stream instance. +* `instance_name` - (Deprecated) Human-readable label that identifies the stream instance. Attribute is deprecated and will be removed in following major versions in favor of `workspace_name`. +* `workspace_name` - (Optional) Human-readable label that identifies the stream instance. Conflicts with `workspace_name`. * `connection_name` - (Required) Human-readable label that identifies the stream connection. In the case of the Sample type, this is the name of the sample source. +~> **NOTE:** Either `workspace_name` or `instance_name` must be provided, but not both. These fields are functionally identical and `workspace_name` is an alias for `instance_name`. `workspace_name` should be used instead of `instance_name`. + ## Attributes Reference * `type` - Type of connection. Can be `AWSLambda`, `Cluster`, `Https`, `Kafka` or `Sample`. diff --git a/docs/data-sources/stream_connections.md b/docs/data-sources/stream_connections.md index fe2020590f..916508347d 100644 --- a/docs/data-sources/stream_connections.md +++ b/docs/data-sources/stream_connections.md @@ -11,14 +11,17 @@ subcategory: "Streams" ```terraform data "mongodbatlas_stream_connections" "test" { project_id = "" - instance_name = "" + workspace_name = "" } ``` ## Argument Reference * `project_id` - (Required) Unique 24-hexadecimal digit string that identifies your project. -* `instance_name` - (Required) Human-readable label that identifies the stream instance. +* `instance_name` - (Deprecated) Human-readable label that identifies the stream instance. Attribute is deprecated and will be removed in following major versions in favor of `workspace_name`. +* `workspace_name` - (Optional) Human-readable label that identifies the stream instance. Conflicts with `instance_name`. + +~> **NOTE:** Either `workspace_name` or `instance_name` must be provided, but not both. These fields are functionally identical and `workspace_name` is an alias for `instance_name`. `workspace_name` should be used instead of `instance_name`. * `page_num` - (Optional) Number of the page that displays the current set of the total objects that the response returns. Defaults to `1`. * `items_per_page` - (Optional) Number of items that the response returns per page, up to a maximum of `500`. Defaults to `100`. @@ -34,7 +37,7 @@ In addition to all arguments above, it also exports the following attributes: ### Stream Connection * `project_id` - Unique 24-hexadecimal digit string that identifies your project. -* `instance_name` - Human-readable label that identifies the stream instance. +* `workspace_name` - Human-readable label that identifies the stream instance. * `connection_name` - Human-readable label that identifies the stream connection. In the case of the Sample type, this is the name of the sample source. * `type` - Type of connection. `AWSLambda`, `Cluster`, `Https`, `Kafka` or `Sample`. diff --git a/docs/resources/stream_connection.md b/docs/resources/stream_connection.md index 6f8bb6778e..d4198695b8 100644 --- a/docs/resources/stream_connection.md +++ b/docs/resources/stream_connection.md @@ -16,7 +16,7 @@ subcategory: "Streams" ```terraform resource "mongodbatlas_stream_connection" "test" { project_id = var.project_id - instance_name = "InstanceName" + workspace_name = "WorkspaceName" connection_name = "ConnectionName" type = "Cluster" cluster_name = "Cluster0" @@ -31,7 +31,7 @@ resource "mongodbatlas_stream_connection" "test" { ```terraform resource "mongodbatlas_stream_connection" "test" { project_id = var.project_id - instance_name = "InstanceName" + workspace_name = "WorskpaceName" connection_name = "ConnectionName" type = "Cluster" cluster_name = "OtherCluster" @@ -44,7 +44,7 @@ resource "mongodbatlas_stream_connection" "test" { ```terraform resource "mongodbatlas_stream_connection" "test" { project_id = var.project_id - instance_name = "NewInstance" + workspace_name = "NewWorkspace" connection_name = "KafkaConnection" type = "Kafka" authentication = { @@ -67,7 +67,7 @@ resource "mongodbatlas_stream_connection" "test" { ```terraform resource "mongodbatlas_stream_connection" "test" { project_id = var.project_id - instance_name = "NewInstance" + workspace_name = "NewWorkspace" connection_name = "KafkaConnection" type = "Kafka" authentication = { @@ -91,7 +91,7 @@ resource "mongodbatlas_stream_connection" "test" { ```terraform resource "mongodbatlas_stream_connection" "test" { project_id = var.project_id - instance_name = "NewInstance" + workspace_name = "NewWorkspace" connection_name = "AWSLambdaConnection" type = "AWSLambda" aws = { @@ -106,7 +106,7 @@ resource "mongodbatlas_stream_connection" "test" { ```terraform resource "mongodbatlas_stream_connection" "example-https" { project_id = var.project_id - instance_name = mongodbatlas_stream_instance.example.instance_name + workspace_name = mongodbatlas_stream_instance.example.instance_name connection_name = "https_connection_tf_new" type = "Https" url = "https://example.com" @@ -120,10 +120,13 @@ resource "mongodbatlas_stream_connection" "example-https" { ## Argument Reference * `project_id` - (Required) Unique 24-hexadecimal digit string that identifies your project. -* `instance_name` - (Required) Human-readable label that identifies the stream instance. +* `instance_name` - (Deprecated) Human-readable label that identifies the stream instance. Attribute is deprecated and will be removed in following major versions in favor of `workspace_name`. +* `workspace_name` - (Optional) Human-readable label that identifies the stream instance. Conflicts with `instance_name`. * `connection_name` - (Required) Human-readable label that identifies the stream connection. In the case of the Sample type, this is the name of the sample source. * `type` - (Required) Type of connection. Can be `AWSLambda`, `Cluster`, `Https`, `Kafka` or `Sample`. +~> **NOTE:** Either `workspace_name` or `instance_name` must be provided, but not both. These fields are functionally identical and `workspace_name` is an alias for `instance_name`. `workspace_name` should be used instead of `instance_name`. + If `type` is of value `Cluster` the following additional arguments are defined: * `cluster_name` - Name of the cluster configured for this connection. * `db_role_to_execute` - The name of a Built in or Custom DB Role to connect to an Atlas Cluster. See [DBRoleToExecute](#DBRoleToExecute). @@ -171,7 +174,7 @@ If `type` is of value `Https` the following additional attributes are defined: ## Import -You can import a stream connection resource using the instance name, project ID, and connection name. The format must be `INSTANCE_NAME-PROJECT_ID-CONNECTION_NAME`. For example: +You can import a stream connection resource using the workspace name, project ID, and connection name. The format must be `WORKSPACE_NAME-PROJECT_ID-CONNECTION_NAME`. For example: ``` $ terraform import mongodbatlas_stream_connection.test "DefaultInstance-12251446ae5f3f6ec7968b13-NewConnection" diff --git a/examples/mongodbatlas_stream_connection/main.tf b/examples/mongodbatlas_stream_connection/main.tf index 8c984caa6b..5680057315 100644 --- a/examples/mongodbatlas_stream_connection/main.tf +++ b/examples/mongodbatlas_stream_connection/main.tf @@ -9,7 +9,7 @@ resource "mongodbatlas_stream_instance" "example" { resource "mongodbatlas_stream_connection" "example-cluster" { project_id = var.project_id - instance_name = mongodbatlas_stream_instance.example.instance_name + workspace_name = mongodbatlas_stream_instance.example.instance_name connection_name = "ClusterConnection" type = "Cluster" cluster_name = var.cluster_name @@ -21,7 +21,7 @@ resource "mongodbatlas_stream_connection" "example-cluster" { resource "mongodbatlas_stream_connection" "example-cross-project-cluster" { project_id = var.project_id - instance_name = mongodbatlas_stream_instance.example.instance_name + workspace_name = mongodbatlas_stream_instance.example.instance_name connection_name = "ClusterCrossProjectConnection" type = "Cluster" cluster_name = var.other_cluster @@ -34,7 +34,7 @@ resource "mongodbatlas_stream_connection" "example-cross-project-cluster" { resource "mongodbatlas_stream_connection" "example-kafka-plaintext" { project_id = var.project_id - instance_name = mongodbatlas_stream_instance.example.instance_name + workspace_name = mongodbatlas_stream_instance.example.instance_name connection_name = "KafkaPlaintextConnection" type = "Kafka" authentication = { @@ -58,7 +58,7 @@ resource "mongodbatlas_stream_connection" "example-kafka-plaintext" { resource "mongodbatlas_stream_connection" "example-kafka-ssl" { project_id = var.project_id - instance_name = mongodbatlas_stream_instance.example.instance_name + workspace_name = mongodbatlas_stream_instance.example.instance_name connection_name = "KafkaSSLConnection" type = "Kafka" authentication = { @@ -78,14 +78,14 @@ resource "mongodbatlas_stream_connection" "example-kafka-ssl" { resource "mongodbatlas_stream_connection" "example-sample" { project_id = var.project_id - instance_name = mongodbatlas_stream_instance.example.instance_name + workspace_name = mongodbatlas_stream_instance.example.instance_name connection_name = "sample_stream_solar" type = "Sample" } resource "mongodbatlas_stream_connection" "example-aws-lambda" { project_id = var.project_id - instance_name = mongodbatlas_stream_instance.example.instance_name + workspace_name = mongodbatlas_stream_instance.example.instance_name connection_name = "AWSLambdaConnection" type = "AWSLambda" aws = { @@ -107,7 +107,7 @@ resource "mongodbatlas_stream_connection" "example-https" { data "mongodbatlas_stream_connection" "example-kafka-ssl" { project_id = var.project_id - instance_name = mongodbatlas_stream_instance.example.instance_name + workspace_name = mongodbatlas_stream_instance.example.instance_name connection_name = mongodbatlas_stream_connection.example-kafka-ssl.connection_name } diff --git a/internal/service/streamconnection/data_source_stream_connection.go b/internal/service/streamconnection/data_source_stream_connection.go index 925cda7096..b4129036d2 100644 --- a/internal/service/streamconnection/data_source_stream_connection.go +++ b/internal/service/streamconnection/data_source_stream_connection.go @@ -2,8 +2,14 @@ package streamconnection import ( "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/datasource" + dsschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/mongodb/terraform-provider-mongodbatlas/internal/common/constant" "github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion" "github.com/mongodb/terraform-provider-mongodbatlas/internal/config" ) @@ -25,7 +31,24 @@ type streamConnectionDS struct { func (d *streamConnectionDS) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { resp.Schema = conversion.DataSourceSchemaFromResource(ResourceSchema(ctx), &conversion.DataSourceSchemaRequest{ - RequiredFields: []string{"project_id", "instance_name", "connection_name"}, + RequiredFields: []string{"project_id", "connection_name"}, + OverridenFields: map[string]dsschema.Attribute{ + "instance_name": dsschema.StringAttribute{ + Optional: true, + MarkdownDescription: "Human-readable label that identifies the stream instance. Conflicts with `workspace_name`.", + DeprecationMessage: fmt.Sprintf(constant.DeprecationParamWithReplacement, "workspace_name"), + Validators: []validator.String{ + stringvalidator.ConflictsWith(path.MatchRoot("workspace_name")), + }, + }, + "workspace_name": dsschema.StringAttribute{ + Optional: true, + MarkdownDescription: "Human-readable label that identifies the stream instance. This is an alias for `instance_name`. Conflicts with `instance_name`.", + Validators: []validator.String{ + stringvalidator.ConflictsWith(path.MatchRoot("instance_name")), + }, + }, + }, }) } @@ -38,15 +61,21 @@ func (d *streamConnectionDS) Read(ctx context.Context, req datasource.ReadReques connV2 := d.Client.AtlasV2 projectID := streamConnectionConfig.ProjectID.ValueString() - instanceName := streamConnectionConfig.InstanceName.ValueString() + workspaceOrInstanceName := getWorkspaceOrInstanceName(&streamConnectionConfig) + if workspaceOrInstanceName == "" { + resp.Diagnostics.AddError("validation error", "workspace_name must be provided") + return + } connectionName := streamConnectionConfig.ConnectionName.ValueString() - apiResp, _, err := connV2.StreamsApi.GetStreamConnection(ctx, projectID, instanceName, connectionName).Execute() + apiResp, _, err := connV2.StreamsApi.GetStreamConnection(ctx, projectID, workspaceOrInstanceName, connectionName).Execute() if err != nil { resp.Diagnostics.AddError("error fetching resource", err.Error()) return } - newStreamConnectionModel, diags := NewTFStreamConnection(ctx, projectID, instanceName, nil, apiResp) + instanceName := streamConnectionConfig.InstanceName.ValueString() + workspaceName := streamConnectionConfig.WorkspaceName.ValueString() + newStreamConnectionModel, diags := NewTFStreamConnectionWithInstanceName(ctx, projectID, instanceName, workspaceName, nil, apiResp) if diags.HasError() { resp.Diagnostics.Append(diags...) return diff --git a/internal/service/streamconnection/data_source_stream_connections.go b/internal/service/streamconnection/data_source_stream_connections.go index 8981205a41..d97224d578 100644 --- a/internal/service/streamconnection/data_source_stream_connections.go +++ b/internal/service/streamconnection/data_source_stream_connections.go @@ -4,8 +4,13 @@ import ( "context" "fmt" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/datasource" + dsschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/mongodb/terraform-provider-mongodbatlas/internal/common/constant" "github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion" "github.com/mongodb/terraform-provider-mongodbatlas/internal/config" "go.mongodb.org/atlas-sdk/v20250312007/admin" @@ -28,11 +33,39 @@ type streamConnectionsDS struct { func (d *streamConnectionsDS) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { resp.Schema = conversion.PluralDataSourceSchemaFromResource(ResourceSchema(ctx), &conversion.PluralDataSourceSchemaRequest{ - RequiredFields: []string{"project_id", "instance_name"}, + RequiredFields: []string{"project_id"}, HasLegacyFields: true, + OverridenRootFields: map[string]dsschema.Attribute{ + "instance_name": dsschema.StringAttribute{ + Optional: true, + MarkdownDescription: "Human-readable label that identifies the stream instance. Conflicts with `workspace_name`.", + DeprecationMessage: fmt.Sprintf(constant.DeprecationParamWithReplacement, "workspace_name"), + Validators: []validator.String{ + stringvalidator.ConflictsWith(path.MatchRoot("workspace_name")), + }, + }, + "workspace_name": dsschema.StringAttribute{ + Optional: true, + MarkdownDescription: "Human-readable label that identifies the stream instance. This is an alias for `instance_name`. Conflicts with `instance_name`.", + Validators: []validator.String{ + stringvalidator.ConflictsWith(path.MatchRoot("instance_name")), + }, + }, + }, }) } +// getWorkspaceOrInstanceNameForDS returns the workspace name from either instance_name or workspace_name field for datasource model +func getWorkspaceOrInstanceNameForDS(model *TFStreamConnectionsDSModel) string { + if !model.WorkspaceName.IsNull() && !model.WorkspaceName.IsUnknown() { + return model.WorkspaceName.ValueString() + } + if !model.InstanceName.IsNull() && !model.InstanceName.IsUnknown() { + return model.InstanceName.ValueString() + } + return "" +} + func (d *streamConnectionsDS) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { var streamConnectionsConfig TFStreamConnectionsDSModel resp.Diagnostics.Append(req.Config.Get(ctx, &streamConnectionsConfig)...) @@ -42,13 +75,17 @@ func (d *streamConnectionsDS) Read(ctx context.Context, req datasource.ReadReque connV2 := d.Client.AtlasV2 projectID := streamConnectionsConfig.ProjectID.ValueString() - instanceName := streamConnectionsConfig.InstanceName.ValueString() + workspaceName := getWorkspaceOrInstanceNameForDS(&streamConnectionsConfig) + if workspaceName == "" { + resp.Diagnostics.AddError("validation error", "workspace_name must be provided") + return + } itemsPerPage := streamConnectionsConfig.ItemsPerPage.ValueInt64Pointer() pageNum := streamConnectionsConfig.PageNum.ValueInt64Pointer() apiResp, _, err := connV2.StreamsApi.ListStreamConnectionsWithParams(ctx, &admin.ListStreamConnectionsApiParams{ GroupId: projectID, - TenantName: instanceName, + TenantName: workspaceName, ItemsPerPage: conversion.Int64PtrToIntPtr(itemsPerPage), PageNum: conversion.Int64PtrToIntPtr(pageNum), }).Execute() @@ -67,11 +104,12 @@ func (d *streamConnectionsDS) Read(ctx context.Context, req datasource.ReadReque } type TFStreamConnectionsDSModel struct { - ID types.String `tfsdk:"id"` - ProjectID types.String `tfsdk:"project_id"` - InstanceName types.String `tfsdk:"instance_name"` - Results []TFStreamConnectionModel `tfsdk:"results"` - PageNum types.Int64 `tfsdk:"page_num"` - ItemsPerPage types.Int64 `tfsdk:"items_per_page"` - TotalCount types.Int64 `tfsdk:"total_count"` + ID types.String `tfsdk:"id"` + ProjectID types.String `tfsdk:"project_id"` + InstanceName types.String `tfsdk:"instance_name"` + WorkspaceName types.String `tfsdk:"workspace_name"` + Results []TFStreamConnectionModel `tfsdk:"results"` + PageNum types.Int64 `tfsdk:"page_num"` + ItemsPerPage types.Int64 `tfsdk:"items_per_page"` + TotalCount types.Int64 `tfsdk:"total_count"` } diff --git a/internal/service/streamconnection/model_stream_connection.go b/internal/service/streamconnection/model_stream_connection.go index 485976a4d5..af938dc5eb 100644 --- a/internal/service/streamconnection/model_stream_connection.go +++ b/internal/service/streamconnection/model_stream_connection.go @@ -117,12 +117,26 @@ func NewStreamConnectionUpdateReq(ctx context.Context, plan *TFStreamConnectionM return streamConnection, nil } -func NewTFStreamConnection(ctx context.Context, projID, instanceName string, currAuthConfig *types.Object, apiResp *admin.StreamsConnection) (*TFStreamConnectionModel, diag.Diagnostics) { - rID := fmt.Sprintf("%s-%s-%s", instanceName, projID, conversion.SafeString(apiResp.Name)) +func NewTFStreamConnection(ctx context.Context, projID, workspaceName string, currAuthConfig *types.Object, apiResp *admin.StreamsConnection) (*TFStreamConnectionModel, diag.Diagnostics) { + return NewTFStreamConnectionWithInstanceName(ctx, projID, "", workspaceName, currAuthConfig, apiResp) +} + +// determines if the original model was created with instance_name or workspace_name and sets the appropriate field +func NewTFStreamConnectionWithInstanceName(ctx context.Context, projID, instanceName, workspaceName string, currAuthConfig *types.Object, apiResp *admin.StreamsConnection) (*TFStreamConnectionModel, diag.Diagnostics) { + if workspaceName != "" && instanceName != "" { + return nil, diag.Diagnostics{diag.NewErrorDiagnostic("Attribute \"workspace_name\" cannot be specified when \"instance_name\" is specified", "")} + } + + // Determine the effective instance/workspace name for the ID + workspaceOrInstanceName := workspaceName + if workspaceOrInstanceName == "" { + workspaceOrInstanceName = instanceName + } + + rID := fmt.Sprintf("%s-%s-%s", workspaceOrInstanceName, projID, conversion.SafeString(apiResp.Name)) connectionModel := TFStreamConnectionModel{ ID: types.StringValue(rID), ProjectID: types.StringValue(projID), - InstanceName: types.StringValue(instanceName), ConnectionName: types.StringPointerValue(apiResp.Name), Type: types.StringPointerValue(apiResp.Type), ClusterName: types.StringPointerValue(apiResp.ClusterName), @@ -131,6 +145,16 @@ func NewTFStreamConnection(ctx context.Context, projID, instanceName string, cur URL: types.StringPointerValue(apiResp.Url), } + // Set the appropriate field based on the original model + if workspaceName != "" { + connectionModel.WorkspaceName = types.StringValue(workspaceName) + connectionModel.InstanceName = types.StringNull() + } else { + // Default to instance_name for backward compatibility + connectionModel.InstanceName = types.StringValue(instanceName) + connectionModel.WorkspaceName = types.StringNull() + } + authModel, diags := newTFConnectionAuthenticationModel(ctx, currAuthConfig, apiResp.Authentication) if diags.HasError() { return nil, diags @@ -242,22 +266,30 @@ func NewTFStreamConnections(ctx context.Context, paginatedResult *admin.PaginatedApiStreamsConnection) (*TFStreamConnectionsDSModel, diag.Diagnostics) { input := paginatedResult.GetResults() results := make([]TFStreamConnectionModel, len(input)) + + workspaceName := streamConnectionsConfig.WorkspaceName.ValueString() + instanceName := streamConnectionsConfig.InstanceName.ValueString() + if workspaceName != "" && instanceName != "" { + return nil, diag.Diagnostics{diag.NewErrorDiagnostic("Attribute \"workspace_name\" cannot be specified when \"instance_name\" is specified", "")} + } + for i := range input { projectID := streamConnectionsConfig.ProjectID.ValueString() - instanceName := streamConnectionsConfig.InstanceName.ValueString() - connectionModel, diags := NewTFStreamConnection(ctx, projectID, instanceName, nil, &input[i]) + connectionModel, diags := NewTFStreamConnectionWithInstanceName(ctx, projectID, instanceName, workspaceName, nil, &input[i]) if diags.HasError() { return nil, diags } results[i] = *connectionModel } + return &TFStreamConnectionsDSModel{ - ID: types.StringValue(id.UniqueId()), - ProjectID: streamConnectionsConfig.ProjectID, - InstanceName: streamConnectionsConfig.InstanceName, - Results: results, - PageNum: streamConnectionsConfig.PageNum, - ItemsPerPage: streamConnectionsConfig.ItemsPerPage, - TotalCount: types.Int64PointerValue(conversion.IntPtrToInt64Ptr(paginatedResult.TotalCount)), + ID: types.StringValue(id.UniqueId()), + ProjectID: streamConnectionsConfig.ProjectID, + InstanceName: streamConnectionsConfig.InstanceName, + WorkspaceName: streamConnectionsConfig.WorkspaceName, + Results: results, + PageNum: streamConnectionsConfig.PageNum, + ItemsPerPage: streamConnectionsConfig.ItemsPerPage, + TotalCount: types.Int64PointerValue(conversion.IntPtrToInt64Ptr(paginatedResult.TotalCount)), }, nil } diff --git a/internal/service/streamconnection/model_stream_connection_test.go b/internal/service/streamconnection/model_stream_connection_test.go index 1052fe7c12..448da649fe 100644 --- a/internal/service/streamconnection/model_stream_connection_test.go +++ b/internal/service/streamconnection/model_stream_connection_test.go @@ -2,6 +2,7 @@ package streamconnection_test import ( "fmt" + "strings" "testing" "github.com/hashicorp/terraform-plugin-framework/types" @@ -68,7 +69,7 @@ func TestStreamConnectionSDKToTFModel(t *testing.T) { providedAuthConfig: nil, expectedTFModel: &streamconnection.TFStreamConnectionModel{ ProjectID: types.StringValue(dummyProjectID), - InstanceName: types.StringValue(instanceName), + WorkspaceName: types.StringValue(instanceName), ConnectionName: types.StringValue(connectionName), Type: types.StringValue("Cluster"), ClusterName: types.StringValue(clusterName), @@ -98,7 +99,7 @@ func TestStreamConnectionSDKToTFModel(t *testing.T) { providedAuthConfig: nil, expectedTFModel: &streamconnection.TFStreamConnectionModel{ ProjectID: types.StringValue(dummyProjectID), - InstanceName: types.StringValue(instanceName), + WorkspaceName: types.StringValue(instanceName), ConnectionName: types.StringValue(connectionName), Type: types.StringValue("Cluster"), ClusterName: types.StringValue(clusterName), @@ -133,7 +134,7 @@ func TestStreamConnectionSDKToTFModel(t *testing.T) { providedAuthConfig: &authConfigWithPasswordDefined, expectedTFModel: &streamconnection.TFStreamConnectionModel{ ProjectID: types.StringValue(dummyProjectID), - InstanceName: types.StringValue(instanceName), + WorkspaceName: types.StringValue(instanceName), ConnectionName: types.StringValue(connectionName), Type: types.StringValue("Kafka"), Authentication: tfAuthenticationObject(t, authMechanism, authUsername, "raw password"), // password value is obtained from config, not api resp. @@ -147,6 +148,7 @@ func TestStreamConnectionSDKToTFModel(t *testing.T) { }, }, { + name: "Kafka connection type SDK response with no optional values provided", SDKResp: &admin.StreamsConnection{ Name: admin.PtrString(connectionName), @@ -157,7 +159,7 @@ func TestStreamConnectionSDKToTFModel(t *testing.T) { providedAuthConfig: nil, expectedTFModel: &streamconnection.TFStreamConnectionModel{ ProjectID: types.StringValue(dummyProjectID), - InstanceName: types.StringValue(instanceName), + WorkspaceName: types.StringValue(instanceName), ConnectionName: types.StringValue(connectionName), Type: types.StringValue("Kafka"), Authentication: types.ObjectNull(streamconnection.ConnectionAuthenticationObjectType.AttrTypes), @@ -190,7 +192,7 @@ func TestStreamConnectionSDKToTFModel(t *testing.T) { providedAuthConfig: nil, expectedTFModel: &streamconnection.TFStreamConnectionModel{ ProjectID: types.StringValue(dummyProjectID), - InstanceName: types.StringValue(instanceName), + WorkspaceName: types.StringValue(instanceName), ConnectionName: types.StringValue(connectionName), Type: types.StringValue("Kafka"), Authentication: tfAuthenticationObjectWithNoPassword(t, authMechanism, authUsername), @@ -213,7 +215,7 @@ func TestStreamConnectionSDKToTFModel(t *testing.T) { providedInstanceName: instanceName, expectedTFModel: &streamconnection.TFStreamConnectionModel{ ProjectID: types.StringValue(dummyProjectID), - InstanceName: types.StringValue(instanceName), + WorkspaceName: types.StringValue(instanceName), ConnectionName: types.StringValue(sampleConnectionName), Type: types.StringValue("Sample"), Authentication: types.ObjectNull(streamconnection.ConnectionAuthenticationObjectType.AttrTypes), @@ -236,7 +238,7 @@ func TestStreamConnectionSDKToTFModel(t *testing.T) { providedInstanceName: instanceName, expectedTFModel: &streamconnection.TFStreamConnectionModel{ ProjectID: types.StringValue(dummyProjectID), - InstanceName: types.StringValue(instanceName), + WorkspaceName: types.StringValue(instanceName), ConnectionName: types.StringValue(awslambdaConnectionName), Type: types.StringValue("AWSLambda"), Authentication: types.ObjectNull(streamconnection.ConnectionAuthenticationObjectType.AttrTypes), @@ -436,6 +438,25 @@ func TestStreamConnectionsSDKToTFModel(t *testing.T) { Results: []streamconnection.TFStreamConnectionModel{}, }, }, + { + name: "With workspace name and no page options", + SDKResp: &admin.PaginatedApiStreamsConnection{ + Results: &[]admin.StreamsConnection{}, + TotalCount: admin.PtrInt(0), + }, + providedConfig: &streamconnection.TFStreamConnectionsDSModel{ + ProjectID: types.StringValue(dummyProjectID), + WorkspaceName: types.StringValue(instanceName), + }, + expectedTFModel: &streamconnection.TFStreamConnectionsDSModel{ + ProjectID: types.StringValue(dummyProjectID), + WorkspaceName: types.StringValue(instanceName), + PageNum: types.Int64Null(), + ItemsPerPage: types.Int64Null(), + TotalCount: types.Int64Value(0), + Results: []streamconnection.TFStreamConnectionModel{}, + }, + }, } for _, tc := range testCases { @@ -452,6 +473,43 @@ func TestStreamConnectionsSDKToTFModel(t *testing.T) { } } +type connectionsSDKToTFModelErrorTestCase struct { + SDKResp *admin.PaginatedApiStreamsConnection + providedConfig *streamconnection.TFStreamConnectionsDSModel + expectedErrorString string + name string +} + +func TestStreamConnectionsSDKToTFModelError(t *testing.T) { + testCases := []connectionsSDKToTFModelErrorTestCase{ + { + name: "With workspace name and instance name", + SDKResp: &admin.PaginatedApiStreamsConnection{ + Results: &[]admin.StreamsConnection{}, + TotalCount: admin.PtrInt(0), + }, + providedConfig: &streamconnection.TFStreamConnectionsDSModel{ + ProjectID: types.StringValue(dummyProjectID), + WorkspaceName: types.StringValue(instanceName), + InstanceName: types.StringValue(instanceName), + }, + expectedErrorString: "Attribute \"workspace_name\" cannot be specified when \"instance_name\" is specified", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + _, diags := streamconnection.NewTFStreamConnections(t.Context(), tc.providedConfig, tc.SDKResp) + if !diags.HasError() { + t.Fatalf("expected error but got none") + } + if !strings.Contains(diags.Errors()[0].Summary(), tc.expectedErrorString) { + t.Fatalf("expected error %s but got %s", tc.expectedErrorString, diags.Errors()[0].Summary()) + } + }) + } +} + type tfToSDKCreateModelTestCase struct { tfModel *streamconnection.TFStreamConnectionModel expectedSDKReq *admin.StreamsConnection diff --git a/internal/service/streamconnection/resource_schema.go b/internal/service/streamconnection/resource_schema.go index 188d5ecbcd..c27550ff45 100644 --- a/internal/service/streamconnection/resource_schema.go +++ b/internal/service/streamconnection/resource_schema.go @@ -2,14 +2,17 @@ package streamconnection import ( "context" + "fmt" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/objectplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/mongodb/terraform-provider-mongodbatlas/internal/common/constant" ) func ResourceSchema(ctx context.Context) schema.Schema { @@ -28,10 +31,25 @@ func ResourceSchema(ctx context.Context) schema.Schema { }, }, "instance_name": schema.StringAttribute{ - Required: true, + Optional: true, + Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.RequiresReplace(), }, + Validators: []validator.String{ + stringvalidator.ConflictsWith(path.MatchRoot("workspace_name")), + }, + DeprecationMessage: fmt.Sprintf(constant.DeprecationParamWithReplacement, "workspace_name"), + }, + "workspace_name": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Validators: []validator.String{ + stringvalidator.ConflictsWith(path.MatchRoot("instance_name")), + }, }, "connection_name": schema.StringAttribute{ Required: true, diff --git a/internal/service/streamconnection/resource_stream_connection.go b/internal/service/streamconnection/resource_stream_connection.go index ddcbd854bb..8d124249b3 100644 --- a/internal/service/streamconnection/resource_stream_connection.go +++ b/internal/service/streamconnection/resource_stream_connection.go @@ -36,6 +36,7 @@ type streamConnectionRS struct { type TFStreamConnectionModel struct { ID types.String `tfsdk:"id"` ProjectID types.String `tfsdk:"project_id"` + WorkspaceName types.String `tfsdk:"workspace_name"` InstanceName types.String `tfsdk:"instance_name"` ConnectionName types.String `tfsdk:"connection_name"` Type types.String `tfsdk:"type"` @@ -116,6 +117,17 @@ func (r *streamConnectionRS) Schema(ctx context.Context, req resource.SchemaRequ conversion.UpdateSchemaDescription(&resp.Schema) } +// getWorkspaceOrInstanceName returns the workspace name from workspace_name or instance_name field +func getWorkspaceOrInstanceName(model *TFStreamConnectionModel) string { + if !model.WorkspaceName.IsNull() && !model.WorkspaceName.IsUnknown() { + return model.WorkspaceName.ValueString() + } + if !model.InstanceName.IsNull() && !model.InstanceName.IsUnknown() { + return model.InstanceName.ValueString() + } + return "" +} + func (r *streamConnectionRS) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { var streamConnectionPlan TFStreamConnectionModel resp.Diagnostics.Append(req.Plan.Get(ctx, &streamConnectionPlan)...) @@ -125,19 +137,27 @@ func (r *streamConnectionRS) Create(ctx context.Context, req resource.CreateRequ connV2 := r.Client.AtlasV2 projectID := streamConnectionPlan.ProjectID.ValueString() - instanceName := streamConnectionPlan.InstanceName.ValueString() + workspaceOrInstanceName := getWorkspaceOrInstanceName(&streamConnectionPlan) + if workspaceOrInstanceName == "" { + resp.Diagnostics.AddError("validation error", "workspace_name must be provided") + return + } + streamConnectionReq, diags := NewStreamConnectionReq(ctx, &streamConnectionPlan) if diags.HasError() { resp.Diagnostics.Append(diags...) return } - apiResp, _, err := connV2.StreamsApi.CreateStreamConnection(ctx, projectID, instanceName, streamConnectionReq).Execute() + apiResp, _, err := connV2.StreamsApi.CreateStreamConnection(ctx, projectID, workspaceOrInstanceName, streamConnectionReq).Execute() if err != nil { resp.Diagnostics.AddError("error creating resource", err.Error()) return } - newStreamConnectionModel, diags := NewTFStreamConnection(ctx, projectID, instanceName, &streamConnectionPlan.Authentication, apiResp) + instanceName := streamConnectionPlan.InstanceName.ValueString() + workspaceName := streamConnectionPlan.WorkspaceName.ValueString() + + newStreamConnectionModel, diags := NewTFStreamConnectionWithInstanceName(ctx, projectID, instanceName, workspaceName, &streamConnectionPlan.Authentication, apiResp) if diags.HasError() { resp.Diagnostics.Append(diags...) return @@ -154,9 +174,13 @@ func (r *streamConnectionRS) Read(ctx context.Context, req resource.ReadRequest, connV2 := r.Client.AtlasV2 projectID := streamConnectionState.ProjectID.ValueString() - instanceName := streamConnectionState.InstanceName.ValueString() + workspaceOrInstanceName := getWorkspaceOrInstanceName(&streamConnectionState) + if workspaceOrInstanceName == "" { + resp.Diagnostics.AddError("validation error", "workspace_name must be provided") + return + } connectionName := streamConnectionState.ConnectionName.ValueString() - apiResp, getResp, err := connV2.StreamsApi.GetStreamConnection(ctx, projectID, instanceName, connectionName).Execute() + apiResp, getResp, err := connV2.StreamsApi.GetStreamConnection(ctx, projectID, workspaceOrInstanceName, connectionName).Execute() if err != nil { if validate.StatusNotFound(getResp) { resp.State.RemoveResource(ctx) @@ -166,7 +190,9 @@ func (r *streamConnectionRS) Read(ctx context.Context, req resource.ReadRequest, return } - newStreamConnectionModel, diags := NewTFStreamConnection(ctx, projectID, instanceName, &streamConnectionState.Authentication, apiResp) + instanceName := streamConnectionState.InstanceName.ValueString() + workspaceName := streamConnectionState.WorkspaceName.ValueString() + newStreamConnectionModel, diags := NewTFStreamConnectionWithInstanceName(ctx, projectID, instanceName, workspaceName, &streamConnectionState.Authentication, apiResp) if diags.HasError() { resp.Diagnostics.Append(diags...) return @@ -183,20 +209,26 @@ func (r *streamConnectionRS) Update(ctx context.Context, req resource.UpdateRequ connV2 := r.Client.AtlasV2 projectID := streamConnectionPlan.ProjectID.ValueString() - instanceName := streamConnectionPlan.InstanceName.ValueString() + workspaceOrInstanceName := getWorkspaceOrInstanceName(&streamConnectionPlan) + if workspaceOrInstanceName == "" { + resp.Diagnostics.AddError("validation error", "workspace_name must be provided") + return + } connectionName := streamConnectionPlan.ConnectionName.ValueString() streamConnectionReq, diags := NewStreamConnectionUpdateReq(ctx, &streamConnectionPlan) if diags.HasError() { resp.Diagnostics.Append(diags...) return } - apiResp, _, err := connV2.StreamsApi.UpdateStreamConnection(ctx, projectID, instanceName, connectionName, streamConnectionReq).Execute() + apiResp, _, err := connV2.StreamsApi.UpdateStreamConnection(ctx, projectID, workspaceOrInstanceName, connectionName, streamConnectionReq).Execute() if err != nil { resp.Diagnostics.AddError("error updating resource", err.Error()) return } - newStreamConnectionModel, diags := NewTFStreamConnection(ctx, projectID, instanceName, &streamConnectionPlan.Authentication, apiResp) + instanceName := streamConnectionPlan.InstanceName.ValueString() + workspaceName := streamConnectionPlan.WorkspaceName.ValueString() + newStreamConnectionModel, diags := NewTFStreamConnectionWithInstanceName(ctx, projectID, instanceName, workspaceName, &streamConnectionPlan.Authentication, apiResp) if diags.HasError() { resp.Diagnostics.Append(diags...) return @@ -213,7 +245,11 @@ func (r *streamConnectionRS) Delete(ctx context.Context, req resource.DeleteRequ connV2 := r.Client.AtlasV2 projectID := streamConnectionState.ProjectID.ValueString() - instanceName := streamConnectionState.InstanceName.ValueString() + instanceName := getWorkspaceOrInstanceName(streamConnectionState) + if instanceName == "" { + resp.Diagnostics.AddError("validation error", "workspace_name must be provided") + return + } connectionName := streamConnectionState.ConnectionName.ValueString() if err := DeleteStreamConnection(ctx, connV2.StreamsApi, projectID, instanceName, connectionName, 10*time.Minute); err != nil { resp.Diagnostics.AddError("error deleting resource", err.Error()) diff --git a/internal/service/streamconnection/resource_stream_connection_test.go b/internal/service/streamconnection/resource_stream_connection_test.go index a23a4f2a54..1e0c9f602a 100644 --- a/internal/service/streamconnection/resource_stream_connection_test.go +++ b/internal/service/streamconnection/resource_stream_connection_test.go @@ -19,7 +19,7 @@ const ( dataSourceConfig = ` data "mongodbatlas_stream_connection" "test" { project_id = mongodbatlas_stream_connection.test.project_id - instance_name = mongodbatlas_stream_connection.test.instance_name + workspace_name = mongodbatlas_stream_connection.test.workspace_name connection_name = mongodbatlas_stream_connection.test.connection_name } ` @@ -27,13 +27,13 @@ data "mongodbatlas_stream_connection" "test" { dataSourcePluralConfig = ` data "mongodbatlas_stream_connections" "test" { project_id = mongodbatlas_stream_connection.test.project_id - instance_name = mongodbatlas_stream_connection.test.instance_name + workspace_name = mongodbatlas_stream_connection.test.workspace_name } ` dataSourcePluralConfigWithPage = ` data "mongodbatlas_stream_connections" "test" { project_id = mongodbatlas_stream_connection.test.project_id - instance_name = mongodbatlas_stream_connection.test.instance_name + workspace_name = mongodbatlas_stream_connection.test.workspace_name page_num = 2 # no specific reason for 2, just to test pagination items_per_page = 1 } @@ -361,6 +361,57 @@ func TestAccStreamRSStreamConnection_AWSLambda(t *testing.T) { }) } +func TestAccStreamRSStreamConnection_workspaceName(t *testing.T) { + var ( + projectID, instanceName = acc.ProjectIDExecutionWithStreamInstance(t) + connectionName = acc.RandomName() + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acc.PreCheckBasic(t) }, + ProtoV6ProviderFactories: acc.TestAccProviderV6Factories, + CheckDestroy: CheckDestroyStreamConnection, + Steps: []resource.TestStep{ + { + Config: configureKafkaWithWorkspaceName(projectID, instanceName, connectionName, "user", "password", "localhost:9092"), + Check: resource.ComposeAggregateTestCheckFunc( + checkStreamConnectionExists(), + resource.TestCheckResourceAttr(resourceName, "workspace_name", instanceName), + resource.TestCheckResourceAttr(resourceName, "connection_name", connectionName), + resource.TestCheckResourceAttr(resourceName, "type", "Kafka"), + resource.TestCheckNoResourceAttr(resourceName, "instance_name"), + ), + }, + { + ResourceName: resourceName, + ImportStateIdFunc: checkStreamConnectionImportStateIDFunc(resourceName), + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"authentication.password"}, + }, + }, + }) +} + +func TestAccStreamRSStreamConnection_conflictingFields(t *testing.T) { + var ( + projectID, instanceName = acc.ProjectIDExecutionWithStreamInstance(t) + connectionName = "conflict-test" + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acc.PreCheckBasic(t) }, + ProtoV6ProviderFactories: acc.TestAccProviderV6Factories, + CheckDestroy: CheckDestroyStreamConnection, + Steps: []resource.TestStep{ + { + Config: configureKafkaWithInstanceAndWorkspaceName(projectID, instanceName, connectionName, "user", "password", "localhost:9092"), + ExpectError: regexp.MustCompile("Attribute \"workspace_name\" cannot be specified when \"instance_name\" is specified"), + }, + }, + }) +} + func configureKafka(projectRef, instanceName, connectionName, username, password, bootstrapServers, configValue, networkingConfig string, useSSL bool) string { securityConfig := ` security = { @@ -377,7 +428,7 @@ func configureKafka(projectRef, instanceName, connectionName, username, password return fmt.Sprintf(` resource "mongodbatlas_stream_connection" "test" { project_id = %[1]s - instance_name = %[2]q + workspace_name = %[2]q connection_name = %[3]q type = "Kafka" authentication = { @@ -403,19 +454,66 @@ func configureSampleStream(projectID, instanceName, sampleName string) string { resource "mongodbatlas_stream_connection" "test" { project_id = mongodbatlas_stream_instance.test.project_id - instance_name = mongodbatlas_stream_instance.test.instance_name + workspace_name = mongodbatlas_stream_instance.test.instance_name connection_name = %[2]q type = "Sample" } `, streamInstanceConfig, sampleName) } +func configureKafkaWithWorkspaceName(projectID, instanceName, connectionName, username, password, bootstrapServers string) string { + return fmt.Sprintf(` + resource "mongodbatlas_stream_connection" "test" { + project_id = %[1]q + workspace_name = %[2]q + connection_name = %[3]q + type = "Kafka" + authentication = { + mechanism = "PLAIN" + username = %[4]q + password = %[5]q + } + bootstrap_servers = %[6]q + config = { + "auto.offset.reset": "earliest" + } + security = { + protocol = "SASL_PLAINTEXT" + } + } + `, projectID, instanceName, connectionName, username, password, bootstrapServers) +} + +func configureKafkaWithInstanceAndWorkspaceName(projectID, instanceName, connectionName, username, password, bootstrapServers string) string { + return fmt.Sprintf(` + resource "mongodbatlas_stream_connection" "test" { + project_id = %[1]q + instance_name = %[2]q + workspace_name = %[2]q + connection_name = %[3]q + type = "Kafka" + authentication = { + mechanism = "PLAIN" + username = %[4]q + password = %[5]q + } + bootstrap_servers = %[6]q + config = { + "auto.offset.reset": "earliest" + } + security = { + protocol = "SASL_PLAINTEXT" + } + } + `, projectID, instanceName, connectionName, username, password, bootstrapServers) +} + func checkSampleStreamAttributes( resourceName, instanceName, sampleName string) resource.TestCheckFunc { resourceChecks := []resource.TestCheckFunc{ checkStreamConnectionExists(), resource.TestCheckResourceAttrSet(resourceName, "project_id"), - resource.TestCheckResourceAttr(resourceName, "instance_name", instanceName), + resource.TestCheckResourceAttr(resourceName, "workspace_name", instanceName), resource.TestCheckResourceAttr(resourceName, "connection_name", sampleName), resource.TestCheckResourceAttr(resourceName, "type", "Sample"), } @@ -425,7 +523,7 @@ func checkSampleStreamAttributes( func checkHTTPSAttributes(instanceName, url string) resource.TestCheckFunc { setChecks := []string{"project_id"} mapChecks := map[string]string{ - "instance_name": instanceName, + "workspace_name": instanceName, "connection_name": "ConnectionNameHttps", "type": "Https", "url": url, @@ -441,7 +539,7 @@ func checkKafkaAttributes( resource.TestCheckResourceAttrSet(resourceName, "project_id"), resource.TestCheckResourceAttr(resourceName, "connection_name", connectionName), resource.TestCheckResourceAttr(resourceName, "type", "Kafka"), - resource.TestCheckResourceAttr(resourceName, "instance_name", instanceName), + resource.TestCheckResourceAttr(resourceName, "workspace_name", instanceName), resource.TestCheckResourceAttr(resourceName, "authentication.mechanism", "PLAIN"), resource.TestCheckResourceAttr(resourceName, "authentication.username", username), resource.TestCheckResourceAttr(resourceName, "bootstrap_servers", bootstrapServers), @@ -468,7 +566,7 @@ func configureCluster(projectID, instanceName, connectionName, clusterName strin return fmt.Sprintf(` resource "mongodbatlas_stream_connection" "test" { project_id = %[1]q - instance_name = %[2]q + workspace_name = %[2]q connection_name = %[3]q type = "Cluster" cluster_name = %[4]q @@ -484,7 +582,7 @@ func configureHTTPS(projectID, instanceName, url, headers string) string { return fmt.Sprintf(` resource "mongodbatlas_stream_connection" "test" { project_id = %[1]q - instance_name = %[2]q + workspace_name = %[2]q connection_name = "ConnectionNameHttps" type = "Https" url = %[3]q @@ -493,7 +591,7 @@ func configureHTTPS(projectID, instanceName, url, headers string) string { data "mongodbatlas_stream_connection" "test" { project_id = %[1]q - instance_name = %[2]q + workspace_name = %[2]q connection_name = mongodbatlas_stream_connection.test.connection_name } `, projectID, instanceName, url, headers) @@ -503,7 +601,7 @@ func checkClusterAttributes(resourceName, clusterName string) resource.TestCheck resourceChecks := []resource.TestCheckFunc{ checkStreamConnectionExists(), resource.TestCheckResourceAttrSet(resourceName, "project_id"), - resource.TestCheckResourceAttrSet(resourceName, "instance_name"), + resource.TestCheckResourceAttrSet(resourceName, "workspace_name"), resource.TestCheckResourceAttrSet(resourceName, "connection_name"), resource.TestCheckResourceAttr(resourceName, "type", "Cluster"), resource.TestCheckResourceAttr(resourceName, "cluster_name", clusterName), @@ -519,7 +617,7 @@ func checkStreamConnectionImportStateIDFunc(resourceName string) resource.Import if !ok { return "", fmt.Errorf("not found: %s", resourceName) } - return fmt.Sprintf("%s-%s-%s", rs.Primary.Attributes["instance_name"], rs.Primary.Attributes["project_id"], rs.Primary.Attributes["connection_name"]), nil + return fmt.Sprintf("%s-%s-%s", rs.Primary.Attributes["workspace_name"], rs.Primary.Attributes["project_id"], rs.Primary.Attributes["connection_name"]), nil } } @@ -530,7 +628,7 @@ func checkStreamConnectionExists() resource.TestCheckFunc { continue } projectID := rs.Primary.Attributes["project_id"] - instanceName := rs.Primary.Attributes["instance_name"] + instanceName := rs.Primary.Attributes["workspace_name"] connectionName := rs.Primary.Attributes["connection_name"] _, _, err := acc.ConnV2().StreamsApi.GetStreamConnection(context.Background(), projectID, instanceName, connectionName).Execute() if err != nil { @@ -550,7 +648,7 @@ func CheckDestroyStreamConnection(state *terraform.State) error { continue } projectID := rs.Primary.Attributes["project_id"] - instanceName := rs.Primary.Attributes["instance_name"] + instanceName := rs.Primary.Attributes["workspace_name"] connectionName := rs.Primary.Attributes["connection_name"] _, _, err := acc.ConnV2().StreamsApi.GetStreamConnection(context.Background(), projectID, instanceName, connectionName).Execute() if err == nil { @@ -621,7 +719,7 @@ func configureAWSLambda(projectID, instanceName, connectionName, awsIamRoleName resource "mongodbatlas_stream_connection" "test" { project_id = %[1]q - instance_name = %[2]q + workspace_name = %[2]q connection_name = %[3]q type = "AWSLambda" aws = { @@ -636,7 +734,7 @@ func checkAWSLambdaAttributes(resourceName, instanceName, connectionName string) resourceChecks := []resource.TestCheckFunc{ checkStreamConnectionExists(), resource.TestCheckResourceAttrSet(resourceName, "project_id"), - resource.TestCheckResourceAttr(resourceName, "instance_name", instanceName), + resource.TestCheckResourceAttr(resourceName, "workspace_name", instanceName), resource.TestCheckResourceAttr(resourceName, "connection_name", connectionName), resource.TestCheckResourceAttr(resourceName, "type", "AWSLambda"), resource.TestCheckResourceAttrSet(resourceName, "aws.role_arn"), @@ -647,7 +745,7 @@ func checkAWSLambdaAttributes(resourceName, instanceName, connectionName string) func streamConnectionsAttributeChecks(resourceName string, pageNum, itemsPerPage *int) resource.TestCheckFunc { resourceChecks := []resource.TestCheckFunc{ resource.TestCheckResourceAttrSet(resourceName, "project_id"), - resource.TestCheckResourceAttrSet(resourceName, "instance_name"), + resource.TestCheckResourceAttrSet(resourceName, "workspace_name"), resource.TestCheckResourceAttrSet(resourceName, "total_count"), resource.TestCheckResourceAttrSet(resourceName, "results.#"), }