From 1f231f219024919761bf5ccd856bd8a82994a553 Mon Sep 17 00:00:00 2001 From: Riley Karson Date: Mon, 10 Dec 2018 21:27:47 +0000 Subject: [PATCH] Mark the deleted field computed in google_project_iam_custom_role --- ...resource_google_project_iam_custom_role.go | 58 +++---------------- ...rce_google_project_iam_custom_role_test.go | 51 +++++++++------- ...ogle_project_iam_custom_role.html.markdown | 7 +++ 3 files changed, 45 insertions(+), 71 deletions(-) diff --git a/google/resource_google_project_iam_custom_role.go b/google/resource_google_project_iam_custom_role.go index 24aa92c896a..71c4ed5f43c 100644 --- a/google/resource_google_project_iam_custom_role.go +++ b/google/resource_google_project_iam_custom_role.go @@ -54,8 +54,7 @@ func resourceGoogleProjectIamCustomRole() *schema.Resource { }, "deleted": { Type: schema.TypeBool, - Optional: true, - Default: false, + Computed: true, }, }, } @@ -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 { @@ -140,26 +135,6 @@ 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() @@ -167,23 +142,13 @@ func resourceGoogleProjectIamCustomRoleUpdate(d *schema.ResourceData, meta inter 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{ @@ -201,6 +166,8 @@ func resourceGoogleProjectIamCustomRoleUpdateNonDeletedFields(d *schema.Resource d.SetPartial("stage") d.SetPartial("permissions") } + + d.Partial(false) return nil } @@ -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 -} diff --git a/google/resource_google_project_iam_custom_role_test.go b/google/resource_google_project_iam_custom_role_test.go index f0e396ca0a3..6590df81a10 100644 --- a/google/resource_google_project_iam_custom_role_test.go +++ b/google/resource_google_project_iam_custom_role_test.go @@ -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", @@ -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", @@ -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) } diff --git a/website/docs/r/google_project_iam_custom_role.html.markdown b/website/docs/r/google_project_iam_custom_role.html.markdown index 339a0c6a8f4..8dbf60cd605 100644 --- a/website/docs/r/google_project_iam_custom_role.html.markdown +++ b/website/docs/r/google_project_iam_custom_role.html.markdown @@ -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.