Skip to content

Commit a125b02

Browse files
authored
INTMDB-285: Fix org_invitations issue (#643)
* added verification to org_invitation for accepted invitations * added documentation * fix documentation * fix doc
1 parent a764900 commit a125b02

File tree

2 files changed

+45
-22
lines changed

2 files changed

+45
-22
lines changed

mongodbatlas/resource_mongodbatlas_org_invitation.go

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@ package mongodbatlas
22

33
import (
44
"context"
5-
"errors"
65
"fmt"
76
"regexp"
7+
"strings"
88

99
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
10-
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
11-
1210
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1312
matlas "go.mongodb.org/atlas/mongodbatlas"
1413
)
1514

@@ -85,45 +84,48 @@ func resourceMongoDBAtlasOrgInvitationRead(ctx context.Context, d *schema.Resour
8584
if err != nil {
8685
// case 404
8786
// deleted in the backend case
88-
var target *matlas.ErrorResponse
89-
if errors.As(err, &target) && target.ErrorCode == "NOT_FOUND" {
90-
d.SetId("")
87+
88+
if strings.Contains(err.Error(), "404") {
89+
accepted, _ := validateOrgInvitationAlreadyAccepted(ctx, meta.(*MongoDBClient), username, orgID)
90+
if !accepted {
91+
d.SetId("")
92+
}
9193
return nil
9294
}
9395

94-
return diag.FromErr(fmt.Errorf("error getting Organization Invitation information: %w", err))
96+
return diag.Errorf("error getting Organization Invitation information: %s", err)
9597
}
9698

9799
if err := d.Set("username", orgInvitation.Username); err != nil {
98-
return diag.FromErr(fmt.Errorf("error getting `username` for Organization Invitation (%s): %w", d.Id(), err))
100+
return diag.Errorf("error getting `username` for Organization Invitation (%s): %s", d.Id(), err)
99101
}
100102

101103
if err := d.Set("org_id", orgInvitation.OrgID); err != nil {
102-
return diag.FromErr(fmt.Errorf("error getting `username` for Organization Invitation (%s): %w", d.Id(), err))
104+
return diag.Errorf("error getting `username` for Organization Invitation (%s): %s", d.Id(), err)
103105
}
104106

105107
if err := d.Set("invitation_id", orgInvitation.ID); err != nil {
106-
return diag.FromErr(fmt.Errorf("error getting `invitation_id` for Organization Invitation (%s): %w", d.Id(), err))
108+
return diag.Errorf("error getting `invitation_id` for Organization Invitation (%s): %s", d.Id(), err)
107109
}
108110

109111
if err := d.Set("expires_at", orgInvitation.ExpiresAt); err != nil {
110-
return diag.FromErr(fmt.Errorf("error getting `expires_at` for Organization Invitation (%s): %w", d.Id(), err))
112+
return diag.Errorf("error getting `expires_at` for Organization Invitation (%s): %s", d.Id(), err)
111113
}
112114

113115
if err := d.Set("created_at", orgInvitation.CreatedAt); err != nil {
114-
return diag.FromErr(fmt.Errorf("error getting `created_at` for Organization Invitation (%s): %w", d.Id(), err))
116+
return diag.Errorf("error getting `created_at` for Organization Invitation (%s): %s", d.Id(), err)
115117
}
116118

117119
if err := d.Set("inviter_username", orgInvitation.InviterUsername); err != nil {
118-
return diag.FromErr(fmt.Errorf("error getting `inviter_username` for Organization Invitation (%s): %w", d.Id(), err))
120+
return diag.Errorf("error getting `inviter_username` for Organization Invitation (%s): %s", d.Id(), err)
119121
}
120122

121123
if err := d.Set("teams_ids", orgInvitation.TeamIDs); err != nil {
122-
return diag.FromErr(fmt.Errorf("error getting `teams_ids` for Organization Invitation (%s): %w", d.Id(), err))
124+
return diag.Errorf("error getting `teams_ids` for Organization Invitation (%s): %s", d.Id(), err)
123125
}
124126

125127
if err := d.Set("roles", orgInvitation.Roles); err != nil {
126-
return diag.FromErr(fmt.Errorf("error getting `roles` for Organization Invitation (%s): %w", d.Id(), err))
128+
return diag.Errorf("error getting `roles` for Organization Invitation (%s): %s", d.Id(), err)
127129
}
128130

129131
d.SetId(encodeStateID(map[string]string{
@@ -148,7 +150,7 @@ func resourceMongoDBAtlasOrgInvitationCreate(ctx context.Context, d *schema.Reso
148150

149151
invitationRes, _, err := conn.Organizations.InviteUser(ctx, orgID, invitationReq)
150152
if err != nil {
151-
return diag.FromErr(fmt.Errorf("error creating Organization invitation for user %s: %w", d.Get("username").(string), err))
153+
return diag.Errorf("error creating Organization invitation for user %s: %s", d.Get("username").(string), err)
152154
}
153155

154156
d.SetId(encodeStateID(map[string]string{
@@ -169,7 +171,7 @@ func resourceMongoDBAtlasOrgInvitationDelete(ctx context.Context, d *schema.Reso
169171

170172
_, err := conn.Organizations.DeleteInvitation(ctx, orgID, invitationID)
171173
if err != nil {
172-
return diag.FromErr(fmt.Errorf("error deleting Organization invitation for user %s: %w", username, err))
174+
return diag.Errorf("error deleting Organization invitation for user %s: %s", username, err)
173175
}
174176

175177
return nil
@@ -188,7 +190,7 @@ func resourceMongoDBAtlasOrgInvitationUpdate(ctx context.Context, d *schema.Reso
188190

189191
_, _, err := conn.Organizations.UpdateInvitationByID(ctx, orgID, invitationID, invitationReq)
190192
if err != nil {
191-
return diag.FromErr(fmt.Errorf("error updating Organization invitation for user %s: for %w", username, err))
193+
return diag.Errorf("error updating Organization invitation for user %s: for %s", username, err)
192194
}
193195

194196
return resourceMongoDBAtlasOrgInvitationRead(ctx, d, meta)
@@ -203,7 +205,7 @@ func resourceMongoDBAtlasOrgInvitationImportState(ctx context.Context, d *schema
203205

204206
orgInvitations, _, err := conn.Organizations.Invitations(ctx, orgID, nil)
205207
if err != nil {
206-
return nil, fmt.Errorf("couldn't import Organization invitations, error: %w", err)
208+
return nil, fmt.Errorf("couldn't import Organization invitations, error: %s", err)
207209
}
208210

209211
for _, orgInvitation := range orgInvitations {
@@ -212,13 +214,13 @@ func resourceMongoDBAtlasOrgInvitationImportState(ctx context.Context, d *schema
212214
}
213215

214216
if err := d.Set("username", orgInvitation.Username); err != nil {
215-
return nil, fmt.Errorf("error getting `username` for Organization Invitation (%s): %w", username, err)
217+
return nil, fmt.Errorf("error getting `username` for Organization Invitation (%s): %s", username, err)
216218
}
217219
if err := d.Set("org_id", orgInvitation.GroupID); err != nil {
218-
return nil, fmt.Errorf("error getting `org_id` for Organization Invitation (%s): %w", username, err)
220+
return nil, fmt.Errorf("error getting `org_id` for Organization Invitation (%s): %s", username, err)
219221
}
220222
if err := d.Set("invitation_id", orgInvitation.ID); err != nil {
221-
return nil, fmt.Errorf("error getting `invitation_id` for Organization Invitation (%s): %w", username, err)
223+
return nil, fmt.Errorf("error getting `invitation_id` for Organization Invitation (%s): %s", username, err)
222224
}
223225
d.SetId(encodeStateID(map[string]string{
224226
"username": username,
@@ -245,3 +247,18 @@ func splitOrgInvitationImportID(id string) (orgID, username string, err error) {
245247

246248
return
247249
}
250+
251+
func validateOrgInvitationAlreadyAccepted(ctx context.Context, conn *MongoDBClient, username, orgID string) (bool, error) {
252+
user, _, err := conn.Atlas.AtlasUsers.GetByName(ctx, username)
253+
if err != nil {
254+
return false, err
255+
}
256+
257+
for _, role := range user.Roles {
258+
if role.OrgID == orgID {
259+
return true, nil
260+
}
261+
}
262+
263+
return false, nil
264+
}

website/docs/r/org_invitation.html.markdown

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,16 @@ In addition to the arguments, this resource exports the following attributes:
6969
* `invitation_id` - Unique 24-hexadecimal digit string that identifies the invitation in Atlas.
7070
* `inviter_username` - Atlas user who invited `username` to the organization.
7171

72+
> **NOTE**: Possible provider behavior depending on the invitee's action:
73+
>* If the user has not yet accepted the invitation, the provider leaves the invitation as is.
74+
>* If the user has accepted the invitation and is now an organization member, the provider will remove the invitation from the Terraform state. The invitation must then be removed from the Terraform resource configuration.
75+
>* If the user accepts the invitation and then leaves the organization, the provider will re-add the invitation if the resource definition is not removed from the Terraform configuration.
76+
7277
## Import
7378

7479
Import a user's invitation to an organization by separating the `org_id` and the `username` with a hyphen:
7580

81+
7682
```
7783
$ terraform import mongodbatlas_org_invitation.my_user [email protected]
7884
```

0 commit comments

Comments
 (0)