Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Adds atlas Organization New Parameters Support #1835

Merged
merged 53 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
27df3ca
apply update-atlas-sdk
lantoli Jan 12, 2024
c2e5a40
revert changes to oldAdmin
lantoli Jan 12, 2024
258cff2
remove atlasSDK alias
lantoli Jan 12, 2024
25ea035
use SlicePtrToSlice and NonEmptySliceToPtrSlice
lantoli Jan 12, 2024
b3e01d9
TEMPORARY - remove DataProcessRegion to make it compile and run tests
lantoli Jan 12, 2024
8c48565
fix linter: fieldalignment: struct with 32 pointer bytes could be 24 …
lantoli Jan 12, 2024
23793e5
fix project tests
lantoli Jan 12, 2024
c28ae5e
apply update-atlas-sdk
lantoli Jan 12, 2024
32d630a
revert changes to oldAdmin
lantoli Jan 12, 2024
2527ba6
remove atlasSDK alias
lantoli Jan 12, 2024
2587fb3
use SlicePtrToSlice and NonEmptySliceToPtrSlice
lantoli Jan 12, 2024
404512e
TEMPORARY - remove DataProcessRegion to make it compile and run tests
lantoli Jan 12, 2024
f93464f
fix linter: fieldalignment: struct with 32 pointer bytes could be 24 …
lantoli Jan 12, 2024
5651c2b
fix project tests
lantoli Jan 12, 2024
d0d2d67
Revert "TEMPORARY - remove DataProcessRegion to make it compile and r…
lantoli Jan 12, 2024
37c0ace
upgrade to atlas sdk
maastha Jan 12, 2024
d9ca6cc
upgrade plural DS to atlas sdk
maastha Jan 12, 2024
db96b10
migrate plural DS to new atlas SDK
maastha Jan 12, 2024
479afb8
migrate plural DS to new atlas SDK
maastha Jan 12, 2024
c98bab9
migrate plural DS to new atlas SDK
maastha Jan 12, 2024
f914609
update sdk to latest
maastha Jan 12, 2024
0859331
update sdk to latest
maastha Jan 12, 2024
7a1caae
update sdk to latest
maastha Jan 12, 2024
58abc5f
user old SDK for online archive as DataProcessRegion was removed
lantoli Jan 12, 2024
0ab62a3
fix merge
maastha Jan 12, 2024
9ca501b
Merge branch 'CLOUDP-222424_sdk_update_pointers' of github.com:mongod…
maastha Jan 12, 2024
1d8dec4
fix merge
maastha Jan 12, 2024
b7818a9
add new API support
maastha Jan 10, 2024
5dd60df
add new APIs and params
maastha Jan 12, 2024
a64c3c2
add new APIs and params
maastha Jan 12, 2024
06cc66e
update templates
lantoli Jan 15, 2024
1d0f3fa
rename to NonEmptySliceToSlicePtr
lantoli Jan 15, 2024
879a09b
tests for slice functions
lantoli Jan 15, 2024
0ab1d20
use Run in tests
lantoli Jan 15, 2024
63671e7
remove SlicePtrToSlice
lantoli Jan 15, 2024
452239a
Merge branch 'CLOUDP-222424_sdk_update_pointers' into CLOUDP-219771-u…
maastha Jan 15, 2024
70c5afa
minor
maastha Jan 15, 2024
02cf0fe
Merge branch 'CLOUDP-219771-update-sdk' into CLOUDP-219771-new-org-pa…
maastha Jan 15, 2024
2524eff
update documentation
maastha Jan 15, 2024
2028d05
Merge branch 'master' into CLOUDP-219771-update-sdk
maastha Jan 16, 2024
f5933ec
minor
maastha Jan 16, 2024
866fff5
fix: undo sh file commit
maastha Jan 16, 2024
49a1d9c
fix: undo sh file commit
maastha Jan 16, 2024
c3cfbd9
add documentation and examples
maastha Jan 16, 2024
7c1ef2c
address PR comments
maastha Jan 17, 2024
046ce94
Merge branch 'CLOUDP-219771-update-sdk' into CLOUDP-219771-new-org-pa…
maastha Jan 17, 2024
a6cc69e
address PR comments
maastha Jan 17, 2024
5a08be6
minor
maastha Jan 17, 2024
9ce0107
Apply suggestions from code review
maastha Jan 17, 2024
de65a01
Merge branch 'CLOUDP-219771-update-sdk' of github.com:mongodb/terrafo…
maastha Jan 17, 2024
8e631e7
minor
maastha Jan 17, 2024
fbe2c8c
Merge branch 'master' of github.com:mongodb/terraform-provider-mongod…
maastha Jan 18, 2024
0d2f77f
update include_deleted_orgs deprecation message
maastha Jan 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions examples/mongodbatlas_organization/organization-step-1/main.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
resource "mongodbatlas_organization" "test" {
org_owner_id = var.org_owner_id
name = "testCreateORG"
description = "test API key from Org Creation Test"
role_names = ["ORG_OWNER"]
org_owner_id = var.org_owner_id
name = "testCreateORG"
description = "test API key from Org Creation Test"
role_names = ["ORG_OWNER"]
multi_factor_auth_required = true
restrict_employee_access = true
api_access_list_required = false
}

