Skip to content

Commit

Permalink
azuread_group: work around replication delays when removing members (…
Browse files Browse the repository at this point in the history
…attempt 10 times, check 10 times)
  • Loading branch information
manicminer committed Jun 18, 2020
1 parent ab0a7e8 commit 66391b5
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 10 deletions.
2 changes: 1 addition & 1 deletion azuread/helpers/graph/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func GroupAddMember(client graphrbac.GroupsClient, ctx context.Context, groupId
time.Sleep(time.Second * 2)
}

if _, err := WaitForListMember(member, func() ([]string, error) {
if _, err := WaitForListAdd(member, func() ([]string, error) {
return GroupAllMembers(client, ctx, groupId)
}); err != nil {
return fmt.Errorf("Error waiting for group membership: %+v", err)
Expand Down
39 changes: 32 additions & 7 deletions azuread/helpers/graph/replication.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,52 @@ func WaitForCreationReplication(f func() (interface{}, error)) (interface{}, err
}).WaitForState()
}

func WaitForListMember(member string, f func() ([]string, error)) (interface{}, error) {
func WaitForListAdd(item string, f func() ([]string, error)) (interface{}, error) {
return (&resource.StateChangeConf{
Pending: []string{"404"},
Target: []string{"Found"},
Timeout: 5 * time.Minute,
MinTimeout: 1 * time.Second,
ContinuousTargetOccurence: 10,
Refresh: func() (interface{}, string, error) {
members, err := f()
listItems, err := f()

if err != nil {
return members, "Error", err
return listItems, "Error", err
}

for _, v := range members {
if v == member {
return members, "Found", nil
for _, v := range listItems {
if v == item {
return listItems, "Found", nil
}
}

return members, "404", nil
return listItems, "404", nil
},
}).WaitForState()
}

func WaitForListRemove(item string, f func() ([]string, error)) (interface{}, error) {
return (&resource.StateChangeConf{
Pending: []string{"Found"},
Target: []string{"404"},
Timeout: 5 * time.Minute,
MinTimeout: 1 * time.Second,
ContinuousTargetOccurence: 10,
Refresh: func() (interface{}, string, error) {
listItems, err := f()

if err != nil {
return listItems, "Error", err
}

for _, v := range listItems {
if v == item {
return listItems, "Found", nil
}
}

return listItems, "404", nil
},
}).WaitForState()
}
21 changes: 19 additions & 2 deletions azuread/resource_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package azuread

import (
"fmt"
"github.com/Azure/go-autorest/autorest"
"log"
"time"

"github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac"
"github.com/Azure/go-autorest/autorest"
Expand Down Expand Up @@ -187,11 +189,26 @@ func resourceGroupUpdate(d *schema.ResourceData, meta interface{}) error {
membersToAdd := slices.Difference(desiredMembers, existingMembers)

for _, existingMember := range membersForRemoval {
var err error
var resp autorest.Response
log.Printf("[DEBUG] Removing member with id %q from Azure AD group with id %q", existingMember, d.Id())
if resp, err := client.RemoveMember(ctx, d.Id(), existingMember); err != nil {
if !ar.ResponseWasNotFound(resp) {
attempts := 10
for i := 0; i <= attempts; i++ {
if resp, err = client.RemoveMember(ctx, d.Id(), existingMember); err != nil {
if ar.ResponseWasNotFound(resp) {
break
}
}
if i == attempts {
return fmt.Errorf("Error Deleting group member %q from Azure AD Group with ID %q: %+v", existingMember, d.Id(), err)
}
time.Sleep(time.Second * 2)
}

if _, err := graph.WaitForListRemove(existingMember, func() ([]string, error) {
return graph.GroupAllMembers(client, ctx, d.Id())
}); err != nil {
return fmt.Errorf("Error waiting for group membership removal: %+v", err)
}
}

Expand Down

0 comments on commit 66391b5

Please sign in to comment.