Skip to content

Commit 174983d

Browse files
Add support for WindowsNodeConfig to GKE NodePool (#13197) (#9559)
[upstream:37b8896aead72d9c755241ea370d49fd550d2a23] Signed-off-by: Modular Magician <[email protected]>
1 parent 9561adb commit 174983d

File tree

4 files changed

+165
-0
lines changed

4 files changed

+165
-0
lines changed

.changelog/13197.txt

+3
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-beta/services/container/node_config.go

+86
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,25 @@ func schemaNodeConfig() *schema.Schema {
699699
},
700700
},
701701
},
702+
"windows_node_config": {
703+
Type: schema.TypeList,
704+
Optional: true,
705+
Computed: true,
706+
MaxItems: 1,
707+
Description: `Parameters that can be configured on Windows nodes.`,
708+
Elem: &schema.Resource{
709+
Schema: map[string]*schema.Schema{
710+
"osversion": {
711+
Type: schema.TypeString,
712+
Optional: true,
713+
ForceNew: true,
714+
Default: "OS_VERSION_UNSPECIFIED",
715+
Description: `The OS Version of the windows nodepool.Values are OS_VERSION_UNSPECIFIED,OS_VERSION_LTSC2019 and OS_VERSION_LTSC2022`,
716+
ValidateFunc: validation.StringInSlice([]string{"OS_VERSION_UNSPECIFIED", "OS_VERSION_LTSC2019", "OS_VERSION_LTSC2022"}, false),
717+
},
718+
},
719+
},
720+
},
702721
"node_group": {
703722
Type: schema.TypeString,
704723
Optional: true,
@@ -1199,6 +1218,10 @@ func expandNodeConfig(v interface{}) *container.NodeConfig {
11991218
nc.LinuxNodeConfig = expandLinuxNodeConfig(v)
12001219
}
12011220

1221+
if v, ok := nodeConfig["windows_node_config"]; ok {
1222+
nc.WindowsNodeConfig = expandWindowsNodeConfig(v)
1223+
}
1224+
12021225
if v, ok := nodeConfig["node_group"]; ok {
12031226
nc.NodeGroup = v.(string)
12041227
}
@@ -1366,6 +1389,24 @@ func expandLinuxNodeConfig(v interface{}) *container.LinuxNodeConfig {
13661389
return linuxNodeConfig
13671390
}
13681391

1392+
func expandWindowsNodeConfig(v interface{}) *container.WindowsNodeConfig {
1393+
if v == nil {
1394+
return nil
1395+
}
1396+
ls := v.([]interface{})
1397+
if len(ls) == 0 {
1398+
return nil
1399+
}
1400+
cfg := ls[0].(map[string]interface{})
1401+
osversionRaw, ok := cfg["osversion"]
1402+
if !ok {
1403+
return nil
1404+
}
1405+
return &container.WindowsNodeConfig{
1406+
OsVersion: osversionRaw.(string),
1407+
}
1408+
}
1409+
13691410
func expandSysctls(cfg map[string]interface{}) map[string]string {
13701411
sysCfgRaw, ok := cfg["sysctls"]
13711412
if !ok {
@@ -1628,6 +1669,7 @@ func flattenNodeConfig(c *container.NodeConfig, v interface{}) []map[string]inte
16281669
"boot_disk_kms_key": c.BootDiskKmsKey,
16291670
"kubelet_config": flattenKubeletConfig(c.KubeletConfig),
16301671
"linux_node_config": flattenLinuxNodeConfig(c.LinuxNodeConfig),
1672+
"windows_node_config": flattenWindowsNodeConfig(c.WindowsNodeConfig),
16311673
"node_group": c.NodeGroup,
16321674
"advanced_machine_features": flattenAdvancedMachineFeaturesConfig(c.AdvancedMachineFeatures),
16331675
"max_run_duration": c.MaxRunDuration,
@@ -1962,6 +2004,16 @@ func flattenLinuxNodeConfig(c *container.LinuxNodeConfig) []map[string]interface
19622004
return result
19632005
}
19642006

2007+
func flattenWindowsNodeConfig(c *container.WindowsNodeConfig) []map[string]interface{} {
2008+
result := []map[string]interface{}{}
2009+
if c != nil {
2010+
result = append(result, map[string]interface{}{
2011+
"osversion": c.OsVersion,
2012+
})
2013+
}
2014+
return result
2015+
}
2016+
19652017
func flattenHugepagesConfig(c *container.HugepagesConfig) []map[string]interface{} {
19662018
result := []map[string]interface{}{}
19672019
if c != nil {
@@ -2616,6 +2668,40 @@ func nodePoolNodeConfigUpdate(d *schema.ResourceData, config *transport_tpg.Conf
26162668

26172669
log.Printf("[INFO] Updated linux_node_config for node pool %s", name)
26182670
}
2671+
if d.HasChange(prefix + "node_config.0.windows_node_config") {
2672+
req := &container.UpdateNodePoolRequest{
2673+
NodePoolId: name,
2674+
WindowsNodeConfig: expandWindowsNodeConfig(
2675+
d.Get(prefix + "node_config.0.windows_node_config")),
2676+
}
2677+
if req.WindowsNodeConfig == nil {
2678+
req.WindowsNodeConfig = &container.WindowsNodeConfig{}
2679+
req.ForceSendFields = []string{"WindowsNodeConfig"}
2680+
}
2681+
updateF := func() error {
2682+
clusterNodePoolsUpdateCall := config.NewContainerClient(userAgent).Projects.Locations.Clusters.NodePools.Update(nodePoolInfo.fullyQualifiedName(name), req)
2683+
if config.UserProjectOverride {
2684+
clusterNodePoolsUpdateCall.Header().Add("X-Goog-User-Project", nodePoolInfo.project)
2685+
}
2686+
op, err := clusterNodePoolsUpdateCall.Do()
2687+
if err != nil {
2688+
return err
2689+
}
2690+
2691+
// Wait until it's updated
2692+
return ContainerOperationWait(config, op,
2693+
nodePoolInfo.project,
2694+
nodePoolInfo.location,
2695+
"updating GKE node pool windows_node_config", userAgent,
2696+
timeout)
2697+
}
2698+
2699+
if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil {
2700+
return err
2701+
}
2702+
2703+
log.Printf("[INFO] Updated windows_node_config for node pool %s", name)
2704+
}
26192705
if d.HasChange(prefix + "node_config.0.fast_socket") {
26202706
req := &container.UpdateNodePoolRequest{
26212707
NodePoolId: name,

google-beta/services/container/resource_container_node_pool_test.go

+67
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,38 @@ func TestAccContainerNodePool_withLinuxNodeConfig(t *testing.T) {
652652
})
653653
}
654654

655+
func TestAccContainerNodePool_withWindowsNodeConfig(t *testing.T) {
656+
t.Parallel()
657+
658+
cluster := fmt.Sprintf("tf-test-cluster-%s", acctest.RandString(t, 10))
659+
np := fmt.Sprintf("tf-test-np-%s", acctest.RandString(t, 10))
660+
661+
acctest.VcrTest(t, resource.TestCase{
662+
PreCheck: func() { acctest.AccTestPreCheck(t) },
663+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
664+
CheckDestroy: testAccCheckContainerClusterDestroyProducer(t),
665+
Steps: []resource.TestStep{
666+
{
667+
Config: testAccContainerNodePool_withWindowsNodeConfig(cluster, np, "OS_VERSION_LTSC2019"),
668+
},
669+
{
670+
ResourceName: "google_container_node_pool.with_windows_node_config",
671+
ImportState: true,
672+
ImportStateVerify: true,
673+
},
674+
// Perform an update.
675+
{
676+
Config: testAccContainerNodePool_withWindowsNodeConfig(cluster, np, "OS_VERSION_LTSC2022"),
677+
},
678+
{
679+
ResourceName: "google_container_node_pool.with_windows_node_config",
680+
ImportState: true,
681+
ImportStateVerify: true,
682+
},
683+
},
684+
})
685+
}
686+
655687
func TestAccContainerNodePool_withCgroupMode(t *testing.T) {
656688
t.Parallel()
657689

@@ -3281,6 +3313,41 @@ resource "google_container_node_pool" "with_linux_node_config" {
32813313
`, cluster, networkName, subnetworkName, np, linuxNodeConfig)
32823314
}
32833315

3316+
func testAccContainerNodePool_withWindowsNodeConfig(cluster, np string, osversion string) string {
3317+
return fmt.Sprintf(`
3318+
data "google_container_engine_versions" "central1a" {
3319+
location = "us-central1-a"
3320+
}
3321+
3322+
resource "google_container_cluster" "cluster" {
3323+
name = "%s"
3324+
location = "us-central1-a"
3325+
initial_node_count = 1
3326+
min_master_version = data.google_container_engine_versions.central1a.latest_master_version
3327+
deletion_protection = false
3328+
networking_mode = "VPC_NATIVE"
3329+
ip_allocation_policy {}
3330+
}
3331+
3332+
resource "google_container_node_pool" "with_windows_node_config" {
3333+
name = "%s"
3334+
location = "us-central1-a"
3335+
cluster = google_container_cluster.cluster.name
3336+
initial_node_count = 1
3337+
node_config {
3338+
image_type = "WINDOWS_LTSC_CONTAINERD"
3339+
windows_node_config {
3340+
osversion = "%s"
3341+
}
3342+
oauth_scopes = [
3343+
"https://www.googleapis.com/auth/logging.write",
3344+
"https://www.googleapis.com/auth/monitoring",
3345+
]
3346+
}
3347+
}
3348+
`, cluster, np, osversion)
3349+
}
3350+
32843351
func testAccContainerNodePool_withCgroupMode(cluster, np, mode, networkName, subnetworkName string) string {
32853352
return fmt.Sprintf(`
32863353
data "google_container_engine_versions" "central1a" {

website/docs/r/container_cluster.html.markdown

+9
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)