From 6977b68b72bde1522791b5167e3ff1b6e618922c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Silva?= Date: Wed, 31 May 2023 10:40:05 +0100 Subject: [PATCH] Fix multiple subsets endpoint --- .../crd/fixtures/with_multiple_subsets.yml | 54 +++++++++++++++++++ .../kubernetes/crd/kubernetes_http.go | 4 +- .../kubernetes/crd/kubernetes_test.go | 44 +++++++++++++++ 3 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 pkg/provider/kubernetes/crd/fixtures/with_multiple_subsets.yml diff --git a/pkg/provider/kubernetes/crd/fixtures/with_multiple_subsets.yml b/pkg/provider/kubernetes/crd/fixtures/with_multiple_subsets.yml new file mode 100644 index 000000000..4d700d7ad --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/with_multiple_subsets.yml @@ -0,0 +1,54 @@ +apiVersion: v1 +kind: Service +metadata: + name: whoami-svc-multiple-subsets + namespace: default + +spec: + ports: + - name: web + port: 80 + - name: web2 + port: 8080 + selector: + app: traefiklabs + task: whoami + +--- +kind: Endpoints +apiVersion: v1 +metadata: + name: whoami-svc-multiple-subsets + namespace: default + +subsets: + - addresses: + - ip: 10.10.0.1 + - ip: 10.10.0.2 + ports: + - name: web + port: 80 + - addresses: + - ip: 10.10.0.3 + - ip: 10.10.0.4 + ports: + - name: web2 + port: 8080 +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: test.route + namespace: default + +spec: + entryPoints: + - foo + + routes: + - match: Host(`foo.com`) && PathPrefix(`/bar`) + kind: Rule + priority: 12 + services: + - name: whoami-svc-multiple-subsets + port: 8080 diff --git a/pkg/provider/kubernetes/crd/kubernetes_http.go b/pkg/provider/kubernetes/crd/kubernetes_http.go index d3b206301..56637a22a 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_http.go +++ b/pkg/provider/kubernetes/crd/kubernetes_http.go @@ -414,8 +414,8 @@ func (c configBuilder) loadServers(parentNamespace string, svc traefikv1alpha1.L return nil, fmt.Errorf("subset not found for %s/%s", namespace, sanitizedName) } - var port int32 for _, subset := range endpoints.Subsets { + var port int32 for _, p := range subset.Ports { if svcPort.Name == p.Name { port = p.Port @@ -424,7 +424,7 @@ func (c configBuilder) loadServers(parentNamespace string, svc traefikv1alpha1.L } if port == 0 { - return nil, fmt.Errorf("cannot define a port for %s/%s", namespace, sanitizedName) + continue } protocol, err := parseServiceProtocol(svc.Scheme, svcPort.Name, svcPort.Port) diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go index e5178eb37..e9620c122 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_test.go +++ b/pkg/provider/kubernetes/crd/kubernetes_test.go @@ -4037,6 +4037,50 @@ func TestLoadIngressRoutes(t *testing.T) { TLS: &dynamic.TLSConfiguration{}, }, }, + { + desc: "IngressRoute, service with multiple subsets", + allowEmptyServices: true, + paths: []string{"services.yml", "with_multiple_subsets.yml"}, + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + TCP: &dynamic.TCPConfiguration{ + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{ + "default-test-route-6b204d94623b3df4370c": { + EntryPoints: []string{"foo"}, + Service: "default-test-route-6b204d94623b3df4370c", + Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", + Priority: 12, + }, + }, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{ + "default-test-route-6b204d94623b3df4370c": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.3:8080", + }, + { + URL: "http://10.10.0.4:8080", + }, + }, + PassHostHeader: Bool(true), + }, + }, + }, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, { desc: "TraefikService, empty service allowed", allowEmptyServices: true,