Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow recreation of recently deleted project and org custom roles #1681

Merged
merged 6 commits into from
Sep 10, 2018

Conversation

emilymye
Copy link
Contributor

  • Undelete-update recently soft-deleted roles instead of giving error

Fixes #1668

}
}

// If role is not deleted, make sure it exists and undelete if needed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this gets called on create, the next bit about d.HasChange will actually return true and send a patch request. It's not a huge deal, but it's still an extra API call that we don't really need. If it's not hard, I think the Undelete should probably just get called straight from Create.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be confused - isn't that what we want? If this gets called on create, what we want is the 1. role.undelete 2. role.patch. If we just call undelete then we still have to call patch to essentially reset the previously deleted role to whatever value we are trying to create.

@paddycarver
Copy link
Contributor

The context of this one scares me, but on the assumption that we can update roles as if they were just now created (i.e., all user-specifiable fields can be updated), I can't see why not.

Projects, on the other hand (I'm not sure if those are intended, but as they have a similar soft-delete, I just want to be explicit about this) I'd argue against taking this approach with, because there are a lot of things about a project that would need to be cleaned up, and some of them can't be cleaned up, so we'd be saying the user has a fresh project when they, in fact, do not.

Anyways, just wanted to call that subtlety out. I'll take a pass at reviewing the code now :)

PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckGoogleOrganizationIamCustomRoleDestroy,
Steps: []resource.TestStep{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to sound really nitpicky, but could we verify that recreating it gets us the results we expect? I'd just hate for it to do the deletion regularly, only for us to find out its failing to set the other properties, or something.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

}
}

// If role is not deleted, make sure it exists and undelete if needed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment Dana pointed out about the unnecessary PATCH applies here, I think.

PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckGoogleProjectIamCustomRoleDestroy,
Steps: []resource.TestStep{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing here about verifying the resource has the expected values.

@morgante
Copy link

morgante commented Jun 25, 2018

Projects, on the other hand (I'm not sure if those are intended, but as they have a similar soft-delete, I just want to be explicit about this) I'd argue against taking this approach with, because there are a lot of things about a project that would need to be cleaned up, and some of them can't be cleaned up, so we'd be saying the user has a fresh project when they, in fact, do not.

I want to echo that this is potentially very dangerous. There's a lot of undefined behavior with project recreation and this could cause more bugs than it fixes IMO.

@emilymye emilymye removed the request for review from nat-henderson June 25, 2018 17:42
@emilymye
Copy link
Contributor Author

Looking at the IAM custom roles docs, it seems like there are two stages of deletion for custom roles:

Stage 1, 0-7 days after deletion: The role can be undeleted but otherwise cannot be used.
Stage 2, 7-37 days after deletion: The role cannot be undeleted but the role ID cannot be used to make a new role. I'm not sure whether calling roles.get() during this stage will return anything.

There are a couple of bugs with the current implementation.

Currently roles can be deleted through either setting role.deleted=true or terraform destroy. Problems with this:

  • If the user runs terraform destroy and terraform apply within 37 days without changing the custom role ID, this will error as shown in issue Terraform doesn't undelete Custom roles on apply #1668
  • If the user makes change in config deleted=true, the role is deleted in GCP. role.get() returns a value for at least 7 days, no changes can be made to this value other than role.undelete(). That means running terraform apply with any other changed attributes will fail because it attempts to patch a deleted role. Running terraform destroy will fail because it attempts to redelete a deleted object.

IMO deleted should be a computed value - I don't think deleted roles should be treated as existing in terraform state at any point. This is also a fairly large breaking change so we probably can't make this change right away.

What I think this PR should do is:

  • If Role in Stage 1: When user runs terraform apply, undelete and patch to have role/$ROLE_ID be the expected value from Terraform state. This is regardless of whether the terraform plan is running ResourceCreate (e.g. apply after destroy) or ResourceUpdate (if the state has or was refreshed and found role deleted=true).
  • If Role in Stage 2: If user runs terraform apply, return an error. We can't do anything about this, so the user pretty much has to abandon that role id. If user runs terraform destroy,

In either case, I'll need to add a check to ResourceDelete so terraform destroy just ignores roles if the role has 'deleted=true' or if role.get() returns nothing. I'm not sure what reading the role returns at during stage 2 - I'll need to find someone to ask in IAM or find a role that has been deleted for > 7 days but < 37 days, neither of which give timely answers.

tl;dr: @paddycarver @danawillow: I think the current solution should run undelete-patch for either create or update, and we should make deleted Computed. Also, I need to add a check for deletion.

@danawillow
Copy link
Contributor

@paddycarver @morgante why is project deletion relevant here? This PR is just about custom roles.

@morgante
Copy link

morgante commented Jun 25, 2018

@danawillow I parsed the title as "Allow recreation of recently deleted (projects) and (org custom roles)" but now realize it's "Allow recreation of recently deleted (project and org) custom roles" so retract my comments. 😄

@paddycarver
Copy link
Contributor

Parsed the title similarly to @morgante, and am also wary of setting precedent. :/

I'm still parsing and processing @emilymye's awesome comment, to try and wrap my brain about this, then I'll take another review pass.

@emilymye
Copy link
Contributor Author

@paddycarver @danawillow I made some new changes that I think (think??) will not cause breakage and actually handle all errors. I added a deprecation message for deleted (as advised by Dana) and tried to make the Create/Update logic easier to follow, but pls re-review.

Also, I don't know if I have access to the team city still but can someone run the org tests for me? I need to set that up -__-

project test run:
TF_ACC=1 go test ./google -v --run="TestAccProjectIamCustomRole" -timeout 120m
=== RUN TestAccProjectIamCustomRole_import
=== PAUSE TestAccProjectIamCustomRole_import
=== RUN TestAccProjectIamCustomRole_basic
=== PAUSE TestAccProjectIamCustomRole_basic
=== RUN TestAccProjectIamCustomRole_undelete
=== PAUSE TestAccProjectIamCustomRole_undelete
=== RUN TestAccProjectIamCustomRole_createAfterDestroy
=== PAUSE TestAccProjectIamCustomRole_createAfterDestroy
=== CONT TestAccProjectIamCustomRole_import
=== CONT TestAccProjectIamCustomRole_undelete
=== CONT TestAccProjectIamCustomRole_createAfterDestroy
=== CONT TestAccProjectIamCustomRole_basic
--- PASS: TestAccProjectIamCustomRole_import (2.24s)
--- PASS: TestAccProjectIamCustomRole_basic (3.54s)
--- PASS: TestAccProjectIamCustomRole_undelete (3.84s)
--- PASS: TestAccProjectIamCustomRole_createAfterDestroy (4.14s)
PASS
ok github.com/terraform-providers/terraform-provider-google/google 4.313s

@paddycarver
Copy link
Contributor

I'll take a look and run the tests tonight, hopefully. In the meantime, I also made sure you have access to the CI server. Feel free to drop an email to paddy@hashicorp if you're having trouble, and I can give you more info.

// 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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to check that the error was actually a 404?

Copy link
Contributor

@paddycarver paddycarver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests pass, and I'm mostly really happy with this. Awesome work, @emilymye! The only thing I'd ask is just, as @danawillow pointed out, that we check the error is actually a 404 and not some other error. Otherwise, I think it's good to merge.

@emilymye
Copy link
Contributor Author

WHOOPS I forgot about this PR

Updates made, also added a warning to docs so custom roles might be less confusing in general. This is a real pickle

$ make testacc TEST=./google TESTARGS='--run="TestAccProjectIamCustomRole"'
==> Checking that code complies with gofmt requirements...
TF_ACC=1 TF_SCHEMA_PANIC_ON_ERROR=1 go test ./google -v --run="TestAccProjectIamCustomRole" -timeout 120m
=== RUN TestAccProjectIamCustomRole_import
=== PAUSE TestAccProjectIamCustomRole_import
=== RUN TestAccProjectIamCustomRole_basic
=== PAUSE TestAccProjectIamCustomRole_basic
=== RUN TestAccProjectIamCustomRole_undelete
=== PAUSE TestAccProjectIamCustomRole_undelete
=== RUN TestAccProjectIamCustomRole_createAfterDestroy
=== PAUSE TestAccProjectIamCustomRole_createAfterDestroy
=== CONT TestAccProjectIamCustomRole_import
=== CONT TestAccProjectIamCustomRole_createAfterDestroy
=== CONT TestAccProjectIamCustomRole_undelete
=== CONT TestAccProjectIamCustomRole_basic
--- PASS: TestAccProjectIamCustomRole_import (2.78s)
--- PASS: TestAccProjectIamCustomRole_basic (3.79s)
--- PASS: TestAccProjectIamCustomRole_createAfterDestroy (4.19s)
--- PASS: TestAccProjectIamCustomRole_undelete (4.49s)
PASS
ok github.com/terraform-providers/terraform-provider-google/google 4.672s

@ghost ghost added the size/l label Sep 10, 2018
@emilymye emilymye merged commit b1338b4 into hashicorp:master Sep 10, 2018
chrisst pushed a commit to chrisst/terraform-provider-google that referenced this pull request Nov 9, 2018
…shicorp#1681)

* undelete-update recently soft-deleted custom roles

* remove my TODO statements

* check values on soft-delete-recreate for custom role tests

* final fixes to make sure delete works; return read() when updating to 'create'

* check for non-404 errors for custom role get

* add warnings to custom roles docs
@ghost
Copy link

ghost commented Nov 16, 2018

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks!

@ghost ghost locked and limited conversation to collaborators Nov 16, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants