mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #114155 from aojea/mirroring_repack
endpointslicemirroring handle endpoints with multiple subsets
This commit is contained in:
commit
2118bc8aec
@ -29,6 +29,7 @@ import (
|
|||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/client-go/tools/record"
|
"k8s.io/client-go/tools/record"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
endpointsv1 "k8s.io/kubernetes/pkg/api/v1/endpoints"
|
||||||
"k8s.io/kubernetes/pkg/controller/endpointslicemirroring/metrics"
|
"k8s.io/kubernetes/pkg/controller/endpointslicemirroring/metrics"
|
||||||
endpointutil "k8s.io/kubernetes/pkg/controller/util/endpoint"
|
endpointutil "k8s.io/kubernetes/pkg/controller/util/endpoint"
|
||||||
endpointsliceutil "k8s.io/kubernetes/pkg/controller/util/endpointslice"
|
endpointsliceutil "k8s.io/kubernetes/pkg/controller/util/endpointslice"
|
||||||
@ -68,7 +69,9 @@ func (r *reconciler) reconcile(endpoints *corev1.Endpoints, existingSlices []*di
|
|||||||
numInvalidAddresses := 0
|
numInvalidAddresses := 0
|
||||||
addressesSkipped := 0
|
addressesSkipped := 0
|
||||||
|
|
||||||
for _, subset := range endpoints.Subsets {
|
// canonicalize the Endpoints subsets before processing them
|
||||||
|
subsets := endpointsv1.RepackSubsets(endpoints.Subsets)
|
||||||
|
for _, subset := range subsets {
|
||||||
multiKey := d.initPorts(subset.Ports)
|
multiKey := d.initPorts(subset.Ports)
|
||||||
|
|
||||||
totalAddresses := len(subset.Addresses) + len(subset.NotReadyAddresses)
|
totalAddresses := len(subset.Addresses) + len(subset.NotReadyAddresses)
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
"k8s.io/client-go/kubernetes/scheme"
|
"k8s.io/client-go/kubernetes/scheme"
|
||||||
"k8s.io/client-go/tools/record"
|
"k8s.io/client-go/tools/record"
|
||||||
"k8s.io/component-base/metrics/testutil"
|
"k8s.io/component-base/metrics/testutil"
|
||||||
|
endpointsv1 "k8s.io/kubernetes/pkg/api/v1/endpoints"
|
||||||
"k8s.io/kubernetes/pkg/controller/endpointslicemirroring/metrics"
|
"k8s.io/kubernetes/pkg/controller/endpointslicemirroring/metrics"
|
||||||
endpointsliceutil "k8s.io/kubernetes/pkg/controller/util/endpointslice"
|
endpointsliceutil "k8s.io/kubernetes/pkg/controller/util/endpointslice"
|
||||||
"k8s.io/utils/pointer"
|
"k8s.io/utils/pointer"
|
||||||
@ -90,6 +91,102 @@ func TestReconcile(t *testing.T) {
|
|||||||
expectedNumSlices: 1,
|
expectedNumSlices: 1,
|
||||||
expectedClientActions: 1,
|
expectedClientActions: 1,
|
||||||
expectedMetrics: &expectedMetrics{desiredSlices: 1, actualSlices: 1, desiredEndpoints: 1, addedPerSync: 1, numCreated: 1},
|
expectedMetrics: &expectedMetrics{desiredSlices: 1, actualSlices: 1, desiredEndpoints: 1, addedPerSync: 1, numCreated: 1},
|
||||||
|
}, {
|
||||||
|
testName: "Endpoints with 2 subset, different port and address",
|
||||||
|
subsets: []corev1.EndpointSubset{
|
||||||
|
{
|
||||||
|
Ports: []corev1.EndpointPort{{
|
||||||
|
Name: "http",
|
||||||
|
Port: 80,
|
||||||
|
Protocol: corev1.ProtocolTCP,
|
||||||
|
}},
|
||||||
|
Addresses: []corev1.EndpointAddress{{
|
||||||
|
IP: "10.0.0.1",
|
||||||
|
Hostname: "pod-1",
|
||||||
|
NodeName: pointer.String("node-1"),
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Ports: []corev1.EndpointPort{{
|
||||||
|
Name: "https",
|
||||||
|
Port: 443,
|
||||||
|
Protocol: corev1.ProtocolTCP,
|
||||||
|
}},
|
||||||
|
Addresses: []corev1.EndpointAddress{{
|
||||||
|
IP: "10.0.0.2",
|
||||||
|
Hostname: "pod-2",
|
||||||
|
NodeName: pointer.String("node-1"),
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
existingEndpointSlices: []*discovery.EndpointSlice{},
|
||||||
|
expectedNumSlices: 2,
|
||||||
|
expectedClientActions: 2,
|
||||||
|
expectedMetrics: &expectedMetrics{desiredSlices: 2, actualSlices: 2, desiredEndpoints: 2, addedPerSync: 2, numCreated: 2},
|
||||||
|
}, {
|
||||||
|
testName: "Endpoints with 2 subset, different port and same address",
|
||||||
|
subsets: []corev1.EndpointSubset{
|
||||||
|
{
|
||||||
|
Ports: []corev1.EndpointPort{{
|
||||||
|
Name: "http",
|
||||||
|
Port: 80,
|
||||||
|
Protocol: corev1.ProtocolTCP,
|
||||||
|
}},
|
||||||
|
Addresses: []corev1.EndpointAddress{{
|
||||||
|
IP: "10.0.0.1",
|
||||||
|
Hostname: "pod-1",
|
||||||
|
NodeName: pointer.String("node-1"),
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Ports: []corev1.EndpointPort{{
|
||||||
|
Name: "https",
|
||||||
|
Port: 443,
|
||||||
|
Protocol: corev1.ProtocolTCP,
|
||||||
|
}},
|
||||||
|
Addresses: []corev1.EndpointAddress{{
|
||||||
|
IP: "10.0.0.1",
|
||||||
|
Hostname: "pod-1",
|
||||||
|
NodeName: pointer.String("node-1"),
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
existingEndpointSlices: []*discovery.EndpointSlice{},
|
||||||
|
expectedNumSlices: 1,
|
||||||
|
expectedClientActions: 1,
|
||||||
|
expectedMetrics: &expectedMetrics{desiredSlices: 1, actualSlices: 1, desiredEndpoints: 1, addedPerSync: 1, numCreated: 1},
|
||||||
|
}, {
|
||||||
|
testName: "Endpoints with 2 subset, different address and same port",
|
||||||
|
subsets: []corev1.EndpointSubset{
|
||||||
|
{
|
||||||
|
Ports: []corev1.EndpointPort{{
|
||||||
|
Name: "http",
|
||||||
|
Port: 80,
|
||||||
|
Protocol: corev1.ProtocolTCP,
|
||||||
|
}},
|
||||||
|
Addresses: []corev1.EndpointAddress{{
|
||||||
|
IP: "10.0.0.1",
|
||||||
|
Hostname: "pod-1",
|
||||||
|
NodeName: pointer.String("node-1"),
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Ports: []corev1.EndpointPort{{
|
||||||
|
Name: "http",
|
||||||
|
Port: 80,
|
||||||
|
Protocol: corev1.ProtocolTCP,
|
||||||
|
}},
|
||||||
|
Addresses: []corev1.EndpointAddress{{
|
||||||
|
IP: "10.0.0.2",
|
||||||
|
Hostname: "pod-2",
|
||||||
|
NodeName: pointer.String("node-1"),
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
existingEndpointSlices: []*discovery.EndpointSlice{},
|
||||||
|
expectedNumSlices: 1,
|
||||||
|
expectedClientActions: 1,
|
||||||
|
expectedMetrics: &expectedMetrics{desiredSlices: 1, actualSlices: 1, desiredEndpoints: 2, addedPerSync: 2, numCreated: 1},
|
||||||
}, {
|
}, {
|
||||||
testName: "Endpoints with 1 subset, port, and address, pending deletion",
|
testName: "Endpoints with 1 subset, port, and address, pending deletion",
|
||||||
subsets: []corev1.EndpointSubset{{
|
subsets: []corev1.EndpointSubset{{
|
||||||
@ -1015,7 +1112,10 @@ func expectEndpointSlices(t *testing.T, num, maxEndpointsPerSubset int, endpoint
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, epSubset := range endpoints.Subsets {
|
// canonicalize endpoints to match the expected endpoints, otherwise the test
|
||||||
|
// that creates more endpoints than allowed fail becaused the list of final
|
||||||
|
// endpoints doesn't match.
|
||||||
|
for _, epSubset := range endpointsv1.RepackSubsets(endpoints.Subsets) {
|
||||||
if len(epSubset.Addresses) == 0 && len(epSubset.NotReadyAddresses) == 0 {
|
if len(epSubset.Addresses) == 0 && len(epSubset.NotReadyAddresses) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ package network
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/onsi/ginkgo/v2"
|
"github.com/onsi/ginkgo/v2"
|
||||||
@ -28,6 +29,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
||||||
"k8s.io/kubernetes/test/e2e/network/common"
|
"k8s.io/kubernetes/test/e2e/network/common"
|
||||||
admissionapi "k8s.io/pod-security-admission/api"
|
admissionapi "k8s.io/pod-security-admission/api"
|
||||||
)
|
)
|
||||||
@ -199,4 +201,135 @@ var _ = common.SIGDescribe("EndpointSliceMirroring", func() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ginkgo.It("should mirror a custom Endpoint with multiple subsets and same IP address", func() {
|
||||||
|
ns := f.Namespace.Name
|
||||||
|
svc := createServiceReportErr(cs, f.Namespace.Name, &v1.Service{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "example-custom-endpoints",
|
||||||
|
},
|
||||||
|
Spec: v1.ServiceSpec{
|
||||||
|
Ports: []v1.ServicePort{
|
||||||
|
{
|
||||||
|
Name: "port80",
|
||||||
|
Port: 80,
|
||||||
|
Protocol: v1.ProtocolTCP,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "port81",
|
||||||
|
Port: 81,
|
||||||
|
Protocol: v1.ProtocolTCP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Add a backend pod to the service in the other node
|
||||||
|
port8080 := []v1.ContainerPort{
|
||||||
|
{
|
||||||
|
ContainerPort: 8090,
|
||||||
|
Protocol: v1.ProtocolTCP,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
port9090 := []v1.ContainerPort{
|
||||||
|
{
|
||||||
|
ContainerPort: 9090,
|
||||||
|
Protocol: v1.ProtocolTCP,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
serverPod := e2epod.NewAgnhostPodFromContainers(
|
||||||
|
"", "pod-handle-http-request", nil,
|
||||||
|
e2epod.NewAgnhostContainer("container-handle-8090-request", nil, port8080, "netexec", "--http-port", "8090", "--udp-port", "-1"),
|
||||||
|
e2epod.NewAgnhostContainer("container-handle-9090-request", nil, port9090, "netexec", "--http-port", "9090", "--udp-port", "-1"),
|
||||||
|
)
|
||||||
|
|
||||||
|
pod := e2epod.NewPodClient(f).CreateSync(serverPod)
|
||||||
|
|
||||||
|
if pod.Status.PodIP == "" {
|
||||||
|
framework.Failf("PodIP not assigned for pod %s", pod.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create custom endpoints
|
||||||
|
endpoints := &v1.Endpoints{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: svc.Name,
|
||||||
|
},
|
||||||
|
Subsets: []v1.EndpointSubset{
|
||||||
|
{
|
||||||
|
Ports: []v1.EndpointPort{{
|
||||||
|
Name: "port80",
|
||||||
|
Port: 8090,
|
||||||
|
}},
|
||||||
|
Addresses: []v1.EndpointAddress{{
|
||||||
|
IP: pod.Status.PodIP,
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Ports: []v1.EndpointPort{{
|
||||||
|
Name: "port81",
|
||||||
|
Port: 9090,
|
||||||
|
}},
|
||||||
|
Addresses: []v1.EndpointAddress{{
|
||||||
|
IP: pod.Status.PodIP,
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
ginkgo.By("mirroring a new custom Endpoint", func() {
|
||||||
|
_, err := cs.CoreV1().Endpoints(f.Namespace.Name).Create(context.TODO(), endpoints, metav1.CreateOptions{})
|
||||||
|
framework.ExpectNoError(err, "Unexpected error creating Endpoints")
|
||||||
|
|
||||||
|
if err := wait.PollImmediate(2*time.Second, 12*time.Second, func() (bool, error) {
|
||||||
|
esList, err := cs.DiscoveryV1().EndpointSlices(f.Namespace.Name).List(context.TODO(), metav1.ListOptions{
|
||||||
|
LabelSelector: discoveryv1.LabelServiceName + "=" + svc.Name,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
framework.Logf("Error listing EndpointSlices: %v", err)
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if len(esList.Items) == 0 {
|
||||||
|
framework.Logf("Waiting for at least 1 EndpointSlice to exist, got %d", len(esList.Items))
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}); err != nil {
|
||||||
|
framework.Failf("Did not find matching EndpointSlice for %s/%s: %s", svc.Namespace, svc.Name, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// connect to the service must work
|
||||||
|
ginkgo.By("Creating a pause pods that will try to connect to the webservers")
|
||||||
|
pausePod := e2epod.NewAgnhostPod(ns, "pause-pod-0", nil, nil, nil)
|
||||||
|
e2epod.NewPodClient(f).CreateSync(pausePod)
|
||||||
|
dest1 := net.JoinHostPort(svc.Spec.ClusterIP, "80")
|
||||||
|
dest2 := net.JoinHostPort(svc.Spec.ClusterIP, "81")
|
||||||
|
execHostnameTest(*pausePod, dest1, pod.Name)
|
||||||
|
execHostnameTest(*pausePod, dest2, pod.Name)
|
||||||
|
|
||||||
|
// delete custom endpoints and wait until the endpoint slices are deleted too
|
||||||
|
ginkgo.By("mirroring deletion of a custom Endpoint", func() {
|
||||||
|
err := cs.CoreV1().Endpoints(f.Namespace.Name).Delete(context.TODO(), endpoints.Name, metav1.DeleteOptions{})
|
||||||
|
framework.ExpectNoError(err, "Unexpected error deleting Endpoints")
|
||||||
|
|
||||||
|
// Expect mirrored EndpointSlice resource to be updated.
|
||||||
|
if err := wait.PollImmediate(2*time.Second, 12*time.Second, func() (bool, error) {
|
||||||
|
esList, err := cs.DiscoveryV1().EndpointSlices(f.Namespace.Name).List(context.TODO(), metav1.ListOptions{
|
||||||
|
LabelSelector: discoveryv1.LabelServiceName + "=" + svc.Name,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if len(esList.Items) != 0 {
|
||||||
|
framework.Logf("Waiting for 0 EndpointSlices to exist, got %d", len(esList.Items))
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}); err != nil {
|
||||||
|
framework.Failf("Did not find matching EndpointSlice for %s/%s: %s", svc.Namespace, svc.Name, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -86,7 +86,7 @@ func TestEndpointSliceMirroring(t *testing.T) {
|
|||||||
testName string
|
testName string
|
||||||
service *corev1.Service
|
service *corev1.Service
|
||||||
customEndpoints *corev1.Endpoints
|
customEndpoints *corev1.Endpoints
|
||||||
expectEndpointSlice bool
|
expectEndpointSlice int
|
||||||
expectEndpointSliceManagedBy string
|
expectEndpointSliceManagedBy string
|
||||||
}{{
|
}{{
|
||||||
testName: "Service with selector",
|
testName: "Service with selector",
|
||||||
@ -103,7 +103,7 @@ func TestEndpointSliceMirroring(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectEndpointSlice: true,
|
expectEndpointSlice: 1,
|
||||||
expectEndpointSliceManagedBy: "endpointslice-controller.k8s.io",
|
expectEndpointSliceManagedBy: "endpointslice-controller.k8s.io",
|
||||||
}, {
|
}, {
|
||||||
testName: "Service without selector",
|
testName: "Service without selector",
|
||||||
@ -130,7 +130,85 @@ func TestEndpointSliceMirroring(t *testing.T) {
|
|||||||
}},
|
}},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
expectEndpointSlice: true,
|
expectEndpointSlice: 1,
|
||||||
|
expectEndpointSliceManagedBy: "endpointslicemirroring-controller.k8s.io",
|
||||||
|
}, {
|
||||||
|
testName: "Service without selector Endpoint multiple subsets and same address",
|
||||||
|
service: &corev1.Service{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test-123",
|
||||||
|
},
|
||||||
|
Spec: corev1.ServiceSpec{
|
||||||
|
Ports: []corev1.ServicePort{{
|
||||||
|
Port: int32(80),
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
customEndpoints: &corev1.Endpoints{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test-123",
|
||||||
|
},
|
||||||
|
Subsets: []corev1.EndpointSubset{
|
||||||
|
{
|
||||||
|
Ports: []corev1.EndpointPort{{
|
||||||
|
Name: "port1",
|
||||||
|
Port: 80,
|
||||||
|
}},
|
||||||
|
Addresses: []corev1.EndpointAddress{{
|
||||||
|
IP: "10.0.0.1",
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Ports: []corev1.EndpointPort{{
|
||||||
|
Name: "port2",
|
||||||
|
Port: 90,
|
||||||
|
}},
|
||||||
|
Addresses: []corev1.EndpointAddress{{
|
||||||
|
IP: "10.0.0.1",
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectEndpointSlice: 1,
|
||||||
|
expectEndpointSliceManagedBy: "endpointslicemirroring-controller.k8s.io",
|
||||||
|
}, {
|
||||||
|
testName: "Service without selector Endpoint multiple subsets",
|
||||||
|
service: &corev1.Service{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test-123",
|
||||||
|
},
|
||||||
|
Spec: corev1.ServiceSpec{
|
||||||
|
Ports: []corev1.ServicePort{{
|
||||||
|
Port: int32(80),
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
customEndpoints: &corev1.Endpoints{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test-123",
|
||||||
|
},
|
||||||
|
Subsets: []corev1.EndpointSubset{
|
||||||
|
{
|
||||||
|
Ports: []corev1.EndpointPort{{
|
||||||
|
Name: "port1",
|
||||||
|
Port: 80,
|
||||||
|
}},
|
||||||
|
Addresses: []corev1.EndpointAddress{{
|
||||||
|
IP: "10.0.0.1",
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Ports: []corev1.EndpointPort{{
|
||||||
|
Name: "port2",
|
||||||
|
Port: 90,
|
||||||
|
}},
|
||||||
|
Addresses: []corev1.EndpointAddress{{
|
||||||
|
IP: "10.0.0.2",
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectEndpointSlice: 2,
|
||||||
expectEndpointSliceManagedBy: "endpointslicemirroring-controller.k8s.io",
|
expectEndpointSliceManagedBy: "endpointslicemirroring-controller.k8s.io",
|
||||||
}, {
|
}, {
|
||||||
testName: "Service without Endpoints",
|
testName: "Service without Endpoints",
|
||||||
@ -148,7 +226,7 @@ func TestEndpointSliceMirroring(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
customEndpoints: nil,
|
customEndpoints: nil,
|
||||||
expectEndpointSlice: true,
|
expectEndpointSlice: 1,
|
||||||
expectEndpointSliceManagedBy: "endpointslice-controller.k8s.io",
|
expectEndpointSliceManagedBy: "endpointslice-controller.k8s.io",
|
||||||
}, {
|
}, {
|
||||||
testName: "Endpoints without Service",
|
testName: "Endpoints without Service",
|
||||||
@ -166,7 +244,7 @@ func TestEndpointSliceMirroring(t *testing.T) {
|
|||||||
}},
|
}},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
expectEndpointSlice: false,
|
expectEndpointSlice: 0,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
for i, tc := range testCases {
|
for i, tc := range testCases {
|
||||||
@ -201,13 +279,13 @@ func TestEndpointSliceMirroring(t *testing.T) {
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if tc.expectEndpointSlice {
|
if tc.expectEndpointSlice > 0 {
|
||||||
if len(esList.Items) == 0 {
|
if len(esList.Items) < tc.expectEndpointSlice {
|
||||||
t.Logf("Waiting for EndpointSlice to be created")
|
t.Logf("Waiting for EndpointSlice to be created")
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
if len(esList.Items) > 1 {
|
if len(esList.Items) != tc.expectEndpointSlice {
|
||||||
return false, fmt.Errorf("Only expected 1 EndpointSlice, got %d", len(esList.Items))
|
return false, fmt.Errorf("Only expected %d EndpointSlice, got %d", tc.expectEndpointSlice, len(esList.Items))
|
||||||
}
|
}
|
||||||
endpointSlice := esList.Items[0]
|
endpointSlice := esList.Items[0]
|
||||||
if tc.expectEndpointSliceManagedBy != "" {
|
if tc.expectEndpointSliceManagedBy != "" {
|
||||||
|
Loading…
Reference in New Issue
Block a user