From 7d9db03b03b0098a537fc1c38ecd14d0f5e0b8a7 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 30 Oct 2025 12:24:49 -0700 Subject: [PATCH] CORS-4220: pass dualstack cluster and service cidrs as comma-separated lists kube-controller-manager expects the dualstack cluster and service CIDRs to be passed as comma-separated list arguments [0]. This ensures the dualstack cluster and service cidrs are indeed passed as comma-separated lists. References [0] https://kubernetes.io/docs/concepts/services-networking/dual-stack/#configure-ipv4-ipv6-dual-stack --- .../config/bootstrap-config-overrides.yaml | 14 +++++++------- .../network/observe_network.go | 3 ++- .../network/observe_networking_test.go | 18 +++++++++++++++++- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/bindata/bootkube/config/bootstrap-config-overrides.yaml b/bindata/bootkube/config/bootstrap-config-overrides.yaml index 0d63d08f6..139c927cd 100644 --- a/bindata/bootkube/config/bootstrap-config-overrides.yaml +++ b/bindata/bootkube/config/bootstrap-config-overrides.yaml @@ -13,17 +13,17 @@ extendedArguments: - "/etc/kubernetes/secrets/kubeconfig" authorization-kubeconfig: - "/etc/kubernetes/secrets/kubeconfig" - {{if .ClusterCIDR }} - cluster-cidr: {{range .ClusterCIDR}} - - {{.}}{{end}} + {{if .ClusterCIDR | len }} + cluster-cidr: + - {{index .ClusterCIDR 0}}{{if gt (.ClusterCIDR | len) 1}},{{index .ClusterCIDR 1}}{{end}} {{end}} - {{if .ServiceClusterIPRange }} - service-cluster-ip-range: {{range .ServiceClusterIPRange}} - - {{.}}{{end}} + {{if .ServiceClusterIPRange | len }} + service-cluster-ip-range: + - {{index .ServiceClusterIPRange 0}}{{if gt (.ServiceClusterIPRange | len) 1}},{{index .ServiceClusterIPRange 1}}{{end}} {{end}} pv-recycler-pod-template-filepath-nfs: # bootstrap KCM doesn't need recycler templates - "" pv-recycler-pod-template-filepath-hostpath: - "" feature-gates: {{range .FeatureGates}} - - {{.}}{{end}} \ No newline at end of file + - {{.}}{{end}} diff --git a/pkg/operator/configobservation/network/observe_network.go b/pkg/operator/configobservation/network/observe_network.go index d059e0c75..1cb5d2fce 100644 --- a/pkg/operator/configobservation/network/observe_network.go +++ b/pkg/operator/configobservation/network/observe_network.go @@ -36,7 +36,8 @@ func ObserveClusterCIDRs(genericListers configobserver.Listers, recorder events. } if len(clusterCIDRs) > 0 { - if err := unstructured.SetNestedStringSlice(observedConfig, clusterCIDRs, clusterCIDRsPath...); err != nil { + clusterIPRange := strings.Join(clusterCIDRs, ",") + if err := unstructured.SetNestedStringSlice(observedConfig, []string{clusterIPRange}, clusterCIDRsPath...); err != nil { errs = append(errs, err) } } diff --git a/pkg/operator/configobservation/network/observe_networking_test.go b/pkg/operator/configobservation/network/observe_networking_test.go index 507f1c7dd..84865831b 100644 --- a/pkg/operator/configobservation/network/observe_networking_test.go +++ b/pkg/operator/configobservation/network/observe_networking_test.go @@ -25,6 +25,22 @@ func TestObserveClusterCIDRs(t *testing.T) { expectedError bool } tests := []Test{ + { + "single cluster network", + &configv1.Network{ + ObjectMeta: metav1.ObjectMeta{Name: "cluster"}, + Status: configv1.NetworkStatus{ClusterNetwork: []configv1.ClusterNetworkEntry{ + {CIDR: "podCIDR"}, + }}, + }, + map[string]interface{}{}, + map[string]interface{}{ + "extendedArguments": map[string]interface{}{ + "cluster-cidr": []interface{}{"podCIDR"}, + }, + }, + false, + }, { "clusterNetworks", &configv1.Network{ @@ -37,7 +53,7 @@ func TestObserveClusterCIDRs(t *testing.T) { map[string]interface{}{ "extendedArguments": map[string]interface{}{ "cluster-cidr": []interface{}{ - "podCIDR1", "podCIDR2", + "podCIDR1,podCIDR2", }, }, },