Skip to content

Commit 534cd1f

Browse files
authored
Support node drain config (#16087)
1 parent 207f3fc commit 534cd1f

File tree

6 files changed

+198
-1
lines changed

6 files changed

+198
-1
lines changed

mmv1/third_party/terraform/services/container/resource_container_cluster_meta.yaml.tmpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,8 @@ fields:
688688
api_field: 'nodePools.config.windowsNodeConfig.osVersion'
689689
- field: 'node_pool.node_config.workload_metadata_config.mode'
690690
api_field: 'nodePools.config.workloadMetadataConfig.mode'
691+
- field: 'node_pool.node_drain_config.respect_pdb_during_node_pool_deletion'
692+
api_field: 'nodePools.nodeDrainConfig.respectPdbDuringNodePoolDeletion'
691693
- field: 'node_pool.node_count'
692694
provider_only: true
693695
- field: 'node_pool.node_locations'

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

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3387,6 +3387,36 @@ func TestAccContainerCluster_withNodePoolNodeConfig(t *testing.T) {
33873387
})
33883388
}
33893389

3390+
func TestAccContainerCluster_withNodePoolNodeDrainConfig(t *testing.T) {
3391+
t.Parallel()
3392+
3393+
cluster := fmt.Sprintf("tf-test-cluster-%s", acctest.RandString(t, 10))
3394+
np := fmt.Sprintf("tf-test-np-%s", acctest.RandString(t, 10))
3395+
networkName := acctest.BootstrapSharedTestNetwork(t, "gke-cluster")
3396+
subnetworkName := acctest.BootstrapSubnet(t, "gke-cluster", networkName)
3397+
3398+
acctest.VcrTest(t, resource.TestCase{
3399+
PreCheck: func() { acctest.AccTestPreCheck(t) },
3400+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
3401+
CheckDestroy: testAccCheckContainerClusterDestroyProducer(t),
3402+
Steps: []resource.TestStep{
3403+
{
3404+
Config: testAccContainerCluster_withNodePoolNodeDrainConfig(cluster, np, networkName, subnetworkName),
3405+
Check: resource.ComposeTestCheckFunc(
3406+
resource.TestCheckResourceAttr("google_container_cluster.with_node_pool_node_drain_config",
3407+
"node_pool.0.node_drain_config.0.respect_pdb_during_node_pool_deletion", "true"),
3408+
),
3409+
},
3410+
{
3411+
ResourceName: "google_container_cluster.with_node_pool_node_drain_config",
3412+
ImportState: true,
3413+
ImportStateVerify: true,
3414+
ImportStateVerifyIgnore: []string{"min_master_version", "deletion_protection"},
3415+
},
3416+
},
3417+
})
3418+
}
3419+
33903420
func TestAccContainerCluster_withMaintenanceWindow(t *testing.T) {
33913421
t.Parallel()
33923422

@@ -10714,6 +10744,31 @@ resource "google_container_cluster" "with_node_pool_node_config" {
1071410744
`, cluster, np, networkName, subnetworkName)
1071510745
}
1071610746

10747+
func testAccContainerCluster_withNodePoolNodeDrainConfig(cluster, np, networkName, subnetworkName string) string {
10748+
return fmt.Sprintf(`
10749+
data "google_container_engine_versions" "central1a" {
10750+
location = "us-central1-a"
10751+
}
10752+
10753+
resource "google_container_cluster" "with_node_pool_node_drain_config" {
10754+
name = "%s"
10755+
location = "us-central1-a"
10756+
min_master_version = data.google_container_engine_versions.central1a.latest_master_version
10757+
node_pool {
10758+
name = "%s"
10759+
initial_node_count = 1
10760+
node_drain_config {
10761+
respect_pdb_during_node_pool_deletion = true
10762+
}
10763+
}
10764+
10765+
network = "%s"
10766+
subnetwork = "%s"
10767+
deletion_protection = false
10768+
}
10769+
`, cluster, np, networkName, subnetworkName)
10770+
}
10771+
1071710772
func testAccContainerCluster_withMaintenanceWindow(clusterName, startTime, networkName, subnetworkName string) string {
1071810773
maintenancePolicy := ""
1071910774
if len(startTime) > 0 {

mmv1/third_party/terraform/services/container/resource_container_node_pool.go.tmpl

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,22 @@ var schemaNodePool = map[string]*schema.Schema{
657657
},
658658
},
659659

660+
"node_drain_config": {
661+
Type: schema.TypeList,
662+
Optional: true,
663+
Computed: true,
664+
Description: `Node drain configuration for this NodePool.`,
665+
Elem: &schema.Resource{
666+
Schema: map[string]*schema.Schema{
667+
"respect_pdb_during_node_pool_deletion": {
668+
Type: schema.TypeBool,
669+
Optional: true,
670+
Description: `Whether to respect PodDisruptionBudget policy during node pool deletion.`,
671+
},
672+
},
673+
},
674+
},
675+
660676
}
661677

662678
type NodePoolInformation struct {
@@ -1268,6 +1284,15 @@ func expandNodePool(d *schema.ResourceData, prefix string) (*container.NodePool,
12681284
}
12691285
}
12701286

1287+
if v, ok := d.GetOk(prefix + "node_drain_config"); ok {
1288+
nodeDrainConfig := v.([]interface{})[0].(map[string]interface{})
1289+
np.NodeDrainConfig = &container.NodeDrainConfig{}
1290+
1291+
if v, ok := nodeDrainConfig["respect_pdb_during_node_pool_deletion"]; ok {
1292+
np.NodeDrainConfig.RespectPdbDuringNodePoolDeletion = v.(bool)
1293+
}
1294+
}
1295+
12711296
return np, nil
12721297
}
12731298

@@ -1329,6 +1354,17 @@ func flattenNodePoolUpgradeSettings(us *container.UpgradeSettings) []map[string]
13291354
return []map[string]interface{}{upgradeSettings}
13301355
}
13311356

1357+
func flattenNodePoolNodeDrainConfig(ndc *container.NodeDrainConfig) []map[string]interface{} {
1358+
if ndc == nil {
1359+
return nil
1360+
}
1361+
1362+
nodeDrainConfig := make(map[string]interface{})
1363+
1364+
nodeDrainConfig["respect_pdb_during_node_pool_deletion"] = ndc.RespectPdbDuringNodePoolDeletion
1365+
return []map[string]interface{}{nodeDrainConfig}
1366+
}
1367+
13321368
func flattenNodePool(d *schema.ResourceData, config *transport_tpg.Config, np *container.NodePool, prefix string) (map[string]interface{}, error) {
13331369
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
13341370
if err != nil {
@@ -1433,6 +1469,10 @@ func flattenNodePool(d *schema.ResourceData, config *transport_tpg.Config, np *c
14331469
delete(nodePool, "upgrade_settings")
14341470
}
14351471

1472+
if np.NodeDrainConfig != nil {
1473+
nodePool["node_drain_config"] = flattenNodePoolNodeDrainConfig(np.NodeDrainConfig)
1474+
}
1475+
14361476
return nodePool, nil
14371477
}
14381478

@@ -1878,6 +1918,43 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
18781918
}
18791919
}
18801920

1921+
if d.HasChange(prefix + "node_drain_config") {
1922+
nodeDrainConfig := &container.NodeDrainConfig{}
1923+
if v, ok := d.GetOk(prefix + "node_drain_config"); ok {
1924+
nodeDrain := v.([]interface{})[0].(map[string]interface{})
1925+
if v, ok := nodeDrain["respect_pdb_during_node_pool_deletion"]; ok {
1926+
nodeDrainConfig.RespectPdbDuringNodePoolDeletion = v.(bool)
1927+
}
1928+
}
1929+
req := &container.UpdateNodePoolRequest{
1930+
NodeDrainConfig: nodeDrainConfig,
1931+
}
1932+
1933+
updateF := func() error {
1934+
clusterNodePoolsUpdateCall := config.NewContainerClient(userAgent).Projects.Locations.Clusters.NodePools.Update(nodePoolInfo.fullyQualifiedName(name),req)
1935+
1936+
if config.UserProjectOverride {
1937+
clusterNodePoolsUpdateCall.Header().Add("X-Goog-User-Project", nodePoolInfo.project)
1938+
}
1939+
op, err := clusterNodePoolsUpdateCall.Do()
1940+
1941+
if err != nil {
1942+
return err
1943+
}
1944+
1945+
// Wait until it's updated
1946+
return ContainerOperationWait(config, op,
1947+
nodePoolInfo.project,
1948+
nodePoolInfo.location,
1949+
"updating GKE node pool node_drain_config", userAgent, timeout)
1950+
}
1951+
1952+
if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil {
1953+
return err
1954+
}
1955+
log.Printf("[INFO] Updated node_drain_config in Node Pool %s", name)
1956+
}
1957+
18811958
return nil
18821959
}
18831960

mmv1/third_party/terraform/services/container/resource_container_node_pool_meta.yaml.tmpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,8 @@ fields:
290290
api_field: 'config.windowsNodeConfig.osVersion'
291291
- field: 'node_config.workload_metadata_config.mode'
292292
api_field: 'config.workloadMetadataConfig.mode'
293+
- field: 'node_drain_config.respect_pdb_during_node_pool_deletion'
294+
api_field: 'nodeDrainConfig.respectPdbDuringNodePoolDeletion'
293295
- field: 'node_count'
294296
provider_only: true
295297
- field: 'node_locations'

mmv1/third_party/terraform/services/container/resource_container_node_pool_test.go.tmpl

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,6 +1594,34 @@ func TestAccContainerNodePool_withManagement(t *testing.T) {
15941594
})
15951595
}
15961596

1597+
func TestAccContainerNodePool_withNodeDrainConfig(t *testing.T) {
1598+
t.Parallel()
1599+
1600+
cluster := fmt.Sprintf("tf-test-cluster-%s", acctest.RandString(t, 10))
1601+
nodePool := fmt.Sprintf("tf-test-nodepool-%s", acctest.RandString(t, 10))
1602+
networkName := acctest.BootstrapSharedTestNetwork(t, "gke-cluster")
1603+
subnetworkName := acctest.BootstrapSubnet(t, "gke-cluster", networkName)
1604+
1605+
acctest.VcrTest(t, resource.TestCase{
1606+
PreCheck: func() { acctest.AccTestPreCheck(t) },
1607+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
1608+
CheckDestroy: testAccCheckContainerNodePoolDestroyProducer(t),
1609+
Steps: []resource.TestStep{
1610+
{
1611+
Config: testAccContainerNodePool_withNodeDrainConfig(cluster, nodePool, networkName, subnetworkName),
1612+
Check: resource.ComposeTestCheckFunc(
1613+
resource.TestCheckResourceAttr("google_container_node_pool.np_with_node_drain_config", "node_drain_config.0.respect_pdb_during_node_pool_deletion", "true"),
1614+
),
1615+
},
1616+
{
1617+
ResourceName: "google_container_node_pool.np_with_node_drain_config",
1618+
ImportState: true,
1619+
ImportStateVerify: true,
1620+
},
1621+
},
1622+
})
1623+
}
1624+
15971625
func TestAccContainerNodePool_withNodeConfigScopeAlias(t *testing.T) {
15981626
t.Parallel()
15991627

@@ -4756,6 +4784,34 @@ resource "google_container_node_pool" "np_with_node_config_scope_alias" {
47564784
`, cluster, networkName, subnetworkName, np)
47574785
}
47584786

