Skip to content

Commit b6db1d3

Browse files
modular-magicianshuyama1
authored andcommitted
container: fix updates for node_config.gcfs_config and make optional (#11717) (#8207)
[upstream:20ac9f9559b3c12d6d637ff4e5f46f029d86997d] Signed-off-by: Modular Magician <[email protected]>
1 parent 8ec8293 commit b6db1d3

6 files changed

+222
-10
lines changed

.changelog/11717.txt

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
```release-note:bug
2+
container: fixed the in-place update for `node_config.gcfs_config` in `google_container_cluster` and `google_container_node_pool`
3+
```
4+
```release-note:bug
5+
container: fixed a permadiff on `node_config.gcfs_config` in `google_container_cluster` and `google_container_node_pool`
6+
```

google-beta/services/container/node_config.go

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ func schemaGcfsConfig() *schema.Schema {
9999
return &schema.Schema{
100100
Type: schema.TypeList,
101101
Optional: true,
102+
Computed: true,
102103
MaxItems: 1,
103104
Description: `GCFS configuration for this node.`,
104105
Elem: &schema.Resource{

google-beta/services/container/resource_container_cluster.go

+49
Original file line numberDiff line numberDiff line change
@@ -3823,6 +3823,55 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
38233823
log.Printf("[INFO] GKE cluster %s: default-pool setting for insecure_kubelet_readonly_port_enabled updated to %s", d.Id(), it)
38243824
}
38253825
}
3826+
3827+
if d.HasChange("node_config.0.gcfs_config") {
3828+
3829+
defaultPool := "default-pool"
3830+
3831+
timeout := d.Timeout(schema.TimeoutCreate)
3832+
3833+
nodePoolInfo, err := extractNodePoolInformationFromCluster(d, config, clusterName)
3834+
if err != nil {
3835+
return err
3836+
}
3837+
3838+
// Acquire write-lock on nodepool.
3839+
npLockKey := nodePoolInfo.nodePoolLockKey(defaultPool)
3840+
3841+
gcfsEnabled := d.Get("node_config.0.gcfs_config.0.enabled").(bool)
3842+
3843+
// While we're getting the value from the drepcated field in
3844+
// node_config.kubelet_config, the actual setting that needs to be updated
3845+
// is on the default nodepool.
3846+
req := &container.UpdateNodePoolRequest{
3847+
Name: defaultPool,
3848+
GcfsConfig: &container.GcfsConfig{
3849+
Enabled: gcfsEnabled,
3850+
},
3851+
}
3852+
3853+
updateF := func() error {
3854+
clusterNodePoolsUpdateCall := config.NewContainerClient(userAgent).Projects.Locations.Clusters.NodePools.Update(nodePoolInfo.fullyQualifiedName(defaultPool), req)
3855+
if config.UserProjectOverride {
3856+
clusterNodePoolsUpdateCall.Header().Add("X-Goog-User-Project", nodePoolInfo.project)
3857+
}
3858+
op, err := clusterNodePoolsUpdateCall.Do()
3859+
if err != nil {
3860+
return err
3861+
}
3862+
3863+
// Wait until it's updated
3864+
return ContainerOperationWait(config, op, nodePoolInfo.project, nodePoolInfo.location,
3865+
"updating GKE node pool gcfs_config", userAgent, timeout)
3866+
}
3867+
3868+
if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil {
3869+
return err
3870+
}
3871+
3872+
log.Printf("[INFO] GKE cluster %s: %s setting for gcfs_config updated to %t", d.Id(), defaultPool, gcfsEnabled)
3873+
}
3874+
38263875
}
38273876

38283877
if d.HasChange("notification_config") {

google-beta/services/container/resource_container_cluster_test.go

+119
Original file line numberDiff line numberDiff line change
@@ -1525,6 +1525,83 @@ func TestAccContainerCluster_withNodeConfig(t *testing.T) {
15251525
})
15261526
}
15271527

