-
Notifications
You must be signed in to change notification settings - Fork 630
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
fix(APITokens): change permission_groups type from list to set of strings #1089
Conversation
d79fcea
to
f2f9399
Compare
…rder - should fail
f2f9399
to
e355a82
Compare
183f60c
to
cb2c654
Compare
cb2c654
to
a2e7fb0
Compare
a2e7fb0
to
4d84648
Compare
@@ -22,9 +22,10 @@ func resourceCloudflareApiToken() *schema.Resource { | |||
Elem: &schema.Schema{Type: schema.TypeString}, | |||
}, | |||
"permission_groups": { | |||
Type: schema.TypeList, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as we are going from a list => set, we will need to
- bump the schema version
- provide a state migration (see https://www.terraform.io/docs/extend/resources/state-migration.html) as we will be changing the internal representation of the data
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really necessary?
I tested this:
- create resource with current provider version
- upgrade to fixed provider
- run
terraform apply
No changes detected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because state representation of a list or a set is the same - json array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TypeList
and TypeSet
definitely aren't the same state representation as sets are stored indexed by a hash calculated based on the attributes in the set whereas list items are stored as a zero indexed items. I'm unsure why you're not seeing a difference here but we may need to dig into why as I've definitely been bit by this in the past.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for late response. But I said that because I checked the state before and after the fix. Even at links you posted are examples, both of them with slices. I think terraform is doing hash keys on the fly and not storing them in the state file.
Just do the test please.
For the given resource
resource "cloudflare_api_token" "test" {
name = "test"
policy {
effect = "allow"
permission_groups = [
"3030687196b94b638145a3953da2b699",
"da6d2d6f2ec8442eaadda60d13f42bca",
"e6d2666161e84845a636613608cee8d5",
"ed07f6c337da4195b4e72a1fb2c6bcae",
"1af1fa2adc104452b74a9a3364202f20",
"4755a26eedb94da69e1066d98aa820be",
]
resources = { "com.cloudflare.api.account.*" = "*" }
}
}
Current provider state
{
"version": 4,
"terraform_version": "0.13.7",
"serial": 1,
"lineage": "f3059c1d-de72-cc99-752d-da6446426758",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "cloudflare_api_token",
"name": "test",
"provider": "provider[\"registry.terraform.io/terraform-providers/cloudflare\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"condition": [],
"id": "e8712ce735c7353116fe7586dcf5bacb",
"issued_on": "2021-07-19T12:26:40Z",
"modified_on": "2021-07-19T14:26:42.035223871+02:00",
"name": "uros-test",
"policy": [
{
"effect": "allow",
"permission_groups": [
"3030687196b94b638145a3953da2b699",
"da6d2d6f2ec8442eaadda60d13f42bca",
"e6d2666161e84845a636613608cee8d5",
"ed07f6c337da4195b4e72a1fb2c6bcae",
"1af1fa2adc104452b74a9a3364202f20",
"4755a26eedb94da69e1066d98aa820be"
],
"resources": {
"com.cloudflare.api.account.*": "*"
}
}
],
"status": "active",
"value": "REDACTED"
},
"private": "bnVsbA=="
}
]
}
]
}
Fixed provider state
{
"version": 4,
"terraform_version": "0.13.7",
"serial": 1,
"lineage": "fb23297b-3d7b-2ce0-21fc-f1e9a7a75219",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "cloudflare_api_token",
"name": "test",
"provider": "provider[\"registry.terraform.io/terraform-providers/cloudflare\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"condition": [],
"id": "8a712ce0983ed8b47adc2710e0094ef6",
"issued_on": "2021-07-19T12:28:08Z",
"modified_on": "2021-07-19T14:28:10.23180693+02:00",
"name": "uros-test",
"policy": [
{
"effect": "allow",
"permission_groups": [
"1af1fa2adc104452b74a9a3364202f20",
"3030687196b94b638145a3953da2b699",
"4755a26eedb94da69e1066d98aa820be",
"da6d2d6f2ec8442eaadda60d13f42bca",
"e6d2666161e84845a636613608cee8d5",
"ed07f6c337da4195b4e72a1fb2c6bcae"
],
"resources": {
"com.cloudflare.api.account.*": "*"
}
}
],
"status": "active",
"value": "REDACTED"
},
"private": "bnVsbA=="
}
]
}
]
}
You can see that state representation of both is json array. And as said already said, I tested creating resource and then upgrading provider. It works like a charm.
I will do it proper way if you convince me that current approach is not working, but sorry, I will no do something that is unnecessary IMO.
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as we're now needing a schema migration we'll need to extend this a little.
the first is that we'll need to test the data migration from a list => set. https://www.terraform.io/docs/extend/resources/state-migration.html covers some examples of asserting that.
the second is that we'll want to update this test to be 2 steps. the first will create the resource with the permissions and the second will be the same permissions but in a different order and we'll want to assert there is no difference which will ensure we're ignoring the ordering.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a test which fails (1st commit) and then a fix for that (2nd commit).
But yeah, I get your point. I can add another step with different order, but don't know how to assert there is no difference. Is there some example of something similar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great start! see comments inline for this changes needed for this one.
Required: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
Set: schema.HashString, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i don't think we need this as it's the default
bump. |
Hey @UrosSimovic this is an issue it is currently affecting my team and I see not much activity since quite a few months. Do you want to continue with this MR or should I take over? |
As said, MR was prepared, but not accepted for unproven reason. I don't want doing unnecessary things. Feel free to take it from here, @tete17. |
Hey @jacobbednarz I opened another MR with the commits of @UrosSimovic with some of my own addressing your comments. #1425 I am still a bit confused with this whole migration thing given we seem to have been through a very similar scenario like this one and no migration was performed 7704f43 . This is the first time I deal with the go sdk so I hope you excuse me if it is 100% unrelated. |
moving to #1425 |
Problem
A diff can be detected when creating API Tokens with multiple permission_groups in a single policy.
Why?
CloudFlare API can return permission_groups in a different order then the posted/updated one.
Solution
Make permission_groups set of strings where order doesn't matter.