Skip to content

Commit

Permalink
feat: Adds new ip_addresses computed attribute in `mongodbatlas_pro…
Browse files Browse the repository at this point in the history
…ject` resource and data sources (#1850)

* wip adding new ip addresses attribute

* support plural data source

* update sdk version to dev-latest

* include unit test for resource terraform model

* make use of object type

* adjust docs including new attribute

* adjust acceptance test and unit test fix

* refactor: define struct for containing project related properties

* refactor: use TF* over Tf* for consistency

* adding unit test for empty IP lists

* Update .github/workflows/code-health.yml

Co-authored-by: Leo Antoli <[email protected]>

* adjust order of defining computed attributes

* extract const for dataSourceName and resourceName

* handle diags when setting object type

* remove redudant if and message when asserting model

---------

Co-authored-by: Leo Antoli <[email protected]>
  • Loading branch information
AgustinBettati and lantoli authored Jan 19, 2024
1 parent 5b0b2de commit 5b34f46
Show file tree
Hide file tree
Showing 15 changed files with 705 additions and 247 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/code-health.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
with:
go-version-file: 'go.mod'
- name: Mock generation
run: make tools && mockery
run: make tools generate-mocks
- name: Check for uncommited files
run: |
export FILES=$(git ls-files -o -m --directory --exclude-standard --no-empty-directory)
Expand Down
16 changes: 11 additions & 5 deletions .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@ filename: "{{ .InterfaceName | snakecase }}.go"
mockname: "{{.InterfaceName}}"

packages:
? github.com/mongodb/terraform-provider-mongodbatlas/internal/service/searchdeployment
? github.com/mongodb/terraform-provider-mongodbatlas/internal/service/encryptionatrest
? github.com/mongodb/terraform-provider-mongodbatlas/internal/service/project
? github.com/mongodb/terraform-provider-mongodbatlas/internal/service/advancedcluster
: interfaces:
github.com/mongodb/terraform-provider-mongodbatlas/internal/service/searchdeployment:
interfaces:
DeploymentService:

github.com/mongodb/terraform-provider-mongodbatlas/internal/service/encryptionatrest:
interfaces:
EarService:

github.com/mongodb/terraform-provider-mongodbatlas/internal/service/project:
interfaces:
GroupProjectService:

github.com/mongodb/terraform-provider-mongodbatlas/internal/service/advancedcluster:
interfaces:
ClusterService:
4 changes: 4 additions & 0 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ link-git-hooks: ## Install git hooks
update-atlas-sdk: ## Update the atlas-sdk dependency
./scripts/update-sdk.sh

.PHONY: generate-mocks
generate-mocks: # uses mockery to generate mocks in folder `internal/testutil/mocksvc`
mockery

# e.g. run: make scaffold resource_name=streamInstance type=resource
# - type argument can have the values: `resource`, `data-source`, `plural-data-source`.
# details on usage can be found in CONTRIBUTING.md under "Scaffolding initial Code and File Structure"
Expand Down
57 changes: 45 additions & 12 deletions internal/service/project/data_source_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,16 @@ type projectDS struct {
config.DSCommon
}

type TfProjectDSModel struct {
RegionUsageRestrictions types.String `tfsdk:"region_usage_restrictions"`
ProjectID types.String `tfsdk:"project_id"`
Name types.String `tfsdk:"name"`
OrgID types.String `tfsdk:"org_id"`
type TFProjectDSModel struct {
IPAddresses types.Object `tfsdk:"ip_addresses"`
Created types.String `tfsdk:"created"`
OrgID types.String `tfsdk:"org_id"`
RegionUsageRestrictions types.String `tfsdk:"region_usage_restrictions"`
ID types.String `tfsdk:"id"`
Limits []*TfLimitModel `tfsdk:"limits"`
Teams []*TfTeamDSModel `tfsdk:"teams"`
Name types.String `tfsdk:"name"`
ProjectID types.String `tfsdk:"project_id"`
Teams []*TFTeamDSModel `tfsdk:"teams"`
Limits []*TFLimitModel `tfsdk:"limits"`
ClusterCount types.Int64 `tfsdk:"cluster_count"`
IsCollectDatabaseSpecificsStatisticsEnabled types.Bool `tfsdk:"is_collect_database_specifics_statistics_enabled"`
IsRealtimePerformancePanelEnabled types.Bool `tfsdk:"is_realtime_performance_panel_enabled"`
Expand All @@ -48,7 +49,7 @@ type TfProjectDSModel struct {
IsDataExplorerEnabled types.Bool `tfsdk:"is_data_explorer_enabled"`
}

type TfTeamDSModel struct {
type TFTeamDSModel struct {
TeamID types.String `tfsdk:"team_id"`
RoleNames types.List `tfsdk:"role_names"`
}
Expand Down Expand Up @@ -137,12 +138,40 @@ func (d *projectDS) Schema(ctx context.Context, req datasource.SchemaRequest, re
},
},
},
"ip_addresses": schema.SingleNestedAttribute{
Computed: true,
Attributes: map[string]schema.Attribute{
"services": schema.SingleNestedAttribute{
Computed: true,
Attributes: map[string]schema.Attribute{
"clusters": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"cluster_name": schema.StringAttribute{
Computed: true,
},
"inbound": schema.ListAttribute{
ElementType: types.StringType,
Computed: true,
},
"outbound": schema.ListAttribute{
ElementType: types.StringType,
Computed: true,
},
},
},
},
},
},
},
},
},
}
}

