Skip to content

Commit

Permalink
feat: new mongodbatlas_stream_instances data source (#1701)
Browse files Browse the repository at this point in the history
  • Loading branch information
AgustinBettati committed Dec 5, 2023
1 parent 9a2c2fa commit 71bcdb2
Show file tree
Hide file tree
Showing 12 changed files with 457 additions and 36 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/acceptance-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
advanced_cluster: ${{ steps.filter.outputs.advanced_cluster }}
cluster: ${{ steps.filter.outputs.cluster }}
search_deployment: ${{ steps.filter.outputs.search_deployment }}
stream_instance: ${{ steps.filter.outputs.stream_instance }}
stream: ${{ steps.filter.outputs.stream }}
generic: ${{ steps.filter.outputs.generic }}
backup_online_archive: ${{ steps.filter.outputs.backup_online_archive }}
backup_snapshots: ${{ steps.filter.outputs.backup_snapshots }}
Expand Down Expand Up @@ -65,7 +65,7 @@ jobs:
- 'internal/service/cluster/*.go'
search_deployment:
- 'internal/service/searchdeployment/*.go'
stream_instance:
stream:
- 'internal/service/streaminstance/*.go'
generic:
- 'internal/service/backupcompliancepolicy/*.go'
Expand Down Expand Up @@ -213,9 +213,9 @@ jobs:
TEST_REGEX: "^TestAccSearchDeployment"
run: make testacc

stream_instance:
stream:
needs: [ change-detection ]
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' }}
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' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
Expand All @@ -234,7 +234,7 @@ jobs:
MONGODB_ATLAS_PRIVATE_KEY: ${{ secrets.MONGODB_ATLAS_PRIVATE_KEY_CLOUD_DEV }}
MONGODB_ATLAS_ORG_ID: ${{ vars.MONGODB_ATLAS_ORG_ID_CLOUD_DEV }}
MONGODB_ATLAS_BASE_URL: ${{ vars.MONGODB_ATLAS_BASE_URL }}
TEST_REGEX: "^TestAccStreamInstance"
TEST_REGEX: "^TestAccStream"
run: make testacc

generic: # Acceptance tests that do not use any time-consuming resource (example: cluster)
Expand Down
34 changes: 34 additions & 0 deletions internal/common/dsschema/pagination_schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package dsschema

import (
"maps"

"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
)

func PaginatedDSSchema(arguments, resultAttributes map[string]schema.Attribute) schema.Schema {
result := schema.Schema{
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Computed: true,
},
"page_num": schema.Int64Attribute{
Optional: true,
},
"items_per_page": schema.Int64Attribute{
Optional: true,
},
"total_count": schema.Int64Attribute{
Computed: true,
},
"results": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: resultAttributes,
},
},
},
}
maps.Copy(result.Attributes, arguments)
return result
}
63 changes: 63 additions & 0 deletions internal/common/dsschema/pagination_schema_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package dsschema_test

import (
"reflect"
"testing"

"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/dsschema"
)

func TestPaginatedDSSchema(t *testing.T) {
expectedSchema := schema.Schema{
Attributes: map[string]schema.Attribute{
"project_id": schema.StringAttribute{
Required: true,
},
"id": schema.StringAttribute{
Computed: true,
},
"page_num": schema.Int64Attribute{
Optional: true,
},
"items_per_page": schema.Int64Attribute{
Optional: true,
},
"total_count": schema.Int64Attribute{
Computed: true,
},
"results": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Computed: true,
},
"instance_name": schema.StringAttribute{
Computed: true,
},
},
},
},
},
}

resultSchema := dsschema.PaginatedDSSchema(
map[string]schema.Attribute{
"project_id": schema.StringAttribute{
Required: true,
},
},
map[string]schema.Attribute{
"id": schema.StringAttribute{
Computed: true,
},
"instance_name": schema.StringAttribute{
Computed: true,
},
})

