Skip to content

Commit 71bcdb2

Browse files
feat: new mongodbatlas_stream_instances data source (#1701)
1 parent 9a2c2fa commit 71bcdb2

12 files changed

+457
-36
lines changed

.github/workflows/acceptance-tests.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
advanced_cluster: ${{ steps.filter.outputs.advanced_cluster }}
3636
cluster: ${{ steps.filter.outputs.cluster }}
3737
search_deployment: ${{ steps.filter.outputs.search_deployment }}
38-
stream_instance: ${{ steps.filter.outputs.stream_instance }}
38+
stream: ${{ steps.filter.outputs.stream }}
3939
generic: ${{ steps.filter.outputs.generic }}
4040
backup_online_archive: ${{ steps.filter.outputs.backup_online_archive }}
4141
backup_snapshots: ${{ steps.filter.outputs.backup_snapshots }}
@@ -65,7 +65,7 @@ jobs:
6565
- 'internal/service/cluster/*.go'
6666
search_deployment:
6767
- 'internal/service/searchdeployment/*.go'
68-
stream_instance:
68+
stream:
6969
- 'internal/service/streaminstance/*.go'
7070
generic:
7171
- 'internal/service/backupcompliancepolicy/*.go'
@@ -213,9 +213,9 @@ jobs:
213213
TEST_REGEX: "^TestAccSearchDeployment"
214214
run: make testacc
215215

216-
stream_instance:
216+
stream:
217217
needs: [ change-detection ]
218-
if: ${{ needs.change-detection.outputs.stream_instance == 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' || github.event.label.name == 'run-testacc' || github.event.label.name == 'run-testacc-stream-instance' }}
218+
if: ${{ needs.change-detection.outputs.stream == 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' || github.event.label.name == 'run-testacc' || github.event.label.name == 'run-testacc-stream' }}
219219
runs-on: ubuntu-latest
220220
steps:
221221
- name: Checkout
@@ -234,7 +234,7 @@ jobs:
234234
MONGODB_ATLAS_PRIVATE_KEY: ${{ secrets.MONGODB_ATLAS_PRIVATE_KEY_CLOUD_DEV }}
235235
MONGODB_ATLAS_ORG_ID: ${{ vars.MONGODB_ATLAS_ORG_ID_CLOUD_DEV }}
236236
MONGODB_ATLAS_BASE_URL: ${{ vars.MONGODB_ATLAS_BASE_URL }}
237-
TEST_REGEX: "^TestAccStreamInstance"
237+
TEST_REGEX: "^TestAccStream"
238238
run: make testacc
239239

240240
generic: # Acceptance tests that do not use any time-consuming resource (example: cluster)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package dsschema
2+
3+
import (
4+
"maps"
5+
6+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
7+
)
8+
9+
func PaginatedDSSchema(arguments, resultAttributes map[string]schema.Attribute) schema.Schema {
10+
result := schema.Schema{
11+
Attributes: map[string]schema.Attribute{
12+
"id": schema.StringAttribute{
13+
Computed: true,
14+
},
15+
"page_num": schema.Int64Attribute{
16+
Optional: true,
17+
},
18+
"items_per_page": schema.Int64Attribute{
19+
Optional: true,
20+
},
21+
"total_count": schema.Int64Attribute{
22+
Computed: true,
23+
},
24+
"results": schema.ListNestedAttribute{
25+
Computed: true,
26+
NestedObject: schema.NestedAttributeObject{
27+
Attributes: resultAttributes,
28+
},
29+
},
30+
},
31+
}
32+
maps.Copy(result.Attributes, arguments)
33+
return result
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package dsschema_test
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
8+
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/dsschema"
9+
)
10+
11+
func TestPaginatedDSSchema(t *testing.T) {
12+
expectedSchema := schema.Schema{
13+
Attributes: map[string]schema.Attribute{
14+
"project_id": schema.StringAttribute{
15+
Required: true,
16+
},
17+
"id": schema.StringAttribute{
18+
Computed: true,
19+
},
20+
"page_num": schema.Int64Attribute{
21+
Optional: true,
22+
},
23+
"items_per_page": schema.Int64Attribute{
24+
Optional: true,
25+
},
26+
"total_count": schema.Int64Attribute{
27+
Computed: true,
28+
},
29+
"results": schema.ListNestedAttribute{
30+
Computed: true,
31+
NestedObject: schema.NestedAttributeObject{
32+
Attributes: map[string]schema.Attribute{
33+
"id": schema.StringAttribute{
34+
Computed: true,
35+
},
36+
"instance_name": schema.StringAttribute{
37+
Computed: true,
38+
},
39+
},
40+
},
41+
},
42+
},
43+
}
44+
45+
resultSchema := dsschema.PaginatedDSSchema(
46+
map[string]schema.Attribute{
47+
"project_id": schema.StringAttribute{
48+
Required: true,
49+
},
50+
},
51+
map[string]schema.Attribute{
52+
"id": schema.StringAttribute{
53+
Computed: true,
54+
},
55+
"instance_name": schema.StringAttribute{
56+
Computed: true,
57+
},
58+
})
59+
60+
if !reflect.DeepEqual(resultSchema, expectedSchema) {
61+
t.Errorf("created schema does not matched expected")
62+
}
63+
}

internal/provider/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ func (p *MongodbtlasProvider) DataSources(context.Context) []func() datasource.D
414414
atlasuser.PluralDataSource,
415415
searchdeployment.DataSource,
416416
streaminstance.DataSource,
417+
streaminstance.PluralDataSource,
417418
}
418419
}
419420

internal/service/streaminstance/data_source_stream_instance.go

+31-23
Original file line numberDiff line numberDiff line change
@@ -26,31 +26,39 @@ type streamInstanceDS struct {
2626

2727
func (d *streamInstanceDS) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
2828
resp.Schema = schema.Schema{
29-
Attributes: map[string]schema.Attribute{
30-
"id": schema.StringAttribute{
31-
Computed: true,
32-
},
33-
"instance_name": schema.StringAttribute{
34-
Required: true,
35-
},
36-
"project_id": schema.StringAttribute{
37-
Required: true,
38-
},
39-
"data_process_region": schema.SingleNestedAttribute{
40-
Computed: true,
41-
Attributes: map[string]schema.Attribute{
42-
"cloud_provider": schema.StringAttribute{
43-
Computed: true,
44-
},
45-
"region": schema.StringAttribute{
46-
Computed: true,
47-
},
29+
Attributes: DSAttributes(true),
30+
}
31+
}
32+
33+
// DSAttributes returns the attribute definitions for a single stream instance.
34+
// `withArguments` marks certain attributes as required (for singular data source) or as computed (for plural data source)
35+
func DSAttributes(withArguments bool) map[string]schema.Attribute {
36+
return map[string]schema.Attribute{
37+
"id": schema.StringAttribute{
38+
Computed: true,
39+
},
40+
"instance_name": schema.StringAttribute{
41+
Required: withArguments,
42+
Computed: !withArguments,
43+
},
44+
"project_id": schema.StringAttribute{
45+
Required: withArguments,
46+
Computed: !withArguments,
47+
},
48+
"data_process_region": schema.SingleNestedAttribute{
49+
Computed: true,
50+
Attributes: map[string]schema.Attribute{
51+
"cloud_provider": schema.StringAttribute{
52+
Computed: true,
53+
},
54+
"region": schema.StringAttribute{
55+
Computed: true,
4856
},
4957
},
50-
"hostnames": schema.ListAttribute{
51-
ElementType: types.StringType,
52-
Computed: true,
53-
},
58+
},
59+
"hostnames": schema.ListAttribute{
60+
ElementType: types.StringType,
61+
Computed: true,
5462
},
5563
}
5664
}

internal/service/streaminstance/data_source_stream_instance_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
"github.com/mongodb/terraform-provider-mongodbatlas/internal/testutil/acc"
1111
)
1212

13-
func TestAccStreamInstanceDS_basic(t *testing.T) {
13+
func TestAccStreamDSStreamInstance_basic(t *testing.T) {
1414
var (
1515
orgID = os.Getenv("MONGODB_ATLAS_ORG_ID")
1616
projectName = acctest.RandomWithPrefix("test-acc-stream")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package streaminstance
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-framework/datasource"
8+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
9+
"github.com/hashicorp/terraform-plugin-framework/types"
10+
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion"
11+
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/dsschema"
12+
"github.com/mongodb/terraform-provider-mongodbatlas/internal/config"
13+
"go.mongodb.org/atlas-sdk/v20231115002/admin"
14+
)
15+
16+
var _ datasource.DataSource = &streamInstancesDS{}
17+
var _ datasource.DataSourceWithConfigure = &streamInstancesDS{}
18+
19+
func PluralDataSource() datasource.DataSource {
20+
return &streamInstancesDS{
21+
DSCommon: config.DSCommon{
22+
DataSourceName: fmt.Sprintf("%ss", streamInstanceName),
23+
},
24+
}
25+
}
26+
27+
type streamInstancesDS struct {
28+
config.DSCommon
29+
}
30+
31+
type TFStreamInstancesModel struct {
32+
ID types.String `tfsdk:"id"`
33+
ProjectID types.String `tfsdk:"project_id"`
34+
Results []TFStreamInstanceModel `tfsdk:"results"`
35+
PageNum types.Int64 `tfsdk:"page_num"`
36+
ItemsPerPage types.Int64 `tfsdk:"items_per_page"`
37+
TotalCount types.Int64 `tfsdk:"total_count"`
38+
}
39+
40+
func (d *streamInstancesDS) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
41+
resp.Schema = dsschema.PaginatedDSSchema(
42+
map[string]schema.Attribute{
43+
"project_id": schema.StringAttribute{
44+
Required: true,
45+
},
46+
},
47+
DSAttributes(false))
48+
}
49+
50+
func (d *streamInstancesDS) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
51+
var streamInstancesConfig TFStreamInstancesModel
52+
resp.Diagnostics.Append(req.Config.Get(ctx, &streamInstancesConfig)...)
53+
if resp.Diagnostics.HasError() {
54+
return
55+
}
56+
57+
connV2 := d.Client.AtlasV2
58+
projectID := streamInstancesConfig.ProjectID.ValueString()
59+
itemsPerPage := streamInstancesConfig.ItemsPerPage.ValueInt64Pointer()
60+
pageNum := streamInstancesConfig.PageNum.ValueInt64Pointer()
61+
apiResp, _, err := connV2.StreamsApi.ListStreamInstancesWithParams(ctx, &admin.ListStreamInstancesApiParams{
62+
GroupId: projectID,
63+
ItemsPerPage: conversion.Int64PtrToIntPtr(itemsPerPage),
64+
PageNum: conversion.Int64PtrToIntPtr(pageNum),
65+
}).Execute()
66+
if err != nil {
67+
resp.Diagnostics.AddError("error fetching results", err.Error())
68+
return
69+
}
70+
71+
newStreamInstancesModel, diags := NewTFStreamInstances(ctx, &streamInstancesConfig, apiResp)
72+
if diags.HasError() {
73+
resp.Diagnostics.Append(diags...)
74+
return
75+
}
76+
resp.Diagnostics.Append(resp.State.Set(ctx, newStreamInstancesModel)...)
77+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package streaminstance_test
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"testing"
7+
8+
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
9+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
10+
"github.com/mongodb/terraform-provider-mongodbatlas/internal/testutil/acc"
11+
"go.mongodb.org/atlas-sdk/v20231115002/admin"
12+
)
13+
14+
func TestAccStreamDSStreamInstances_basic(t *testing.T) {
15+
var (
16+
orgID = os.Getenv("MONGODB_ATLAS_ORG_ID")
17+
projectName = acctest.RandomWithPrefix("test-acc-stream")
18+
instanceName = acctest.RandomWithPrefix("test-acc-name")
19+
dataSourceName = "data.mongodbatlas_stream_instances.test"
20+
)
21+
resource.ParallelTest(t, resource.TestCase{
22+
PreCheck: func() { acc.PreCheckBasic(t) },
23+
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
24+
CheckDestroy: checkDestroyStreamInstance,
25+
Steps: []resource.TestStep{
26+
{
27+
Config: streamInstancesDataSourceConfig(orgID, projectName, instanceName, region, cloudProvider),
28+
Check: streamInstancesAttributeChecks(dataSourceName, nil, nil, 1),
29+
},
30+
},
31+
})
32+
}
33+
34+
func TestAccStreamDSStreamInstances_withPageConfig(t *testing.T) {
35+
var (
36+
orgID = os.Getenv("MONGODB_ATLAS_ORG_ID")
37+
projectName = acctest.RandomWithPrefix("test-acc-stream")
38+
instanceName = acctest.RandomWithPrefix("test-acc-name")
39+
dataSourceName = "data.mongodbatlas_stream_instances.test"
40+
)
41+
resource.ParallelTest(t, resource.TestCase{
42+
PreCheck: func() { acc.PreCheckBasic(t) },
43+
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
44+
CheckDestroy: checkDestroyStreamInstance,
45+
Steps: []resource.TestStep{
46+
{
47+
Config: streamInstancesWithPageAttrDataSourceConfig(orgID, projectName, instanceName, region, cloudProvider),
48+
Check: streamInstancesAttributeChecks(dataSourceName, admin.PtrInt(2), admin.PtrInt(1), 0),
49+
},
50+
},
51+
})
52+
}
53+
54+
func streamInstancesDataSourceConfig(orgID, projectName, instanceName, region, cloudProvider string) string {
55+
return fmt.Sprintf(`
56+
%s
57+
58+
data "mongodbatlas_stream_instances" "test" {
59+
project_id = mongodbatlas_stream_instance.test.project_id
60+
}
61+
`, streamInstanceConfig(orgID, projectName, instanceName, region, cloudProvider))
62+
}
63+
64+
func streamInstancesWithPageAttrDataSourceConfig(orgID, projectName, instanceName, region, cloudProvider string) string {
65+
return fmt.Sprintf(`
66+
%s
67+
68+
data "mongodbatlas_stream_instances" "test" {
69+
project_id = mongodbatlas_stream_instance.test.project_id
70+
page_num = 2
71+
items_per_page = 1
72+
}
73+
`, streamInstanceConfig(orgID, projectName, instanceName, region, cloudProvider))
74+
}
75+
76+
func streamInstancesAttributeChecks(resourceName string, pageNum, itemsPerPage *int, totalCount int) resource.TestCheckFunc {
77+
resourceChecks := []resource.TestCheckFunc{
78+
resource.TestCheckResourceAttrSet(resourceName, "project_id"),
79+
resource.TestCheckResourceAttrSet(resourceName, "total_count"),
80+
resource.TestCheckResourceAttr(resourceName, "results.#", fmt.Sprint(totalCount)),
81+
}
82+
if pageNum != nil {
83+
resourceChecks = append(resourceChecks, resource.TestCheckResourceAttr(resourceName, "page_num", fmt.Sprint(*pageNum)))
84+
}
85+
if itemsPerPage != nil {
86+
resourceChecks = append(resourceChecks, resource.TestCheckResourceAttr(resourceName, "items_per_page", fmt.Sprint(*itemsPerPage)))
87+
}
88+
return resource.ComposeTestCheckFunc(resourceChecks...)
89+
}

0 commit comments

Comments
 (0)