From c934bb87e85ef1b5f665d10f75ed81caec3f1e48 Mon Sep 17 00:00:00 2001 From: Stefan Bueringer Date: Thu, 15 May 2025 08:31:59 +0200 Subject: [PATCH] Remove IPFamily from public APIs (move to CAPD/kind util) --- .golangci-kal.yml | 2 +- .golangci.yml | 4 - api/v1beta2/cluster_types.go | 88 -------- api/v1beta2/cluster_types_test.go | 197 ------------------ .../cluster-class/write-clusterclass.md | 3 +- .../topologymutation_variable_types.go | 6 - .../api/v1alpha1/zz_generated.openapi.go | 7 - .../cluster/patches/variables/variables.go | 26 +-- .../patches/variables/variables_test.go | 12 +- internal/webhooks/patch_validation.go | 1 - test/framework/bootstrap/kind_provider.go | 11 +- test/framework/bootstrap/kind_util.go | 5 +- test/infrastructure/container/docker.go | 3 +- test/infrastructure/container/interface.go | 88 +++++++- .../container/interface_test.go | 176 ++++++++++++++++ .../docker/internal/docker/loadbalancer.go | 21 +- .../docker/internal/docker/machine.go | 22 +- .../docker/internal/docker/manager.go | 9 +- .../docker/internal/docker/manager_test.go | 9 +- 19 files changed, 312 insertions(+), 378 deletions(-) delete mode 100644 api/v1beta2/cluster_types_test.go diff --git a/.golangci-kal.yml b/.golangci-kal.yml index a8ab84cb6676..21144217372f 100644 --- a/.golangci-kal.yml +++ b/.golangci-kal.yml @@ -63,7 +63,7 @@ linters: text: "Conditions field must be a slice of metav1.Condition" linters: - kubeapilinter - - path: "api/v1beta2/*|api/v1beta1/*" + - path: "api/v1beta1/*" text: "type ClusterIPFamily should not use an int, int8 or int16. Use int32 or int64 depending on bounding requirements" linters: - kubeapilinter diff --git a/.golangci.yml b/.golangci.yml index 997567c07f92..80d2f5be2d35 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -239,10 +239,6 @@ linters: - linters: - staticcheck text: 'SA1019: (bootstrapv1.ClusterStatus|KubeadmConfigSpec.UseExperimentalRetryJoin|scope.Config.Spec.UseExperimentalRetryJoin|DockerMachine.Spec.Bootstrapped|machineStatus.Bootstrapped|dockerMachine.Spec.Backend.Docker.Bootstrapped|dockerMachine.Spec.Bootstrapped|devMachine.Spec.Backend.Docker.Bootstrapped|c.TopologyPlan|clusterv1.ClusterClassVariableMetadata|clusterv1beta1.ClusterClassVariableMetadata|(variable|currentDefinition|specVar|newVariableDefinition|statusVarDefinition).Metadata) is deprecated' - # Deprecations forGetIPFamily - - linters: - - staticcheck - text: 'SA1019: cluster.GetIPFamily is deprecated: IPFamily is not a concept in Kubernetes. It was originally introduced in CAPI for CAPD. IPFamily will be dropped in a future release. More details at https://github.com/kubernetes-sigs/cluster-api/issues/7521' # Deprecations for MD revision management - linters: - staticcheck diff --git a/api/v1beta2/cluster_types.go b/api/v1beta2/cluster_types.go index c48ff2f8e36e..53acfa8ae78a 100644 --- a/api/v1beta2/cluster_types.go +++ b/api/v1beta2/cluster_types.go @@ -22,7 +22,6 @@ import ( "net" "strings" - "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -1222,93 +1221,6 @@ func (c *Cluster) SetConditions(conditions []metav1.Condition) { c.Status.Conditions = conditions } -// GetIPFamily returns a ClusterIPFamily from the configuration provided. -// -// Deprecated: IPFamily is not a concept in Kubernetes. It was originally introduced in CAPI for CAPD. -// IPFamily will be dropped in a future release. More details at https://github.com/kubernetes-sigs/cluster-api/issues/7521 -func (c *Cluster) GetIPFamily() (ClusterIPFamily, error) { - var podCIDRs, serviceCIDRs []string - if c.Spec.ClusterNetwork != nil { - if c.Spec.ClusterNetwork.Pods != nil { - podCIDRs = c.Spec.ClusterNetwork.Pods.CIDRBlocks - } - if c.Spec.ClusterNetwork.Services != nil { - serviceCIDRs = c.Spec.ClusterNetwork.Services.CIDRBlocks - } - } - if len(podCIDRs) == 0 && len(serviceCIDRs) == 0 { - return IPv4IPFamily, nil - } - - podsIPFamily, err := ipFamilyForCIDRStrings(podCIDRs) - if err != nil { - return InvalidIPFamily, fmt.Errorf("pods: %s", err) - } - if len(serviceCIDRs) == 0 { - return podsIPFamily, nil - } - - servicesIPFamily, err := ipFamilyForCIDRStrings(serviceCIDRs) - if err != nil { - return InvalidIPFamily, fmt.Errorf("services: %s", err) - } - if len(podCIDRs) == 0 { - return servicesIPFamily, nil - } - - if podsIPFamily == DualStackIPFamily { - return DualStackIPFamily, nil - } else if podsIPFamily != servicesIPFamily { - return InvalidIPFamily, errors.New("pods and services IP family mismatch") - } - - return podsIPFamily, nil -} - -func ipFamilyForCIDRStrings(cidrs []string) (ClusterIPFamily, error) { - if len(cidrs) > 2 { - return InvalidIPFamily, errors.New("too many CIDRs specified") - } - var foundIPv4 bool - var foundIPv6 bool - for _, cidr := range cidrs { - ip, _, err := net.ParseCIDR(cidr) - if err != nil { - return InvalidIPFamily, fmt.Errorf("could not parse CIDR: %s", err) - } - if ip.To4() != nil { - foundIPv4 = true - } else { - foundIPv6 = true - } - } - switch { - case foundIPv4 && foundIPv6: - return DualStackIPFamily, nil - case foundIPv4: - return IPv4IPFamily, nil - case foundIPv6: - return IPv6IPFamily, nil - default: - return InvalidIPFamily, nil - } -} - -// ClusterIPFamily defines the types of supported IP families. -type ClusterIPFamily int - -// Define the ClusterIPFamily constants. -const ( - InvalidIPFamily ClusterIPFamily = iota - IPv4IPFamily - IPv6IPFamily - DualStackIPFamily -) - -func (f ClusterIPFamily) String() string { - return [...]string{"InvalidIPFamily", "IPv4IPFamily", "IPv6IPFamily", "DualStackIPFamily"}[f] -} - // +kubebuilder:object:root=true // ClusterList contains a list of Cluster. diff --git a/api/v1beta2/cluster_types_test.go b/api/v1beta2/cluster_types_test.go deleted file mode 100644 index 29d27c80307b..000000000000 --- a/api/v1beta2/cluster_types_test.go +++ /dev/null @@ -1,197 +0,0 @@ -/* -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 v1beta2 - -import ( - "testing" - - . "github.com/onsi/gomega" -) - -func TestClusterIPFamily(t *testing.T) { - clusterWithNetwork := func(podCIDRs, serviceCIDRs []string) *Cluster { - return &Cluster{ - Spec: ClusterSpec{ - ClusterNetwork: &ClusterNetwork{ - Pods: &NetworkRanges{ - CIDRBlocks: podCIDRs, - }, - Services: &NetworkRanges{ - CIDRBlocks: serviceCIDRs, - }, - }, - }, - } - } - - validAndUnambiguous := []struct { - name string - expectRes ClusterIPFamily - c *Cluster - }{ - { - name: "pods: ipv4, services: ipv4", - expectRes: IPv4IPFamily, - c: clusterWithNetwork([]string{"192.168.0.0/16"}, []string{"10.128.0.0/12"}), - }, - { - name: "pods: ipv4, services: nil", - expectRes: IPv4IPFamily, - c: clusterWithNetwork([]string{"192.168.0.0/16"}, nil), - }, - { - name: "pods: ipv6, services: nil", - expectRes: IPv6IPFamily, - c: clusterWithNetwork([]string{"fd00:100:96::/48"}, nil), - }, - { - name: "pods: ipv6, services: ipv6", - expectRes: IPv6IPFamily, - c: clusterWithNetwork([]string{"fd00:100:96::/48"}, []string{"fd00:100:64::/108"}), - }, - { - name: "pods: dual-stack, services: nil", - expectRes: DualStackIPFamily, - c: clusterWithNetwork([]string{"192.168.0.0/16", "fd00:100:96::/48"}, nil), - }, - { - name: "pods: dual-stack, services: ipv4", - expectRes: DualStackIPFamily, - c: clusterWithNetwork([]string{"192.168.0.0/16", "fd00:100:96::/48"}, []string{"10.128.0.0/12"}), - }, - { - name: "pods: dual-stack, services: ipv6", - expectRes: DualStackIPFamily, - c: clusterWithNetwork([]string{"192.168.0.0/16", "fd00:100:96::/48"}, []string{"fd00:100:64::/108"}), - }, - { - name: "pods: dual-stack, services: dual-stack", - expectRes: DualStackIPFamily, - c: clusterWithNetwork([]string{"192.168.0.0/16", "fd00:100:96::/48"}, []string{"10.128.0.0/12", "fd00:100:64::/108"}), - }, - { - name: "pods: nil, services: dual-stack", - expectRes: DualStackIPFamily, - c: clusterWithNetwork(nil, []string{"10.128.0.0/12", "fd00:100:64::/108"}), - }, - } - - for _, tt := range validAndUnambiguous { - t.Run(tt.name, func(t *testing.T) { - g := NewWithT(t) - ipFamily, err := tt.c.GetIPFamily() - g.Expect(ipFamily).To(Equal(tt.expectRes)) - g.Expect(err).ToNot(HaveOccurred()) - }) - } - - validButAmbiguous := []struct { - name string - expectRes ClusterIPFamily - c *Cluster - }{ - { - name: "pods: nil, services: nil", - // this could be ipv4, ipv6, or dual-stack; assume ipv4 for now though - expectRes: IPv4IPFamily, - c: clusterWithNetwork(nil, nil), - }, - { - name: "pods: nil, services: ipv4", - // this could be a dual-stack; assume ipv4 for now though - expectRes: IPv4IPFamily, - c: clusterWithNetwork(nil, []string{"10.128.0.0/12"}), - }, - { - name: "pods: nil, services: ipv6", - // this could be dual-stack; assume ipv6 for now though - expectRes: IPv6IPFamily, - c: clusterWithNetwork(nil, []string{"fd00:100:64::/108"}), - }, - } - - for _, tt := range validButAmbiguous { - t.Run(tt.name, func(t *testing.T) { - g := NewWithT(t) - ipFamily, err := tt.c.GetIPFamily() - g.Expect(ipFamily).To(Equal(tt.expectRes)) - g.Expect(err).ToNot(HaveOccurred()) - }) - } - - invalid := []struct { - name string - expectErr string - c *Cluster - }{ - { - name: "pods: ipv4, services: ipv6", - expectErr: "pods and services IP family mismatch", - c: clusterWithNetwork([]string{"192.168.0.0/16"}, []string{"fd00:100:64::/108"}), - }, - { - name: "pods: ipv6, services: ipv4", - expectErr: "pods and services IP family mismatch", - c: clusterWithNetwork([]string{"fd00:100:96::/48"}, []string{"10.128.0.0/12"}), - }, - { - name: "pods: ipv6, services: dual-stack", - expectErr: "pods and services IP family mismatch", - c: clusterWithNetwork([]string{"fd00:100:96::/48"}, []string{"10.128.0.0/12", "fd00:100:64::/108"}), - }, - { - name: "pods: ipv4, services: dual-stack", - expectErr: "pods and services IP family mismatch", - c: clusterWithNetwork([]string{"192.168.0.0/16"}, []string{"10.128.0.0/12", "fd00:100:64::/108"}), - }, - { - name: "pods: ipv4, services: dual-stack", - expectErr: "pods and services IP family mismatch", - c: clusterWithNetwork([]string{"192.168.0.0/16"}, []string{"10.128.0.0/12", "fd00:100:64::/108"}), - }, - { - name: "pods: bad cidr", - expectErr: "pods: could not parse CIDR", - c: clusterWithNetwork([]string{"foo"}, nil), - }, - { - name: "services: bad cidr", - expectErr: "services: could not parse CIDR", - c: clusterWithNetwork([]string{"192.168.0.0/16"}, []string{"foo"}), - }, - { - name: "pods: too many cidrs", - expectErr: "pods: too many CIDRs specified", - c: clusterWithNetwork([]string{"192.168.0.0/16", "fd00:100:96::/48", "10.128.0.0/12"}, nil), - }, - { - name: "services: too many cidrs", - expectErr: "services: too many CIDRs specified", - c: clusterWithNetwork(nil, []string{"192.168.0.0/16", "fd00:100:96::/48", "10.128.0.0/12"}), - }, - } - - for _, tt := range invalid { - t.Run(tt.name, func(t *testing.T) { - g := NewWithT(t) - ipFamily, err := tt.c.GetIPFamily() - g.Expect(err).To(HaveOccurred()) - g.Expect(err).To(MatchError(ContainSubstring(tt.expectErr))) - g.Expect(ipFamily).To(Equal(InvalidIPFamily)) - }) - } -} diff --git a/docs/book/src/tasks/experimental-features/cluster-class/write-clusterclass.md b/docs/book/src/tasks/experimental-features/cluster-class/write-clusterclass.md index 341cfabb40be..861bc2de080b 100644 --- a/docs/book/src/tasks/experimental-features/cluster-class/write-clusterclass.md +++ b/docs/book/src/tasks/experimental-features/cluster-class/write-clusterclass.md @@ -610,8 +610,7 @@ In addition to variables specified in the ClusterClass, the following builtin va referenced in patches: - `builtin.cluster.{name,namespace,uid,metadata.labels,metadata.annotations}` - `builtin.cluster.topology.{version,class,classNamespace}` -- `builtin.cluster.network.{serviceDomain,services,pods,ipFamily}` - - Note: ipFamily is deprecated and will be removed in a future release. see https://github.com/kubernetes-sigs/cluster-api/issues/7521. +- `builtin.cluster.network.{serviceDomain,services,pods}` - `builtin.controlPlane.{replicas,version,name,metadata.labels,metadata.annotations}` - Please note, these variables are only available when patching control plane or control plane machine templates. diff --git a/exp/runtime/hooks/api/v1alpha1/topologymutation_variable_types.go b/exp/runtime/hooks/api/v1alpha1/topologymutation_variable_types.go index 2f4dc7ae85b1..4b953c6ab003 100644 --- a/exp/runtime/hooks/api/v1alpha1/topologymutation_variable_types.go +++ b/exp/runtime/hooks/api/v1alpha1/topologymutation_variable_types.go @@ -96,12 +96,6 @@ type ClusterNetworkBuiltins struct { // pods is the network ranges from which Pod networks are allocated. // +optional Pods []string `json:"pods,omitempty"` - // ipFamily is the IPFamily the Cluster is operating in. One of Invalid, IPv4, IPv6, DualStack. - // - // Deprecated: IPFamily is not a concept in Kubernetes. It was originally introduced in CAPI for CAPD. - // IPFamily will be dropped in a future release. More details at https://github.com/kubernetes-sigs/cluster-api/issues/7521 - // +optional - IPFamily string `json:"ipFamily,omitempty"` } // ControlPlaneBuiltins represents builtin ControlPlane variables. diff --git a/exp/runtime/hooks/api/v1alpha1/zz_generated.openapi.go b/exp/runtime/hooks/api/v1alpha1/zz_generated.openapi.go index b0c1176a9b1f..ba27fd1b5ba0 100644 --- a/exp/runtime/hooks/api/v1alpha1/zz_generated.openapi.go +++ b/exp/runtime/hooks/api/v1alpha1/zz_generated.openapi.go @@ -856,13 +856,6 @@ func schema_runtime_hooks_api_v1alpha1_ClusterNetworkBuiltins(ref common.Referen }, }, }, - "ipFamily": { - SchemaProps: spec.SchemaProps{ - Description: "ipFamily is the IPFamily the Cluster is operating in. One of Invalid, IPv4, IPv6, DualStack.\n\nDeprecated: IPFamily is not a concept in Kubernetes. It was originally introduced in CAPI for CAPD. IPFamily will be dropped in a future release. More details at https://github.com/kubernetes-sigs/cluster-api/issues/7521", - Type: []string{"string"}, - Format: "", - }, - }, }, }, }, diff --git a/internal/controllers/topology/cluster/patches/variables/variables.go b/internal/controllers/topology/cluster/patches/variables/variables.go index 594b81fcb994..cdf054c57c97 100644 --- a/internal/controllers/topology/cluster/patches/variables/variables.go +++ b/internal/controllers/topology/cluster/patches/variables/variables.go @@ -69,17 +69,22 @@ func Global(clusterTopology *clusterv1.Topology, cluster *clusterv1.Cluster, pat } } if cluster.Spec.ClusterNetwork != nil { - clusterNetworkIPFamily, _ := cluster.GetIPFamily() - builtin.Cluster.Network = &runtimehooksv1.ClusterNetworkBuiltins{ - IPFamily: ipFamilyToString(clusterNetworkIPFamily), - } if cluster.Spec.ClusterNetwork.ServiceDomain != "" { + if builtin.Cluster.Network == nil { + builtin.Cluster.Network = &runtimehooksv1.ClusterNetworkBuiltins{} + } builtin.Cluster.Network.ServiceDomain = &cluster.Spec.ClusterNetwork.ServiceDomain } if cluster.Spec.ClusterNetwork.Services != nil && cluster.Spec.ClusterNetwork.Services.CIDRBlocks != nil { + if builtin.Cluster.Network == nil { + builtin.Cluster.Network = &runtimehooksv1.ClusterNetworkBuiltins{} + } builtin.Cluster.Network.Services = cluster.Spec.ClusterNetwork.Services.CIDRBlocks } if cluster.Spec.ClusterNetwork.Pods != nil && cluster.Spec.ClusterNetwork.Pods.CIDRBlocks != nil { + if builtin.Cluster.Network == nil { + builtin.Cluster.Network = &runtimehooksv1.ClusterNetworkBuiltins{} + } builtin.Cluster.Network.Pods = cluster.Spec.ClusterNetwork.Pods.CIDRBlocks } } @@ -280,16 +285,3 @@ func toVariable(name string, value interface{}) (*runtimehooksv1.Variable, error Value: apiextensionsv1.JSON{Raw: marshalledValue}, }, nil } - -func ipFamilyToString(ipFamily clusterv1.ClusterIPFamily) string { - switch ipFamily { - case clusterv1.DualStackIPFamily: - return "DualStack" - case clusterv1.IPv4IPFamily: - return "IPv4" - case clusterv1.IPv6IPFamily: - return "IPv6" - default: - return "Invalid" - } -} diff --git a/internal/controllers/topology/cluster/patches/variables/variables_test.go b/internal/controllers/topology/cluster/patches/variables/variables_test.go index 35646e255a1d..ce2c48db1242 100644 --- a/internal/controllers/topology/cluster/patches/variables/variables_test.go +++ b/internal/controllers/topology/cluster/patches/variables/variables_test.go @@ -113,8 +113,7 @@ func TestGlobal(t *testing.T) { "network":{ "serviceDomain":"cluster.local", "services":["10.10.10.1/24"], - "pods":["11.10.10.1/24"], - "ipFamily": "IPv4" + "pods":["11.10.10.1/24"] } }}`), }, @@ -186,8 +185,7 @@ func TestGlobal(t *testing.T) { "network":{ "serviceDomain":"cluster.local", "services":["10.10.10.1/24"], - "pods":["11.10.10.1/24"], - "ipFamily": "IPv4" + "pods":["11.10.10.1/24"] } }}`), }, @@ -258,8 +256,7 @@ func TestGlobal(t *testing.T) { }, "network":{ "services":["10.10.10.1/24"], - "pods":["11.10.10.1/24"], - "ipFamily": "IPv4" + "pods":["11.10.10.1/24"] } }}`), }, @@ -326,8 +323,7 @@ func TestGlobal(t *testing.T) { "classNamespace": "default" }, "network":{ - "serviceDomain":"cluster.local", - "ipFamily": "IPv4" + "serviceDomain":"cluster.local" } }}`), }, diff --git a/internal/webhooks/patch_validation.go b/internal/webhooks/patch_validation.go index edc67742aebc..dfc80de69448 100644 --- a/internal/webhooks/patch_validation.go +++ b/internal/webhooks/patch_validation.go @@ -486,7 +486,6 @@ var builtinVariables = sets.Set[string]{}.Insert( "builtin.cluster.network.serviceDomain", "builtin.cluster.network.services", "builtin.cluster.network.pods", - "builtin.cluster.network.ipFamily", // ControlPlane builtins. "builtin.controlPlane", diff --git a/test/framework/bootstrap/kind_provider.go b/test/framework/bootstrap/kind_provider.go index 30219408ba82..91d81d33378e 100644 --- a/test/framework/bootstrap/kind_provider.go +++ b/test/framework/bootstrap/kind_provider.go @@ -28,7 +28,6 @@ import ( "sigs.k8s.io/kind/pkg/cmd" "sigs.k8s.io/kind/pkg/exec" - clusterv1 "sigs.k8s.io/cluster-api/api/v1beta2" "sigs.k8s.io/cluster-api/test/framework/internal/log" ) @@ -70,7 +69,7 @@ func WithDockerSockMount() KindClusterOption { // the new kind cluster. func WithIPv6Family() KindClusterOption { return kindClusterOptionAdapter(func(k *KindClusterProvider) { - k.ipFamily = clusterv1.IPv6IPFamily + k.ipFamily = kindv1.IPv6Family }) } @@ -78,7 +77,7 @@ func WithIPv6Family() KindClusterOption { // the new kind cluster. func WithDualStackFamily() KindClusterOption { return kindClusterOptionAdapter(func(k *KindClusterProvider) { - k.ipFamily = clusterv1.DualStackIPFamily + k.ipFamily = kindv1.DualStackFamily }) } @@ -115,7 +114,7 @@ type KindClusterProvider struct { withDockerSock bool kubeconfigPath string nodeImage string - ipFamily clusterv1.ClusterIPFamily + ipFamily kindv1.ClusterIPFamily logFolder string extraPortMappings []kindv1.PortMapping } @@ -155,10 +154,10 @@ func (k *KindClusterProvider) createKindCluster() { }, } - if k.ipFamily == clusterv1.IPv6IPFamily { + if k.ipFamily == kindv1.IPv6Family { cfg.Networking.IPFamily = kindv1.IPv6Family } - if k.ipFamily == clusterv1.DualStackIPFamily { + if k.ipFamily == kindv1.DualStackFamily { cfg.Networking.IPFamily = kindv1.DualStackFamily } kindv1.SetDefaultsCluster(cfg) diff --git a/test/framework/bootstrap/kind_util.go b/test/framework/bootstrap/kind_util.go index e60e587cccd7..faeb70b93ecb 100644 --- a/test/framework/bootstrap/kind_util.go +++ b/test/framework/bootstrap/kind_util.go @@ -20,6 +20,7 @@ import ( "context" "os" "path/filepath" + "strings" "github.com/blang/semver/v4" . "github.com/onsi/gomega" @@ -84,10 +85,10 @@ func CreateKindBootstrapClusterAndLoadImages(ctx context.Context, input CreateKi if input.RequiresDockerSock { options = append(options, WithDockerSockMount()) } - if input.IPFamily == "IPv6" { + if strings.EqualFold(input.IPFamily, string(kindv1.IPv6Family)) { options = append(options, WithIPv6Family()) } - if input.IPFamily == "dual" { + if strings.EqualFold(input.IPFamily, string(kindv1.DualStackFamily)) { options = append(options, WithDualStackFamily()) } if input.LogFolder != "" { diff --git a/test/infrastructure/container/docker.go b/test/infrastructure/container/docker.go index e19c9837f4d2..6eae6c27d467 100644 --- a/test/infrastructure/container/docker.go +++ b/test/infrastructure/container/docker.go @@ -42,7 +42,6 @@ import ( kerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/utils/ptr" - clusterv1 "sigs.k8s.io/cluster-api/api/v1beta2" "sigs.k8s.io/cluster-api/test/infrastructure/kind" ) @@ -416,7 +415,7 @@ func (d *dockerRuntime) RunContainer(ctx context.Context, runConfig *RunContaine hostConfig.CgroupnsMode = "private" } - if runConfig.IPFamily == clusterv1.IPv6IPFamily || runConfig.IPFamily == clusterv1.DualStackIPFamily { + if runConfig.IPFamily == IPv6IPFamily || runConfig.IPFamily == DualStackIPFamily { hostConfig.Sysctls = map[string]string{ "net.ipv6.conf.all.disable_ipv6": "0", "net.ipv6.conf.all.forwarding": "1", diff --git a/test/infrastructure/container/interface.go b/test/infrastructure/container/interface.go index d5561569281a..2a840ade5b52 100644 --- a/test/infrastructure/container/interface.go +++ b/test/infrastructure/container/interface.go @@ -20,8 +20,10 @@ import ( "context" "fmt" "io" + "net" dockercontainer "github.com/docker/docker/api/types/container" + "github.com/pkg/errors" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta2" "sigs.k8s.io/cluster-api/test/infrastructure/kind" @@ -97,7 +99,7 @@ type RunContainerInput struct { // PortMappings contains host<>container ports to map. PortMappings []PortMapping // IPFamily is the IP version to use. - IPFamily clusterv1.ClusterIPFamily + IPFamily ClusterIPFamily // RestartPolicy to use for the container. // If not set, defaults to RestartPolicyUnlessStopped. RestartPolicy dockercontainer.RestartPolicyMode @@ -157,3 +159,87 @@ func RuntimeFrom(ctx context.Context) (Runtime, error) { func RuntimeInto(ctx context.Context, runtime Runtime) context.Context { return context.WithValue(ctx, providerKey{}, runtime) } + +// GetClusterIPFamily returns a ClusterIPFamily based on the Cluster provided. +func GetClusterIPFamily(c *clusterv1.Cluster) (ClusterIPFamily, error) { + var podCIDRs, serviceCIDRs []string + if c.Spec.ClusterNetwork != nil { + if c.Spec.ClusterNetwork.Pods != nil { + podCIDRs = c.Spec.ClusterNetwork.Pods.CIDRBlocks + } + if c.Spec.ClusterNetwork.Services != nil { + serviceCIDRs = c.Spec.ClusterNetwork.Services.CIDRBlocks + } + } + if len(podCIDRs) == 0 && len(serviceCIDRs) == 0 { + return IPv4IPFamily, nil + } + + podsIPFamily, err := ipFamilyForCIDRStrings(podCIDRs) + if err != nil { + return InvalidIPFamily, fmt.Errorf("pods: %s", err) + } + if len(serviceCIDRs) == 0 { + return podsIPFamily, nil + } + + servicesIPFamily, err := ipFamilyForCIDRStrings(serviceCIDRs) + if err != nil { + return InvalidIPFamily, fmt.Errorf("services: %s", err) + } + if len(podCIDRs) == 0 { + return servicesIPFamily, nil + } + + if podsIPFamily == DualStackIPFamily { + return DualStackIPFamily, nil + } else if podsIPFamily != servicesIPFamily { + return InvalidIPFamily, errors.New("pods and services IP family mismatch") + } + + return podsIPFamily, nil +} + +func ipFamilyForCIDRStrings(cidrs []string) (ClusterIPFamily, error) { + if len(cidrs) > 2 { + return InvalidIPFamily, errors.New("too many CIDRs specified") + } + var foundIPv4 bool + var foundIPv6 bool + for _, cidr := range cidrs { + ip, _, err := net.ParseCIDR(cidr) + if err != nil { + return InvalidIPFamily, fmt.Errorf("could not parse CIDR: %s", err) + } + if ip.To4() != nil { + foundIPv4 = true + } else { + foundIPv6 = true + } + } + switch { + case foundIPv4 && foundIPv6: + return DualStackIPFamily, nil + case foundIPv4: + return IPv4IPFamily, nil + case foundIPv6: + return IPv6IPFamily, nil + default: + return InvalidIPFamily, nil + } +} + +// ClusterIPFamily defines the types of supported IP families. +type ClusterIPFamily int + +// Define the ClusterIPFamily constants. +const ( + InvalidIPFamily ClusterIPFamily = iota + IPv4IPFamily + IPv6IPFamily + DualStackIPFamily +) + +func (f ClusterIPFamily) String() string { + return [...]string{"InvalidIPFamily", "IPv4IPFamily", "IPv6IPFamily", "DualStackIPFamily"}[f] +} diff --git a/test/infrastructure/container/interface_test.go b/test/infrastructure/container/interface_test.go index aba3484a2696..ae1cb89d4c29 100644 --- a/test/infrastructure/container/interface_test.go +++ b/test/infrastructure/container/interface_test.go @@ -21,6 +21,8 @@ import ( "testing" . "github.com/onsi/gomega" + + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta2" ) func TestFilterBuildKeyValue(t *testing.T) { @@ -70,3 +72,177 @@ func TestInvalidContext(t *testing.T) { _, err := RuntimeFrom(context.Background()) g.Expect(err).Should(HaveOccurred()) } + +func TestGetClusterIPFamily(t *testing.T) { + clusterWithNetwork := func(podCIDRs, serviceCIDRs []string) *clusterv1.Cluster { + return &clusterv1.Cluster{ + Spec: clusterv1.ClusterSpec{ + ClusterNetwork: &clusterv1.ClusterNetwork{ + Pods: &clusterv1.NetworkRanges{ + CIDRBlocks: podCIDRs, + }, + Services: &clusterv1.NetworkRanges{ + CIDRBlocks: serviceCIDRs, + }, + }, + }, + } + } + + validAndUnambiguous := []struct { + name string + expectRes ClusterIPFamily + c *clusterv1.Cluster + }{ + { + name: "pods: ipv4, services: ipv4", + expectRes: IPv4IPFamily, + c: clusterWithNetwork([]string{"192.168.0.0/16"}, []string{"10.128.0.0/12"}), + }, + { + name: "pods: ipv4, services: nil", + expectRes: IPv4IPFamily, + c: clusterWithNetwork([]string{"192.168.0.0/16"}, nil), + }, + { + name: "pods: ipv6, services: nil", + expectRes: IPv6IPFamily, + c: clusterWithNetwork([]string{"fd00:100:96::/48"}, nil), + }, + { + name: "pods: ipv6, services: ipv6", + expectRes: IPv6IPFamily, + c: clusterWithNetwork([]string{"fd00:100:96::/48"}, []string{"fd00:100:64::/108"}), + }, + { + name: "pods: dual-stack, services: nil", + expectRes: DualStackIPFamily, + c: clusterWithNetwork([]string{"192.168.0.0/16", "fd00:100:96::/48"}, nil), + }, + { + name: "pods: dual-stack, services: ipv4", + expectRes: DualStackIPFamily, + c: clusterWithNetwork([]string{"192.168.0.0/16", "fd00:100:96::/48"}, []string{"10.128.0.0/12"}), + }, + { + name: "pods: dual-stack, services: ipv6", + expectRes: DualStackIPFamily, + c: clusterWithNetwork([]string{"192.168.0.0/16", "fd00:100:96::/48"}, []string{"fd00:100:64::/108"}), + }, + { + name: "pods: dual-stack, services: dual-stack", + expectRes: DualStackIPFamily, + c: clusterWithNetwork([]string{"192.168.0.0/16", "fd00:100:96::/48"}, []string{"10.128.0.0/12", "fd00:100:64::/108"}), + }, + { + name: "pods: nil, services: dual-stack", + expectRes: DualStackIPFamily, + c: clusterWithNetwork(nil, []string{"10.128.0.0/12", "fd00:100:64::/108"}), + }, + } + + for _, tt := range validAndUnambiguous { + t.Run(tt.name, func(t *testing.T) { + g := NewWithT(t) + ipFamily, err := GetClusterIPFamily(tt.c) + g.Expect(ipFamily).To(Equal(tt.expectRes)) + g.Expect(err).ToNot(HaveOccurred()) + }) + } + + validButAmbiguous := []struct { + name string + expectRes ClusterIPFamily + c *clusterv1.Cluster + }{ + { + name: "pods: nil, services: nil", + // this could be ipv4, ipv6, or dual-stack; assume ipv4 for now though + expectRes: IPv4IPFamily, + c: clusterWithNetwork(nil, nil), + }, + { + name: "pods: nil, services: ipv4", + // this could be a dual-stack; assume ipv4 for now though + expectRes: IPv4IPFamily, + c: clusterWithNetwork(nil, []string{"10.128.0.0/12"}), + }, + { + name: "pods: nil, services: ipv6", + // this could be dual-stack; assume ipv6 for now though + expectRes: IPv6IPFamily, + c: clusterWithNetwork(nil, []string{"fd00:100:64::/108"}), + }, + } + + for _, tt := range validButAmbiguous { + t.Run(tt.name, func(t *testing.T) { + g := NewWithT(t) + ipFamily, err := GetClusterIPFamily(tt.c) + g.Expect(ipFamily).To(Equal(tt.expectRes)) + g.Expect(err).ToNot(HaveOccurred()) + }) + } + + invalid := []struct { + name string + expectErr string + c *clusterv1.Cluster + }{ + { + name: "pods: ipv4, services: ipv6", + expectErr: "pods and services IP family mismatch", + c: clusterWithNetwork([]string{"192.168.0.0/16"}, []string{"fd00:100:64::/108"}), + }, + { + name: "pods: ipv6, services: ipv4", + expectErr: "pods and services IP family mismatch", + c: clusterWithNetwork([]string{"fd00:100:96::/48"}, []string{"10.128.0.0/12"}), + }, + { + name: "pods: ipv6, services: dual-stack", + expectErr: "pods and services IP family mismatch", + c: clusterWithNetwork([]string{"fd00:100:96::/48"}, []string{"10.128.0.0/12", "fd00:100:64::/108"}), + }, + { + name: "pods: ipv4, services: dual-stack", + expectErr: "pods and services IP family mismatch", + c: clusterWithNetwork([]string{"192.168.0.0/16"}, []string{"10.128.0.0/12", "fd00:100:64::/108"}), + }, + { + name: "pods: ipv4, services: dual-stack", + expectErr: "pods and services IP family mismatch", + c: clusterWithNetwork([]string{"192.168.0.0/16"}, []string{"10.128.0.0/12", "fd00:100:64::/108"}), + }, + { + name: "pods: bad cidr", + expectErr: "pods: could not parse CIDR", + c: clusterWithNetwork([]string{"foo"}, nil), + }, + { + name: "services: bad cidr", + expectErr: "services: could not parse CIDR", + c: clusterWithNetwork([]string{"192.168.0.0/16"}, []string{"foo"}), + }, + { + name: "pods: too many cidrs", + expectErr: "pods: too many CIDRs specified", + c: clusterWithNetwork([]string{"192.168.0.0/16", "fd00:100:96::/48", "10.128.0.0/12"}, nil), + }, + { + name: "services: too many cidrs", + expectErr: "services: too many CIDRs specified", + c: clusterWithNetwork(nil, []string{"192.168.0.0/16", "fd00:100:96::/48", "10.128.0.0/12"}), + }, + } + + for _, tt := range invalid { + t.Run(tt.name, func(t *testing.T) { + g := NewWithT(t) + ipFamily, err := GetClusterIPFamily(tt.c) + g.Expect(err).To(HaveOccurred()) + g.Expect(err).To(MatchError(ContainSubstring(tt.expectErr))) + g.Expect(ipFamily).To(Equal(InvalidIPFamily)) + }) + } +} diff --git a/test/infrastructure/docker/internal/docker/loadbalancer.go b/test/infrastructure/docker/internal/docker/loadbalancer.go index 2c825cd4341a..c94b3b277892 100644 --- a/test/infrastructure/docker/internal/docker/loadbalancer.go +++ b/test/infrastructure/docker/internal/docker/loadbalancer.go @@ -31,7 +31,7 @@ import ( ) type lbCreator interface { - CreateExternalLoadBalancerNode(ctx context.Context, name, image, clusterName, listenAddress string, port int32, ipFamily clusterv1.ClusterIPFamily) (*types.Node, error) + CreateExternalLoadBalancerNode(ctx context.Context, name, image, clusterName, listenAddress string, port int32, ipFamily container.ClusterIPFamily) (*types.Node, error) } // LoadBalancer manages the load balancer for a specific docker cluster. @@ -39,7 +39,7 @@ type LoadBalancer struct { name string image string container *types.Node - ipFamily clusterv1.ClusterIPFamily + ipFamily container.ClusterIPFamily lbCreator lbCreator backendControlPlanePort string frontendControlPlanePort string @@ -58,15 +58,12 @@ func NewLoadBalancer(ctx context.Context, cluster *clusterv1.Cluster, imageRepos filters.AddKeyNameValue(filterLabel, clusterLabelKey, cluster.Name) filters.AddKeyNameValue(filterLabel, nodeRoleLabelKey, constants.ExternalLoadBalancerNodeRoleValue) - container, err := getContainer(ctx, filters) + c, err := getContainer(ctx, filters) if err != nil { return nil, err } - // We tolerate this until removal; - // after removal IPFamily will become an internal CAPD concept. - // See https://github.com/kubernetes-sigs/cluster-api/issues/7521. - ipFamily, err := cluster.GetIPFamily() + ipFamily, err := container.GetClusterIPFamily(cluster) if err != nil { return nil, fmt.Errorf("create load balancer: %s", err) } @@ -80,7 +77,7 @@ func NewLoadBalancer(ctx context.Context, cluster *clusterv1.Cluster, imageRepos return &LoadBalancer{ name: cluster.Name, image: image, - container: container, + container: c, ipFamily: ipFamily, lbCreator: &Manager{}, frontendControlPlanePort: frontendControlPlanePort, @@ -112,7 +109,7 @@ func (s *LoadBalancer) Create(ctx context.Context) error { log = log.WithValues("ipFamily", s.ipFamily, "loadbalancer", s.name) listenAddr := "0.0.0.0" - if s.ipFamily == clusterv1.IPv6IPFamily { + if s.ipFamily == container.IPv6IPFamily { listenAddr = "::" } // Create if not exists. @@ -148,7 +145,7 @@ func (s *LoadBalancer) UpdateConfiguration(ctx context.Context, weights map[stri FrontendControlPlanePort: s.frontendControlPlanePort, BackendControlPlanePort: s.backendControlPlanePort, BackendServers: map[string]loadbalancer.BackendServer{}, - IPv6: s.ipFamily == clusterv1.IPv6IPFamily, + IPv6: s.ipFamily == container.IPv6IPFamily, } // collect info about the existing controlplane nodes @@ -167,7 +164,7 @@ func (s *LoadBalancer) UpdateConfiguration(ctx context.Context, weights map[stri if err != nil { return errors.Wrapf(err, "failed to get IP for container %s", n.String()) } - if s.ipFamily == clusterv1.IPv6IPFamily { + if s.ipFamily == container.IPv6IPFamily { backendServer.Address = controlPlaneIPv6 } else { backendServer.Address = controlPlaneIPv4 @@ -216,7 +213,7 @@ func (s *LoadBalancer) IP(ctx context.Context) (string, error) { return "", errors.WithStack(err) } var lbIP string - if s.ipFamily == clusterv1.IPv6IPFamily { + if s.ipFamily == container.IPv6IPFamily { lbIP = lbIPv6 } else { lbIP = lbIPv4 diff --git a/test/infrastructure/docker/internal/docker/machine.go b/test/infrastructure/docker/internal/docker/machine.go index c6b66eb084cd..481e060ab9f2 100644 --- a/test/infrastructure/docker/internal/docker/machine.go +++ b/test/infrastructure/docker/internal/docker/machine.go @@ -55,15 +55,15 @@ var ( ) type nodeCreator interface { - CreateControlPlaneNode(ctx context.Context, name, clusterName, listenAddress string, port int32, mounts []v1alpha4.Mount, portMappings []v1alpha4.PortMapping, labels map[string]string, ipFamily clusterv1.ClusterIPFamily, kindMapping kind.Mapping) (node *types.Node, err error) - CreateWorkerNode(ctx context.Context, name, clusterName string, mounts []v1alpha4.Mount, portMappings []v1alpha4.PortMapping, labels map[string]string, ipFamily clusterv1.ClusterIPFamily, kindMapping kind.Mapping) (node *types.Node, err error) + CreateControlPlaneNode(ctx context.Context, name, clusterName, listenAddress string, port int32, mounts []v1alpha4.Mount, portMappings []v1alpha4.PortMapping, labels map[string]string, ipFamily container.ClusterIPFamily, kindMapping kind.Mapping) (node *types.Node, err error) + CreateWorkerNode(ctx context.Context, name, clusterName string, mounts []v1alpha4.Mount, portMappings []v1alpha4.PortMapping, labels map[string]string, ipFamily container.ClusterIPFamily, kindMapping kind.Mapping) (node *types.Node, err error) } // Machine implement a service for managing the docker containers hosting a kubernetes nodes. type Machine struct { cluster string machine string - ipFamily clusterv1.ClusterIPFamily + ipFamily container.ClusterIPFamily container *types.Node nodeCreator nodeCreator } @@ -92,10 +92,7 @@ func NewMachine(ctx context.Context, cluster *clusterv1.Cluster, machine string, return nil, err } - // We tolerate this until removal; - // after removal IPFamily will become an internal CAPD concept. - // See https://github.com/kubernetes-sigs/cluster-api/issues/7521. - ipFamily, err := cluster.GetIPFamily() + ipFamily, err := container.GetClusterIPFamily(cluster) if err != nil { return nil, fmt.Errorf("create docker machine: %s", err) } @@ -129,10 +126,7 @@ func ListMachinesByCluster(ctx context.Context, cluster *clusterv1.Cluster, labe return nil, err } - // We tolerate this until removal; - // after removal IPFamily will become an internal CAPD concept. - // See https://github.com/kubernetes-sigs/cluster-api/issues/7521 . - ipFamily, err := cluster.GetIPFamily() + ipFamily, err := container.GetClusterIPFamily(cluster) if err != nil { return nil, fmt.Errorf("list docker machines by cluster: %s", err) } @@ -187,11 +181,11 @@ func (m *Machine) Address(ctx context.Context) ([]string, error) { return nil, err } switch m.ipFamily { - case clusterv1.IPv6IPFamily: + case container.IPv6IPFamily: return []string{ipv6}, nil - case clusterv1.IPv4IPFamily: + case container.IPv4IPFamily: return []string{ipv4}, nil - case clusterv1.DualStackIPFamily: + case container.DualStackIPFamily: return []string{ipv4, ipv6}, nil } return nil, errors.New("unknown ipFamily") diff --git a/test/infrastructure/docker/internal/docker/manager.go b/test/infrastructure/docker/internal/docker/manager.go index 32bb637a6115..4c365c9e7ea1 100644 --- a/test/infrastructure/docker/internal/docker/manager.go +++ b/test/infrastructure/docker/internal/docker/manager.go @@ -24,7 +24,6 @@ import ( "sigs.k8s.io/kind/pkg/apis/config/v1alpha4" "sigs.k8s.io/kind/pkg/cluster/constants" - clusterv1 "sigs.k8s.io/cluster-api/api/v1beta2" "sigs.k8s.io/cluster-api/test/infrastructure/container" "sigs.k8s.io/cluster-api/test/infrastructure/docker/internal/docker/types" "sigs.k8s.io/cluster-api/test/infrastructure/kind" @@ -56,14 +55,14 @@ type nodeCreateOpts struct { Mounts []v1alpha4.Mount PortMappings []v1alpha4.PortMapping Labels map[string]string - IPFamily clusterv1.ClusterIPFamily + IPFamily container.ClusterIPFamily KindMapping kind.Mapping } // CreateControlPlaneNode will create a new control plane container. // NOTE: If port is 0 picking a host port for the control plane is delegated to the container runtime and is not stable across container restarts. // This means that connection to a control plane node may take some time to recover if the underlying container is restarted. -func (m *Manager) CreateControlPlaneNode(ctx context.Context, name, clusterName, listenAddress string, port int32, mounts []v1alpha4.Mount, portMappings []v1alpha4.PortMapping, labels map[string]string, ipFamily clusterv1.ClusterIPFamily, kindMapping kind.Mapping) (*types.Node, error) { +func (m *Manager) CreateControlPlaneNode(ctx context.Context, name, clusterName, listenAddress string, port int32, mounts []v1alpha4.Mount, portMappings []v1alpha4.PortMapping, labels map[string]string, ipFamily container.ClusterIPFamily, kindMapping kind.Mapping) (*types.Node, error) { // add api server port mapping portMappingsWithAPIServer := append(portMappings, v1alpha4.PortMapping{ ListenAddress: listenAddress, @@ -90,7 +89,7 @@ func (m *Manager) CreateControlPlaneNode(ctx context.Context, name, clusterName, } // CreateWorkerNode will create a new worker container. -func (m *Manager) CreateWorkerNode(ctx context.Context, name, clusterName string, mounts []v1alpha4.Mount, portMappings []v1alpha4.PortMapping, labels map[string]string, ipFamily clusterv1.ClusterIPFamily, kindMapping kind.Mapping) (*types.Node, error) { +func (m *Manager) CreateWorkerNode(ctx context.Context, name, clusterName string, mounts []v1alpha4.Mount, portMappings []v1alpha4.PortMapping, labels map[string]string, ipFamily container.ClusterIPFamily, kindMapping kind.Mapping) (*types.Node, error) { createOpts := &nodeCreateOpts{ Name: name, ClusterName: clusterName, @@ -107,7 +106,7 @@ func (m *Manager) CreateWorkerNode(ctx context.Context, name, clusterName string // CreateExternalLoadBalancerNode will create a new container to act as the load balancer for external access. // NOTE: If port is 0 picking a host port for the load balancer is delegated to the container runtime and is not stable across container restarts. // This can break the Kubeconfig in kind, i.e. the file resulting from `kind get kubeconfig -n $CLUSTER_NAME' if the load balancer container is restarted. -func (m *Manager) CreateExternalLoadBalancerNode(ctx context.Context, name, image, clusterName, listenAddress string, port int32, _ clusterv1.ClusterIPFamily) (*types.Node, error) { +func (m *Manager) CreateExternalLoadBalancerNode(ctx context.Context, name, image, clusterName, listenAddress string, port int32, _ container.ClusterIPFamily) (*types.Node, error) { // load balancer port mapping portMappings := []v1alpha4.PortMapping{ { diff --git a/test/infrastructure/docker/internal/docker/manager_test.go b/test/infrastructure/docker/internal/docker/manager_test.go index 9cd5ea37660e..41215b9855ca 100644 --- a/test/infrastructure/docker/internal/docker/manager_test.go +++ b/test/infrastructure/docker/internal/docker/manager_test.go @@ -24,7 +24,6 @@ import ( "sigs.k8s.io/kind/pkg/apis/config/v1alpha4" "sigs.k8s.io/kind/pkg/cluster/constants" - clusterv1 "sigs.k8s.io/cluster-api/api/v1beta2" "sigs.k8s.io/cluster-api/test/infrastructure/container" "sigs.k8s.io/cluster-api/test/infrastructure/kind" ) @@ -49,7 +48,7 @@ func TestCreateNode(t *testing.T) { Role: constants.ControlPlaneNodeRoleValue, PortMappings: portMappingsWithAPIServer, Mounts: []v1alpha4.Mount{}, - IPFamily: clusterv1.IPv4IPFamily, + IPFamily: container.IPv4IPFamily, KindMapping: kind.Mapping{ Image: "TestImage", Mode: kind.ModeNone, // no impact on the fake runtime. @@ -80,7 +79,7 @@ func TestCreateControlPlaneNode(t *testing.T) { containerRuntime.ResetRunContainerCallLogs() m := Manager{} - node, err := m.CreateControlPlaneNode(ctx, "TestName", "TestCluster", "100.100.100.100", 80, []v1alpha4.Mount{}, []v1alpha4.PortMapping{}, make(map[string]string), clusterv1.IPv4IPFamily, kind.Mapping{Image: "TestImage"}) + node, err := m.CreateControlPlaneNode(ctx, "TestName", "TestCluster", "100.100.100.100", 80, []v1alpha4.Mount{}, []v1alpha4.PortMapping{}, make(map[string]string), container.IPv4IPFamily, kind.Mapping{Image: "TestImage"}) g.Expect(err).ShouldNot(HaveOccurred()) g.Expect(node.Role()).Should(Equal(constants.ControlPlaneNodeRoleValue)) @@ -103,7 +102,7 @@ func TestCreateWorkerNode(t *testing.T) { containerRuntime.ResetRunContainerCallLogs() m := Manager{} - node, err := m.CreateWorkerNode(ctx, "TestName", "TestCluster", []v1alpha4.Mount{}, []v1alpha4.PortMapping{}, make(map[string]string), clusterv1.IPv4IPFamily, kind.Mapping{Image: "TestImage"}) + node, err := m.CreateWorkerNode(ctx, "TestName", "TestCluster", []v1alpha4.Mount{}, []v1alpha4.PortMapping{}, make(map[string]string), container.IPv4IPFamily, kind.Mapping{Image: "TestImage"}) g.Expect(err).ShouldNot(HaveOccurred()) g.Expect(node.Role()).Should(Equal(constants.WorkerNodeRoleValue)) @@ -126,7 +125,7 @@ func TestCreateExternalLoadBalancerNode(t *testing.T) { containerRuntime.ResetRunContainerCallLogs() m := Manager{} - node, err := m.CreateExternalLoadBalancerNode(ctx, "TestName", "TestImage", "TestCluster", "100.100.100.100", 0, clusterv1.IPv4IPFamily) + node, err := m.CreateExternalLoadBalancerNode(ctx, "TestName", "TestImage", "TestCluster", "100.100.100.100", 0, container.IPv4IPFamily) g.Expect(err).ShouldNot(HaveOccurred()) g.Expect(node.Role()).Should(Equal(constants.ExternalLoadBalancerNodeRoleValue))