mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-05 09:06:58 +02:00
perf(source): benchmarks on EndpointTargetsFromServices (#5536)
* chore(benchmarking): added benchmarks to EndpointTargetsFromServices Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com> * chore(benchmarking): added benchmarks to EndpointTargetsFromServices Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com> * chore(benchmarking): added benchmarks to EndpointTargetsFromServices Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com> * chore(benchmarking): added benchmarks to EndpointTargetsFromServices Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com> --------- Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
This commit is contained in:
parent
0fae060dff
commit
36e3e53190
233
source/endpoint_benchmark_test.go
Normal file
233
source/endpoint_benchmark_test.go
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
/*
|
||||||
|
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 source
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"math/rand/v2"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
kubeinformers "k8s.io/client-go/informers"
|
||||||
|
coreinformers "k8s.io/client-go/informers/core/v1"
|
||||||
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
|
|
||||||
|
v1alpha3 "istio.io/api/networking/v1alpha3"
|
||||||
|
istiov1a "istio.io/client-go/pkg/apis/networking/v1"
|
||||||
|
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkEndpointTargetsFromServicesMedium(b *testing.B) {
|
||||||
|
svcInformer, err := svcInformerWithServices(36, 1000)
|
||||||
|
assert.NoError(b, err)
|
||||||
|
|
||||||
|
sel := map[string]string{"app": "nginx", "env": "prod"}
|
||||||
|
|
||||||
|
for b.Loop() {
|
||||||
|
targets, _ := EndpointTargetsFromServices(svcInformer, "default", sel)
|
||||||
|
assert.Equal(b, 36, targets.Len())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkEndpointTargetsFromServicesMediumIterateOverGateways(b *testing.B) {
|
||||||
|
svcInformer, err := svcInformerWithServices(36, 500)
|
||||||
|
assert.NoError(b, err)
|
||||||
|
|
||||||
|
gateways := fixturesIstioGatewaySvcWithLabels(15, 70)
|
||||||
|
|
||||||
|
for b.Loop() {
|
||||||
|
for _, gateway := range gateways {
|
||||||
|
_, _ = EndpointTargetsFromServices(svcInformer, gateway.Namespace, gateway.Spec.Selector)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkEndpointTargetsFromServicesHigh(b *testing.B) {
|
||||||
|
svcInformer, err := svcInformerWithServices(36, 40000)
|
||||||
|
assert.NoError(b, err)
|
||||||
|
sel := map[string]string{"app": "nginx", "env": "prod"}
|
||||||
|
|
||||||
|
for b.Loop() {
|
||||||
|
targets, _ := EndpointTargetsFromServices(svcInformer, "default", sel)
|
||||||
|
assert.Equal(b, 36, targets.Len())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This benchmark tests the performance of EndpointTargetsFromServices with a high number of services and gateways.
|
||||||
|
func BenchmarkEndpointTargetsFromServicesHighIterateOverGateways(b *testing.B) {
|
||||||
|
svcInformer, err := svcInformerWithServices(36, 40000)
|
||||||
|
assert.NoError(b, err)
|
||||||
|
|
||||||
|
gateways := fixturesIstioGatewaySvcWithLabels(50, 1000)
|
||||||
|
|
||||||
|
for b.Loop() {
|
||||||
|
for _, gateway := range gateways {
|
||||||
|
_, _ = EndpointTargetsFromServices(svcInformer, gateway.Namespace, gateway.Spec.Selector)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// helperToPopulateFakeClientWithServices populates a fake Kubernetes client with a specified services.
|
||||||
|
func svcInformerWithServices(toLookup, underTest int) (coreinformers.ServiceInformer, error) {
|
||||||
|
client := fake.NewClientset()
|
||||||
|
informerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(client, 0, kubeinformers.WithNamespace("default"))
|
||||||
|
svcInformer := informerFactory.Core().V1().Services()
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
_, err := svcInformer.Informer().AddEventHandler(
|
||||||
|
cache.ResourceEventHandlerFuncs{
|
||||||
|
AddFunc: func(obj interface{}) {
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to add event handler: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
services := fixturesSvcWithLabels(toLookup, underTest)
|
||||||
|
for _, svc := range services {
|
||||||
|
_, err := client.CoreV1().Services(svc.Namespace).Create(ctx, svc, metav1.CreateOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create service %s: %w", svc.Name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stopCh := make(chan struct{})
|
||||||
|
defer close(stopCh)
|
||||||
|
informerFactory.Start(stopCh)
|
||||||
|
cache.WaitForCacheSync(stopCh, svcInformer.Informer().HasSynced)
|
||||||
|
return svcInformer, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// fixturesSvcWithLabels creates a list of Services for testing purposes.
|
||||||
|
// It generates a specified number of services with static labels and random labels.
|
||||||
|
// The first `toLookup` services have specific labels, while the next `underTest` services have random labels.
|
||||||
|
func fixturesSvcWithLabels(toLookup, underTest int) []*corev1.Service {
|
||||||
|
var services []*corev1.Service
|
||||||
|
|
||||||
|
var randomLabels = func(input int) map[string]string {
|
||||||
|
if input%3 == 0 {
|
||||||
|
// every third service has no labels
|
||||||
|
return map[string]string{}
|
||||||
|
}
|
||||||
|
return map[string]string{
|
||||||
|
"app": fmt.Sprintf("service-%d", rand.IntN(100)),
|
||||||
|
fmt.Sprintf("key%d", rand.IntN(100)): fmt.Sprintf("value%d", rand.IntN(100)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var randomIPs = func() []string {
|
||||||
|
ip := rand.Uint32()
|
||||||
|
buf := make([]byte, 4)
|
||||||
|
binary.LittleEndian.PutUint32(buf, ip)
|
||||||
|
return []string{net.IP(buf).String()}
|
||||||
|
}
|
||||||
|
|
||||||
|
var createService = func(name string, namespace string, selector map[string]string) *corev1.Service {
|
||||||
|
return &corev1.Service{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Namespace: namespace,
|
||||||
|
},
|
||||||
|
Spec: corev1.ServiceSpec{
|
||||||
|
Selector: selector,
|
||||||
|
ExternalIPs: randomIPs(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// services with specific labels
|
||||||
|
for i := 0; i < toLookup; i++ {
|
||||||
|
svc := createService("nginx-svc-"+strconv.Itoa(i), "default", map[string]string{"app": "nginx", "env": "prod"})
|
||||||
|
services = append(services, svc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// services with random labels
|
||||||
|
for i := 0; i < underTest; i++ {
|
||||||
|
svc := createService("random-svc-"+strconv.Itoa(i), "default", randomLabels(i))
|
||||||
|
services = append(services, svc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shuffle the services to ensure randomness
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
rand.Shuffle(len(services), func(i, j int) {
|
||||||
|
services[i], services[j] = services[j], services[i]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return services
|
||||||
|
}
|
||||||
|
|
||||||
|
// fixturesIstioGatewaySvcWithLabels creates a list of Services for testing purposes.
|
||||||
|
// It generates a specified number of gateways with static labels and random labels.
|
||||||
|
// The first `toLookup` services have specific labels, while the next `underTest` services have random labels.
|
||||||
|
func fixturesIstioGatewaySvcWithLabels(toLookup, underTest int) []*istiov1a.Gateway {
|
||||||
|
var result []*istiov1a.Gateway
|
||||||
|
|
||||||
|
var randomLabels = func(input int) map[string]string {
|
||||||
|
if input%3 == 0 {
|
||||||
|
// every third service has no labels
|
||||||
|
return map[string]string{}
|
||||||
|
}
|
||||||
|
return map[string]string{
|
||||||
|
"app": fmt.Sprintf("service-%d", rand.IntN(100)),
|
||||||
|
fmt.Sprintf("key%d", rand.IntN(100)): fmt.Sprintf("value%d", rand.IntN(100)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var createGateway = func(name string, namespace string, selector map[string]string) *istiov1a.Gateway {
|
||||||
|
return &istiov1a.Gateway{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Namespace: namespace,
|
||||||
|
},
|
||||||
|
Spec: v1alpha3.Gateway{
|
||||||
|
Selector: selector,
|
||||||
|
Servers: []*v1alpha3.Server{
|
||||||
|
{
|
||||||
|
Port: &v1alpha3.Port{},
|
||||||
|
Hosts: []string{"*"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// services with specific labels
|
||||||
|
for i := 0; i < toLookup; i++ {
|
||||||
|
svc := createGateway("istio-gw-"+strconv.Itoa(i), "default", map[string]string{"app": "nginx", "env": "prod"})
|
||||||
|
result = append(result, svc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// services with random labels
|
||||||
|
for i := 0; i < underTest; i++ {
|
||||||
|
svc := createGateway("istio-random-svc-"+strconv.Itoa(i), "default", randomLabels(i))
|
||||||
|
result = append(result, svc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shuffle the services to ensure randomness
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
rand.Shuffle(len(result), func(i, j int) {
|
||||||
|
result[i], result[j] = result[j], result[i]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
@ -85,6 +85,7 @@ func EndpointTargetsFromServices(svcInformer coreinformers.ServiceInformer, name
|
|||||||
targets := endpoint.Targets{}
|
targets := endpoint.Targets{}
|
||||||
|
|
||||||
services, err := svcInformer.Lister().Services(namespace).List(labels.Everything())
|
services, err := svcInformer.Lister().Services(namespace).List(labels.Everything())
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to list labels for services in namespace %q: %w", namespace, err)
|
return nil, fmt.Errorf("failed to list labels for services in namespace %q: %w", namespace, err)
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
kubeinformers "k8s.io/client-go/informers"
|
kubeinformers "k8s.io/client-go/informers"
|
||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
|
|
||||||
"sigs.k8s.io/external-dns/endpoint"
|
"sigs.k8s.io/external-dns/endpoint"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -137,7 +138,6 @@ func TestEndpointTargetsFromServices(t *testing.T) {
|
|||||||
namespace: "default",
|
namespace: "default",
|
||||||
selector: map[string]string{"app": "nginx"},
|
selector: map[string]string{"app": "nginx"},
|
||||||
expected: endpoint.Targets{},
|
expected: endpoint.Targets{},
|
||||||
wantErr: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "matching service with external IPs",
|
name: "matching service with external IPs",
|
||||||
@ -156,7 +156,23 @@ func TestEndpointTargetsFromServices(t *testing.T) {
|
|||||||
namespace: "default",
|
namespace: "default",
|
||||||
selector: map[string]string{"app": "nginx"},
|
selector: map[string]string{"app": "nginx"},
|
||||||
expected: endpoint.Targets{"192.0.2.1", "158.123.32.23"},
|
expected: endpoint.Targets{"192.0.2.1", "158.123.32.23"},
|
||||||
wantErr: false,
|
},
|
||||||
|
{
|
||||||
|
name: "no matching service as service without selector",
|
||||||
|
services: []*corev1.Service{
|
||||||
|
{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "svc1",
|
||||||
|
Namespace: "default",
|
||||||
|
},
|
||||||
|
Spec: corev1.ServiceSpec{
|
||||||
|
ExternalIPs: []string{"192.0.2.1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
namespace: "default",
|
||||||
|
selector: map[string]string{"app": "nginx"},
|
||||||
|
expected: endpoint.Targets{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "matching service with load balancer IP",
|
name: "matching service with load balancer IP",
|
||||||
@ -181,7 +197,6 @@ func TestEndpointTargetsFromServices(t *testing.T) {
|
|||||||
namespace: "default",
|
namespace: "default",
|
||||||
selector: map[string]string{"app": "nginx"},
|
selector: map[string]string{"app": "nginx"},
|
||||||
expected: endpoint.Targets{"192.0.2.2"},
|
expected: endpoint.Targets{"192.0.2.2"},
|
||||||
wantErr: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "matching service with load balancer hostname",
|
name: "matching service with load balancer hostname",
|
||||||
@ -206,7 +221,6 @@ func TestEndpointTargetsFromServices(t *testing.T) {
|
|||||||
namespace: "default",
|
namespace: "default",
|
||||||
selector: map[string]string{"app": "nginx"},
|
selector: map[string]string{"app": "nginx"},
|
||||||
expected: endpoint.Targets{"lb.example.com"},
|
expected: endpoint.Targets{"lb.example.com"},
|
||||||
wantErr: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "no matching services",
|
name: "no matching services",
|
||||||
@ -224,13 +238,12 @@ func TestEndpointTargetsFromServices(t *testing.T) {
|
|||||||
namespace: "default",
|
namespace: "default",
|
||||||
selector: map[string]string{"app": "nginx"},
|
selector: map[string]string{"app": "nginx"},
|
||||||
expected: endpoint.Targets{},
|
expected: endpoint.Targets{},
|
||||||
wantErr: false,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
client := fake.NewSimpleClientset()
|
client := fake.NewClientset()
|
||||||
informerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(client, 0,
|
informerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(client, 0,
|
||||||
kubeinformers.WithNamespace(tt.namespace))
|
kubeinformers.WithNamespace(tt.namespace))
|
||||||
serviceInformer := informerFactory.Core().V1().Services()
|
serviceInformer := informerFactory.Core().V1().Services()
|
||||||
@ -253,3 +266,14 @@ func TestEndpointTargetsFromServices(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEndpointTargetsFromServicesWithFixtures(t *testing.T) {
|
||||||
|
svcInformer, err := svcInformerWithServices(2, 9)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
sel := map[string]string{"app": "nginx", "env": "prod"}
|
||||||
|
|
||||||
|
targets, err := EndpointTargetsFromServices(svcInformer, "default", sel)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 2, targets.Len())
|
||||||
|
}
|
||||||
|
@ -329,7 +329,7 @@ func TestF5VirtualServerEndpoints(t *testing.T) {
|
|||||||
|
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
fakeKubernetesClient := fakeKube.NewSimpleClientset()
|
fakeKubernetesClient := fakeKube.NewClientset()
|
||||||
scheme := runtime.NewScheme()
|
scheme := runtime.NewScheme()
|
||||||
scheme.AddKnownTypes(f5VirtualServerGVR.GroupVersion(), &f5.VirtualServer{}, &f5.VirtualServerList{})
|
scheme.AddKnownTypes(f5VirtualServerGVR.GroupVersion(), &f5.VirtualServer{}, &f5.VirtualServerList{})
|
||||||
fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(scheme)
|
fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(scheme)
|
||||||
|
@ -260,13 +260,7 @@ func (sc *gatewaySource) targetsFromGateway(ctx context.Context, gateway *networ
|
|||||||
return sc.targetsFromIngress(ctx, ingressStr, gateway)
|
return sc.targetsFromIngress(ctx, ingressStr, gateway)
|
||||||
}
|
}
|
||||||
|
|
||||||
targets, err := EndpointTargetsFromServices(sc.serviceInformer, sc.namespace, gateway.Spec.Selector)
|
return EndpointTargetsFromServices(sc.serviceInformer, sc.namespace, gateway.Spec.Selector)
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return targets, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// endpointsFromGatewayConfig extracts the endpoints from an Istio Gateway Config object
|
// endpointsFromGatewayConfig extracts the endpoints from an Istio Gateway Config object
|
||||||
@ -323,12 +317,3 @@ func (sc *gatewaySource) hostNamesFromGateway(gateway *networkingv1alpha3.Gatewa
|
|||||||
|
|
||||||
return hostnames, nil
|
return hostnames, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func gatewaySelectorMatchesServiceSelector(gwSelector, svcSelector map[string]string) bool {
|
|
||||||
for k, v := range gwSelector {
|
|
||||||
if lbl, ok := svcSelector[k]; !ok || lbl != v {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
@ -46,7 +46,7 @@ type GatewaySuite struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *GatewaySuite) SetupTest() {
|
func (suite *GatewaySuite) SetupTest() {
|
||||||
fakeKubernetesClient := fake.NewSimpleClientset()
|
fakeKubernetesClient := fake.NewClientset()
|
||||||
fakeIstioClient := istiofake.NewSimpleClientset()
|
fakeIstioClient := istiofake.NewSimpleClientset()
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -166,7 +166,7 @@ func TestNewIstioGatewaySource(t *testing.T) {
|
|||||||
|
|
||||||
_, err := NewIstioGatewaySource(
|
_, err := NewIstioGatewaySource(
|
||||||
context.TODO(),
|
context.TODO(),
|
||||||
fake.NewSimpleClientset(),
|
fake.NewClientset(),
|
||||||
istiofake.NewSimpleClientset(),
|
istiofake.NewSimpleClientset(),
|
||||||
"",
|
"",
|
||||||
ti.annotationFilter,
|
ti.annotationFilter,
|
||||||
|
@ -453,42 +453,16 @@ func (sc *virtualServiceSource) targetsFromIngress(ctx context.Context, ingressS
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *virtualServiceSource) targetsFromGateway(ctx context.Context, gateway *networkingv1alpha3.Gateway) (targets endpoint.Targets, err error) {
|
func (sc *virtualServiceSource) targetsFromGateway(ctx context.Context, gateway *networkingv1alpha3.Gateway) (endpoint.Targets, error) {
|
||||||
targets = annotations.TargetsFromTargetAnnotation(gateway.Annotations)
|
targets := annotations.TargetsFromTargetAnnotation(gateway.Annotations)
|
||||||
if len(targets) > 0 {
|
if len(targets) > 0 {
|
||||||
return
|
return targets, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ingressStr, ok := gateway.Annotations[IstioGatewayIngressSource]
|
ingressStr, ok := gateway.Annotations[IstioGatewayIngressSource]
|
||||||
if ok && ingressStr != "" {
|
if ok && ingressStr != "" {
|
||||||
targets, err = sc.targetsFromIngress(ctx, ingressStr, gateway)
|
return sc.targetsFromIngress(ctx, ingressStr, gateway)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
services, err := sc.serviceInformer.Lister().Services(sc.namespace).List(labels.Everything())
|
return EndpointTargetsFromServices(sc.serviceInformer, sc.namespace, gateway.Spec.Selector)
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, service := range services {
|
|
||||||
if !gatewaySelectorMatchesServiceSelector(gateway.Spec.Selector, service.Spec.Selector) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(service.Spec.ExternalIPs) > 0 {
|
|
||||||
targets = append(targets, service.Spec.ExternalIPs...)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, lb := range service.Status.LoadBalancer.Ingress {
|
|
||||||
if lb.IP != "" {
|
|
||||||
targets = append(targets, lb.IP)
|
|
||||||
} else if lb.Hostname != "" {
|
|
||||||
targets = append(targets, lb.Hostname)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
@ -2035,7 +2035,7 @@ func testGatewaySelectorMatchesService(t *testing.T) {
|
|||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(ti.title, func(t *testing.T) {
|
t.Run(ti.title, func(t *testing.T) {
|
||||||
require.Equal(t, ti.expected, gatewaySelectorMatchesServiceSelector(ti.gwSelector, ti.lbSelector))
|
require.Equal(t, ti.expected, MatchesServiceSelector(ti.gwSelector, ti.lbSelector))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user