Merge pull request #119081 from sttts/sttts-public-ip-validation-move
kube-apiserver: move "public IP matches IP family" check to option validation
This commit is contained in:
		@@ -22,9 +22,13 @@ import (
 | 
				
			|||||||
	"net"
 | 
						"net"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						genericoptions "k8s.io/apiserver/pkg/server/options"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
						utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
	netutils "k8s.io/utils/net"
 | 
						netutils "k8s.io/utils/net"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						controlplaneapiserver "k8s.io/kubernetes/pkg/controlplane/apiserver/options"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/controlplane/reconcilers"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/features"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: Longer term we should read this from some config store, rather than a flag.
 | 
					// TODO: Longer term we should read this from some config store, rather than a flag.
 | 
				
			||||||
@@ -102,6 +106,25 @@ func validateServiceNodePort(options Extra) []error {
 | 
				
			|||||||
	return errs
 | 
						return errs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func validatePublicIPServiceClusterIPRangeIPFamilies(extra Extra, generic genericoptions.ServerRunOptions) []error {
 | 
				
			||||||
 | 
						// The "kubernetes.default" Service is SingleStack based on the configured ServiceIPRange.
 | 
				
			||||||
 | 
						// If the bootstrap controller reconcile the kubernetes.default Service and Endpoints, it must
 | 
				
			||||||
 | 
						// guarantee that the Service ClusterIPRepairConfig and the associated Endpoints have the same IP family, or
 | 
				
			||||||
 | 
						// it will not work for clients because of the IP family mismatch.
 | 
				
			||||||
 | 
						// TODO: revisit for dual-stack https://github.com/kubernetes/enhancements/issues/2438
 | 
				
			||||||
 | 
						if reconcilers.Type(extra.EndpointReconcilerType) != reconcilers.NoneEndpointReconcilerType {
 | 
				
			||||||
 | 
							serviceIPRange, _, err := controlplaneapiserver.ServiceIPRange(extra.PrimaryServiceClusterIPRange)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return []error{fmt.Errorf("error determining service IP ranges: %w", err)}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if netutils.IsIPv4CIDR(&serviceIPRange) != netutils.IsIPv4(generic.AdvertiseAddress) {
 | 
				
			||||||
 | 
								return []error{fmt.Errorf("service IP family %q must match public address family %q", extra.PrimaryServiceClusterIPRange.String(), generic.AdvertiseAddress.String())}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Validate checks ServerRunOptions and return a slice of found errs.
 | 
					// Validate checks ServerRunOptions and return a slice of found errs.
 | 
				
			||||||
func (s CompletedOptions) Validate() []error {
 | 
					func (s CompletedOptions) Validate() []error {
 | 
				
			||||||
	var errs []error
 | 
						var errs []error
 | 
				
			||||||
@@ -109,6 +132,7 @@ func (s CompletedOptions) Validate() []error {
 | 
				
			|||||||
	errs = append(errs, s.CompletedOptions.Validate()...)
 | 
						errs = append(errs, s.CompletedOptions.Validate()...)
 | 
				
			||||||
	errs = append(errs, validateClusterIPFlags(s.Extra)...)
 | 
						errs = append(errs, validateClusterIPFlags(s.Extra)...)
 | 
				
			||||||
	errs = append(errs, validateServiceNodePort(s.Extra)...)
 | 
						errs = append(errs, validateServiceNodePort(s.Extra)...)
 | 
				
			||||||
 | 
						errs = append(errs, validatePublicIPServiceClusterIPRangeIPFamilies(s.Extra, *s.GenericServerRunOptions)...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if s.MasterCount <= 0 {
 | 
						if s.MasterCount <= 0 {
 | 
				
			||||||
		errs = append(errs, fmt.Errorf("--apiserver-count should be a positive number, but value '%d' provided", s.MasterCount))
 | 
							errs = append(errs, fmt.Errorf("--apiserver-count should be a positive number, but value '%d' provided", s.MasterCount))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,10 +21,12 @@ import (
 | 
				
			|||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	utilnet "k8s.io/apimachinery/pkg/util/net"
 | 
						utilnet "k8s.io/apimachinery/pkg/util/net"
 | 
				
			||||||
 | 
						apiserveroptions "k8s.io/apiserver/pkg/server/options"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
						utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
				
			||||||
	featuregatetesting "k8s.io/component-base/featuregate/testing"
 | 
						featuregatetesting "k8s.io/component-base/featuregate/testing"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
	netutils "k8s.io/utils/net"
 | 
						netutils "k8s.io/utils/net"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/features"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func makeOptionsWithCIDRs(serviceCIDR string, secondaryServiceCIDR string) *ServerRunOptions {
 | 
					func makeOptionsWithCIDRs(serviceCIDR string, secondaryServiceCIDR string) *ServerRunOptions {
 | 
				
			||||||
@@ -155,6 +157,136 @@ func TestClusterServiceIPRange(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestValidatePublicIPServiceClusterIPRangeIPFamilies(t *testing.T) {
 | 
				
			||||||
 | 
						_, ipv4cidr, err := netutils.ParseCIDRSloppy("192.168.0.0/24")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("Unexpected error %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, ipv6cidr, err := netutils.ParseCIDRSloppy("2001:db8::/112")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("Unexpected error %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ipv4address := netutils.ParseIPSloppy("192.168.1.1")
 | 
				
			||||||
 | 
						ipv6address := netutils.ParseIPSloppy("2001:db8::1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							name    string
 | 
				
			||||||
 | 
							generic apiserveroptions.ServerRunOptions
 | 
				
			||||||
 | 
							extra   Extra
 | 
				
			||||||
 | 
							wantErr bool
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "master endpoint reconciler - IPv4 families",
 | 
				
			||||||
 | 
								extra: Extra{
 | 
				
			||||||
 | 
									EndpointReconcilerType:       "master-count",
 | 
				
			||||||
 | 
									PrimaryServiceClusterIPRange: *ipv4cidr,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								generic: apiserveroptions.ServerRunOptions{
 | 
				
			||||||
 | 
									AdvertiseAddress: ipv4address,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantErr: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "master endpoint reconciler - IPv6 families",
 | 
				
			||||||
 | 
								extra: Extra{
 | 
				
			||||||
 | 
									EndpointReconcilerType:       "master-count",
 | 
				
			||||||
 | 
									PrimaryServiceClusterIPRange: *ipv6cidr,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								generic: apiserveroptions.ServerRunOptions{
 | 
				
			||||||
 | 
									AdvertiseAddress: ipv6address,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantErr: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "master endpoint reconciler - wrong IP families",
 | 
				
			||||||
 | 
								extra: Extra{
 | 
				
			||||||
 | 
									EndpointReconcilerType:       "master-count",
 | 
				
			||||||
 | 
									PrimaryServiceClusterIPRange: *ipv4cidr,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								generic: apiserveroptions.ServerRunOptions{
 | 
				
			||||||
 | 
									AdvertiseAddress: ipv6address,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantErr: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "master endpoint reconciler - wrong IP families",
 | 
				
			||||||
 | 
								extra: Extra{
 | 
				
			||||||
 | 
									EndpointReconcilerType:       "master-count",
 | 
				
			||||||
 | 
									PrimaryServiceClusterIPRange: *ipv6cidr,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								generic: apiserveroptions.ServerRunOptions{
 | 
				
			||||||
 | 
									AdvertiseAddress: ipv4address,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantErr: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "lease endpoint reconciler - IPv4 families",
 | 
				
			||||||
 | 
								extra: Extra{
 | 
				
			||||||
 | 
									EndpointReconcilerType:       "lease",
 | 
				
			||||||
 | 
									PrimaryServiceClusterIPRange: *ipv4cidr,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								generic: apiserveroptions.ServerRunOptions{
 | 
				
			||||||
 | 
									AdvertiseAddress: ipv4address,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantErr: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "lease endpoint reconciler - IPv6 families",
 | 
				
			||||||
 | 
								extra: Extra{
 | 
				
			||||||
 | 
									EndpointReconcilerType:       "lease",
 | 
				
			||||||
 | 
									PrimaryServiceClusterIPRange: *ipv6cidr,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								generic: apiserveroptions.ServerRunOptions{
 | 
				
			||||||
 | 
									AdvertiseAddress: ipv6address,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantErr: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "lease endpoint reconciler - wrong IP families",
 | 
				
			||||||
 | 
								extra: Extra{
 | 
				
			||||||
 | 
									EndpointReconcilerType:       "lease",
 | 
				
			||||||
 | 
									PrimaryServiceClusterIPRange: *ipv4cidr,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								generic: apiserveroptions.ServerRunOptions{
 | 
				
			||||||
 | 
									AdvertiseAddress: ipv6address,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantErr: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "lease endpoint reconciler - wrong IP families",
 | 
				
			||||||
 | 
								extra: Extra{
 | 
				
			||||||
 | 
									EndpointReconcilerType:       "lease",
 | 
				
			||||||
 | 
									PrimaryServiceClusterIPRange: *ipv6cidr,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								generic: apiserveroptions.ServerRunOptions{
 | 
				
			||||||
 | 
									AdvertiseAddress: ipv4address,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantErr: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "none endpoint reconciler - wrong IP families",
 | 
				
			||||||
 | 
								extra: Extra{
 | 
				
			||||||
 | 
									EndpointReconcilerType:       "none",
 | 
				
			||||||
 | 
									PrimaryServiceClusterIPRange: *ipv4cidr,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								generic: apiserveroptions.ServerRunOptions{
 | 
				
			||||||
 | 
									AdvertiseAddress: ipv6address,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantErr: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, tt := range tests {
 | 
				
			||||||
 | 
							t.Run(tt.name, func(t *testing.T) {
 | 
				
			||||||
 | 
								errs := validatePublicIPServiceClusterIPRangeIPFamilies(tt.extra, tt.generic)
 | 
				
			||||||
 | 
								if (len(errs) > 0) != tt.wantErr {
 | 
				
			||||||
 | 
									t.Fatalf("completedConfig.New() errors = %+v, wantErr %v", errs, tt.wantErr)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getIPnetFromCIDR(cidr string) *net.IPNet {
 | 
					func getIPnetFromCIDR(cidr string) *net.IPNet {
 | 
				
			||||||
	_, ipnet, _ := netutils.ParseCIDRSloppy(cidr)
 | 
						_, ipnet, _ := netutils.ParseCIDRSloppy(cidr)
 | 
				
			||||||
	return ipnet
 | 
						return ipnet
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,176 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2014 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 controlplane
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	genericapiserver "k8s.io/apiserver/pkg/server"
 | 
					 | 
				
			||||||
	"k8s.io/client-go/kubernetes"
 | 
					 | 
				
			||||||
	netutils "k8s.io/utils/net"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/controlplane/reconcilers"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func Test_completedConfig_NewBootstrapController(t *testing.T) {
 | 
					 | 
				
			||||||
	_, ipv4cidr, err := netutils.ParseCIDRSloppy("192.168.0.0/24")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Fatalf("Unexpected error %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_, ipv6cidr, err := netutils.ParseCIDRSloppy("2001:db8::/112")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Fatalf("Unexpected error %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ipv4address := netutils.ParseIPSloppy("192.168.1.1")
 | 
					 | 
				
			||||||
	ipv6address := netutils.ParseIPSloppy("2001:db8::1")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	type args struct {
 | 
					 | 
				
			||||||
		client kubernetes.Interface
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	tests := []struct {
 | 
					 | 
				
			||||||
		name        string
 | 
					 | 
				
			||||||
		config      genericapiserver.Config
 | 
					 | 
				
			||||||
		extraConfig *ExtraConfig
 | 
					 | 
				
			||||||
		args        args
 | 
					 | 
				
			||||||
		wantErr     bool
 | 
					 | 
				
			||||||
	}{
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "master endpoint reconciler - IPv4 families",
 | 
					 | 
				
			||||||
			extraConfig: &ExtraConfig{
 | 
					 | 
				
			||||||
				EndpointReconcilerType: reconcilers.MasterCountReconcilerType,
 | 
					 | 
				
			||||||
				ServiceIPRange:         *ipv4cidr,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			config: genericapiserver.Config{
 | 
					 | 
				
			||||||
				PublicAddress: ipv4address,
 | 
					 | 
				
			||||||
				SecureServing: &genericapiserver.SecureServingInfo{Listener: fakeLocalhost443Listener{}},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			wantErr: false,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "master endpoint reconciler - IPv6 families",
 | 
					 | 
				
			||||||
			extraConfig: &ExtraConfig{
 | 
					 | 
				
			||||||
				EndpointReconcilerType: reconcilers.MasterCountReconcilerType,
 | 
					 | 
				
			||||||
				ServiceIPRange:         *ipv6cidr,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			config: genericapiserver.Config{
 | 
					 | 
				
			||||||
				PublicAddress: ipv6address,
 | 
					 | 
				
			||||||
				SecureServing: &genericapiserver.SecureServingInfo{Listener: fakeLocalhost443Listener{}},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			wantErr: false,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "master endpoint reconciler - wrong IP families",
 | 
					 | 
				
			||||||
			extraConfig: &ExtraConfig{
 | 
					 | 
				
			||||||
				EndpointReconcilerType: reconcilers.MasterCountReconcilerType,
 | 
					 | 
				
			||||||
				ServiceIPRange:         *ipv4cidr,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			config: genericapiserver.Config{
 | 
					 | 
				
			||||||
				PublicAddress: ipv6address,
 | 
					 | 
				
			||||||
				SecureServing: &genericapiserver.SecureServingInfo{Listener: fakeLocalhost443Listener{}},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			wantErr: true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "master endpoint reconciler - wrong IP families",
 | 
					 | 
				
			||||||
			extraConfig: &ExtraConfig{
 | 
					 | 
				
			||||||
				EndpointReconcilerType: reconcilers.MasterCountReconcilerType,
 | 
					 | 
				
			||||||
				ServiceIPRange:         *ipv6cidr,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			config: genericapiserver.Config{
 | 
					 | 
				
			||||||
				PublicAddress: ipv4address,
 | 
					 | 
				
			||||||
				SecureServing: &genericapiserver.SecureServingInfo{Listener: fakeLocalhost443Listener{}},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			wantErr: true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "lease endpoint reconciler - IPv4 families",
 | 
					 | 
				
			||||||
			extraConfig: &ExtraConfig{
 | 
					 | 
				
			||||||
				EndpointReconcilerType: reconcilers.LeaseEndpointReconcilerType,
 | 
					 | 
				
			||||||
				ServiceIPRange:         *ipv4cidr,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			config: genericapiserver.Config{
 | 
					 | 
				
			||||||
				PublicAddress: ipv4address,
 | 
					 | 
				
			||||||
				SecureServing: &genericapiserver.SecureServingInfo{Listener: fakeLocalhost443Listener{}},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			wantErr: false,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "lease endpoint reconciler - IPv6 families",
 | 
					 | 
				
			||||||
			extraConfig: &ExtraConfig{
 | 
					 | 
				
			||||||
				EndpointReconcilerType: reconcilers.LeaseEndpointReconcilerType,
 | 
					 | 
				
			||||||
				ServiceIPRange:         *ipv6cidr,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			config: genericapiserver.Config{
 | 
					 | 
				
			||||||
				PublicAddress: ipv6address,
 | 
					 | 
				
			||||||
				SecureServing: &genericapiserver.SecureServingInfo{Listener: fakeLocalhost443Listener{}},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			wantErr: false,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "lease endpoint reconciler - wrong IP families",
 | 
					 | 
				
			||||||
			extraConfig: &ExtraConfig{
 | 
					 | 
				
			||||||
				EndpointReconcilerType: reconcilers.LeaseEndpointReconcilerType,
 | 
					 | 
				
			||||||
				ServiceIPRange:         *ipv4cidr,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			config: genericapiserver.Config{
 | 
					 | 
				
			||||||
				PublicAddress: ipv6address,
 | 
					 | 
				
			||||||
				SecureServing: &genericapiserver.SecureServingInfo{Listener: fakeLocalhost443Listener{}},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			wantErr: true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "lease endpoint reconciler - wrong IP families",
 | 
					 | 
				
			||||||
			extraConfig: &ExtraConfig{
 | 
					 | 
				
			||||||
				EndpointReconcilerType: reconcilers.LeaseEndpointReconcilerType,
 | 
					 | 
				
			||||||
				ServiceIPRange:         *ipv6cidr,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			config: genericapiserver.Config{
 | 
					 | 
				
			||||||
				PublicAddress: ipv4address,
 | 
					 | 
				
			||||||
				SecureServing: &genericapiserver.SecureServingInfo{Listener: fakeLocalhost443Listener{}},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			wantErr: true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "none endpoint reconciler - wrong IP families",
 | 
					 | 
				
			||||||
			extraConfig: &ExtraConfig{
 | 
					 | 
				
			||||||
				EndpointReconcilerType: reconcilers.NoneEndpointReconcilerType,
 | 
					 | 
				
			||||||
				ServiceIPRange:         *ipv4cidr,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			config: genericapiserver.Config{
 | 
					 | 
				
			||||||
				PublicAddress: ipv6address,
 | 
					 | 
				
			||||||
				SecureServing: &genericapiserver.SecureServingInfo{Listener: fakeLocalhost443Listener{}},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			wantErr: false,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, tt := range tests {
 | 
					 | 
				
			||||||
		t.Run(tt.name, func(t *testing.T) {
 | 
					 | 
				
			||||||
			c := &completedConfig{
 | 
					 | 
				
			||||||
				GenericConfig: tt.config.Complete(nil),
 | 
					 | 
				
			||||||
				ExtraConfig:   tt.extraConfig,
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			_, err := c.newKubernetesServiceControllerConfig(tt.args.client)
 | 
					 | 
				
			||||||
			if (err != nil) != tt.wantErr {
 | 
					 | 
				
			||||||
				t.Errorf("completedConfig.NewBootstrapController() error = %v, wantErr %v", err, tt.wantErr)
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -89,7 +89,6 @@ import (
 | 
				
			|||||||
	"k8s.io/kubernetes/pkg/routes"
 | 
						"k8s.io/kubernetes/pkg/routes"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/serviceaccount"
 | 
						"k8s.io/kubernetes/pkg/serviceaccount"
 | 
				
			||||||
	"k8s.io/utils/clock"
 | 
						"k8s.io/utils/clock"
 | 
				
			||||||
	netutils "k8s.io/utils/net"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// RESTStorage installers
 | 
						// RESTStorage installers
 | 
				
			||||||
	admissionregistrationrest "k8s.io/kubernetes/pkg/registry/admissionregistration/rest"
 | 
						admissionregistrationrest "k8s.io/kubernetes/pkg/registry/admissionregistration/rest"
 | 
				
			||||||
@@ -631,17 +630,6 @@ func (c completedConfig) newKubernetesServiceControllerConfig(client kubernetes.
 | 
				
			|||||||
		return nil, fmt.Errorf("failed to get listener address: %w", err)
 | 
							return nil, fmt.Errorf("failed to get listener address: %w", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// The "kubernetes.default" Service is SingleStack based on the configured ServiceIPRange.
 | 
					 | 
				
			||||||
	// If the bootstrap controller reconcile the kubernetes.default Service and Endpoints, it must
 | 
					 | 
				
			||||||
	// guarantee that the Service ClusterIP and the associated Endpoints have the same IP family, or
 | 
					 | 
				
			||||||
	// it will not work for clients because of the IP family mismatch.
 | 
					 | 
				
			||||||
	// TODO: revisit for dual-stack https://github.com/kubernetes/enhancements/issues/2438
 | 
					 | 
				
			||||||
	if c.ExtraConfig.EndpointReconcilerType != reconcilers.NoneEndpointReconcilerType {
 | 
					 | 
				
			||||||
		if netutils.IsIPv4CIDR(&c.ExtraConfig.ServiceIPRange) != netutils.IsIPv4(c.GenericConfig.PublicAddress) {
 | 
					 | 
				
			||||||
			return nil, fmt.Errorf("service IP family %q must match public address family %q", c.ExtraConfig.ServiceIPRange.String(), c.GenericConfig.PublicAddress.String())
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &kubernetesservice.Config{
 | 
						return &kubernetesservice.Config{
 | 
				
			||||||
		Client:    client,
 | 
							Client:    client,
 | 
				
			||||||
		Informers: c.ExtraConfig.VersionedInformers,
 | 
							Informers: c.ExtraConfig.VersionedInformers,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user