From d547718fdd200f199aabad167c8192b77d8bbd22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Guiard?= <555535+jeromeguiard@users.noreply.github.com> Date: Tue, 22 Nov 2022 10:18:04 +0100 Subject: [PATCH] Support of allowEmptyServices in TraefikService --- .../crd/fixtures/with_empty_services_ts.yml | 65 ++++++++++++++ pkg/provider/kubernetes/crd/kubernetes.go | 16 +++- .../kubernetes/crd/kubernetes_test.go | 85 +++++++++++++++++++ 3 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 pkg/provider/kubernetes/crd/fixtures/with_empty_services_ts.yml diff --git a/pkg/provider/kubernetes/crd/fixtures/with_empty_services_ts.yml b/pkg/provider/kubernetes/crd/fixtures/with_empty_services_ts.yml new file mode 100644 index 000000000..92500f3fd --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/with_empty_services_ts.yml @@ -0,0 +1,65 @@ +apiVersion: traefik.containo.us/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: test-weighted + kind: TraefikService + - name: test-mirror + kind: TraefikService + middlewares: + - name: test-errorpage + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: TraefikService +metadata: + name: test-weighted + namespace: default + +spec: + weighted: + services: + - name: whoami-without-endpoints-subsets + weight: 1 + port: 80 + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: TraefikService +metadata: + name: test-mirror + namespace: default + +spec: + mirroring: + name: whoami-without-endpoints-subsets + port: 80 + mirrors: + - name: whoami-without-endpoints-subsets + port: 80 + - name: test-weighted + kind: TraefikService + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: test-errorpage + namespace: default + +spec: + errors: + service: + name: whoami-without-endpoints-subsets + port: 80 diff --git a/pkg/provider/kubernetes/crd/kubernetes.go b/pkg/provider/kubernetes/crd/kubernetes.go index a43345e67..67e639d39 100644 --- a/pkg/provider/kubernetes/crd/kubernetes.go +++ b/pkg/provider/kubernetes/crd/kubernetes.go @@ -292,7 +292,12 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) } } - cb := configBuilder{client: client, allowCrossNamespace: p.AllowCrossNamespace, allowExternalNameServices: p.AllowExternalNameServices} + cb := configBuilder{ + client: client, + allowCrossNamespace: p.AllowCrossNamespace, + allowExternalNameServices: p.AllowExternalNameServices, + allowEmptyServices: p.AllowEmptyServices, + } for _, service := range client.GetTraefikServices() { err := cb.buildTraefikService(ctx, service, conf.HTTP.Services) @@ -578,7 +583,14 @@ func (p *Provider) createErrorPageMiddleware(client Client, namespace string, er Query: errorPage.Query, } - balancerServerHTTP, err := configBuilder{client: client, allowCrossNamespace: p.AllowCrossNamespace, allowExternalNameServices: p.AllowExternalNameServices}.buildServersLB(namespace, errorPage.Service.LoadBalancerSpec) + cb := configBuilder{ + client: client, + allowCrossNamespace: p.AllowCrossNamespace, + allowExternalNameServices: p.AllowExternalNameServices, + allowEmptyServices: p.AllowEmptyServices, + } + + balancerServerHTTP, err := cb.buildServersLB(namespace, errorPage.Service.LoadBalancerSpec) if err != nil { return nil, nil, err } diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go index 7465c8fae..52cdae1e0 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_test.go +++ b/pkg/provider/kubernetes/crd/kubernetes_test.go @@ -4037,6 +4037,91 @@ func TestLoadIngressRoutes(t *testing.T) { TLS: &dynamic.TLSConfiguration{}, }, }, + { + desc: "TraefikService, empty service allowed", + allowEmptyServices: true, + paths: []string{"services.yml", "with_empty_services_ts.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"}, + Middlewares: []string{"default-test-errorpage"}, + Service: "default-test-route-6b204d94623b3df4370c", + Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", + Priority: 12, + }, + }, + Middlewares: map[string]*dynamic.Middleware{ + "default-test-errorpage": { + Errors: &dynamic.ErrorPage{ + Service: "default-test-errorpage-errorpage-service", + }, + }, + }, + Services: map[string]*dynamic.Service{ + "default-test-route-6b204d94623b3df4370c": { + Weighted: &dynamic.WeightedRoundRobin{ + Services: []dynamic.WRRService{ + { + Name: "default-test-weighted", + Weight: func(i int) *int { return &i }(1), + }, + { + Name: "default-test-mirror", + Weight: func(i int) *int { return &i }(1), + }, + }, + }, + }, + "default-test-errorpage-errorpage-service": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), + }, + }, + "default-test-weighted": { + Weighted: &dynamic.WeightedRoundRobin{ + Services: []dynamic.WRRService{ + { + Name: "default-whoami-without-endpoints-subsets-80", + Weight: func(i int) *int { return &i }(1), + }, + }, + }, + }, + "default-test-mirror": { + Mirroring: &dynamic.Mirroring{ + Service: "default-whoami-without-endpoints-subsets-80", + Mirrors: []dynamic.MirrorService{ + { + Name: "default-whoami-without-endpoints-subsets-80", + }, + { + Name: "default-test-weighted", + }, + }, + }, + }, + "default-whoami-without-endpoints-subsets-80": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), + }, + }, + }, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, } for _, test := range testCases {