diff --git a/pkg/model/gcemodel/autoscalinggroup.go b/pkg/model/gcemodel/autoscalinggroup.go index e06044d5a8373..56184467df134 100644 --- a/pkg/model/gcemodel/autoscalinggroup.go +++ b/pkg/model/gcemodel/autoscalinggroup.go @@ -313,6 +313,7 @@ func (b *AutoscalingGroupModelBuilder) Build(c *fi.CloudupModelBuilderContext) e Lifecycle: b.Lifecycle, Zone: s(zone), TargetSize: fi.PtrTo(int64(targetSize)), + UpdatePolicy: &gcetasks.UpdatePolicy{MinimalAction: "REPLACE", Type: "OPPORTUNISTIC"}, BaseInstanceName: s(ig.ObjectMeta.Name), InstanceTemplate: instanceTemplate, ListManagedInstancesResults: "PAGINATED", diff --git a/tests/integration/update_cluster/ha_gce/kubernetes.tf b/tests/integration/update_cluster/ha_gce/kubernetes.tf index 13746bdc130b8..6d316c03d472a 100644 --- a/tests/integration/update_cluster/ha_gce/kubernetes.tf +++ b/tests/integration/update_cluster/ha_gce/kubernetes.tf @@ -497,6 +497,10 @@ resource "google_compute_instance_group_manager" "a-master-us-test1-a-ha-gce-exa list_managed_instances_results = "PAGINATED" name = "a-master-us-test1-a-ha-gce-example-com" target_size = 1 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.master-us-test1-a-ha-gce-example-com.self_link } @@ -508,6 +512,10 @@ resource "google_compute_instance_group_manager" "a-nodes-ha-gce-example-com" { list_managed_instances_results = "PAGINATED" name = "a-nodes-ha-gce-example-com" target_size = 1 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.nodes-ha-gce-example-com.self_link } @@ -519,6 +527,10 @@ resource "google_compute_instance_group_manager" "b-master-us-test1-b-ha-gce-exa list_managed_instances_results = "PAGINATED" name = "b-master-us-test1-b-ha-gce-example-com" target_size = 1 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.master-us-test1-b-ha-gce-example-com.self_link } @@ -530,6 +542,10 @@ resource "google_compute_instance_group_manager" "b-nodes-ha-gce-example-com" { list_managed_instances_results = "PAGINATED" name = "b-nodes-ha-gce-example-com" target_size = 1 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.nodes-ha-gce-example-com.self_link } @@ -541,6 +557,10 @@ resource "google_compute_instance_group_manager" "c-master-us-test1-c-ha-gce-exa list_managed_instances_results = "PAGINATED" name = "c-master-us-test1-c-ha-gce-example-com" target_size = 1 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.master-us-test1-c-ha-gce-example-com.self_link } @@ -552,6 +572,10 @@ resource "google_compute_instance_group_manager" "c-nodes-ha-gce-example-com" { list_managed_instances_results = "PAGINATED" name = "c-nodes-ha-gce-example-com" target_size = 0 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.nodes-ha-gce-example-com.self_link } diff --git a/tests/integration/update_cluster/many-addons-gce/kubernetes.tf b/tests/integration/update_cluster/many-addons-gce/kubernetes.tf index f5952945197d6..633022b3aae2c 100644 --- a/tests/integration/update_cluster/many-addons-gce/kubernetes.tf +++ b/tests/integration/update_cluster/many-addons-gce/kubernetes.tf @@ -425,6 +425,10 @@ resource "google_compute_instance_group_manager" "a-master-us-test1-a-minimal-ex list_managed_instances_results = "PAGINATED" name = "a-master-us-test1-a-minimal-example-com" target_size = 1 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.master-us-test1-a-minimal-example-com.self_link } @@ -436,6 +440,10 @@ resource "google_compute_instance_group_manager" "a-nodes-minimal-example-com" { list_managed_instances_results = "PAGINATED" name = "a-nodes-minimal-example-com" target_size = 1 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.nodes-minimal-example-com.self_link } diff --git a/tests/integration/update_cluster/minimal_gce/kubernetes.tf b/tests/integration/update_cluster/minimal_gce/kubernetes.tf index 572dd1a95f5b7..eb8e2240fcbb6 100644 --- a/tests/integration/update_cluster/minimal_gce/kubernetes.tf +++ b/tests/integration/update_cluster/minimal_gce/kubernetes.tf @@ -401,6 +401,10 @@ resource "google_compute_instance_group_manager" "a-master-us-test1-a-minimal-gc list_managed_instances_results = "PAGINATED" name = "a-master-us-test1-a-minimal-gce-example-com" target_size = 1 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.master-us-test1-a-minimal-gce-example-com.self_link } @@ -412,6 +416,10 @@ resource "google_compute_instance_group_manager" "a-nodes-minimal-gce-example-co list_managed_instances_results = "PAGINATED" name = "a-nodes-minimal-gce-example-com" target_size = 2 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.nodes-minimal-gce-example-com.self_link } diff --git a/tests/integration/update_cluster/minimal_gce_dns-none/kubernetes.tf b/tests/integration/update_cluster/minimal_gce_dns-none/kubernetes.tf index 270b511740d35..889634f89fa9e 100644 --- a/tests/integration/update_cluster/minimal_gce_dns-none/kubernetes.tf +++ b/tests/integration/update_cluster/minimal_gce_dns-none/kubernetes.tf @@ -465,6 +465,10 @@ resource "google_compute_instance_group_manager" "a-master-us-test1-a-minimal-gc list_managed_instances_results = "PAGINATED" name = "a-master-us-test1-a-minimal-gce-example-com" target_size = 1 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.master-us-test1-a-minimal-gce-example-com.self_link } @@ -476,6 +480,10 @@ resource "google_compute_instance_group_manager" "a-nodes-minimal-gce-example-co list_managed_instances_results = "PAGINATED" name = "a-nodes-minimal-gce-example-com" target_size = 2 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.nodes-minimal-gce-example-com.self_link } diff --git a/tests/integration/update_cluster/minimal_gce_ilb/kubernetes.tf b/tests/integration/update_cluster/minimal_gce_ilb/kubernetes.tf index 6bdbbb70f54b1..71fbc6d562edb 100644 --- a/tests/integration/update_cluster/minimal_gce_ilb/kubernetes.tf +++ b/tests/integration/update_cluster/minimal_gce_ilb/kubernetes.tf @@ -434,6 +434,10 @@ resource "google_compute_instance_group_manager" "a-master-us-test1-a-minimal-gc list_managed_instances_results = "PAGINATED" name = "a-master-us-test1-a-minimal-gce-ilb-example-com" target_size = 1 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.master-us-test1-a-minimal-gce-ilb-example-com.self_link } @@ -445,6 +449,10 @@ resource "google_compute_instance_group_manager" "a-nodes-minimal-gce-ilb-exampl list_managed_instances_results = "PAGINATED" name = "a-nodes-minimal-gce-ilb-example-com" target_size = 2 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.nodes-minimal-gce-ilb-example-com.self_link } diff --git a/tests/integration/update_cluster/minimal_gce_ilb_longclustername/kubernetes.tf b/tests/integration/update_cluster/minimal_gce_ilb_longclustername/kubernetes.tf index a9b1189818fe6..1ca57d8767e9b 100644 --- a/tests/integration/update_cluster/minimal_gce_ilb_longclustername/kubernetes.tf +++ b/tests/integration/update_cluster/minimal_gce_ilb_longclustername/kubernetes.tf @@ -434,6 +434,10 @@ resource "google_compute_instance_group_manager" "a-master-us-test1-a-minimal-gc list_managed_instances_results = "PAGINATED" name = "a-master-us-test1-a-minimal-gce-with-a-very-very-very-ve-j0fh8f" target_size = 1 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.master-us-test1-a-minimal-gce-with-a-very-very-very-very-very-long-name-example-com.self_link } @@ -445,6 +449,10 @@ resource "google_compute_instance_group_manager" "a-nodes-minimal-gce-with-a-ver list_managed_instances_results = "PAGINATED" name = "a-nodes-minimal-gce-with-a-very-very-very-very-very-long-qk78uj" target_size = 2 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.nodes-minimal-gce-with-a-very-very-very-very-very-long-name-example-com.self_link } diff --git a/tests/integration/update_cluster/minimal_gce_longclustername/kubernetes.tf b/tests/integration/update_cluster/minimal_gce_longclustername/kubernetes.tf index 5e1e295480597..ded566e6bdd2b 100644 --- a/tests/integration/update_cluster/minimal_gce_longclustername/kubernetes.tf +++ b/tests/integration/update_cluster/minimal_gce_longclustername/kubernetes.tf @@ -401,6 +401,10 @@ resource "google_compute_instance_group_manager" "a-master-us-test1-a-minimal-gc list_managed_instances_results = "PAGINATED" name = "a-master-us-test1-a-minimal-gce-with-a-very-very-very-ve-j0fh8f" target_size = 1 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.master-us-test1-a-minimal-gce-with-a-very-very-very-very-very-long-name-example-com.self_link } @@ -412,6 +416,10 @@ resource "google_compute_instance_group_manager" "a-nodes-minimal-gce-with-a-ver list_managed_instances_results = "PAGINATED" name = "a-nodes-minimal-gce-with-a-very-very-very-very-very-long-qk78uj" target_size = 2 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.nodes-minimal-gce-with-a-very-very-very-very-very-long-name-example-com.self_link } diff --git a/tests/integration/update_cluster/minimal_gce_plb/kubernetes.tf b/tests/integration/update_cluster/minimal_gce_plb/kubernetes.tf index d7d78780aea6d..4db3c772a5655 100644 --- a/tests/integration/update_cluster/minimal_gce_plb/kubernetes.tf +++ b/tests/integration/update_cluster/minimal_gce_plb/kubernetes.tf @@ -458,6 +458,10 @@ resource "google_compute_instance_group_manager" "a-master-us-test1-a-minimal-gc name = "a-master-us-test1-a-minimal-gce-plb-example-com" target_pools = [google_compute_target_pool.api-minimal-gce-plb-example-com.self_link] target_size = 1 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.master-us-test1-a-minimal-gce-plb-example-com.self_link } @@ -469,6 +473,10 @@ resource "google_compute_instance_group_manager" "a-nodes-minimal-gce-plb-exampl list_managed_instances_results = "PAGINATED" name = "a-nodes-minimal-gce-plb-example-com" target_size = 2 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.nodes-minimal-gce-plb-example-com.self_link } diff --git a/tests/integration/update_cluster/minimal_gce_private/kubernetes.tf b/tests/integration/update_cluster/minimal_gce_private/kubernetes.tf index fb1ce6c5bb1de..f4da3ef3624b8 100644 --- a/tests/integration/update_cluster/minimal_gce_private/kubernetes.tf +++ b/tests/integration/update_cluster/minimal_gce_private/kubernetes.tf @@ -401,6 +401,10 @@ resource "google_compute_instance_group_manager" "a-master-us-test1-a-minimal-gc list_managed_instances_results = "PAGINATED" name = "a-master-us-test1-a-minimal-gce-private-example-com" target_size = 1 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.master-us-test1-a-minimal-gce-private-example-com.self_link } @@ -412,6 +416,10 @@ resource "google_compute_instance_group_manager" "a-nodes-minimal-gce-private-ex list_managed_instances_results = "PAGINATED" name = "a-nodes-minimal-gce-private-example-com" target_size = 2 + update_policy { + minimal_action = "REPLACE" + type = "OPPORTUNISTIC" + } version { instance_template = google_compute_instance_template.nodes-minimal-gce-private-example-com.self_link } diff --git a/upup/pkg/fi/cloudup/gcetasks/instancegroupmanager.go b/upup/pkg/fi/cloudup/gcetasks/instancegroupmanager.go index 8788992a2eb3d..300f01cb0e543 100644 --- a/upup/pkg/fi/cloudup/gcetasks/instancegroupmanager.go +++ b/upup/pkg/fi/cloudup/gcetasks/instancegroupmanager.go @@ -37,6 +37,7 @@ type InstanceGroupManager struct { InstanceTemplate *InstanceTemplate ListManagedInstancesResults string TargetSize *int64 + UpdatePolicy *UpdatePolicy TargetPools []*TargetPool } @@ -66,6 +67,10 @@ func (e *InstanceGroupManager) Find(c *fi.CloudupContext) (*InstanceGroupManager actual.InstanceTemplate = &InstanceTemplate{ID: fi.PtrTo(lastComponent(r.InstanceTemplate))} actual.ListManagedInstancesResults = r.ListManagedInstancesResults + if policy := r.UpdatePolicy; policy != nil { + actual.UpdatePolicy = &UpdatePolicy{MinimalAction: policy.MinimalAction, Type: policy.Type} + } + for _, targetPool := range r.TargetPools { actual.TargetPools = append(actual.TargetPools, &TargetPool{ Name: fi.PtrTo(lastComponent(targetPool)), @@ -104,6 +109,13 @@ func (_ *InstanceGroupManager) RenderGCE(t *gce.GCEAPITarget, a, e, changes *Ins ListManagedInstancesResults: e.ListManagedInstancesResults, } + if policy := e.UpdatePolicy; policy != nil { + i.UpdatePolicy = &compute.InstanceGroupManagerUpdatePolicy{ + MinimalAction: policy.MinimalAction, + Type: policy.Type, + } + } + for _, targetPool := range e.TargetPools { i.TargetPools = append(i.TargetPools, targetPool.URL(t.Cloud)) } @@ -181,9 +193,15 @@ type terraformInstanceGroupManager struct { ListManagedInstancesResults string `cty:"list_managed_instances_results"` Version *terraformVersion `cty:"version"` TargetSize *int64 `cty:"target_size"` + UpdatePolicy *terraformUpdatePolicy `cty:"update_policy"` TargetPools []*terraformWriter.Literal `cty:"target_pools"` } +type terraformUpdatePolicy struct { + MinimalAction string `cty:"minimal_action"` + Type string `cty:"type"` +} + type terraformVersion struct { InstanceTemplate *terraformWriter.Literal `cty:"instance_template"` } @@ -196,6 +214,12 @@ func (_ *InstanceGroupManager) RenderTerraform(t *terraform.TerraformTarget, a, TargetSize: e.TargetSize, ListManagedInstancesResults: e.ListManagedInstancesResults, } + if policy := e.UpdatePolicy; policy != nil { + tf.UpdatePolicy = &terraformUpdatePolicy{ + MinimalAction: policy.MinimalAction, + Type: policy.Type, + } + } tf.Version = &terraformVersion{ InstanceTemplate: e.InstanceTemplate.TerraformLink(), } diff --git a/upup/pkg/fi/cloudup/gcetasks/updatepolicy.go b/upup/pkg/fi/cloudup/gcetasks/updatepolicy.go new file mode 100644 index 0000000000000..8a65f9395e1ca --- /dev/null +++ b/upup/pkg/fi/cloudup/gcetasks/updatepolicy.go @@ -0,0 +1,31 @@ +/* +Copyright 2025 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package gcetasks + +import "k8s.io/kops/upup/pkg/fi" + +// UpdatePolicy represents a GCE instance group manager UpdatePolicy +type UpdatePolicy struct { + MinimalAction string + Type string +} + +var _ fi.CloudupHasDependencies = &UpdatePolicy{} + +func (_ *UpdatePolicy) GetDependencies(tasks map[string]fi.CloudupTask) []fi.CloudupTask { + return nil +}