Skip to content

Commit 01db497

Browse files
Add support for WindowsNodeConfig to GKE NodePool (#13197) (#21876)
[upstream:37b8896aead72d9c755241ea370d49fd550d2a23] Signed-off-by: Modular Magician <[email protected]>
1 parent a880124 commit 01db497

File tree

4 files changed

+165
-0
lines changed

4 files changed

+165
-0
lines changed

.changelog/13197.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
container: added `node_config.windows_node_config` field to `google_container_node_pool` resource.
3+
```

google/services/container/node_config.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,25 @@ func schemaNodeConfig() *schema.Schema {
662662
},
663663
},
664664
},
665+
"windows_node_config": {
666+
Type: schema.TypeList,
667+
Optional: true,
668+
Computed: true,
669+
MaxItems: 1,
670+
Description: `Parameters that can be configured on Windows nodes.`,
671+
Elem: &schema.Resource{
672+
Schema: map[string]*schema.Schema{
673+
"osversion": {
674+
Type: schema.TypeString,
675+
Optional: true,
676+
ForceNew: true,
677+
Default: "OS_VERSION_UNSPECIFIED",
678+
Description: `The OS Version of the windows nodepool.Values are OS_VERSION_UNSPECIFIED,OS_VERSION_LTSC2019 and OS_VERSION_LTSC2022`,
679+
ValidateFunc: validation.StringInSlice([]string{"OS_VERSION_UNSPECIFIED", "OS_VERSION_LTSC2019", "OS_VERSION_LTSC2022"}, false),
680+
},
681+
},
682+
},
683+
},
665684
"node_group": {
666685
Type: schema.TypeString,
667686
Optional: true,
@@ -1150,6 +1169,10 @@ func expandNodeConfig(v interface{}) *container.NodeConfig {
11501169
nc.LinuxNodeConfig = expandLinuxNodeConfig(v)
11511170
}
11521171

1172+
if v, ok := nodeConfig["windows_node_config"]; ok {
1173+
nc.WindowsNodeConfig = expandWindowsNodeConfig(v)
1174+
}
1175+
11531176
if v, ok := nodeConfig["node_group"]; ok {
11541177
nc.NodeGroup = v.(string)
11551178
}
@@ -1313,6 +1336,24 @@ func expandLinuxNodeConfig(v interface{}) *container.LinuxNodeConfig {
13131336
return linuxNodeConfig
13141337
}
13151338

1339+
func expandWindowsNodeConfig(v interface{}) *container.WindowsNodeConfig {
1340+
if v == nil {
1341+
return nil
1342+
}
1343+
ls := v.([]interface{})
1344+
if len(ls) == 0 {
1345+
return nil
1346+
}
1347+
cfg := ls[0].(map[string]interface{})
1348+
osversionRaw, ok := cfg["osversion"]
1349+
if !ok {
1350+
return nil
1351+
}
1352+
return &container.WindowsNodeConfig{
1353+
OsVersion: osversionRaw.(string),
1354+
}
1355+
}
1356+
13161357
func expandSysctls(cfg map[string]interface{}) map[string]string {
13171358
sysCfgRaw, ok := cfg["sysctls"]
13181359
if !ok {
@@ -1555,6 +1596,7 @@ func flattenNodeConfig(c *container.NodeConfig, v interface{}) []map[string]inte
15551596
"boot_disk_kms_key": c.BootDiskKmsKey,
15561597
"kubelet_config": flattenKubeletConfig(c.KubeletConfig),
15571598
"linux_node_config": flattenLinuxNodeConfig(c.LinuxNodeConfig),
1599+
"windows_node_config": flattenWindowsNodeConfig(c.WindowsNodeConfig),
15581600
"node_group": c.NodeGroup,
15591601
"advanced_machine_features": flattenAdvancedMachineFeaturesConfig(c.AdvancedMachineFeatures),
15601602
"max_run_duration": c.MaxRunDuration,
@@ -1823,6 +1865,16 @@ func flattenLinuxNodeConfig(c *container.LinuxNodeConfig) []map[string]interface
18231865
return result
18241866
}
18251867

1868+
func flattenWindowsNodeConfig(c *container.WindowsNodeConfig) []map[string]interface{} {
1869+
result := []map[string]interface{}{}
1870+
if c != nil {
1871+
result = append(result, map[string]interface{}{
1872+
"osversion": c.OsVersion,
1873+
})
1874+
}
1875+
return result
1876+
}
1877+
18261878
func flattenHugepagesConfig(c *container.HugepagesConfig) []map[string]interface{} {
18271879
result := []map[string]interface{}{}
18281880
if c != nil {
@@ -2466,6 +2518,40 @@ func nodePoolNodeConfigUpdate(d *schema.ResourceData, config *transport_tpg.Conf
24662518

24672519
log.Printf("[INFO] Updated linux_node_config for node pool %s", name)
24682520
}
2521+
if d.HasChange(prefix + "node_config.0.windows_node_config") {
2522+
req := &container.UpdateNodePoolRequest{
2523+
NodePoolId: name,
2524+
WindowsNodeConfig: expandWindowsNodeConfig(
2525+
d.Get(prefix + "node_config.0.windows_node_config")),
2526+
}
2527+
if req.WindowsNodeConfig == nil {
2528+
req.WindowsNodeConfig = &container.WindowsNodeConfig{}
2529+
req.ForceSendFields = []string{"WindowsNodeConfig"}
2530+
}
2531+
updateF := func() error {
2532+
clusterNodePoolsUpdateCall := config.NewContainerClient(userAgent).Projects.Locations.Clusters.NodePools.Update(nodePoolInfo.fullyQualifiedName(name), req)
2533+
if config.UserProjectOverride {
2534+
clusterNodePoolsUpdateCall.Header().Add("X-Goog-User-Project", nodePoolInfo.project)
2535+
}
2536+
op, err := clusterNodePoolsUpdateCall.Do()
2537+
if err != nil {
2538+
return err
2539+
}
2540+
2541+
// Wait until it's updated
2542+
return ContainerOperationWait(config, op,
2543+
nodePoolInfo.project,
2544+
nodePoolInfo.location,
2545+
"updating GKE node pool windows_node_config", userAgent,
2546+
timeout)
2547+
}
2548+
2549+
if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil {
2550+
return err
2551+
}
2552+
2553+
log.Printf("[INFO] Updated windows_node_config for node pool %s", name)
2554+
}
24692555
if d.HasChange(prefix + "node_config.0.fast_socket") {
24702556
req := &container.UpdateNodePoolRequest{
24712557
NodePoolId: name,

google/services/container/resource_container_node_pool_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,38 @@ func TestAccContainerNodePool_withLinuxNodeConfig(t *testing.T) {
623623
})
624624
}
625625

626+
func TestAccContainerNodePool_withWindowsNodeConfig(t *testing.T) {
627+
t.Parallel()
628+
629+
cluster := fmt.Sprintf("tf-test-cluster-%s", acctest.RandString(t, 10))
630+
np := fmt.Sprintf("tf-test-np-%s", acctest.RandString(t, 10))
631+
632+
acctest.VcrTest(t, resource.TestCase{
633+
PreCheck: func() { acctest.AccTestPreCheck(t) },
634+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
635+
CheckDestroy: testAccCheckContainerClusterDestroyProducer(t),
636+
Steps: []resource.TestStep{
637+
{
638+
Config: testAccContainerNodePool_withWindowsNodeConfig(cluster, np, "OS_VERSION_LTSC2019"),
639+
},
640+
{
641+
ResourceName: "google_container_node_pool.with_windows_node_config",
642+
ImportState: true,
643+
ImportStateVerify: true,
644+
},
645+
// Perform an update.
646+
{
647+
Config: testAccContainerNodePool_withWindowsNodeConfig(cluster, np, "OS_VERSION_LTSC2022"),
648+
},
649+
{
650+
ResourceName: "google_container_node_pool.with_windows_node_config",
651+
ImportState: true,
652+
ImportStateVerify: true,
653+
},
654+
},
655+
})
656+
}
657+
626658
func TestAccContainerNodePool_withCgroupMode(t *testing.T) {
627659
t.Parallel()
628660

@@ -3124,6 +3156,41 @@ resource "google_container_node_pool" "with_linux_node_config" {
31243156
`, cluster, networkName, subnetworkName, np, linuxNodeConfig)
31253157
}
31263158

