Skip to content

Commit

Permalink
final fixes to make sure delete works; return read() when updating to…
Browse files Browse the repository at this point in the history
… 'create'
  • Loading branch information
emilymye committed Jun 26, 2018
1 parent 7ee11e5 commit 2fd16dd
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 80 deletions.
118 changes: 76 additions & 42 deletions google/resource_google_organization_iam_custom_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ func resourceGoogleOrganizationIamCustomRole() *schema.Resource {
Optional: true,
},
"deleted": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Type: schema.TypeBool,
Optional: true,
Default: false,
Deprecated: `deleted will be converted to a computed-only field soon - if you want to delete this role, please use destroy`,
},
},
}
Expand All @@ -62,40 +63,48 @@ func resourceGoogleOrganizationIamCustomRoleCreate(d *schema.ResourceData, meta
config := meta.(*Config)

if d.Get("deleted").(bool) {
return fmt.Errorf("Cannot create a custom organization role with a deleted state. `deleted` field should be false.")
return fmt.Errorf("cannot create a custom organization role with a deleted state. `deleted` field should be false.")
}

org := d.Get("org_id").(string)
roleId := fmt.Sprintf("organizations/%s/roles/%s", org, d.Get("role_id").(string))
orgId := fmt.Sprintf("organizations/%s", org)

// Look for role with given ID.
// If it exists in deleted state, update to match "created" role state
// If it exists and and is enabled, return error - we should not try to recreate.
r, err := config.clientIAM.Organizations.Roles.Get(roleId).Do()
if err == nil {
if r.Deleted {
// Roles have soft deletes - creating a role with the same name
// as a recently deleted role must instead be undelete/update.
// This role was soft-deleted; update to match new state.
d.SetId(r.Name)
return resourceGoogleOrganizationIamCustomRoleUpdate(d, meta)
if err := resourceGoogleOrganizationIamCustomRoleUpdate(d, meta); err != nil {
// If update failed, make sure it wasn't actually added to state.
d.SetId("")
return err
}
} else {
// If a role with same name exists and is enabled, just return error
return fmt.Errorf("Custom project role %s already exists and must be imported", roleId)
}
} else {
// If no role was found, actually create a new role.
role, err := config.clientIAM.Organizations.Roles.Create(orgId, &iam.CreateRoleRequest{
RoleId: d.Get("role_id").(string),
Role: &iam.Role{
Title: d.Get("title").(string),
Description: d.Get("description").(string),
Stage: d.Get("stage").(string),
IncludedPermissions: convertStringSet(d.Get("permissions").(*schema.Set)),
},
}).Do()
if err != nil {
return fmt.Errorf("Error creating the custom organization role %s: %s", d.Get("title").(string), err)
}
// If old role with same name exists, just return error
return fmt.Errorf("Custom project role %s already exists and must be imported", roleId)
}

// If no role is found, actually create a new role.
role, err := config.clientIAM.Organizations.Roles.Create("organizations/"+d.Get("org_id").(string), &iam.CreateRoleRequest{
RoleId: d.Get("role_id").(string),
Role: &iam.Role{
Title: d.Get("title").(string),
Description: d.Get("description").(string),
Stage: d.Get("stage").(string),
IncludedPermissions: convertStringSet(d.Get("permissions").(*schema.Set)),
},
}).Do()

if err != nil {
return fmt.Errorf("Error creating the custom organization role %s: %s", d.Get("title").(string), err)
d.SetId(role.Name)
}

d.SetId(role.Name)

return resourceGoogleOrganizationIamCustomRoleRead(d, meta)
}