output "org_id" {
Expand Down
5 changes: 5 additions & 0 deletions internal/common/constant/access_level.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package constant

const (
OrgOwner = "ORG_OWNER"
)
26 changes: 26 additions & 0 deletions internal/service/organization/data_source_organization.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ func DataSource() *schema.Resource {
},
},
},
"api_access_list_required": {
Type: schema.TypeBool,
Computed: true,
},
"multi_factor_auth_required": {
Type: schema.TypeBool,
Computed: true,
},
"restrict_employee_access": {
Type: schema.TypeBool,
Computed: true,
},
},
}
}
Expand Down Expand Up @@ -69,6 +81,20 @@ func dataSourceMongoDBAtlasOrganizationRead(ctx context.Context, d *schema.Resou
return diag.FromErr(fmt.Errorf("error setting `is_deleted`: %s", err))
}

settings, _, err := conn.OrganizationsApi.GetOrganizationSettings(ctx, orgID).Execute()
if err != nil {
return diag.FromErr(fmt.Errorf("error getting organization settings: %s", err))
}
if err := d.Set("api_access_list_required", settings.ApiAccessListRequired); err != nil {
return diag.Errorf("error setting `api_access_list_required` for organization (%s): %s", orgID, err)
}
if err := d.Set("multi_factor_auth_required", settings.MultiFactorAuthRequired); err != nil {
return diag.Errorf("error setting `multi_factor_auth_required` for organization (%s): %s", orgID, err)
}
if err := d.Set("restrict_employee_access", settings.RestrictEmployeeAccess); err != nil {
return diag.Errorf("error setting `restrict_employee_access` for organization (%s): %s", orgID, err)
}

d.SetId(organization.GetId())

return nil
Expand Down
11 changes: 8 additions & 3 deletions internal/service/organization/data_source_organization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,26 @@ import (
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"

"github.com/mongodb/terraform-provider-mongodbatlas/internal/testutil/acc"
)

func TestAccConfigDSOrganization_basic(t *testing.T) {
var (
orgID = os.Getenv("MONGODB_ATLAS_ORG_ID")
orgID = os.Getenv("MONGODB_ATLAS_ORG_ID")
datasourceName = "data.mongodbatlas_organization.test"
)
resource.ParallelTest(t, resource.TestCase{
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
Steps: []resource.TestStep{
{
Config: testAccMongoDBAtlasOrganizationConfigWithDS(orgID),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.mongodbatlas_organization.test", "name"),
resource.TestCheckResourceAttrSet("data.mongodbatlas_organization.test", "id"),
resource.TestCheckResourceAttrSet(datasourceName, "name"),
resource.TestCheckResourceAttrSet(datasourceName, "id"),
resource.TestCheckResourceAttrSet(datasourceName, "restrict_employee_access"),
lantoli marked this conversation as resolved.
Show resolved Hide resolved
resource.TestCheckResourceAttrSet(datasourceName, "multi_factor_auth_required"),
resource.TestCheckResourceAttrSet(datasourceName, "api_access_list_required"),
),
},
},
Expand Down
35 changes: 28 additions & 7 deletions internal/service/organization/data_source_organizations.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package organization
import (
"context"
"fmt"
"log"

"go.mongodb.org/atlas-sdk/v20231115003/admin"

Expand All @@ -26,7 +27,7 @@ func PluralDataSource() *schema.Resource {
"include_deleted_orgs": {
Type: schema.TypeBool,
Optional: true,
Deprecated: fmt.Sprintf(constant.DeprecationParamByDate, "January 2025"),
Deprecated: fmt.Sprintf(constant.DeprecationParamByVersion, "1.16.0"),
},
"page_num": {
Type: schema.TypeInt,
Expand Down Expand Up @@ -69,6 +70,18 @@ func PluralDataSource() *schema.Resource {
},
},
},
"api_access_list_required": {
Type: schema.TypeBool,
Computed: true,
},
"multi_factor_auth_required": {
Type: schema.TypeBool,
Computed: true,
},
"restrict_employee_access": {
Type: schema.TypeBool,
Computed: true,
},
},
},
},
Expand Down Expand Up @@ -96,7 +109,7 @@ func dataSourceMongoDBAtlasOrganizationsRead(ctx context.Context, d *schema.Reso
return diag.FromErr(fmt.Errorf("error getting organization information: %s", err))
}