3159+
func testAccContainerNodePool_withWindowsNodeConfig(cluster, np string, osversion string) string {
3160+
return fmt.Sprintf(`
3161+
data "google_container_engine_versions" "central1a" {
3162+
location = "us-central1-a"
3163+
}
3164+
3165+
resource "google_container_cluster" "cluster" {
3166+
name = "%s"
3167+
location = "us-central1-a"
3168+
initial_node_count = 1
3169+
min_master_version = data.google_container_engine_versions.central1a.latest_master_version
3170+
deletion_protection = false
3171+
networking_mode = "VPC_NATIVE"
3172+
ip_allocation_policy {}
3173+
}
3174+
3175+
resource "google_container_node_pool" "with_windows_node_config" {
3176+
name = "%s"
3177+
location = "us-central1-a"
3178+
cluster = google_container_cluster.cluster.name
3179+
initial_node_count = 1
3180+
node_config {
3181+
image_type = "WINDOWS_LTSC_CONTAINERD"
3182+
windows_node_config {
3183+
osversion = "%s"
3184+
}
3185+
oauth_scopes = [
3186+
"https://www.googleapis.com/auth/logging.write",
3187+
"https://www.googleapis.com/auth/monitoring",
3188+
]
3189+
}
3190+
}
3191+
`, cluster, np, osversion)
3192+
}
3193+
31273194
func testAccContainerNodePool_withCgroupMode(cluster, np, mode, networkName, subnetworkName string) string {
31283195
return fmt.Sprintf(`
31293196
data "google_container_engine_versions" "central1a" {

website/docs/r/container_cluster.html.markdown

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,15 @@ kubelet_config {
10031003

10041004
* `linux_node_config` - (Optional) Parameters that can be configured on Linux nodes. Structure is [documented below](#nested_linux_node_config).
10051005

1006+
* `windows_node_config` - (Optional)
1007+
Windows node configuration, currently supporting OSVersion [attribute](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1/NodeConfig#osversion). The value must be one of [OS_VERSION_UNSPECIFIED, OS_VERSION_LTSC2019, OS_VERSION_LTSC2019]. For example:
1008+
1009+
```hcl
1010+
windows_node_config {
1011+
osversion = "OS_VERSION_LTSC2019"
1012+
}
1013+
```
1014+
10061015
* `containerd_config` - (Optional) Parameters to customize containerd runtime. Structure is [documented below](#nested_containerd_config).
10071016

10081017
* `node_group` - (Optional) Setting this field will assign instances of this pool to run on the specified node group. This is useful for running workloads on [sole tenant nodes](https://cloud.google.com/compute/docs/nodes/sole-tenant-nodes).

0 commit comments

Comments
 (0)