1528+
func TestAccContainerCluster_withNodeConfigGcfsConfig(t *testing.T) {
1529+
t.Parallel()
1530+
clusterName := fmt.Sprintf("tf-test-cluster-%s", acctest.RandString(t, 10))
1531+
networkName := acctest.BootstrapSharedTestNetwork(t, "gke-cluster")
1532+
subnetworkName := acctest.BootstrapSubnet(t, "gke-cluster", networkName)
1533+
1534+
acctest.VcrTest(t, resource.TestCase{
1535+
PreCheck: func() { acctest.AccTestPreCheck(t) },
1536+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
1537+
CheckDestroy: testAccCheckContainerClusterDestroyProducer(t),
1538+
Steps: []resource.TestStep{
1539+
{
1540+
Config: testAccContainerCluster_withNodeConfigGcfsConfig(clusterName, networkName, subnetworkName, false),
1541+
ConfigPlanChecks: resource.ConfigPlanChecks{
1542+
PreApply: []plancheck.PlanCheck{
1543+
acctest.ExpectNoDelete(),
1544+
},
1545+
},
1546+
},
1547+
{
1548+
ResourceName: "google_container_cluster.with_node_config_gcfs_config",
1549+
ImportState: true,
1550+
ImportStateVerify: true,
1551+
ImportStateVerifyIgnore: []string{"deletion_protection"},
1552+
},
1553+
{
1554+
Config: testAccContainerCluster_withNodeConfigGcfsConfig(clusterName, networkName, subnetworkName, true),
1555+
ConfigPlanChecks: resource.ConfigPlanChecks{
1556+
PreApply: []plancheck.PlanCheck{
1557+
acctest.ExpectNoDelete(),
1558+
},
1559+
},
1560+
},
1561+
{
1562+
ResourceName: "google_container_cluster.with_node_config_gcfs_config",
1563+
ImportState: true,
1564+
ImportStateVerify: true,
1565+
ImportStateVerifyIgnore: []string{"deletion_protection"},
1566+
},
1567+
},
1568+
})
1569+
}
1570+
1571+
// Note: Updates for these are currently known to be broken (b/361634104), and
1572+
// so are not tested here.
1573+
// They can probably be made similar to, or consolidated with,
1574+
// TestAccContainerCluster_withInsecureKubeletReadonlyPortEnabledInNodeConfigUpdates
1575+
// after that's resolved.
1576+
func TestAccContainerCluster_withNodeConfigKubeletConfigSettings(t *testing.T) {
1577+
t.Parallel()
1578+
clusterName := fmt.Sprintf("tf-test-cluster-%s", acctest.RandString(t, 10))
1579+
networkName := acctest.BootstrapSharedTestNetwork(t, "gke-cluster")
1580+
subnetworkName := acctest.BootstrapSubnet(t, "gke-cluster", networkName)
1581+
1582+
acctest.VcrTest(t, resource.TestCase{
1583+
PreCheck: func() { acctest.AccTestPreCheck(t) },
1584+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
1585+
CheckDestroy: testAccCheckContainerClusterDestroyProducer(t),
1586+
Steps: []resource.TestStep{
1587+
{
1588+
Config: testAccContainerCluster_withNodeConfigKubeletConfigSettings(clusterName, networkName, subnetworkName),
1589+
ConfigPlanChecks: resource.ConfigPlanChecks{
1590+
PreApply: []plancheck.PlanCheck{
1591+
acctest.ExpectNoDelete(),
1592+
},
1593+
},
1594+
},
1595+
{
1596+
ResourceName: "google_container_cluster.with_node_config_kubelet_config_settings",
1597+
ImportState: true,
1598+
ImportStateVerify: true,
1599+
ImportStateVerifyIgnore: []string{"deletion_protection"},
1600+
},
1601+
},
1602+
})
1603+
}
1604+
15281605
// This is for node_config.kubelet_config, which affects the default node-pool
15291606
// (default-pool) when created via the google_container_cluster resource
15301607
func TestAccContainerCluster_withInsecureKubeletReadonlyPortEnabledInNodeConfigUpdates(t *testing.T) {
@@ -6664,6 +6741,48 @@ resource "google_container_cluster" "with_node_config" {
66646741
`, clusterName, networkName, subnetworkName)
66656742
}
66666743

6744+
func testAccContainerCluster_withNodeConfigGcfsConfig(clusterName, networkName, subnetworkName string, enabled bool) string {
6745+
return fmt.Sprintf(`
6746+
resource "google_container_cluster" "with_node_config_gcfs_config" {
6747+
name = "%s"
6748+
location = "us-central1-f"
6749+
initial_node_count = 1
6750+
6751+
node_config {
6752+
gcfs_config {
6753+
enabled = %t
6754+
}
6755+
}
6756+
6757+
deletion_protection = false
6758+
network = "%s"
6759+
subnetwork = "%s"
6760+
}
6761+
`, clusterName, enabled, networkName, subnetworkName)
6762+
}
6763+
6764+
func testAccContainerCluster_withNodeConfigKubeletConfigSettings(clusterName, networkName, subnetworkName string) string {
6765+
return fmt.Sprintf(`
6766+
resource "google_container_cluster" "with_node_config_kubelet_config_settings" {
6767+
name = "%s"
6768+
location = "us-central1-f"
6769+
initial_node_count = 1
6770+
6771+
node_config {
6772+
kubelet_config {
6773+
cpu_manager_policy = "static"
6774+
cpu_cfs_quota = true
6775+
cpu_cfs_quota_period = "100ms"
6776+
pod_pids_limit = 2048
6777+
}
6778+
}
6779+
deletion_protection = false
6780+
network = "%s"
6781+
subnetwork = "%s"
6782+
}
6783+
`, clusterName, networkName, subnetworkName)
6784+
}
6785+
66676786
func testAccContainerCluster_withInsecureKubeletReadonlyPortEnabledInNodeConfig(clusterName, networkName, subnetworkName, insecureKubeletReadonlyPortEnabled string) string {
66686787
return fmt.Sprintf(`
66696788
resource "google_container_cluster" "with_insecure_kubelet_readonly_port_enabled_in_node_config" {

google-beta/services/container/resource_container_node_pool.go

+33
Original file line numberDiff line numberDiff line change
@@ -1770,6 +1770,39 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
17701770
log.Printf("[INFO] Updated workload_metadata_config for node pool %s", name)
17711771
}
17721772

1773+
if d.HasChange(prefix + "node_config.0.gcfs_config") {
1774+
gcfsEnabled := bool(d.Get(prefix + "node_config.0.gcfs_config.0.enabled").(bool))
1775+
req := &container.UpdateNodePoolRequest{
1776+
NodePoolId: name,
1777+
GcfsConfig: &container.GcfsConfig{
1778+
Enabled: gcfsEnabled,
1779+
},
1780+
}
1781+
updateF := func() error {
1782+
clusterNodePoolsUpdateCall := config.NewContainerClient(userAgent).Projects.Locations.Clusters.NodePools.Update(nodePoolInfo.fullyQualifiedName(name), req)
1783+
if config.UserProjectOverride {
1784+
clusterNodePoolsUpdateCall.Header().Add("X-Goog-User-Project", nodePoolInfo.project)
1785+
}
1786+
op, err := clusterNodePoolsUpdateCall.Do()
1787+
if err != nil {
1788+
return err
1789+
}
1790+
1791+
// Wait until it's updated
1792+
return ContainerOperationWait(config, op,
1793+
nodePoolInfo.project,
1794+
nodePoolInfo.location,
1795+
"updating GKE node pool gcfs_config", userAgent,
1796+
timeout)
1797+
}
1798+
1799+
if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil {
1800+
return err
1801+
}
1802+
1803+
log.Printf("[INFO] Updated gcfs_config for node pool %s", name)
1804+
}
1805+
17731806
if d.HasChange(prefix + "node_config.0.kubelet_config") {
17741807
req := &container.UpdateNodePoolRequest{
17751808
NodePoolId: name,

google-beta/services/container/resource_container_node_pool_test.go

+14-10
Original file line numberDiff line numberDiff line change
@@ -1705,9 +1705,9 @@ resource "google_container_node_pool" "np" {
17051705
node_config {
17061706
machine_type = "n1-standard-8"
17071707
image_type = "COS_CONTAINERD"
1708-
gcfs_config {
1709-
enabled = true
1710-
}
1708+
gcfs_config {
1709+
enabled = true
1710+
}
17111711
secondary_boot_disks {
17121712
disk_image = ""
17131713
mode = "CONTAINER_IMAGE_CACHE"
@@ -1724,9 +1724,9 @@ resource "google_container_node_pool" "np-no-mode" {
17241724
node_config {
17251725
machine_type = "n1-standard-8"
17261726
image_type = "COS_CONTAINERD"
1727-
gcfs_config {
1728-
enabled = true
1729-
}
1727+
gcfs_config {
1728+
enabled = true
1729+
}
17301730
secondary_boot_disks {
17311731
disk_image = ""
17321732
}
@@ -1750,10 +1750,14 @@ func TestAccContainerNodePool_gcfsConfig(t *testing.T) {
17501750
Steps: []resource.TestStep{
17511751
{
17521752
Config: testAccContainerNodePool_gcfsConfig(cluster, np, networkName, subnetworkName, true),
1753-
Check: resource.ComposeTestCheckFunc(
1754-
resource.TestCheckResourceAttr("google_container_node_pool.np",
1755-
"node_config.0.gcfs_config.0.enabled", "true"),
1756-
),
1753+
},
1754+
{
1755+
ResourceName: "google_container_node_pool.np",
1756+
ImportState: true,
1757+
ImportStateVerify: true,
1758+
},
1759+
{
1760+
Config: testAccContainerNodePool_gcfsConfig(cluster, np, networkName, subnetworkName, false),
17571761
},
17581762
{
17591763
ResourceName: "google_container_node_pool.np",

0 commit comments

Comments
 (0)