Expand Down Expand Up @@ -128,30 +137,51 @@ func resourceGoogleOrganizationIamCustomRoleUpdate(d *schema.ResourceData, meta

d.Partial(true)

if d.HasChange("deleted") {
if d.Get("deleted").(bool) {
if d.Get("deleted").(bool) {
if d.HasChange("deleted") {
// If other fields were changed, we need to update those first and then delete.
// If we don't update, we will get diffs from re-apply
// If we delete and then try to update, we will get an error.
if err := resourceGoogleOrganizationIamCustomRoleUpdateNonDeletedFields(d, meta); err != nil {
return err
}

if err := resourceGoogleOrganizationIamCustomRoleDelete(d, meta); err != nil {
return err
}

d.SetPartial("deleted")
d.Partial(false)
return nil
} else {
return fmt.Errorf("cannot make changes to deleted custom organization role %s", d.Id())
}
}

// If role is not deleted, make sure it exists and undelete if needed.
if !d.Get("deleted").(bool) {
r, err := config.clientIAM.Organizations.Roles.Get(d.Id()).Do()
if err != nil {
return fmt.Errorf("unable to find custom project role %s to update: %v", d.Id(), err)
}
if r.Deleted {
// Undelete if deleted previously
if err := resourceGoogleOrganizationIamCustomRoleUndelete(d, meta); err != nil {
return err
}
d.SetPartial("deleted")
// We want to update the role to some undeleted state.
// Make sure the role with given ID exists and is un-deleted before patching.
r, err := config.clientIAM.Organizations.Roles.Get(d.Id()).Do()
if err != nil {
return fmt.Errorf("unable to find custom project role %s to update: %v", d.Id(), err)
}
if r.Deleted {
if err := resourceGoogleOrganizationIamCustomRoleUndelete(d, meta); err != nil {
return err
}
d.SetPartial("deleted")
}

if err := resourceGoogleOrganizationIamCustomRoleUpdateNonDeletedFields(d, meta); err != nil {
return err
}
d.Partial(false)

return nil
}

func resourceGoogleOrganizationIamCustomRoleUpdateNonDeletedFields(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

if d.HasChange("title") || d.HasChange("description") || d.HasChange("stage") || d.HasChange("permissions") {
_, err := config.clientIAM.Organizations.Roles.Patch(d.Id(), &iam.Role{
Title: d.Get("title").(string),
Expand All @@ -169,15 +199,19 @@ func resourceGoogleOrganizationIamCustomRoleUpdate(d *schema.ResourceData, meta
d.SetPartial("permissions")
}

d.Partial(false)

return nil
}

func resourceGoogleOrganizationIamCustomRoleDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

_, err := config.clientIAM.Organizations.Roles.Delete(d.Id()).Do()
r, err := config.clientIAM.Organizations.Roles.Get(d.Id()).Do()
if err == nil && r != nil && r.Deleted && d.Get("deleted").(bool) {
// This role has already been deleted, don't try again.
return nil
}

_, err = config.clientIAM.Organizations.Roles.Delete(d.Id()).Do()
if err != nil {
return fmt.Errorf("Error deleting the custom organization role %s: %s", d.Get("title").(string), err)
}
Expand Down
97 changes: 59 additions & 38 deletions google/resource_google_project_iam_custom_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,32 +75,35 @@ func resourceGoogleProjectIamCustomRoleCreate(d *schema.ResourceData, meta inter
r, err := config.clientIAM.Projects.Roles.Get(roleId).Do()
if err == nil {
if r.Deleted {
// Roles have soft deletes - creating a role with the same name
// as a recently deleted role must instead be undelete/update.
// This role was soft-deleted; update to match new state.
d.SetId(r.Name)
return resourceGoogleProjectIamCustomRoleUpdate(d, meta)
if err := resourceGoogleProjectIamCustomRoleUpdate(d, meta); err != nil {
// If update failed, make sure it wasn't actually added to state.
d.SetId("")
return err
}
} else {
// If a role with same name exists and is enabled, just return error
return fmt.Errorf("Custom project role %s already exists and must be imported", roleId)
}
} else {
// If no role is found, actually create a new role.
role, err := config.clientIAM.Projects.Roles.Create("projects/"+project, &iam.CreateRoleRequest{
RoleId: d.Get("role_id").(string),
Role: &iam.Role{
Title: d.Get("title").(string),
Description: d.Get("description").(string),
Stage: d.Get("stage").(string),
IncludedPermissions: convertStringSet(d.Get("permissions").(*schema.Set)),
},
}).Do()
if err != nil {
return fmt.Errorf("Error creating the custom project role %s: %v", roleId, err)
}
// If old role with same name exists, just return error
return fmt.Errorf("Custom project role %s already exists and must be imported", roleId)
}

// If no role is found, actually create a new role.
role, err := config.clientIAM.Projects.Roles.Create("projects/"+project, &iam.CreateRoleRequest{
RoleId: d.Get("role_id").(string),
Role: &iam.Role{
Title: d.Get("title").(string),
Description: d.Get("description").(string),
Stage: d.Get("stage").(string),
IncludedPermissions: convertStringSet(d.Get("permissions").(*schema.Set)),
},
}).Do()

if err != nil {
return fmt.Errorf("Error creating the custom project role %s: %s", d.Get("title").(string), err)
d.SetId(role.Name)
}

d.SetId(role.Name)

return resourceGoogleProjectIamCustomRoleRead(d, meta)
}

Expand Down Expand Up @@ -133,30 +136,51 @@ func resourceGoogleProjectIamCustomRoleUpdate(d *schema.ResourceData, meta inter

d.Partial(true)

if d.HasChange("deleted") {
if d.Get("deleted").(bool) {
if d.Get("deleted").(bool) {
if d.HasChange("deleted") {
// If other fields were changed, we need to update those first and then delete.
// If we don't update, we will get diffs from re-apply
// If we delete and then try to update, we will get an error.
if err := resourceGoogleProjectIamCustomRoleUpdateNonDeletedFields(d, meta); err != nil {
return err
}
if err := resourceGoogleProjectIamCustomRoleDelete(d, meta); err != nil {
return err
}

d.SetPartial("deleted")
d.Partial(false)
return nil
} else {
return fmt.Errorf("cannot make changes to deleted custom project role %s", d.Id())
}
}

// If role is not deleted, make sure it exists and undelete if needed.
if !d.Get("deleted").(bool) {
r, err := config.clientIAM.Projects.Roles.Get(d.Id()).Do()
if err != nil {
return fmt.Errorf("unable to find custom project role %s to update: %v", d.Id(), err)
}
if r.Deleted {
// Undelete if deleted previously
if err := resourceGoogleProjectIamCustomRoleUndelete(d, meta); err != nil {
return err
}
d.SetPartial("deleted")
// We want to update the role to some undeleted state.
// Make sure the role with given ID exists and is un-deleted before patching.
r, err := config.clientIAM.Projects.Roles.Get(d.Id()).Do()
if err != nil {
return fmt.Errorf("unable to find custom project role %s to update: %v", d.Id(), err)
}
if r.Deleted {
// Undelete if deleted previously
if err := resourceGoogleProjectIamCustomRoleUndelete(d, meta); err != nil {
return err
}
d.SetPartial("deleted")
}

if err := resourceGoogleProjectIamCustomRoleUpdateNonDeletedFields(d, meta); err != nil {
return err
}
d.Partial(false)

return nil
}

func resourceGoogleProjectIamCustomRoleUpdateNonDeletedFields(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

if d.HasChange("title") || d.HasChange("description") || d.HasChange("stage") || d.HasChange("permissions") {
_, err := config.clientIAM.Projects.Roles.Patch(d.Id(), &iam.Role{
Title: d.Get("title").(string),
Expand All @@ -173,9 +197,6 @@ func resourceGoogleProjectIamCustomRoleUpdate(d *schema.ResourceData, meta inter
d.SetPartial("stage")
d.SetPartial("permissions")
}

d.Partial(false)

return nil
}

Expand Down

0 comments on commit 2fd16dd

Please sign in to comment.