Skip to content

Commit

Permalink
Mark the deleted field computed in google_project_iam_custom_role (#2619
Browse files Browse the repository at this point in the history
)

<!-- This change is generated by MagicModules. -->
/cc @rileykarson
  • Loading branch information
modular-magician authored and nat-henderson committed Dec 21, 2018
1 parent bec3ebe commit 219bd09
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 71 deletions.
58 changes: 7 additions & 51 deletions google/resource_google_project_iam_custom_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ func resourceGoogleProjectIamCustomRole() *schema.Resource {
},
"deleted": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Computed: true,
},
},
}
Expand All @@ -69,10 +68,6 @@ func resourceGoogleProjectIamCustomRoleCreate(d *schema.ResourceData, meta inter
return err
}

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

roleId := fmt.Sprintf("projects/%s/roles/%s", project, d.Get("role_id").(string))
r, err := config.clientIAM.Projects.Roles.Get(roleId).Do()
if err == nil {
Expand Down Expand Up @@ -140,50 +135,20 @@ func resourceGoogleProjectIamCustomRoleUpdate(d *schema.ResourceData, meta inter

d.Partial(true)

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())
}
}

// 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
_, err := config.clientIAM.Projects.Roles.Undelete(d.Id(), &iam.UndeleteRoleRequest{}).Do()
if err != nil {
return fmt.Errorf("Error undeleting the custom project role %s: %s", d.Get("title").(string), err)
}
d.SetPartial("deleted")
}

if err := resourceGoogleProjectIamCustomRoleUpdateNonDeletedFields(d, meta); err != nil {
return err
d.SetPartial("deleted")
}
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{
Expand All @@ -201,6 +166,8 @@ func resourceGoogleProjectIamCustomRoleUpdateNonDeletedFields(d *schema.Resource
d.SetPartial("stage")
d.SetPartial("permissions")
}

d.Partial(false)
return nil
}

Expand All @@ -214,14 +181,3 @@ func resourceGoogleProjectIamCustomRoleDelete(d *schema.ResourceData, meta inter

return nil
}

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

_, err := config.clientIAM.Projects.Roles.Undelete(d.Id(), &iam.UndeleteRoleRequest{}).Do()
if err != nil {
return fmt.Errorf("Error undeleting the custom project role %s: %s", d.Get("title").(string), err)
}

return nil
}
51 changes: 31 additions & 20 deletions google/resource_google_project_iam_custom_role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func TestAccProjectIamCustomRole_undelete(t *testing.T) {
Steps: []resource.TestStep{
{
Config: testAccCheckGoogleProjectIamCustomRole_basic(roleId),
Check: resource.TestCheckResourceAttr("google_project_iam_custom_role.foo", "deleted", "false"),
Check: testAccCheckGoogleProjectIamCustomRoleDeletionStatus("google_project_iam_custom_role.foo", false),
},
{
ResourceName: "google_project_iam_custom_role.foo",
Expand All @@ -61,18 +61,15 @@ func TestAccProjectIamCustomRole_undelete(t *testing.T) {
},
// Soft-delete
{
Config: testAccCheckGoogleProjectIamCustomRole_deleted(roleId),
Check: resource.TestCheckResourceAttr("google_project_iam_custom_role.foo", "deleted", "true"),
},
{
ResourceName: "google_project_iam_custom_role.foo",
ImportState: true,
ImportStateVerify: true,
Config: testAccCheckGoogleProjectIamCustomRole_basic(roleId),
Check: testAccCheckGoogleProjectIamCustomRoleDeletionStatus("google_project_iam_custom_role.foo", true),
Destroy: true,
},
// Terraform doesn't have a config because of Destroy: true, so an import step would fail
// Undelete
{
Config: testAccCheckGoogleProjectIamCustomRole_basic(roleId),
Check: resource.TestCheckResourceAttr("google_project_iam_custom_role.foo", "deleted", "false"),
Check: testAccCheckGoogleProjectIamCustomRoleDeletionStatus("google_project_iam_custom_role.foo", false),
},
{
ResourceName: "google_project_iam_custom_role.foo",
Expand Down Expand Up @@ -141,25 +138,39 @@ func testAccCheckGoogleProjectIamCustomRoleDestroy(s *terraform.State) error {
return nil
}

func testAccCheckGoogleProjectIamCustomRole_basic(roleId string) string {
return fmt.Sprintf(`
resource "google_project_iam_custom_role" "foo" {
role_id = "%s"
title = "My Custom Role"
description = "foo"
permissions = ["iam.roles.list"]
}
`, roleId)
func testAccCheckGoogleProjectIamCustomRoleDeletionStatus(n string, deleted bool) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("No ID is set")
}

config := testAccProvider.Meta().(*Config)
role, err := config.clientIAM.Projects.Roles.Get(rs.Primary.ID).Do()

if err != nil {
return err
}

if deleted != role.Deleted {
return fmt.Errorf("Incorrect deletion status. Expected %t, got %t", deleted, role.Deleted)
}

return nil
}
}

func testAccCheckGoogleProjectIamCustomRole_deleted(roleId string) string {
func testAccCheckGoogleProjectIamCustomRole_basic(roleId string) string {
return fmt.Sprintf(`
resource "google_project_iam_custom_role" "foo" {
role_id = "%s"
title = "My Custom Role"
description = "foo"
permissions = ["iam.roles.list"]
deleted = true
}
`, roleId)
}
Expand Down
7 changes: 7 additions & 0 deletions website/docs/r/google_project_iam_custom_role.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ The following arguments are supported:

* `description` - (Optional) A human-readable description for the role.

## Attributes Reference

In addition to the arguments listed above, the following computed attributes are
exported:

* `deleted` - (Optional) The current deleted state of the role.

## Import

Customized IAM project role can be imported using their URI, e.g.
Expand Down

0 comments on commit 219bd09

Please sign in to comment.