Skip to content

Commit 1ebf074

Browse files
csanxCristina Sánchez Sánchezdavidhou17
authored
feat: Adds users attribute to mongodbatlas_team singular data source. (#3483)
* Extracted users attribute common schema to dsschema/users_schema.go * Added attribute users to team data source * Modified tests * Modified doc * Added changelog * Update docs/data-sources/team.md Co-authored-by: davidhou17 <[email protected]> * Update docs/data-sources/team.md Co-authored-by: davidhou17 <[email protected]> * Addressed comments * Fixed typos and added comment. * Refactor: extract regex matchers for tests, relocate and update function visibility --------- Co-authored-by: Cristina Sánchez Sánchez <[email protected]> Co-authored-by: davidhou17 <[email protected]>
1 parent 4b8d0e7 commit 1ebf074

File tree

10 files changed

+302
-166
lines changed

10 files changed

+302
-166
lines changed

.changelog/3483.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
data-source/mongodbatlas_team: Adds `users` attribute
3+
```

docs/data-sources/team.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,27 @@ In addition to all arguments above, the following attributes are exported:
5050
* `id` - Terraform's unique identifier used internally for state management.
5151
* `team_id` - The unique identifier for the team.
5252
* `name` - The name of the team you want to create.
53-
* `usernames` - The users who are part of the organization.
53+
* `usernames` - The users who are part of the team.
54+
* `users`- Returns a list of all pending and active MongoDB Cloud users associated with the specified team.
55+
56+
### Users
57+
* `id` - Unique 24-hexadecimal digit string that identifies the MongoDB Cloud user.
58+
* `org_membership_status` - String enum that indicates whether the MongoDB Cloud user has a pending invitation to join the organization or are already active in the organization.
59+
* `roles` - Organization and project-level roles assigned to one MongoDB Cloud user within one organization.
60+
* `team_ids` - List of unique 24-hexadecimal digit strings that identifies the teams to which this MongoDB Cloud user belongs.
61+
* `username` - Email address that represents the username of the MongoDB Cloud user.
62+
* `country` - Two-character alphabetical string that identifies the MongoDB Cloud user's geographic location. This parameter uses the ISO 3166-1a2 code format.
63+
* `invitation_created_at` - Date and time when MongoDB Cloud sent the invitation. MongoDB Cloud represents this timestamp in ISO 8601 format in UTC.
64+
* `invitation_expires_at` - Date and time when the invitation from MongoDB Cloud expires. MongoDB Cloud represents this timestamp in ISO 8601 format in UTC.
65+
* `inviter_username` - Username of the MongoDB Cloud user who sent the invitation to join the organization.
66+
* `created_at` - Date and time when MongoDB Cloud created the current account. This value is in the ISO 8601 timestamp format in UTC.
67+
* `first_name` - First or given name that belongs to the MongoDB Cloud user.
68+
* `last_auth` - Date and time when the current account last authenticated. This value is in the ISO 8601 timestamp format in UTC.
69+
* `last_name` - Last name, family name, or surname that belongs to the MongoDB Cloud user.
70+
* `mobile_number` - Mobile phone number that belongs to the MongoDB Cloud user.
71+
72+
73+
~> **NOTE:** - Users with pending invitations created using [`mongodbatlas_project_invitation`](../resources/project_invitation.md) resource or via the deprecated [Invite One MongoDB Cloud User to Join One Project](https://www.mongodb.com/docs/api/doc/atlas-admin-api-v2/operation/operation-createprojectinvitation) endpoint are excluded (or cannot be managed) with this resource. See [MongoDB Atlas API](https://www.mongodb.com/docs/api/doc/atlas-admin-api-v2/group/endpoint-mongodb-cloud-users) for details.
74+
To manage these users with this resource/data source, refer to our [migration guide]<link-to-migration-guide>.
5475

5576
See detailed information for arguments and attributes: [MongoDB API Teams](https://docs.atlas.mongodb.com/reference/api/teams-create-one/)

internal/common/conversion/flatten_expand.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package conversion
22

33
import (
4+
"time"
5+
46
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
57

68
"go.mongodb.org/atlas-sdk/v20250312005/admin"
@@ -28,6 +30,57 @@ func FlattenTags(tags []admin.ResourceTag) []map[string]string {
2830
return ret
2931
}
3032

33+
func FlattenUsers(users []admin.OrgUserResponse) []map[string]any {
34+
ret := make([]map[string]any, len(users))
35+
for i := range users {
36+
user := &users[i]
37+
ret[i] = map[string]any{
38+
"id": user.GetId(),
39+
"org_membership_status": user.GetOrgMembershipStatus(),
40+
"roles": flattenUserRoles(user.GetRoles()),
41+
"team_ids": user.GetTeamIds(),
42+
"username": user.GetUsername(),
43+
"invitation_created_at": user.GetInvitationCreatedAt().Format(time.RFC3339),
44+
"invitation_expires_at": user.GetInvitationExpiresAt().Format(time.RFC3339),
45+
"inviter_username": user.GetInviterUsername(),
46+
"country": user.GetCountry(),
47+
"created_at": user.GetCreatedAt().Format(time.RFC3339),
48+
"first_name": user.GetFirstName(),
49+
"last_auth": user.GetLastAuth().Format(time.RFC3339),
50+
"last_name": user.GetLastName(),
51+
"mobile_number": user.GetMobileNumber(),
52+
}
53+
}
54+
return ret
55+
}
56+
57+
func flattenUserRoles(roles admin.OrgUserRolesResponse) []map[string]any {
58+
ret := make([]map[string]any, 0)
59+
roleMap := map[string]any{
60+
"org_roles": []string{},
61+
"project_roles_assignments": []map[string]any{},
62+
}
63+
if roles.HasOrgRoles() {
64+
roleMap["org_roles"] = roles.GetOrgRoles()
65+
}
66+
if roles.HasGroupRoleAssignments() {
67+
roleMap["project_roles_assignments"] = flattenProjectRolesAssignments(roles.GetGroupRoleAssignments())
68+
}
69+
ret = append(ret, roleMap)
70+
return ret
71+
}
72+
73+
func flattenProjectRolesAssignments(assignments []admin.GroupRoleAssignment) []map[string]any {
74+
ret := make([]map[string]any, 0, len(assignments))
75+
for _, assignment := range assignments {
76+
ret = append(ret, map[string]any{
77+
"project_id": assignment.GetGroupId(),
78+
"project_roles": assignment.GetGroupRoles(),
79+
})
80+
}
81+
return ret
82+
}
83+
3184
func ExpandTagsFromSetSchema(d *schema.ResourceData) *[]admin.ResourceTag {
3285
list := d.Get("tags").(*schema.Set)
3386
ret := make([]admin.ResourceTag, list.Len())
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package dsschema
2+
3+
import (
4+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
5+
)
6+
7+
func DSOrgUsersSchema() *schema.Schema {
8+
return &schema.Schema{
9+
Type: schema.TypeSet,
10+
Computed: true,
11+
Elem: &schema.Resource{
12+
Schema: map[string]*schema.Schema{
13+
"id": {
14+
Type: schema.TypeString,
15+
Computed: true,
16+
},
17+
"org_membership_status": {
18+
Type: schema.TypeString,
19+
Computed: true,
20+
},
21+
"roles": {
22+
Type: schema.TypeList,
23+
Computed: true,
24+
Elem: &schema.Resource{
25+
Schema: map[string]*schema.Schema{
26+
"org_roles": {
27+
Type: schema.TypeSet,
28+
Computed: true,
29+
Elem: &schema.Schema{Type: schema.TypeString},
30+
},
31+
"project_roles_assignments": {
32+
Type: schema.TypeSet,
33+
Computed: true,
34+
Elem: &schema.Resource{
35+
Schema: map[string]*schema.Schema{
36+
"project_id": {
37+
Type: schema.TypeString,
38+
Computed: true,
39+
},
40+
"project_roles": {
41+
Type: schema.TypeSet,
42+
Computed: true,
43+
Elem: &schema.Schema{Type: schema.TypeString},
44+
},
45+
},
46+
},
47+
},
48+
},
49+
},
50+
},
51+
"team_ids": {
52+
Type: schema.TypeList,
53+
Computed: true,
54+
Elem: &schema.Schema{Type: schema.TypeString},
55+
},
56+
"username": {
57+
Type: schema.TypeString,
58+
Computed: true,
59+
},
60+
"invitation_created_at": {
61+
Type: schema.TypeString,
62+
Computed: true,
63+
},
64+
"invitation_expires_at": {
65+
Type: schema.TypeString,
66+
Computed: true,
67+
},
68+
"inviter_username": {
69+
Type: schema.TypeString,
70+
Computed: true,
71+
},
72+
"country": {
73+
Type: schema.TypeString,
74+
Computed: true,
75+
},
76+
"created_at": {
77+
Type: schema.TypeString,
78+
Computed: true,
79+
},
80+
"first_name": {
81+
Type: schema.TypeString,
82+
Computed: true,
83+
},
84+
"last_auth": {
85+
Type: schema.TypeString,
86+
Computed: true,
87+
},
88+
"last_name": {
89+
Type: schema.TypeString,
90+
Computed: true,
91+
},
92+
"mobile_number": {
93+
Type: schema.TypeString,
94+
Computed: true,
95+
},
96+
},
97+
},
98+
}
99+
}

internal/service/organization/data_source_organization.go

Lines changed: 2 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"fmt"
66
"net/http"
7-
"time"
87

98
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
109
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@@ -15,100 +14,6 @@ import (
1514
"github.com/mongodb/terraform-provider-mongodbatlas/internal/config"
1615
)
1716

18-
var (
19-
DSOrgUsersSchema = schema.Schema{
20-
Type: schema.TypeSet,
21-
Computed: true,
22-
Elem: &schema.Resource{
23-
Schema: map[string]*schema.Schema{
24-
"id": {
25-
Type: schema.TypeString,
26-
Computed: true,
27-
},
28-
"org_membership_status": {
29-
Type: schema.TypeString,
30-
Computed: true,
31-
},
32-
"roles": {
33-
Type: schema.TypeList,
34-
Computed: true,
35-
Elem: &schema.Resource{
36-
Schema: map[string]*schema.Schema{
37-
"org_roles": {
38-
Type: schema.TypeSet,
39-
Computed: true,
40-
Elem: &schema.Schema{Type: schema.TypeString},
41-
},
42-
"project_roles_assignments": {
43-
Type: schema.TypeSet,
44-
Computed: true,
45-
Elem: &schema.Resource{
46-
Schema: map[string]*schema.Schema{
47-
"project_id": {
48-
Type: schema.TypeString,
49-
Computed: true,
50-
},
51-
"project_roles": {
52-
Type: schema.TypeSet,
53-
Computed: true,
54-
Elem: &schema.Schema{Type: schema.TypeString},
55-
},
56-
},
57-
},
58-
},
59-
},
60-
},
61-
},
62-
"team_ids": {
63-
Type: schema.TypeList,
64-
Computed: true,
65-
Elem: &schema.Schema{Type: schema.TypeString},
66-
},
67-
"username": {
68-
Type: schema.TypeString,
69-
Computed: true,
70-
},
71-
"invitation_created_at": {
72-
Type: schema.TypeString,
73-
Computed: true,
74-
},
75-
"invitation_expires_at": {
76-
Type: schema.TypeString,
77-
Computed: true,
78-
},
79-
"inviter_username": {
80-
Type: schema.TypeString,
81-
Computed: true,
82-
},
83-
"country": {
84-
Type: schema.TypeString,
85-
Computed: true,
86-
},
87-
"created_at": {
88-
Type: schema.TypeString,
89-
Computed: true,
90-
},
91-
"first_name": {
92-
Type: schema.TypeString,
93-
Computed: true,
94-
},
95-
"last_auth": {
96-
Type: schema.TypeString,
97-
Computed: true,
98-
},
99-
"last_name": {
100-
Type: schema.TypeString,
101-
Computed: true,
102-
},
103-
"mobile_number": {
104-
Type: schema.TypeString,
105-
Computed: true,
106-
},
107-
},
108-
},
109-
}
110-
)
111-
11217
func DataSource() *schema.Resource {
11318
return &schema.Resource{
11419
ReadContext: dataSourceRead,
@@ -141,7 +46,7 @@ func DataSource() *schema.Resource {
14146
},
14247
},
14348
},
144-
"users": &DSOrgUsersSchema,
49+
"users": dsschema.DSOrgUsersSchema(),
14550
"api_access_list_required": {
14651
Type: schema.TypeBool,
14752
Computed: true,
@@ -170,57 +75,6 @@ func DataSource() *schema.Resource {
17075
}
17176
}
17277

173-
func flattenUsers(users []admin.OrgUserResponse) []map[string]any {
174-
ret := make([]map[string]any, len(users))
175-
for i := range users {
176-
user := &users[i]
177-
ret[i] = map[string]any{
178-
"id": user.GetId(),
179-
"org_membership_status": user.GetOrgMembershipStatus(),
180-
"roles": flattenUserRoles(user.GetRoles()),
181-
"team_ids": user.GetTeamIds(),
182-
"username": user.GetUsername(),
183-
"invitation_created_at": user.GetInvitationCreatedAt().Format(time.RFC3339),
184-
"invitation_expires_at": user.GetInvitationExpiresAt().Format(time.RFC3339),
185-
"inviter_username": user.GetInviterUsername(),
186-
"country": user.GetCountry(),
187-
"created_at": user.GetCreatedAt().Format(time.RFC3339),
188-
"first_name": user.GetFirstName(),
189-
"last_auth": user.GetLastAuth().Format(time.RFC3339),
190-
"last_name": user.GetLastName(),
191-
"mobile_number": user.GetMobileNumber(),
192-
}
193-
}
194-
return ret
195-
}
196-
197-
func flattenUserRoles(roles admin.OrgUserRolesResponse) []map[string]any {
198-
ret := make([]map[string]any, 0)
199-
roleMap := map[string]any{
200-
"org_roles": []string{},
201-
"project_roles_assignments": []map[string]any{},
202-
}
203-
if roles.HasOrgRoles() {
204-
roleMap["org_roles"] = roles.GetOrgRoles()
205-
}
206-
if roles.HasGroupRoleAssignments() {
207-
roleMap["project_roles_assignments"] = flattenProjectRolesAssignments(roles.GetGroupRoleAssignments())
208-
}
209-
ret = append(ret, roleMap)
210-
return ret
211-
}
212-
213-
func flattenProjectRolesAssignments(assignments []admin.GroupRoleAssignment) []map[string]any {
214-
ret := make([]map[string]any, 0, len(assignments))
215-
for _, assignment := range assignments {
216-
ret = append(ret, map[string]any{
217-
"project_id": assignment.GetGroupId(),
218-
"project_roles": assignment.GetGroupRoles(),
219-
})
220-
}
221-
return ret
222-
}
223-
22478
func dataSourceRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
22579
conn := meta.(*config.MongoDBClient).AtlasV2
22680
orgID := d.Get("org_id").(string)
@@ -251,7 +105,7 @@ func dataSourceRead(ctx context.Context, d *schema.ResourceData, meta any) diag.
251105
if err != nil {
252106
return diag.FromErr(fmt.Errorf("error getting organization users: %s", err))
253107
}
254-
if err := d.Set("users", flattenUsers(users)); err != nil {
108+
if err := d.Set("users", conversion.FlattenUsers(users)); err != nil {
255109
return diag.FromErr(fmt.Errorf("error setting `users`: %s", err))
256110
}
257111

0 commit comments

Comments
 (0)