if err := d.Set("results", flattenOrganizations(organizations.GetResults())); err != nil {
if err := d.Set("results", flattenOrganizations(ctx, conn, organizations.GetResults())); err != nil {
return diag.FromErr(fmt.Errorf("error setting `results`: %s", err))
}

Expand All @@ -123,7 +136,7 @@ func flattenOrganizationLinks(links []admin.Link) []map[string]any {
return linksList
}

func flattenOrganizations(organizations []admin.AtlasOrganization) []map[string]any {
func flattenOrganizations(ctx context.Context, conn *admin.APIClient, organizations []admin.AtlasOrganization) []map[string]any {
var results []map[string]any

if len(organizations) == 0 {
Expand All @@ -133,11 +146,19 @@ func flattenOrganizations(organizations []admin.AtlasOrganization) []map[string]
results = make([]map[string]any, len(organizations))

for k, organization := range organizations {
settings, _, err := conn.OrganizationsApi.GetOrganizationSettings(ctx, *organization.Id).Execute()
if err != nil {
log.Printf("[WARN] Error getting organization settings (organization ID: %s): %s", *organization.Id, err)
}

results[k] = map[string]any{
"id": organization.Id,
"name": organization.Name,
"is_deleted": organization.IsDeleted,
"links": flattenOrganizationLinks(organization.GetLinks()),
"id": organization.Id,
"name": organization.Name,
"is_deleted": organization.IsDeleted,
"links": flattenOrganizationLinks(organization.GetLinks()),
"api_access_list_required": settings.ApiAccessListRequired,
"multi_factor_auth_required": settings.MultiFactorAuthRequired,
"restrict_employee_access": settings.RestrictEmployeeAccess,
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"

"github.com/mongodb/terraform-provider-mongodbatlas/internal/testutil/acc"
)

Expand All @@ -21,6 +22,9 @@ func TestAccConfigDSOrganizations_basic(t *testing.T) {
resource.TestCheckResourceAttrSet(datasourceName, "results.#"),
resource.TestCheckResourceAttrSet(datasourceName, "results.0.name"),
resource.TestCheckResourceAttrSet(datasourceName, "results.0.id"),
resource.TestCheckResourceAttrSet(datasourceName, "results.0.restrict_employee_access"),
resource.TestCheckResourceAttrSet(datasourceName, "results.0.multi_factor_auth_required"),
resource.TestCheckResourceAttrSet(datasourceName, "results.0.api_access_list_required"),
),
},
},
Expand Down
94 changes: 91 additions & 3 deletions internal/service/organization/resource_organization.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/mwielbut/pointy"

"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"
)
Expand Down Expand Up @@ -61,11 +62,30 @@ func Resource() *schema.Resource {
Type: schema.TypeString,
Optional: true,
},
"api_access_list_required": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"multi_factor_auth_required": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"restrict_employee_access": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
},
}
}

func resourceMongoDBAtlasOrganizationCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
if err := ValidateAPIKeyIsOrgOwner(conversion.ExpandStringList(d.Get("role_names").(*schema.Set).List())); err != nil {
return diag.FromErr(err)
}

conn := meta.(*config.MongoDBClient).AtlasV2
organization, resp, err := conn.OrganizationsApi.CreateOrganization(ctx, newCreateOrganizationRequest(d)).Execute()
if err != nil {
Expand All @@ -74,7 +94,30 @@ func resourceMongoDBAtlasOrganizationCreate(ctx context.Context, d *schema.Resou
return nil
}

return diag.FromErr(fmt.Errorf("error create Organization: %s", err))
return diag.FromErr(fmt.Errorf("error creating Organization: %s", err))
}

orgID := organization.Organization.GetId()

// update settings using new keys for this created organization because
// the provider/requesting API keys are not applicable for performing updates/delete for this new organization
cfg := config.Config{
PublicKey: *organization.ApiKey.PublicKey,
PrivateKey: *organization.ApiKey.PrivateKey,
BaseURL: meta.(*config.MongoDBClient).Config.BaseURL,
}

