-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Add support for master authorized networks in google_container_cluster
#626
Add support for master authorized networks in google_container_cluster
#626
Conversation
b09279c
to
f299bbf
Compare
google/resource_container_cluster.go
Outdated
Schema: map[string]*schema.Schema{ | ||
"enabled": { | ||
Type: schema.TypeBool, | ||
Required: true, |
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 wasn't entirely sure what made sense here for Optional
/ Computed
/ Required
/ Default
. In the end, Required: true
made the most sense to me, but only marginally so. I'll test upstream for implicit requirements/defaults tomorrow.
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'd actually recommend not having an enabled
field at all, and instead just relying on the presence of any master_authorized_networks_config
s to determine what that value should be, similar to how we do autoscaling. The reason for this is that when enabled
is false, GCP won't return anything for cidrBlocks
:
"masterAuthorizedNetworksConfig": {},
This means that a config like this:
master_authorized_networks_config {
enabled = false
cidr_blocks = ["172.16.0.0/12", "10.0.0.0/8"]
}
is equivalent to:
master_authorized_networks_config {
enabled = false
}
Because we want to set the state based on what's actually true in GCP, the state will always resemble the second config above, and thus planning immediately after applying with the first config will show a diff.
"But wait!" you might ask, "I added a test for the enabled=false
case and it passed!" Ah yes, and this tripped me up for a while too. I'll explain in a comment below.
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.
Totally, I almost did that, but wasn't sure and opted for mimicking the API. I'll follow that pattern elsewhere.
17745c1
to
49c51bc
Compare
the two failures below happen on master as well. I'm guessing this is a known issue?
|
google/resource_container_cluster.go
Outdated
Optional: true, | ||
Computed: true, | ||
ForceNew: true, | ||
ValidateFunc: validation.CIDRNetwork(11, 19), |
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.
Where did the numbers 11 and 19 come from? (I want to make sure we don't break any existing configs with this change)
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.
Good call – I was extrapolating API-level constraints based on my experience with the console/UI, which requires a mask in that range, but now that I'm hitting the API directly, you're right -- it doesn't seem to be a thing! RFC1918 is a strict requirement here, though, and I added logic specifically to validate this attribute against those ranges, then lost it on rebase. I'll add it back + remove this constraint.
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.
Done.
google/resource_container_cluster.go
Outdated
Optional: true, | ||
Computed: true, | ||
MaxItems: 10, | ||
Elem: &schema.Schema{ |
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.
Do you think anyone would want to set the displayName field inside of cidr block?
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.
For sure, I'll add that now.
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.
Done.
google/resource_container_cluster.go
Outdated
Schema: map[string]*schema.Schema{ | ||
"enabled": { | ||
Type: schema.TypeBool, | ||
Required: true, |
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'd actually recommend not having an enabled
field at all, and instead just relying on the presence of any master_authorized_networks_config
s to determine what that value should be, similar to how we do autoscaling. The reason for this is that when enabled
is false, GCP won't return anything for cidrBlocks
:
"masterAuthorizedNetworksConfig": {},
This means that a config like this:
master_authorized_networks_config {
enabled = false
cidr_blocks = ["172.16.0.0/12", "10.0.0.0/8"]
}
is equivalent to:
master_authorized_networks_config {
enabled = false
}
Because we want to set the state based on what's actually true in GCP, the state will always resemble the second config above, and thus planning immediately after applying with the first config will show a diff.
"But wait!" you might ask, "I added a test for the enabled=false
case and it passed!" Ah yes, and this tripped me up for a while too. I'll explain in a comment below.
google/resource_container_cluster.go
Outdated
result := []map[string]interface{}{ | ||
map[string]interface{}{ | ||
"enabled": c.Enabled, | ||
"cidr_blocks": cidrBlocks, |
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.
Turns out, if flattenMasterAuthorizedNetworksConfig
returns something that looks like this:
result: [map[enabled:false cidr_blocks:[]]]
d.Set
will actually return an error: Invalid address to set: []string{"master_authorized_networks_config", "0", "cidr_blocks"}
This is fairly cryptic, but it basically just means that you can't set an empty slice in config, you have to just set no slice at all.
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.
Hrmmmmm, alright. I'll add that as a test case, too.
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.
Done.
google/resource_container_cluster.go
Outdated
@@ -514,6 +536,30 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er | |||
|
|||
d.Partial(true) | |||
|
|||
if d.HasChange("master_authorized_networks_config") { | |||
if c, ok := d.GetOk("master_authorized_networks_config"); ok { |
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.
This means that if a user removes the master_authorized_networks_config
block from their config, nothing actually changes. Is that intentional? I'd assume it would remove the configuration.
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.
That was definitely not intentional, and is now fixed.
af411e0
to
b362224
Compare
@danawillow I worked through your comments, and left this second round of changes is in a separate commit for now. I can squash/rebase once everything's ready to merge. Do you think it makes sense to collapse the schema a bit, as below? I've basically translated the upstream structure, and the result feels a bit verbose to me. I know how painful backwards compatibility issues can be, though. I'll defer to you. resource "google_container_cluster" "foo" {
master_authorized_network {
cidr_block = "1.2.3.4/32"
}
master_authorized_network {
cidr_block = "5.6.7.8/32"
}
} Test output:
|
@@ -31,3 +39,25 @@ func validateRegexp(re string) schema.SchemaValidateFunc { | |||
return | |||
} | |||
} | |||
|
|||
func validateRFC1918Network(min, max int) schema.SchemaValidateFunc { |
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.
This validation has enough logic in it that I wouldn't mind seeing a unit test.
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.
Done.
|
||
master_authorized_networks_config { | ||
%s | ||
} |
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.
nit: indentation
Config: testAccContainerCluster_withMasterAuthorizedNetworksConfig(clusterName, []string{"8.8.8.8/32"}), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckContainerCluster("google_container_cluster.with_master_authorized_networks"), | ||
resource.TestCheckNoResourceAttr("google_container_cluster.with_master_authorized_networks", |
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 think you want to check that the block is there though, right?
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.
Right. Fixed.
google/resource_container_cluster.go
Outdated
"display_name": v.DisplayName, | ||
}) | ||
} | ||
// now does this adhere to the schema? |
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'm not quite sure what this comment is for
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.
Oh, that definitely wasn't supposed to make it in. 😺
I'm fine with the schema as-is. Also feel free to just always do separate commits- I default to "squash and merge" for the final merge :) |
- remove `google_container_cluster.master_authorized_networks_config.enabled` - add `display_name` and restructure schema as follows: master_authorized_networks_config { cidr_blocks { cidr_block = "0.0.0.0/0" display_name = "foo" } } - amend tests
b362224
to
edd19a7
Compare
Thanks @davidquarles! Looks good! |
…er` (hashicorp#626) * Add support for master authorized networks in `google_container_cluster` * [review] remove enabled flag / restructure schema - remove `google_container_cluster.master_authorized_networks_config.enabled` - add `display_name` and restructure schema as follows: master_authorized_networks_config { cidr_blocks { cidr_block = "0.0.0.0/0" display_name = "foo" } } - amend tests * [review] add test for validateRFC1918Network, fix acc test
Signed-off-by: Modular Magician <[email protected]>
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! |
Fixes #619.
google_container_cluster