if !reflect.DeepEqual(resultSchema, expectedSchema) {
t.Errorf("created schema does not matched expected")
}
}
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ func (p *MongodbtlasProvider) DataSources(context.Context) []func() datasource.D
atlasuser.PluralDataSource,
searchdeployment.DataSource,
streaminstance.DataSource,
streaminstance.PluralDataSource,
}
}

Expand Down
54 changes: 31 additions & 23 deletions internal/service/streaminstance/data_source_stream_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,39 @@ type streamInstanceDS struct {

func (d *streamInstanceDS) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Computed: true,
},
"instance_name": schema.StringAttribute{
Required: true,
},
"project_id": schema.StringAttribute{
Required: true,
},
"data_process_region": schema.SingleNestedAttribute{
Computed: true,
Attributes: map[string]schema.Attribute{
"cloud_provider": schema.StringAttribute{
Computed: true,
},
"region": schema.StringAttribute{
Computed: true,
},
Attributes: DSAttributes(true),
}
}

// DSAttributes returns the attribute definitions for a single stream instance.
// `withArguments` marks certain attributes as required (for singular data source) or as computed (for plural data source)
func DSAttributes(withArguments bool) map[string]schema.Attribute {
return map[string]schema.Attribute{
"id": schema.StringAttribute{
Computed: true,
},
"instance_name": schema.StringAttribute{
Required: withArguments,
Computed: !withArguments,
},
"project_id": schema.StringAttribute{
Required: withArguments,
Computed: !withArguments,
},
"data_process_region": schema.SingleNestedAttribute{
Computed: true,
Attributes: map[string]schema.Attribute{
"cloud_provider": schema.StringAttribute{
Computed: true,
},
"region": schema.StringAttribute{
Computed: true,
},
},
"hostnames": schema.ListAttribute{
ElementType: types.StringType,
Computed: true,
},
},
"hostnames": schema.ListAttribute{
ElementType: types.StringType,
Computed: true,
},
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/mongodb/terraform-provider-mongodbatlas/internal/testutil/acc"
)

func TestAccStreamInstanceDS_basic(t *testing.T) {
func TestAccStreamDSStreamInstance_basic(t *testing.T) {
var (
orgID = os.Getenv("MONGODB_ATLAS_ORG_ID")
projectName = acctest.RandomWithPrefix("test-acc-stream")
Expand Down
77 changes: 77 additions & 0 deletions internal/service/streaminstance/data_source_stream_instances.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package streaminstance

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/dsschema"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/config"
"go.mongodb.org/atlas-sdk/v20231115002/admin"
)

var _ datasource.DataSource = &streamInstancesDS{}
var _ datasource.DataSourceWithConfigure = &streamInstancesDS{}

func PluralDataSource() datasource.DataSource {
return &streamInstancesDS{
DSCommon: config.DSCommon{
DataSourceName: fmt.Sprintf("%ss", streamInstanceName),
},
}
}

type streamInstancesDS struct {
config.DSCommon
}

type TFStreamInstancesModel struct {
ID types.String `tfsdk:"id"`
ProjectID types.String `tfsdk:"project_id"`
Results []TFStreamInstanceModel `tfsdk:"results"`
PageNum types.Int64 `tfsdk:"page_num"`
ItemsPerPage types.Int64 `tfsdk:"items_per_page"`
TotalCount types.Int64 `tfsdk:"total_count"`
}

func (d *streamInstancesDS) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = dsschema.PaginatedDSSchema(
map[string]schema.Attribute{
"project_id": schema.StringAttribute{
Required: true,
},
},
DSAttributes(false))
}

func (d *streamInstancesDS) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var streamInstancesConfig TFStreamInstancesModel
resp.Diagnostics.Append(req.Config.Get(ctx, &streamInstancesConfig)...)
if resp.Diagnostics.HasError() {
return
}

connV2 := d.Client.AtlasV2
projectID := streamInstancesConfig.ProjectID.ValueString()
itemsPerPage := streamInstancesConfig.ItemsPerPage.ValueInt64Pointer()
pageNum := streamInstancesConfig.PageNum.ValueInt64Pointer()
apiResp, _, err := connV2.StreamsApi.ListStreamInstancesWithParams(ctx, &admin.ListStreamInstancesApiParams{
GroupId: projectID,
ItemsPerPage: conversion.Int64PtrToIntPtr(itemsPerPage),
PageNum: conversion.Int64PtrToIntPtr(pageNum),
}).Execute()
if err != nil {
resp.Diagnostics.AddError("error fetching results", err.Error())
return
}

newStreamInstancesModel, diags := NewTFStreamInstances(ctx, &streamInstancesConfig, apiResp)
if diags.HasError() {
resp.Diagnostics.Append(diags...)
return
}
resp.Diagnostics.Append(resp.State.Set(ctx, newStreamInstancesModel)...)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package streaminstance_test

import (
"fmt"
"os"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/testutil/acc"
"go.mongodb.org/atlas-sdk/v20231115002/admin"
)

func TestAccStreamDSStreamInstances_basic(t *testing.T) {
var (
orgID = os.Getenv("MONGODB_ATLAS_ORG_ID")
projectName = acctest.RandomWithPrefix("test-acc-stream")
instanceName = acctest.RandomWithPrefix("test-acc-name")
dataSourceName = "data.mongodbatlas_stream_instances.test"
)
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acc.PreCheckBasic(t) },
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
CheckDestroy: checkDestroyStreamInstance,
Steps: []resource.TestStep{
{
Config: streamInstancesDataSourceConfig(orgID, projectName, instanceName, region, cloudProvider),
Check: streamInstancesAttributeChecks(dataSourceName, nil, nil, 1),
},
},
})
}