func (d *projectDS) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var projectState TfProjectDSModel
var projectState TFProjectDSModel
connV2 := d.Client.AtlasV2

resp.Diagnostics.Append(req.Config.Get(ctx, &projectState)...)
Expand Down Expand Up @@ -173,15 +202,19 @@ func (d *projectDS) Read(ctx context.Context, req datasource.ReadRequest, resp *
}
}

atlasTeams, atlasLimits, atlasProjectSettings, err := GetProjectPropsFromAPI(ctx, ServiceFromClient(connV2), project.GetId())
projectProps, err := GetProjectPropsFromAPI(ctx, ServiceFromClient(connV2), project.GetId())
if err != nil {
resp.Diagnostics.AddError("error when getting project properties", fmt.Sprintf(ErrorProjectRead, project.GetId(), err.Error()))
return
}

projectState = NewTFProjectDataSourceModel(ctx, project, atlasTeams, atlasProjectSettings, atlasLimits)
newProjectState, diags := NewTFProjectDataSourceModel(ctx, project, *projectProps)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

resp.Diagnostics.Append(resp.State.Set(ctx, &projectState)...)
resp.Diagnostics.Append(resp.State.Set(ctx, &newProjectState)...)
if resp.Diagnostics.HasError() {
return
}
Expand Down
39 changes: 21 additions & 18 deletions internal/service/project/data_source_project_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/mongodb/terraform-provider-mongodbatlas/internal/testutil/acc"
)

const dataSourceName = "data.mongodbatlas_project.test"

func TestAccProjectDSProject_byID(t *testing.T) {
var (
projectName = acctest.RandomWithPrefix("test-acc")
Expand All @@ -36,9 +38,10 @@ func TestAccProjectDSProject_byID(t *testing.T) {
},
)),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("mongodbatlas_project.test", "name"),
resource.TestCheckResourceAttrSet("mongodbatlas_project.test", "org_id"),
resource.TestCheckResourceAttr("mongodbatlas_project.test", "teams.#", "2"),
resource.TestCheckResourceAttrSet(dataSourceName, "name"),
resource.TestCheckResourceAttrSet(dataSourceName, "org_id"),
resource.TestCheckResourceAttr(dataSourceName, "teams.#", "2"),
resource.TestCheckResourceAttrSet(dataSourceName, "ip_addresses.services.clusters.#"),
),
},
},
Expand Down Expand Up @@ -69,9 +72,9 @@ func TestAccProjectDSProject_byName(t *testing.T) {
},
)),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("mongodbatlas_project.test", "name"),
resource.TestCheckResourceAttrSet("mongodbatlas_project.test", "org_id"),
resource.TestCheckResourceAttr("mongodbatlas_project.test", "teams.#", "2"),
resource.TestCheckResourceAttrSet(dataSourceName, "name"),
resource.TestCheckResourceAttrSet(dataSourceName, "org_id"),
resource.TestCheckResourceAttr(dataSourceName, "teams.#", "2"),
),
},
},
Expand Down Expand Up @@ -102,15 +105,15 @@ func TestAccProjectDSProject_defaultFlags(t *testing.T) {
},
)),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("mongodbatlas_project.test", "name"),
resource.TestCheckResourceAttrSet("mongodbatlas_project.test", "org_id"),
resource.TestCheckResourceAttrSet("mongodbatlas_project.test", "is_collect_database_specifics_statistics_enabled"),
resource.TestCheckResourceAttrSet("mongodbatlas_project.test", "is_data_explorer_enabled"),
resource.TestCheckResourceAttrSet("mongodbatlas_project.test", "is_extended_storage_sizes_enabled"),
resource.TestCheckResourceAttrSet("mongodbatlas_project.test", "is_performance_advisor_enabled"),
resource.TestCheckResourceAttrSet("mongodbatlas_project.test", "is_realtime_performance_panel_enabled"),
resource.TestCheckResourceAttrSet("mongodbatlas_project.test", "is_schema_advisor_enabled"),
resource.TestCheckResourceAttr("mongodbatlas_project.test", "teams.#", "2"),
resource.TestCheckResourceAttrSet(dataSourceName, "name"),
resource.TestCheckResourceAttrSet(dataSourceName, "org_id"),
resource.TestCheckResourceAttrSet(dataSourceName, "is_collect_database_specifics_statistics_enabled"),
resource.TestCheckResourceAttrSet(dataSourceName, "is_data_explorer_enabled"),
resource.TestCheckResourceAttrSet(dataSourceName, "is_extended_storage_sizes_enabled"),
resource.TestCheckResourceAttrSet(dataSourceName, "is_performance_advisor_enabled"),
resource.TestCheckResourceAttrSet(dataSourceName, "is_realtime_performance_panel_enabled"),
resource.TestCheckResourceAttrSet(dataSourceName, "is_schema_advisor_enabled"),
resource.TestCheckResourceAttr(dataSourceName, "teams.#", "2"),
),
},
},
Expand All @@ -129,9 +132,9 @@ func TestAccProjectDSProject_limits(t *testing.T) {
{
Config: testAccMongoDBAtlasProjectDSByNameUsingRS(acc.ConfigProjectWithLimits(projectName, orgID, []*admin.DataFederationLimit{})),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.mongodbatlas_project.test", "name"),
resource.TestCheckResourceAttrSet("data.mongodbatlas_project.test", "org_id"),
resource.TestCheckResourceAttrSet("data.mongodbatlas_project.test", "limits.0.name"),
resource.TestCheckResourceAttrSet(dataSourceName, "name"),
resource.TestCheckResourceAttrSet(dataSourceName, "org_id"),
resource.TestCheckResourceAttrSet(dataSourceName, "limits.0.name"),
),
},
},
Expand Down
53 changes: 43 additions & 10 deletions internal/service/project/data_source_projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion"
Expand All @@ -32,7 +33,7 @@ type ProjectsDS struct {

type tfProjectsDSModel struct {
ID types.String `tfsdk:"id"`
Results []*TfProjectDSModel `tfsdk:"results"`
Results []*TFProjectDSModel `tfsdk:"results"`
PageNum types.Int64 `tfsdk:"page_num"`
ItemsPerPage types.Int64 `tfsdk:"items_per_page"`
TotalCount types.Int64 `tfsdk:"total_count"`
Expand Down Expand Up @@ -134,6 +135,34 @@ func (d *ProjectsDS) Schema(ctx context.Context, req datasource.SchemaRequest, r
},
},
},
"ip_addresses": schema.SingleNestedAttribute{
Computed: true,
Attributes: map[string]schema.Attribute{
"services": schema.SingleNestedAttribute{
Computed: true,
Attributes: map[string]schema.Attribute{
"clusters": schema.ListNestedAttribute{
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"cluster_name": schema.StringAttribute{
Computed: true,
},
"inbound": schema.ListAttribute{
ElementType: types.StringType,
Computed: true,
},
"outbound": schema.ListAttribute{
ElementType: types.StringType,
Computed: true,
},
},
},
},
},
},
},
},
},
},
},
Expand All @@ -157,9 +186,9 @@ func (d *ProjectsDS) Read(ctx context.Context, req datasource.ReadRequest, resp
return
}

