Skip to content

Commit a63b620

Browse files
committed
container: Add node_kublet_config support for autopilot clusters
Add support for `node_kubelet_config in `node_pool_auto_config`. See: hashicorp/terraform-provider-google#15208 (comment) Per: https://pkg.go.dev/google.golang.org/api/container/v1#NodePoolAutoConfig Currently only `insecure_kubelet_readonly_port_enabled` can be set here. Fixes hashicorp/terraform-provider-google#19236 Fixes hashicorp/terraform-provider-google#19153
1 parent b7538e9 commit a63b620

File tree

4 files changed

+146
-33
lines changed

4 files changed

+146
-33
lines changed

mmv1/third_party/terraform/services/container/node_config.go.erb

+36-33
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,41 @@ func schemaGcfsConfig(forceNew bool) *schema.Schema {
120120
}
121121
}
122122

123+
func schemaKubeletConfig() *schema.Schema {
124+
return &schema.Schema{
125+
Type: schema.TypeList,
126+
Optional: true,
127+
MaxItems: 1,
128+
Description: `Node kubelet configs.`,
129+
Elem: &schema.Resource{
130+
Schema: map[string]*schema.Schema{
131+
"cpu_manager_policy": {
132+
Type: schema.TypeString,
133+
Required: true,
134+
ValidateFunc: validation.StringInSlice([]string{"static", "none", ""}, false),
135+
Description: `Control the CPU management policy on the node.`,
136+
},
137+
"cpu_cfs_quota": {
138+
Type: schema.TypeBool,
139+
Optional: true,
140+
Description: `Enable CPU CFS quota enforcement for containers that specify CPU limits.`,
141+
},
142+
"cpu_cfs_quota_period": {
143+
Type: schema.TypeString,
144+
Optional: true,
145+
Description: `Set the CPU CFS quota period value 'cpu.cfs_period_us'.`,
146+
},
147+
"insecure_kubelet_readonly_port_enabled": schemaInsecureKubeletReadonlyPortEnabled(),
148+
"pod_pids_limit": {
149+
Type: schema.TypeInt,
150+
Optional: true,
151+
Description: `Controls the maximum number of processes allowed to run in a pod.`,
152+
},
153+
},
154+
},
155+
}
156+
}
157+
123158
func schemaNodeConfig() *schema.Schema {
124159
return &schema.Schema{
125160
Type: schema.TypeList,
@@ -586,39 +621,7 @@ func schemaNodeConfig() *schema.Schema {
586621
},
587622
// Note that AtLeastOneOf can't be set because this schema is reused by
588623
// two different resources.
589-
"kubelet_config": {
590-
Type: schema.TypeList,
591-
Optional: true,
592-
MaxItems: 1,
593-
Description: `Node kubelet configs.`,
594-
Elem: &schema.Resource{
595-
Schema: map[string]*schema.Schema{
596-
"cpu_manager_policy": {
597-
Type: schema.TypeString,
598-
Required: true,
599-
ValidateFunc: validation.StringInSlice([]string{"static", "none", ""}, false),
600-
Description: `Control the CPU management policy on the node.`,
601-
},
602-
"cpu_cfs_quota": {
603-
Type: schema.TypeBool,
604-
Optional: true,
605-
Description: `Enable CPU CFS quota enforcement for containers that specify CPU limits.`,
606-
},
607-
"cpu_cfs_quota_period": {
608-
Type: schema.TypeString,
609-
Optional: true,
610-
Description: `Set the CPU CFS quota period value 'cpu.cfs_period_us'.`,
611-
},
612-
"insecure_kubelet_readonly_port_enabled": schemaInsecureKubeletReadonlyPortEnabled(),
613-
"pod_pids_limit": {
614-
Type: schema.TypeInt,
615-
Optional: true,
616-
Description: `Controls the maximum number of processes allowed to run in a pod.`,
617-
},
618-
},
619-
},
620-
},
621-
624+
"kubelet_config": schemaKubeletConfig(),
622625
"linux_node_config": {
623626
Type: schema.TypeList,
624627
Optional: true,

mmv1/third_party/terraform/services/container/resource_container_cluster.go.erb

+26
Original file line numberDiff line numberDiff line change
@@ -1505,6 +1505,7 @@ func ResourceContainerCluster() *schema.Resource {
15051505
Description: `Node pool configs that apply to all auto-provisioned node pools in autopilot clusters and node auto-provisioning enabled clusters.`,
15061506
Elem: &schema.Resource{
15071507
Schema: map[string]*schema.Schema{
1508+
"node_kubelet_config": schemaKubeletConfig(),
15081509
"network_tags": {
15091510
Type: schema.TypeList,
15101511
Optional: true,
@@ -4403,6 +4404,24 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
44034404
}
44044405
}
44054406

4407+
if d.HasChange("node_pool_auto_config.0.node_kubelet_config") {
4408+
req := &container.UpdateClusterRequest{
4409+
Update: &container.ClusterUpdate{
4410+
DesiredNodePoolAutoConfigKubeletConfig: expandKubeletConfig(
4411+
d.Get("node_pool_auto_config.0.node_kubelet_config"),
4412+
),
4413+
},
4414+
}
4415+
4416+
updateF := updateFunc(req, "updating GKE cluster node pool auto config node_kubelet_config parameters")
4417+
// Call update serially.
4418+
if err := transport_tpg.LockedCall(lockKey, updateF); err != nil {
4419+
return err
4420+
}
4421+
4422+
log.Printf("[INFO] GKE cluster %s node pool auto config node_kubelet_config parameters have been updated", d.Id())
4423+
}
4424+
44064425
if d.HasChange("node_pool_auto_config.0.network_tags.0.tags") {
44074426
tags := d.Get("node_pool_auto_config.0.network_tags.0.tags").([]interface{})
44084427

@@ -5737,6 +5756,10 @@ func expandNodePoolAutoConfig(configured interface{}) *container.NodePoolAutoCon
57375756
npac := &container.NodePoolAutoConfig{}
57385757
config := l[0].(map[string]interface{})
57395758

5759+
if v, ok := config["node_kubelet_config"]; ok {
5760+
npac.NodeKubeletConfig = expandKubeletConfig(v)
5761+
}
5762+
57405763
if v, ok := config["network_tags"]; ok && len(v.([]interface{})) > 0 {
57415764
npac.NetworkTags = expandNodePoolAutoConfigNetworkTags(v)
57425765
}
@@ -6575,6 +6598,9 @@ func flattenNodePoolAutoConfig(c *container.NodePoolAutoConfig) []map[string]int
65756598
}
65766599

65776600
result := make(map[string]interface{})
6601+
if c.NodeKubeletConfig != nil {
6602+
result["node_kubelet_config"] = flattenKubeletConfig(c.NodeKubeletConfig)
6603+
}
65786604
if c.NetworkTags != nil {
65796605
result["network_tags"] = flattenNodePoolAutoConfigNetworkTags(c.NetworkTags)
65806606
}

mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.erb

+81
Original file line numberDiff line numberDiff line change
@@ -3248,6 +3248,52 @@ func TestAccContainerCluster_withAutopilotNetworkTags(t *testing.T) {
32483248
})
32493249
}
32503250

3251+
func TestAccContainerCluster_withAutopilotKubeletConfig(t *testing.T) {
3252+
t.Parallel()
3253+
3254+
randomSuffix := acctest.RandString(t, 10)
3255+
clusterName := fmt.Sprintf("tf-test-cluster-%s", randomSuffix)
3256+
3257+
acctest.VcrTest(t, resource.TestCase{
3258+
PreCheck: func() { acctest.AccTestPreCheck(t) },
3259+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
3260+
ExternalProviders: map[string]resource.ExternalProvider{
3261+
"time": {},
3262+
},
3263+
CheckDestroy: testAccCheckContainerClusterDestroyProducer(t),
3264+
Steps: []resource.TestStep{
3265+
{
3266+
Config: testAccContainerCluster_withAutopilotKubeletConfigBaseline(clusterName),
3267+
},
3268+
{
3269+
ResourceName: "google_container_cluster.with_autopilot_kubelet_config",
3270+
ImportState: true,
3271+
ImportStateVerify: true,
3272+
ImportStateVerifyIgnore: []string{"min_master_version", "deletion_protection"},
3273+
},
3274+
{
3275+
Config: testAccContainerCluster_withAutopilotKubeletConfigUpdates(clusterName, "FALSE"),
3276+
},
3277+
{
3278+
ResourceName: "google_container_cluster.with_autopilot",
3279+
ImportState: true,
3280+
ImportStateVerify: true,
3281+
ImportStateVerifyIgnore: []string{"min_master_version", "deletion_protection"},
3282+
},
3283+
{
3284+
Config: testAccContainerCluster_withAutopilotKubeletConfigUpdates(clusterName, "TRUE"),
3285+
},
3286+
{
3287+
ResourceName: "google_container_cluster.with_autopilot",
3288+
ImportState: true,
3289+
ImportStateVerify: true,
3290+
ImportStateVerifyIgnore: []string{"min_master_version", "deletion_protection"},
3291+
},
3292+
},
3293+
})
3294+
}
3295+
3296+
32513297
func TestAccContainerCluster_withAutopilotResourceManagerTags(t *testing.T) {
32523298
t.Parallel()
32533299

@@ -10517,6 +10563,41 @@ func testAccContainerCluster_withWorkloadALTSConfigAutopilot(projectID, name str
1051710563

1051810564
<% end -%>
1051910565

10566+
func testAccContainerCluster_withAutopilotKubeletConfigBaseline(name string) string {
10567+
return fmt.Sprintf(`
10568+
resource "google_container_cluster" "with_autopilot_kubelet_config" {
10569+
name = "%s"
10570+
location = "us-central1"
10571+
initial_node_count = 1
10572+
enable_autopilot = true
10573+
deletion_protection = false
10574+
}
10575+
`, name)
10576+
}
10577+
10578+
func testAccContainerCluster_withAutopilotKubeletConfigUpdates(name, insecureKubeletReadonlyPortEnabled string) string {
10579+
return fmt.Sprintf(`
10580+
resource "google_container_cluster" "with_autopilot_kubelet_config" {
10581+
name = "%s"
10582+
location = "us-central1"
10583+
initial_node_count = 1
10584+
10585+
node_pool_auto_config {
10586+
node_kubelet_config {
10587+
# Needed to work around being required but not actually needed
10588+
cpu_manager_policy = ""
10589+
10590+
# Currently the only supported parameter here
10591+
insecure_kubelet_readonly_port_enabled = "%s"
10592+
}
10593+
}
10594+
10595+
enable_autopilot = true
10596+
deletion_protection = false
10597+
}
10598+
`, name, insecureKubeletReadonlyPortEnabled)
10599+
}
10600+
1052010601
func testAccContainerCluster_resourceManagerTags(projectID, clusterName, networkName, subnetworkName, randomSuffix string) string {
1052110602
return fmt.Sprintf(`
1052210603
data "google_project" "project" {

mmv1/third_party/terraform/website/docs/r/container_cluster.html.markdown

+3
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,9 @@ workload_identity_config {
10841084

10851085
<a name="nested_node_pool_auto_config"></a>The `node_pool_auto_config` block supports:
10861086

1087+
* `node_kubelet_config` - (Optional) Kubelet configuration. Currently, only `insecure_kubelet_readonly_port_enabled` is supported here.
1088+
Structure is [documented below](#nested_kubelet_config).
1089+
10871090
* `resource_manager_tags` - (Optional) A map of resource manager tag keys and values to be attached to the nodes for managing Compute Engine firewalls using Network Firewall Policies. Tags must be according to specifications found [here](https://cloud.google.com/vpc/docs/tags-firewalls-overview#specifications). A maximum of 5 tag key-value pairs can be specified. Existing tags will be replaced with new values. Tags must be in one of the following formats ([KEY]=[VALUE]) 1. `tagKeys/{tag_key_id}=tagValues/{tag_value_id}` 2. `{org_id}/{tag_key_name}={tag_value_name}` 3. `{project_id}/{tag_key_name}={tag_value_name}`.
10881091

10891092
* `network_tags` (Optional) - The network tag config for the cluster's automatically provisioned node pools.

0 commit comments

Comments
 (0)