Skip to content

Commit

Permalink
azuread_[group|user]: wait for replication (#91)
Browse files Browse the repository at this point in the history
fixs #72
  • Loading branch information
katbyte committed Jun 4, 2019
1 parent a5aa644 commit dc0f5c5
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 65 deletions.
35 changes: 35 additions & 0 deletions azuread/helpers/graph/replication.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package graph

import (
"fmt"
"time"

"github.com/Azure/go-autorest/autorest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/ar"
)

func WaitForReplication(f func() (interface{}, error)) (interface{}, error) {
return (&resource.StateChangeConf{
Pending: []string{"404", "BadCast"},
Target: []string{"Found"},
Timeout: 5 * time.Minute,
MinTimeout: 1 * time.Second,
ContinuousTargetOccurence: 10,
Refresh: func() (interface{}, string, error) {
i, err := f()
if err != nil {
r, ok := i.(autorest.Response)
if !ok {
return i, "BadCast", nil // sometimes the SDK bubbles up an entirely empty object
}
if ar.ResponseWasNotFound(r) {
return i, "404", nil
}
return i, "Error", fmt.Errorf("Error calling f, response was not 404 (%d): %v", r.StatusCode, err)
}

return i, "Found", nil
},
}).WaitForState()
}
4 changes: 0 additions & 4 deletions azuread/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package azuread

import (
"fmt"
"time"

"github.com/hashicorp/go-azure-helpers/authentication"
"github.com/hashicorp/terraform/helper/mutexkv"
Expand All @@ -13,9 +12,6 @@ import (
// armMutexKV is the instance of MutexKV for ARM resources
var armMutexKV = mutexkv.NewMutexKV()

const azureAdReplicationTimeout = 5 * time.Minute
const azureAdReplicationTargetOccurence = 10

// Provider returns a terraform.ResourceProvider.
func Provider() terraform.ResourceProvider {
p := &schema.Provider{
Expand Down
28 changes: 6 additions & 22 deletions azuread/resource_application.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package azuread
import (
"fmt"
"log"
"time"

"github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac"
"github.com/hashicorp/terraform/helper/resource"

"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/ar"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/graph"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/p"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/tf"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/validate"
Expand Down Expand Up @@ -229,28 +229,12 @@ func resourceApplicationCreate(d *schema.ResourceData, meta interface{}) error {
}
d.SetId(*app.ObjectID)

i, err := (&resource.StateChangeConf{
Pending: []string{"404"},
Target: []string{"Found"},
Timeout: azureAdReplicationTimeout,
MinTimeout: 1 * time.Second,
ContinuousTargetOccurence: azureAdReplicationTargetOccurence,
Refresh: func() (interface{}, string, error) {
resp, err2 := client.Get(ctx, *app.ObjectID)
if err2 != nil {
if ar.ResponseWasNotFound(resp.Response) {
return resp, "404", nil
}
return resp, "Error", fmt.Errorf("Error retrieving Application ID %q: %+v", *app.ObjectID, err2)
}

return resp, "Found", nil
},
}).WaitForState()
_, err = graph.WaitForReplication(func() (interface{}, error) {
return client.Get(ctx, *app.ObjectID)
})
if err != nil {
return fmt.Errorf("Error waiting for application: %+v", err)
return fmt.Errorf("Error waiting for Application with ObjectId %q: %+v", *app.ObjectID, err)
}
app = i.(graphrbac.Application)

// follow suggested hack for azure-cli
// AAD graph doesn't have the API to create a native app, aka public client, the recommended hack is
Expand Down
16 changes: 13 additions & 3 deletions azuread/resource_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/ar"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/graph"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/p"
)

Expand All @@ -17,6 +18,7 @@ func resourceGroup() *schema.Resource {
Create: resourceGroupCreate,
Read: resourceGroupRead,
Delete: resourceGroupDelete,

Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Expand Down Expand Up @@ -47,11 +49,20 @@ func resourceGroupCreate(d *schema.ResourceData, meta interface{}) error {

group, err := client.Create(ctx, properties)
if err != nil {
return err
return fmt.Errorf("Error creating Group (%q): %+v", name, err)
}
if group.ObjectID == nil {
return fmt.Errorf("nil Group ID for %q: %+v", name, err)
}

d.SetId(*group.ObjectID)

_, err = graph.WaitForReplication(func() (interface{}, error) {
return client.Get(ctx, *group.ObjectID)
})
if err != nil {
return fmt.Errorf("Error waiting for Group (%s) with ObjectId %q: %+v", name, *group.ObjectID, err)
}

return resourceGroupRead(d, meta)
}

Expand All @@ -71,7 +82,6 @@ func resourceGroupRead(d *schema.ResourceData, meta interface{}) error {
}

d.Set("name", resp.DisplayName)

return nil
}

Expand Down
27 changes: 5 additions & 22 deletions azuread/resource_service_principal.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ package azuread
import (
"fmt"
"log"
"time"

"github.com/hashicorp/terraform/helper/resource"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/graph"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/tf"

"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/validate"
Expand Down Expand Up @@ -80,28 +79,12 @@ func resourceServicePrincipalCreate(d *schema.ResourceData, meta interface{}) er
}
d.SetId(*sp.ObjectID)

i, err := (&resource.StateChangeConf{
Pending: []string{"404"},
Target: []string{"Found"},
Timeout: azureAdReplicationTimeout,
MinTimeout: 1 * time.Second,
ContinuousTargetOccurence: azureAdReplicationTargetOccurence,
Refresh: func() (interface{}, string, error) {
resp, err2 := client.Get(ctx, *sp.ObjectID)
if err2 != nil {
if ar.ResponseWasNotFound(resp.Response) {
return resp, "404", nil
}
return resp, "Error", fmt.Errorf("Error retrieving Service Principal ID %q: %+v", *sp.ObjectID, err2)
}

return resp, "Found", nil
},
}).WaitForState()
_, err = graph.WaitForReplication(func() (interface{}, error) {
return client.Get(ctx, *sp.ObjectID)
})
if err != nil {
return fmt.Errorf("Error waiting for application: %+v", err)
return fmt.Errorf("Error waiting for Service Pricipal with ObjectId %q: %+v", *sp.ObjectID, err)
}
sp = i.(graphrbac.ServicePrincipal)

return resourceServicePrincipalRead(d, meta)
}
Expand Down
28 changes: 14 additions & 14 deletions azuread/resource_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/ar"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/graph"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/p"
"github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/validate"
)
Expand All @@ -19,6 +20,7 @@ func resourceUser() *schema.Resource {
Read: resourceUserRead,
Update: resourceUserUpdate,
Delete: resourceUserDelete,

Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Expand Down Expand Up @@ -74,7 +76,7 @@ func resourceUserCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).usersClient
ctx := meta.(*ArmClient).StopContext

userPrincipalName := d.Get("user_principal_name").(string)
upn := d.Get("user_principal_name").(string)
displayName := d.Get("display_name").(string)
mailNickName := d.Get("mail_nickname").(string)
accountEnabled := d.Get("account_enabled").(bool)
Expand All @@ -83,7 +85,7 @@ func resourceUserCreate(d *schema.ResourceData, meta interface{}) error {

//default mail nickname to the first part of the UPN (matches the portal)
if mailNickName == "" {
mailNickName = strings.Split(userPrincipalName, "@")[0]
mailNickName = strings.Split(upn, "@")[0]
}

userCreateParameters := graphrbac.UserCreateParameters{
Expand All @@ -94,25 +96,24 @@ func resourceUserCreate(d *schema.ResourceData, meta interface{}) error {
ForceChangePasswordNextLogin: &forcePasswordChange,
Password: &password,
},
UserPrincipalName: &userPrincipalName,
UserPrincipalName: &upn,
}

user, err := client.Create(ctx, userCreateParameters)
if err != nil {
return fmt.Errorf("Error creating User %q: %+v", userPrincipalName, err)
return fmt.Errorf("Error creating User (%q): %+v", upn, err)
}
if user.ObjectID == nil {
return fmt.Errorf("nil User ID for %q: %+v", upn, err)
}
d.SetId(*user.ObjectID)

objectId := user.ObjectID

resp, err := client.Get(ctx, *objectId)
_, err = graph.WaitForReplication(func() (interface{}, error) {
return client.Get(ctx, *user.ObjectID)
})
if err != nil {
return fmt.Errorf("Error retrieving User (%q) with ObjectID %q: %+v", userPrincipalName, *objectId, err)
return fmt.Errorf("Error waiting for User (%s) with ObjectId %q: %+v", upn, *user.ObjectID, err)
}
if resp.ObjectID == nil {
return fmt.Errorf("User objectId is nil")
}

d.SetId(*resp.ObjectID)

return resourceUserRead(d, meta)
}
Expand All @@ -138,7 +139,6 @@ func resourceUserRead(d *schema.ResourceData, meta interface{}) error {
d.Set("mail", user.Mail)
d.Set("mail_nickname", user.MailNickname)
d.Set("account_enabled", user.AccountEnabled)

return nil
}

Expand Down

0 comments on commit dc0f5c5

Please sign in to comment.