Skip to content

Commit

Permalink
container: update default node-pool fields in place
Browse files Browse the repository at this point in the history
This resolves an issue where many subfields of `node_config` in a
cluster (which affects the default node-pool "default-pool" when
`remove_default_node_pool` is not set to `false`) don't support updates
properly.

Fixes hashicorp/terraform-provider-google#19225

Followup to #11826 where the code used by the regular node pool update
code was broken out.
  • Loading branch information
wyardley committed Oct 19, 2024
1 parent 3f06b2e commit d8f75a5
Showing 1 changed file with 5 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3812,133 +3812,15 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
}

if d.HasChange("node_config") {
if d.HasChange("node_config.0.image_type") {
it := d.Get("node_config.0.image_type").(string)
req := &container.UpdateClusterRequest{
Update: &container.ClusterUpdate{
DesiredImageType: it,
},
}

updateF := func() error {
name := containerClusterFullName(project, location, clusterName)
clusterUpdateCall := config.NewContainerClient(userAgent).Projects.Locations.Clusters.Update(name, req)
if config.UserProjectOverride {
clusterUpdateCall.Header().Add("X-Goog-User-Project", project)
}
op, err := clusterUpdateCall.Do()
if err != nil {
return err
}
defaultPool := "default-pool"

// Wait until it's updated
return ContainerOperationWait(config, op, project, location, "updating GKE image type", userAgent, d.Timeout(schema.TimeoutUpdate))
}

// Call update serially.
if err := transport_tpg.LockedCall(lockKey, updateF); err != nil {
return err
}

log.Printf("[INFO] GKE cluster %s: image type has been updated to %s", d.Id(), it)
}

if d.HasChange("node_config.0.kubelet_config") {

defaultPool := "default-pool"

timeout := d.Timeout(schema.TimeoutCreate)

nodePoolInfo, err := extractNodePoolInformationFromCluster(d, config, clusterName)
if err != nil {
return err
}

// Acquire write-lock on nodepool.
npLockKey := nodePoolInfo.nodePoolLockKey(defaultPool)

// Still should be further consolidated / DRYed up
// See b/361634104
it := d.Get("node_config.0.kubelet_config")

// While we're getting the value from fields in
// node_config.kubelet_config, the actual setting that needs to be
// updated is on the default nodepool.
req := &container.UpdateNodePoolRequest{
Name: defaultPool,
KubeletConfig: expandKubeletConfig(it),
}

updateF := func() error {
clusterNodePoolsUpdateCall := config.NewContainerClient(userAgent).Projects.Locations.Clusters.NodePools.Update(nodePoolInfo.fullyQualifiedName(defaultPool), req)
if config.UserProjectOverride {
clusterNodePoolsUpdateCall.Header().Add("X-Goog-User-Project", nodePoolInfo.project)
}
op, err := clusterNodePoolsUpdateCall.Do()
if err != nil {
return err
}

// Wait until it's updated
return ContainerOperationWait(config, op, nodePoolInfo.project, nodePoolInfo.location,
"updating GKE node pool kubelet_config", userAgent, timeout)
}

if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil {
return err
}

log.Printf("[INFO] GKE cluster %s: kubelet_config updated", d.Id())
}

if d.HasChange("node_config.0.gcfs_config") {

defaultPool := "default-pool"

timeout := d.Timeout(schema.TimeoutCreate)

nodePoolInfo, err := extractNodePoolInformationFromCluster(d, config, clusterName)
if err != nil {
return err
}

// Acquire write-lock on nodepool.
npLockKey := nodePoolInfo.nodePoolLockKey(defaultPool)

gcfsEnabled := d.Get("node_config.0.gcfs_config.0.enabled").(bool)

// While we're getting the value from the drepcated field in
// node_config.kubelet_config, the actual setting that needs to be updated
// is on the default nodepool.
req := &container.UpdateNodePoolRequest{
Name: defaultPool,
GcfsConfig: &container.GcfsConfig{
Enabled: gcfsEnabled,
},
}

updateF := func() error {
clusterNodePoolsUpdateCall := config.NewContainerClient(userAgent).Projects.Locations.Clusters.NodePools.Update(nodePoolInfo.fullyQualifiedName(defaultPool), req)
if config.UserProjectOverride {
clusterNodePoolsUpdateCall.Header().Add("X-Goog-User-Project", nodePoolInfo.project)
}
op, err := clusterNodePoolsUpdateCall.Do()
if err != nil {
return err
}

// Wait until it's updated
return ContainerOperationWait(config, op, nodePoolInfo.project, nodePoolInfo.location,
"updating GKE node pool gcfs_config", userAgent, timeout)
}

if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil {
return err
}

log.Printf("[INFO] GKE cluster %s: %s setting for gcfs_config updated to %t", d.Id(), defaultPool, gcfsEnabled)
nodePoolInfo, err := extractNodePoolInformationFromCluster(d, config, clusterName)
if err != nil {
return err
}

nodePoolNodeConfigUpdate(d, config, nodePoolInfo, "", defaultPool, d.Timeout(schema.TimeoutUpdate))
}

if d.HasChange("notification_config") {
Expand Down

0 comments on commit d8f75a5

Please sign in to comment.