4787+
func testAccContainerNodePool_withNodeDrainConfig(cluster, np, networkName, subnetworkName string) string {
4788+
return fmt.Sprintf(`
4789+
data "google_container_engine_versions" "central1a" {
4790+
location = "us-central1-a"
4791+
}
4792+
4793+
resource "google_container_cluster" "cluster" {
4794+
name = "%s"
4795+
location = "us-central1-a"
4796+
initial_node_count = 1
4797+
min_master_version = data.google_container_engine_versions.central1a.latest_master_version
4798+
deletion_protection = false
4799+
network = "%s"
4800+
subnetwork = "%s"
4801+
}
4802+
4803+
resource "google_container_node_pool" "np_with_node_drain_config" {
4804+
name = "%s"
4805+
location = "us-central1-a"
4806+
cluster = google_container_cluster.cluster.name
4807+
initial_node_count = 1
4808+
node_drain_config {
4809+
respect_pdb_during_node_pool_deletion = true
4810+
}
4811+
}
4812+
`, cluster, networkName, subnetworkName, np)
4813+
}
4814+
47594815
func testAccContainerNodePool_version(cluster, np, networkName, subnetworkName string) string {
47604816
return fmt.Sprintf(`
47614817
data "google_container_engine_versions" "central1a" {

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ cluster.
154154
* `node_count` - (Optional) The number of nodes per instance group. This field can be used to
155155
update the number of nodes per instance group but should not be used alongside `autoscaling`.
156156

157+
* `node_drain_config` - (Optional) The node drain configuration of the pool. Structure is [documented below](#nested_node_drain_config).
158+
157159
* `project` - (Optional) The ID of the project in which to create the node pool. If blank,
158160
the provider-configured project will be used.
159161

@@ -240,12 +242,15 @@ cluster.
240242
<a name="network_performance_config"></a>The `network_performance_config` block supports:
241243

242244
* `total_egress_bandwidth_tier` (Required) - Specifies the total network bandwidth tier for the NodePool. [Valid values](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1/projects.locations.clusters.nodePools#NodePool.Tier) include: "TIER_1" and "TIER_UNSPECIFIED".
243-
* ```
244245

245246
<a name="pod_cidr_overprovision_config"></a>The `pod_cidr_overprovision_config` block supports:
246247

247248
* `disabled` (Required) - Whether pod cidr overprovision is disabled.
248249

250+
<a name="nested_node_drain_config"></a>The `node_drain_config` block supports:
251+
252+
* `respect_pdb_during_node_pool_deletion` - (Optional) Whether to respect PodDisruptionBudget policy during node pool deletion.
253+
249254
<a name="nested_upgrade_settings"></a>The `upgrade_settings` block supports:
250255

251256
* `max_surge` - (Optional) The number of additional nodes that can be added to the node pool during

0 commit comments

Comments
 (0)