@@ -177,32 +177,36 @@ func (r *OrgMemberResource) Create(ctx context.Context, req resource.CreateReque
177177 return
178178 }
179179
180- inviteResp , err := r .client . InviteOrgMember (ctx , data .OrgName .ValueString (), data . Role . ValueString (), [] string { invitee }, false )
180+ current , found , err := r .orgMember (ctx , data .OrgName .ValueString (), invitee )
181181 if err != nil {
182- errMsg := fmt .Sprintf ("Unable to create org_member resource: %v" , err )
183- resp .Diagnostics .AddError ("Error Creating Resource" , errMsg )
182+ resp .Diagnostics .AddError ("Error Checking Existing Member" , err .Error ())
184183 return
185184 }
186185
187- if len (inviteResp .OrgInvitees ) == 0 {
188- errMsg := "No invitees were returned from the Docker Hub API."
189- resp .Diagnostics .AddError ("Invite Failed" , errMsg )
190- return
191- }
192-
193- invite := inviteResp .OrgInvitees [0 ]
194- if invite .Invite .ID != "" {
195- data .InviteID = types .StringValue (invite .Invite .ID )
186+ if found {
187+ // Set computed fields.
188+ data .InviteID = current .InviteID
189+ data .Email = current .Email
196190 } else {
197- // If the invite is in a pending state, then InviteOrgMember does not return
198- // the invite ID. We need to get the invite ID from the org invites.
199- member , err := r . orgMember ( ctx , data .OrgName .ValueString (), invitee )
191+ // If the member is not found, invite them now.
192+ inviteResp , err := r . client . InviteOrgMember ( ctx ,
193+ data . OrgName . ValueString () , data .Role .ValueString (), [] string { invitee }, false )
200194 if err != nil {
201- errMsg := fmt .Sprintf ("Could not resolve member status : %v" , err )
195+ errMsg := fmt .Sprintf ("Unable to create org_member resource : %v" , err )
202196 resp .Diagnostics .AddError ("Error Creating Resource" , errMsg )
203197 return
204198 }
205- data .InviteID = member .InviteID
199+
200+ if len (inviteResp .OrgInvitees ) == 0 {
201+ errMsg := "No invitees were returned from the Docker Hub API."
202+ resp .Diagnostics .AddError ("Invite Failed" , errMsg )
203+ return
204+ }
205+
206+ invite := inviteResp .OrgInvitees [0 ]
207+ if invite .Invite .ID != "" {
208+ data .InviteID = types .StringValue (invite .Invite .ID )
209+ }
206210 }
207211
208212 resp .Diagnostics .Append (resp .State .Set (ctx , & data )... )
@@ -225,11 +229,15 @@ func (r *OrgMemberResource) Read(ctx context.Context, req resource.ReadRequest,
225229 return
226230 }
227231
228- data , err := r .orgMember (ctx , state .OrgName .ValueString (), invitee )
232+ data , found , err := r .orgMember (ctx , state .OrgName .ValueString (), invitee )
229233 if err != nil {
230234 resp .Diagnostics .AddError ("Error Reading Resource" , err .Error ())
231235 return
232236 }
237+ if ! found {
238+ resp .Diagnostics .AddError ("Resource Not Found" ,
239+ fmt .Sprintf ("Member not found in %s: %s" , state .OrgName .ValueString (), invitee ))
240+ }
233241
234242 if data .Role .ValueString () == "" {
235243 data .Role = state .Role
@@ -242,7 +250,10 @@ func (r *OrgMemberResource) Read(ctx context.Context, req resource.ReadRequest,
242250 }
243251}
244252
245- // TODO: setup update
253+ // NOTE(nicks): currently, we treat all fields as immutable,
254+ // so in theory update should never happen.
255+ //
256+ // Future work: update the provider to allow role changes.
246257func (r * OrgMemberResource ) Update (ctx context.Context , req resource.UpdateRequest , resp * resource.UpdateResponse ) {
247258 return
248259}
@@ -308,7 +319,9 @@ func (r *OrgMemberResource) ImportState(ctx context.Context, req resource.Import
308319//
309320// Our org_member represents both invited and accepted members, so
310321// we need to merge the results from both endpoints.
311- func (r * OrgMemberResource ) orgMember (ctx context.Context , orgName string , userName string ) (OrgMemberResourceModel , error ) {
322+ //
323+ // Returns true if the member was found, false if not found.
324+ func (r * OrgMemberResource ) orgMember (ctx context.Context , orgName string , userName string ) (OrgMemberResourceModel , bool , error ) {
312325 r .mu .Lock ()
313326 defer r .mu .Unlock ()
314327
@@ -317,7 +330,7 @@ func (r *OrgMemberResource) orgMember(ctx context.Context, orgName string, userN
317330 var err error
318331 members , err = r .client .ListOrgMembers (ctx , orgName )
319332 if err != nil {
320- return OrgMemberResourceModel {}, err
333+ return OrgMemberResourceModel {}, false , err
321334 }
322335 r .orgMembers [orgName ] = members
323336 }
@@ -329,7 +342,7 @@ func (r *OrgMemberResource) orgMember(ctx context.Context, orgName string, userN
329342 UserName : types .StringValue (member .Username ),
330343 Role : types .StringValue (strings .ToLower (member .Role )),
331344 Email : types .StringValue (member .Email ),
332- }, nil
345+ }, true , nil
333346 }
334347 }
335348
@@ -338,7 +351,7 @@ func (r *OrgMemberResource) orgMember(ctx context.Context, orgName string, userN
338351 var err error
339352 invites , err = r .client .ListOrgInvites (ctx , orgName )
340353 if err != nil {
341- return OrgMemberResourceModel {}, err
354+ return OrgMemberResourceModel {}, false , err
342355 }
343356 r .orgInvites [orgName ] = invites
344357 }
@@ -354,9 +367,9 @@ func (r *OrgMemberResource) orgMember(ctx context.Context, orgName string, userN
354367 } else {
355368 result .UserName = types .StringValue (userName )
356369 }
357- return result , nil
370+ return result , true , nil
358371 }
359372 }
360373
361- return OrgMemberResourceModel {}, fmt . Errorf ( "member not found in org. Org: %s, User: %s" , orgName , userName )
374+ return OrgMemberResourceModel {}, false , nil
362375}
0 commit comments