clients, _ := cfg.NewClient(ctx)
conn = clients.(*config.MongoDBClient).AtlasV2

_, _, errUpdate := conn.OrganizationsApi.UpdateOrganizationSettings(ctx, orgID, newOrganizationSettings(d)).Execute()
if errUpdate != nil {
if _, _, err := conn.OrganizationsApi.DeleteOrganization(ctx, orgID).Execute(); err != nil {
d.SetId("")
return diag.FromErr(fmt.Errorf("an error occurred when updating Organization settings: %s.\n Unable to delete organization, there may be dangling resources: %s", errUpdate.Error(), err.Error()))
}
d.SetId("")
return diag.FromErr(fmt.Errorf("an error occurred when updating Organization settings: %s", err))
}

if err := d.Set("private_key", organization.ApiKey.GetPrivateKey()); err != nil {
Expand Down Expand Up @@ -119,6 +162,26 @@ func resourceMongoDBAtlasOrganizationRead(ctx context.Context, d *schema.Resourc
}
return diag.FromErr(fmt.Errorf("error reading organization information: %s", err))
}

if err := d.Set("name", organization.Name); err != nil {
return diag.Errorf("error setting `name` for organization (%s): %s", *organization.Id, err)
}

settings, _, err := conn.OrganizationsApi.GetOrganizationSettings(ctx, orgID).Execute()
if err != nil {
return diag.FromErr(fmt.Errorf("error reading organization settings: %s", err))
}

if err := d.Set("api_access_list_required", settings.ApiAccessListRequired); err != nil {
return diag.Errorf("error setting `api_access_list_required` for organization (%s): %s", orgID, err)
}
if err := d.Set("multi_factor_auth_required", settings.MultiFactorAuthRequired); err != nil {
return diag.Errorf("error setting `multi_factor_auth_required` for organization (%s): %s", orgID, err)
}
if err := d.Set("restrict_employee_access", settings.RestrictEmployeeAccess); err != nil {
return diag.Errorf("error setting `restrict_employee_access` for organization (%s): %s", orgID, err)
}

d.SetId(conversion.EncodeStateID(map[string]string{
"org_id": organization.GetId(),
}))
Expand All @@ -143,9 +206,16 @@ func resourceMongoDBAtlasOrganizationUpdate(ctx context.Context, d *schema.Resou
updateRequest.Name = d.Get("name").(string)
_, _, err := conn.OrganizationsApi.RenameOrganization(ctx, orgID, updateRequest).Execute()
if err != nil {
return diag.FromErr(fmt.Errorf("error updating Organization: %s", err))
return diag.FromErr(fmt.Errorf("error updating Organization name: %s", err))
}
}

if d.HasChange("api_access_list_required") || d.HasChange("multi_factor_auth_required") || d.HasChange("restrict_employee_access") {
if _, _, err := conn.OrganizationsApi.UpdateOrganizationSettings(ctx, orgID, newOrganizationSettings(d)).Execute(); err != nil {
return diag.FromErr(fmt.Errorf("error updating Organization settings: %s", err))
}
}

return resourceMongoDBAtlasOrganizationRead(ctx, d, meta)
}

Expand All @@ -163,7 +233,7 @@ func resourceMongoDBAtlasOrganizationDelete(ctx context.Context, d *schema.Resou
orgID := ids["org_id"]

if _, _, err := conn.OrganizationsApi.DeleteOrganization(ctx, orgID).Execute(); err != nil {
return diag.FromErr(fmt.Errorf("error Organization: %s", err))
return diag.FromErr(fmt.Errorf("error deleting Organization: %s", err))
}
return nil
}
Expand All @@ -185,3 +255,21 @@ func newCreateOrganizationRequest(d *schema.ResourceData) *admin.CreateOrganizat

return createRequest
}

func newOrganizationSettings(d *schema.ResourceData) *admin.OrganizationSettings {
return &admin.OrganizationSettings{
ApiAccessListRequired: pointy.Bool(d.Get("api_access_list_required").(bool)),
MultiFactorAuthRequired: pointy.Bool(d.Get("multi_factor_auth_required").(bool)),
RestrictEmployeeAccess: pointy.Bool(d.Get("restrict_employee_access").(bool)),
}
}

func ValidateAPIKeyIsOrgOwner(roles []string) error {
for _, role := range roles {
if role == constant.OrgOwner {
return nil
}
}

return fmt.Errorf("`role_names` for new API Key must have the ORG_OWNER role to use this resource")
}
Loading