func TestAccStreamDSStreamInstances_withPageConfig(t *testing.T) {
var (
orgID = os.Getenv("MONGODB_ATLAS_ORG_ID")
projectName = acctest.RandomWithPrefix("test-acc-stream")
instanceName = acctest.RandomWithPrefix("test-acc-name")
dataSourceName = "data.mongodbatlas_stream_instances.test"
)
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acc.PreCheckBasic(t) },
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
CheckDestroy: checkDestroyStreamInstance,
Steps: []resource.TestStep{
{
Config: streamInstancesWithPageAttrDataSourceConfig(orgID, projectName, instanceName, region, cloudProvider),
Check: streamInstancesAttributeChecks(dataSourceName, admin.PtrInt(2), admin.PtrInt(1), 0),
},
},
})
}

func streamInstancesDataSourceConfig(orgID, projectName, instanceName, region, cloudProvider string) string {
return fmt.Sprintf(`
%s
data "mongodbatlas_stream_instances" "test" {
project_id = mongodbatlas_stream_instance.test.project_id
}
`, streamInstanceConfig(orgID, projectName, instanceName, region, cloudProvider))
}

func streamInstancesWithPageAttrDataSourceConfig(orgID, projectName, instanceName, region, cloudProvider string) string {
return fmt.Sprintf(`
%s
data "mongodbatlas_stream_instances" "test" {
project_id = mongodbatlas_stream_instance.test.project_id
page_num = 2
items_per_page = 1
}
`, streamInstanceConfig(orgID, projectName, instanceName, region, cloudProvider))
}

func streamInstancesAttributeChecks(resourceName string, pageNum, itemsPerPage *int, totalCount int) resource.TestCheckFunc {
resourceChecks := []resource.TestCheckFunc{
resource.TestCheckResourceAttrSet(resourceName, "project_id"),
resource.TestCheckResourceAttrSet(resourceName, "total_count"),
resource.TestCheckResourceAttr(resourceName, "results.#", fmt.Sprint(totalCount)),
}
if pageNum != nil {
resourceChecks = append(resourceChecks, resource.TestCheckResourceAttr(resourceName, "page_num", fmt.Sprint(*pageNum)))
}
if itemsPerPage != nil {
resourceChecks = append(resourceChecks, resource.TestCheckResourceAttr(resourceName, "items_per_page", fmt.Sprint(*itemsPerPage)))
}
return resource.ComposeTestCheckFunc(resourceChecks...)
}

0 comments on commit 71bcdb2

Please sign in to comment.