err = populateProjectsDataSourceModel(ctx, connV2, &stateModel, projectsRes)
if err != nil {
resp.Diagnostics.AddError("error in monogbatlas_projects data source", err.Error())
diags := populateProjectsDataSourceModel(ctx, connV2, &stateModel, projectsRes)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

Expand All @@ -169,19 +198,23 @@ func (d *ProjectsDS) Read(ctx context.Context, req datasource.ReadRequest, resp
}
}

func populateProjectsDataSourceModel(ctx context.Context, connV2 *admin.APIClient, stateModel *tfProjectsDSModel, projectsRes *admin.PaginatedAtlasGroup) error {
func populateProjectsDataSourceModel(ctx context.Context, connV2 *admin.APIClient, stateModel *tfProjectsDSModel, projectsRes *admin.PaginatedAtlasGroup) diag.Diagnostics {
diagnostics := []diag.Diagnostic{}
input := projectsRes.GetResults()
results := make([]*TfProjectDSModel, 0, len(input))
results := make([]*TFProjectDSModel, 0, len(input))
for i := range input {
project := input[i]
atlasTeams, atlasLimits, atlasProjectSettings, err := GetProjectPropsFromAPI(ctx, ServiceFromClient(connV2), project.GetId())
projectProps, err := GetProjectPropsFromAPI(ctx, ServiceFromClient(connV2), project.GetId())
if err == nil { // if the project is still valid, e.g. could have just been deleted
projectModel := NewTFProjectDataSourceModel(ctx, &project, atlasTeams, atlasProjectSettings, atlasLimits)
results = append(results, &projectModel)
projectModel, diags := NewTFProjectDataSourceModel(ctx, &project, *projectProps)
diagnostics = append(diagnostics, diags...)
if projectModel != nil {
results = append(results, projectModel)
}
}
}
stateModel.Results = results
stateModel.TotalCount = types.Int64Value(int64(projectsRes.GetTotalCount()))
stateModel.ID = types.StringValue(id.UniqueId())
return nil
return diagnostics
}
Loading

0 comments on commit 5b34f46

Please sign in to comment.