From 3eb7ecce193615f86a7da077746b80145eb24306 Mon Sep 17 00:00:00 2001 From: Romain Date: Tue, 3 Sep 2024 12:10:04 +0200 Subject: [PATCH] Improve Kubernetes GatewayAPI TCPRoute and TLSRoute support --- .../experimental-v3.1-default-report.yaml | 8 + integration/k8s_conformance_test.go | 13 +- integration/testdata/rawdata-gateway.json | 32 +- .../tcproute/with_wrong_service_port.yml | 4 + .../tlsroute/with_wrong_service_port.yml | 6 +- pkg/provider/kubernetes/gateway/grpcroute.go | 6 +- pkg/provider/kubernetes/gateway/httproute.go | 16 +- pkg/provider/kubernetes/gateway/kubernetes.go | 36 +- .../kubernetes/gateway/kubernetes_test.go | 556 +++++++++--------- pkg/provider/kubernetes/gateway/tcproute.go | 314 ++++++---- pkg/provider/kubernetes/gateway/tlsroute.go | 183 ++++-- 11 files changed, 690 insertions(+), 484 deletions(-) diff --git a/integration/conformance-reports/v1.1.0/experimental-v3.1-default-report.yaml b/integration/conformance-reports/v1.1.0/experimental-v3.1-default-report.yaml index e668037eb..64047e5b2 100644 --- a/integration/conformance-reports/v1.1.0/experimental-v3.1-default-report.yaml +++ b/integration/conformance-reports/v1.1.0/experimental-v3.1-default-report.yaml @@ -53,3 +53,11 @@ profiles: - HTTPRouteRequestTimeout name: GATEWAY-HTTP summary: Core tests succeeded. Extended tests succeeded. +- core: + result: success + statistics: + Failed: 0 + Passed: 11 + Skipped: 0 + name: GATEWAY-TLS + summary: Core tests succeeded. diff --git a/integration/k8s_conformance_test.go b/integration/k8s_conformance_test.go index 70ec948ea..9316715af 100644 --- a/integration/k8s_conformance_test.go +++ b/integration/k8s_conformance_test.go @@ -8,6 +8,7 @@ import ( "os" "path/filepath" "slices" + "strings" "testing" "time" @@ -193,7 +194,11 @@ func (s *K8sConformanceSuite) TestK8sGatewayAPIConformance() { Version: *k8sConformanceTraefikVersion, Contact: []string{"@traefik/maintainers"}, }, - ConformanceProfiles: sets.New(ksuite.GatewayHTTPConformanceProfileName, ksuite.GatewayGRPCConformanceProfileName), + ConformanceProfiles: sets.New( + ksuite.GatewayHTTPConformanceProfileName, + ksuite.GatewayGRPCConformanceProfileName, + ksuite.GatewayTLSConformanceProfileName, + ), SupportedFeatures: sets.New( features.SupportGateway, features.SupportGatewayPort8080, @@ -207,6 +212,7 @@ func (s *K8sConformanceSuite) TestK8sGatewayAPIConformance() { features.SupportHTTPRoutePathRewrite, features.SupportHTTPRoutePathRedirect, features.SupportHTTPRouteResponseHeaderModification, + features.SupportTLSRoute, ), }) require.NoError(s.T(), err) @@ -224,6 +230,11 @@ func (s *K8sConformanceSuite) TestK8sGatewayAPIConformance() { // TODO: to publish this report automatically, we have to figure out how to handle the date diff. report.Date = "-" + // Ordering profile reports for the serialized report to be comparable. + slices.SortFunc(report.ProfileReports, func(a, b v1.ProfileReport) int { + return strings.Compare(a.Name, b.Name) + }) + rawReport, err := yaml.Marshal(report) require.NoError(s.T(), err) s.T().Logf("Conformance report:\n%s", string(rawReport)) diff --git a/integration/testdata/rawdata-gateway.json b/integration/testdata/rawdata-gateway.json index d4dd467b0..15ee8b6ce 100644 --- a/integration/testdata/rawdata-gateway.json +++ b/integration/testdata/rawdata-gateway.json @@ -34,7 +34,7 @@ "entryPoints": [ "web" ], - "service": "default-http-app-1-my-gateway-web-0-wrr", + "service": "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", "rule": "Host(`foo.com`) \u0026\u0026 Path(`/bar`)", "ruleSyntax": "v3", "priority": 100008, @@ -47,7 +47,7 @@ "entryPoints": [ "websecure" ], - "service": "default-http-app-1-my-https-gateway-websecure-0-wrr", + "service": "default-http-app-1-my-https-gateway-websecure-0-1c0cf64bde37d9d0df06-wrr", "rule": "Host(`foo.com`) \u0026\u0026 Path(`/bar`)", "ruleSyntax": "v3", "priority": 100008, @@ -96,7 +96,7 @@ "dashboard@internal" ] }, - "default-http-app-1-my-gateway-web-0-wrr@kubernetesgateway": { + "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr@kubernetesgateway": { "weighted": { "services": [ { @@ -110,7 +110,7 @@ "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06@kubernetesgateway" ] }, - "default-http-app-1-my-https-gateway-websecure-0-wrr@kubernetesgateway": { + "default-http-app-1-my-https-gateway-websecure-0-1c0cf64bde37d9d0df06-wrr@kubernetesgateway": { "weighted": { "services": [ { @@ -150,11 +150,11 @@ } }, "tcpRouters": { - "default-tcp-app-1-my-tcp-gateway-footcp@kubernetesgateway": { + "default-tcp-app-1-my-tcp-gateway-footcp-0-e3b0c44298fc1c149afb@kubernetesgateway": { "entryPoints": [ "footcp" ], - "service": "default-tcp-app-1-my-tcp-gateway-footcp-wrr-0", + "service": "default-tcp-app-1-my-tcp-gateway-footcp-0-e3b0c44298fc1c149afb-wrr", "rule": "HostSNI(`*`)", "ruleSyntax": "v3", "priority": -1, @@ -163,11 +163,11 @@ "footcp" ] }, - "default-tcp-app-1-my-tls-gateway-footlsterminate@kubernetesgateway": { + "default-tcp-app-1-my-tls-gateway-footlsterminate-0-e3b0c44298fc1c149afb@kubernetesgateway": { "entryPoints": [ "footlsterminate" ], - "service": "default-tcp-app-1-my-tls-gateway-footlsterminate-wrr-0", + "service": "default-tcp-app-1-my-tls-gateway-footlsterminate-0-e3b0c44298fc1c149afb-wrr", "rule": "HostSNI(`*`)", "ruleSyntax": "v3", "priority": -1, @@ -179,11 +179,11 @@ "footlsterminate" ] }, - "default-tls-app-1-my-tls-gateway-footlspassthrough-2279fe75c5156dc5eb26@kubernetesgateway": { + "default-tls-app-1-my-tls-gateway-footlspassthrough-0-e3b0c44298fc1c149afb@kubernetesgateway": { "entryPoints": [ "footlspassthrough" ], - "service": "default-tls-app-1-my-tls-gateway-footlspassthrough-2279fe75c5156dc5eb26-wrr-0", + "service": "default-tls-app-1-my-tls-gateway-footlspassthrough-0-e3b0c44298fc1c149afb-wrr", "rule": "HostSNI(`foo.bar`)", "ruleSyntax": "v3", "priority": 18, @@ -197,7 +197,7 @@ } }, "tcpServices": { - "default-tcp-app-1-my-tcp-gateway-footcp-wrr-0@kubernetesgateway": { + "default-tcp-app-1-my-tcp-gateway-footcp-0-e3b0c44298fc1c149afb-wrr@kubernetesgateway": { "weighted": { "services": [ { @@ -208,10 +208,10 @@ }, "status": "enabled", "usedBy": [ - "default-tcp-app-1-my-tcp-gateway-footcp@kubernetesgateway" + "default-tcp-app-1-my-tcp-gateway-footcp-0-e3b0c44298fc1c149afb@kubernetesgateway" ] }, - "default-tcp-app-1-my-tls-gateway-footlsterminate-wrr-0@kubernetesgateway": { + "default-tcp-app-1-my-tls-gateway-footlsterminate-0-e3b0c44298fc1c149afb-wrr@kubernetesgateway": { "weighted": { "services": [ { @@ -222,10 +222,10 @@ }, "status": "enabled", "usedBy": [ - "default-tcp-app-1-my-tls-gateway-footlsterminate@kubernetesgateway" + "default-tcp-app-1-my-tls-gateway-footlsterminate-0-e3b0c44298fc1c149afb@kubernetesgateway" ] }, - "default-tls-app-1-my-tls-gateway-footlspassthrough-2279fe75c5156dc5eb26-wrr-0@kubernetesgateway": { + "default-tls-app-1-my-tls-gateway-footlspassthrough-0-e3b0c44298fc1c149afb-wrr@kubernetesgateway": { "weighted": { "services": [ { @@ -236,7 +236,7 @@ }, "status": "enabled", "usedBy": [ - "default-tls-app-1-my-tls-gateway-footlspassthrough-2279fe75c5156dc5eb26@kubernetesgateway" + "default-tls-app-1-my-tls-gateway-footlspassthrough-0-e3b0c44298fc1c149afb@kubernetesgateway" ] }, "default-whoamitcp-8080@kubernetesgateway": { diff --git a/pkg/provider/kubernetes/gateway/fixtures/tcproute/with_wrong_service_port.yml b/pkg/provider/kubernetes/gateway/fixtures/tcproute/with_wrong_service_port.yml index 6de20a14a..ee629a6db 100644 --- a/pkg/provider/kubernetes/gateway/fixtures/tcproute/with_wrong_service_port.yml +++ b/pkg/provider/kubernetes/gateway/fixtures/tcproute/with_wrong_service_port.yml @@ -32,6 +32,10 @@ metadata: name: TCP-app-1 namespace: default spec: + parentRefs: + - name: my-gateway + kind: Gateway + group: gateway.networking.k8s.io rules: - backendRefs: - name: whoami diff --git a/pkg/provider/kubernetes/gateway/fixtures/tlsroute/with_wrong_service_port.yml b/pkg/provider/kubernetes/gateway/fixtures/tlsroute/with_wrong_service_port.yml index c0c472a55..5d296c248 100644 --- a/pkg/provider/kubernetes/gateway/fixtures/tlsroute/with_wrong_service_port.yml +++ b/pkg/provider/kubernetes/gateway/fixtures/tlsroute/with_wrong_service_port.yml @@ -36,16 +36,16 @@ spec: group: "" allowedRoutes: kinds: - - kind: TCPRoute + - kind: TLSRoute group: gateway.networking.k8s.io namespaces: from: Same --- -kind: TCPRoute +kind: TLSRoute apiVersion: gateway.networking.k8s.io/v1alpha2 metadata: - name: tcp-app-1 + name: tls-app-1 namespace: default spec: parentRefs: diff --git a/pkg/provider/kubernetes/gateway/grpcroute.go b/pkg/provider/kubernetes/gateway/grpcroute.go index baee82876..9447943a0 100644 --- a/pkg/provider/kubernetes/gateway/grpcroute.go +++ b/pkg/provider/kubernetes/gateway/grpcroute.go @@ -216,7 +216,7 @@ func (p *Provider) loadGRPCService(conf *dynamic.Configuration, routeKey string, } func (p *Provider) loadGRPCBackendRef(route *gatev1.GRPCRoute, backendRef gatev1.GRPCBackendRef) (string, *dynamic.Service, *metav1.Condition) { - kind := ptr.Deref(backendRef.Kind, "Service") + kind := ptr.Deref(backendRef.Kind, kindService) group := groupCore if backendRef.Group != nil && *backendRef.Group != "" { @@ -230,7 +230,7 @@ func (p *Provider) loadGRPCBackendRef(route *gatev1.GRPCRoute, backendRef gatev1 serviceName := provider.Normalize(namespace + "-" + string(backendRef.Name)) - if group != groupCore || kind != "Service" { + if group != groupCore || kind != kindService { return serviceName, nil, &metav1.Condition{ Type: string(gatev1.RouteConditionResolvedRefs), Status: metav1.ConditionFalse, @@ -241,7 +241,7 @@ func (p *Provider) loadGRPCBackendRef(route *gatev1.GRPCRoute, backendRef gatev1 } } - if err := p.isReferenceGranted(groupGateway, kindGRPCRoute, route.Namespace, group, string(kind), string(backendRef.Name), namespace); err != nil { + if err := p.isReferenceGranted(kindGRPCRoute, route.Namespace, group, string(kind), string(backendRef.Name), namespace); err != nil { return serviceName, nil, &metav1.Condition{ Type: string(gatev1.RouteConditionResolvedRefs), Status: metav1.ConditionFalse, diff --git a/pkg/provider/kubernetes/gateway/httproute.go b/pkg/provider/kubernetes/gateway/httproute.go index ed4efc659..685a6fbfd 100644 --- a/pkg/provider/kubernetes/gateway/httproute.go +++ b/pkg/provider/kubernetes/gateway/httproute.go @@ -158,7 +158,7 @@ func (p *Provider) loadHTTPRoute(ctx context.Context, listener gatewayListener, default: var serviceCondition *metav1.Condition - router.Service, serviceCondition = p.loadService(conf, routeKey, routeRule, route) + router.Service, serviceCondition = p.loadWRRService(conf, routerName, routeRule, route) if serviceCondition != nil { condition = *serviceCondition } @@ -173,7 +173,7 @@ func (p *Provider) loadHTTPRoute(ctx context.Context, listener gatewayListener, return conf, condition } -func (p *Provider) loadService(conf *dynamic.Configuration, routeKey string, routeRule gatev1.HTTPRouteRule, route *gatev1.HTTPRoute) (string, *metav1.Condition) { +func (p *Provider) loadWRRService(conf *dynamic.Configuration, routeKey string, routeRule gatev1.HTTPRouteRule, route *gatev1.HTTPRoute) (string, *metav1.Condition) { name := routeKey + "-wrr" if _, ok := conf.HTTP.Services[name]; ok { return name, nil @@ -182,7 +182,7 @@ func (p *Provider) loadService(conf *dynamic.Configuration, routeKey string, rou var wrr dynamic.WeightedRoundRobin var condition *metav1.Condition for _, backendRef := range routeRule.BackendRefs { - svcName, svc, errCondition := p.loadHTTPService(route, backendRef) + svcName, svc, errCondition := p.loadService(route, backendRef) weight := ptr.To(int(ptr.Deref(backendRef.Weight, 1))) if errCondition != nil { condition = errCondition @@ -208,10 +208,10 @@ func (p *Provider) loadService(conf *dynamic.Configuration, routeKey string, rou return name, condition } -// loadHTTPService returns a dynamic.Service config corresponding to the given gatev1.HTTPBackendRef. +// loadService returns a dynamic.Service config corresponding to the given gatev1.HTTPBackendRef. // Note that the returned dynamic.Service config can be nil (for cross-provider, internal services, and backendFunc). -func (p *Provider) loadHTTPService(route *gatev1.HTTPRoute, backendRef gatev1.HTTPBackendRef) (string, *dynamic.Service, *metav1.Condition) { - kind := ptr.Deref(backendRef.Kind, "Service") +func (p *Provider) loadService(route *gatev1.HTTPRoute, backendRef gatev1.HTTPBackendRef) (string, *dynamic.Service, *metav1.Condition) { + kind := ptr.Deref(backendRef.Kind, kindService) group := groupCore if backendRef.Group != nil && *backendRef.Group != "" { @@ -225,7 +225,7 @@ func (p *Provider) loadHTTPService(route *gatev1.HTTPRoute, backendRef gatev1.HT serviceName := provider.Normalize(namespace + "-" + string(backendRef.Name)) - if err := p.isReferenceGranted(groupGateway, kindHTTPRoute, route.Namespace, group, string(kind), string(backendRef.Name), namespace); err != nil { + if err := p.isReferenceGranted(kindHTTPRoute, route.Namespace, group, string(kind), string(backendRef.Name), namespace); err != nil { return serviceName, nil, &metav1.Condition{ Type: string(gatev1.RouteConditionResolvedRefs), Status: metav1.ConditionFalse, @@ -236,7 +236,7 @@ func (p *Provider) loadHTTPService(route *gatev1.HTTPRoute, backendRef gatev1.HT } } - if group != groupCore || kind != "Service" { + if group != groupCore || kind != kindService { name, service, err := p.loadHTTPBackendRef(namespace, backendRef) if err != nil { return serviceName, nil, &metav1.Condition{ diff --git a/pkg/provider/kubernetes/gateway/kubernetes.go b/pkg/provider/kubernetes/gateway/kubernetes.go index 7a65ea977..b8c878627 100644 --- a/pkg/provider/kubernetes/gateway/kubernetes.go +++ b/pkg/provider/kubernetes/gateway/kubernetes.go @@ -47,6 +47,7 @@ const ( kindGRPCRoute = "GRPCRoute" kindTCPRoute = "TCPRoute" kindTLSRoute = "TLSRoute" + kindService = "Service" ) // Provider holds configurations of the provider. @@ -376,11 +377,19 @@ func (p *Provider) loadConfigurationFromGateways(ctx context.Context) *dynamic.C } } - gatewayStatus, err := p.makeGatewayStatus(gateway, listeners, addresses) - if err != nil { + gatewayStatus, errConditions := p.makeGatewayStatus(gateway, listeners, addresses) + if len(errConditions) > 0 { + messages := map[string]struct{}{} + for _, condition := range errConditions { + messages[condition.Message] = struct{}{} + } + var conditionsErr error + for message := range messages { + conditionsErr = multierror.Append(conditionsErr, errors.New(message)) + } logger.Error(). - Err(err). - Msg("Unable to create Gateway status") + Err(conditionsErr). + Msg("Gateway Not Accepted") } if err = p.client.UpdateGatewayStatus(ctx, ktypes.NamespacedName{Name: gateway.Name, Namespace: gateway.Namespace}, gatewayStatus); err != nil { @@ -576,7 +585,7 @@ func (p *Provider) loadGatewayListeners(ctx context.Context, gateway *gatev1.Gat certificateNamespace = string(*certificateRef.Namespace) } - if err := p.isReferenceGranted(groupGateway, kindGateway, gateway.Namespace, groupCore, "Secret", string(certificateRef.Name), certificateNamespace); err != nil { + if err := p.isReferenceGranted(kindGateway, gateway.Namespace, groupCore, "Secret", string(certificateRef.Name), certificateNamespace); err != nil { gatewayListeners[i].Status.Conditions = append(gatewayListeners[i].Status.Conditions, metav1.Condition{ Type: string(gatev1.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, @@ -631,10 +640,10 @@ func (p *Provider) loadGatewayListeners(ctx context.Context, gateway *gatev1.Gat return gatewayListeners } -func (p *Provider) makeGatewayStatus(gateway *gatev1.Gateway, listeners []gatewayListener, addresses []gatev1.GatewayStatusAddress) (gatev1.GatewayStatus, error) { +func (p *Provider) makeGatewayStatus(gateway *gatev1.Gateway, listeners []gatewayListener, addresses []gatev1.GatewayStatusAddress) (gatev1.GatewayStatus, []metav1.Condition) { gatewayStatus := gatev1.GatewayStatus{Addresses: addresses} - var result error + var errorConditions []metav1.Condition for _, listener := range listeners { if len(listener.Status.Conditions) == 0 { listener.Status.Conditions = append(listener.Status.Conditions, @@ -669,14 +678,11 @@ func (p *Provider) makeGatewayStatus(gateway *gatev1.Gateway, listeners []gatewa continue } - for _, condition := range listener.Status.Conditions { - result = multierror.Append(result, errors.New(condition.Message)) - } - + errorConditions = append(errorConditions, listener.Status.Conditions...) gatewayStatus.Listeners = append(gatewayStatus.Listeners, *listener.Status) } - if result != nil { + if len(errorConditions) > 0 { // GatewayConditionReady "Ready", GatewayConditionReason "ListenersNotValid" gatewayStatus.Conditions = append(gatewayStatus.Conditions, metav1.Condition{ Type: string(gatev1.GatewayConditionAccepted), @@ -687,7 +693,7 @@ func (p *Provider) makeGatewayStatus(gateway *gatev1.Gateway, listeners []gatewa Message: "All Listeners must be valid", }) - return gatewayStatus, result + return gatewayStatus, errorConditions } gatewayStatus.Conditions = append(gatewayStatus.Conditions, @@ -783,7 +789,7 @@ func (p *Provider) entryPointName(port gatev1.PortNumber, protocol gatev1.Protoc return "", fmt.Errorf("no matching entryPoint for port %d and protocol %q", port, protocol) } -func (p *Provider) isReferenceGranted(fromGroup, fromKind, fromNamespace, toGroup, toKind, toName, toNamespace string) error { +func (p *Provider) isReferenceGranted(fromKind, fromNamespace, toGroup, toKind, toName, toNamespace string) error { if toNamespace == fromNamespace { return nil } @@ -793,7 +799,7 @@ func (p *Provider) isReferenceGranted(fromGroup, fromKind, fromNamespace, toGrou return fmt.Errorf("listing ReferenceGrant: %w", err) } - refGrants = filterReferenceGrantsFrom(refGrants, fromGroup, fromKind, fromNamespace) + refGrants = filterReferenceGrantsFrom(refGrants, groupGateway, fromKind, fromNamespace) refGrants = filterReferenceGrantsTo(refGrants, toGroup, toKind, toName) if len(refGrants) == 0 { return errors.New("missing ReferenceGrant") diff --git a/pkg/provider/kubernetes/gateway/kubernetes_test.go b/pkg/provider/kubernetes/gateway/kubernetes_test.go index 414a85f19..79750f4c8 100644 --- a/pkg/provider/kubernetes/gateway/kubernetes_test.go +++ b/pkg/provider/kubernetes/gateway/kubernetes_test.go @@ -181,7 +181,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, { - desc: "Empty caused by multi ports service with wrong TargetPort", + desc: "Router with service in error caused by wrong TargetPort", entryPoints: map[string]Entrypoint{"web": { Address: ":80", }}, @@ -201,7 +201,7 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -209,7 +209,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -570,7 +570,7 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -578,7 +578,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -665,7 +665,7 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-websecure-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"websecure"}, - Service: "default-http-app-1-my-gateway-websecure-0-wrr", + Service: "default-http-app-1-my-gateway-websecure-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -674,7 +674,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-websecure-0-wrr": { + "default-http-app-1-my-gateway-websecure-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -736,7 +736,7 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-66e726cd8903b49727ae": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-66e726cd8903b49727ae-wrr", Rule: "(Host(`foo.com`) || Host(`bar.com`)) && PathPrefix(`/`)", Priority: 9, RuleSyntax: "v3", @@ -744,7 +744,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-66e726cd8903b49727ae-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -797,7 +797,7 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-baa117c0219e3878749f": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-baa117c0219e3878749f-wrr", Rule: "(Host(`foo.com`) || HostRegexp(`^[a-z0-9-\\.]+\\.bar\\.com$`)) && PathPrefix(`/`)", Priority: 11, RuleSyntax: "v3", @@ -805,7 +805,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-baa117c0219e3878749f-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -858,7 +858,7 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-45eba2eaf40ac792e036": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-45eba2eaf40ac792e036-wrr", Rule: "(Host(`foo.com`) || HostRegexp(`^[a-z0-9-\\.]+\\.foo\\.com$`)) && PathPrefix(`/`)", Priority: 11, RuleSyntax: "v3", @@ -866,7 +866,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-45eba2eaf40ac792e036-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -922,19 +922,19 @@ func TestLoadHTTPRoutes(t *testing.T) { Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100009, RuleSyntax: "v3", - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", }, "default-http-app-1-my-gateway-web-1-d737b4933fa88e68ab8a": { EntryPoints: []string{"web"}, Rule: "Host(`foo.com`) && Path(`/bir`)", Priority: 100008, RuleSyntax: "v3", - Service: "default-http-app-1-my-gateway-web-1-wrr", + Service: "default-http-app-1-my-gateway-web-1-d737b4933fa88e68ab8a-wrr", }, }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -944,7 +944,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, }, - "default-http-app-1-my-gateway-web-1-wrr": { + "default-http-app-1-my-gateway-web-1-d737b4933fa88e68ab8a-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1016,12 +1016,12 @@ func TestLoadHTTPRoutes(t *testing.T) { Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", }, }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1099,14 +1099,14 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-http-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-http-web-0-wrr", + Service: "default-http-app-1-my-gateway-http-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", }, "default-http-app-1-my-gateway-https-websecure-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"websecure"}, - Service: "default-http-app-1-my-gateway-https-websecure-0-wrr", + Service: "default-http-app-1-my-gateway-https-websecure-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -1115,7 +1115,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-http-web-0-wrr": { + "default-http-app-1-my-gateway-http-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1125,7 +1125,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, }, - "default-http-app-1-my-gateway-https-websecure-0-wrr": { + "default-http-app-1-my-gateway-https-websecure-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1192,14 +1192,14 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", }, "default-http-app-1-my-gateway-websecure-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"websecure"}, - Service: "default-http-app-1-my-gateway-websecure-0-wrr", + Service: "default-http-app-1-my-gateway-websecure-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -1208,7 +1208,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1218,7 +1218,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, }, - "default-http-app-1-my-gateway-websecure-0-wrr": { + "default-http-app-1-my-gateway-websecure-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1283,26 +1283,26 @@ func TestLoadHTTPRoutes(t *testing.T) { Rule: "Host(`foo.com`) && (Path(`/bar`) || PathPrefix(`/bar/`)) && Header(`my-header`,`foo`) && Header(`my-header2`,`bar`)", Priority: 10610, RuleSyntax: "v3", - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-6cf37fa71907768d925c-wrr", }, "default-http-app-1-my-gateway-web-2-d23f7039bc8036fb918c": { EntryPoints: []string{"web"}, Rule: "Host(`foo.com`) && PathRegexp(`^/buzz/[0-9]+$`)", Priority: 11408, RuleSyntax: "v3", - Service: "default-http-app-1-my-gateway-web-2-wrr", + Service: "default-http-app-1-my-gateway-web-2-d23f7039bc8036fb918c-wrr", }, "default-http-app-1-my-gateway-web-1-aaba0f24fd26e1ca2276": { EntryPoints: []string{"web"}, Rule: "Host(`foo.com`) && Path(`/bar`) && Header(`my-header`,`bar`)", Priority: 100109, RuleSyntax: "v3", - Service: "default-http-app-1-my-gateway-web-1-wrr", + Service: "default-http-app-1-my-gateway-web-1-aaba0f24fd26e1ca2276-wrr", }, }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-6cf37fa71907768d925c-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1312,7 +1312,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, }, - "default-http-app-1-my-gateway-web-2-wrr": { + "default-http-app-1-my-gateway-web-2-d23f7039bc8036fb918c-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1322,7 +1322,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, }, - "default-http-app-1-my-gateway-web-1-wrr": { + "default-http-app-1-my-gateway-web-1-aaba0f24fd26e1ca2276-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1378,12 +1378,12 @@ func TestLoadHTTPRoutes(t *testing.T) { Rule: "Host(`foo.com`) && (Path(`/foo`) || PathPrefix(`/foo/`)) && Method(`GET`)", Priority: 11408, RuleSyntax: "v3", - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-74ad70a7cf090becdd3c-wrr", }, }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-74ad70a7cf090becdd3c-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1439,12 +1439,12 @@ func TestLoadHTTPRoutes(t *testing.T) { Rule: "Host(`foo.com`) && (Path(`/foo`) || PathPrefix(`/foo/`)) && Query(`foo`,`bar`) && QueryRegexp(`baz`,`buz`)", Priority: 10428, RuleSyntax: "v3", - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-bb7b03c9610e982fd627-wrr", }, }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-bb7b03c9610e982fd627-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1497,7 +1497,7 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-default-my-gateway-web-0-efde1997778109a1f6eb": { EntryPoints: []string{"web"}, - Service: "default-http-app-default-my-gateway-web-0-wrr", + Service: "default-http-app-default-my-gateway-web-0-efde1997778109a1f6eb-wrr", Rule: "Host(`foo.com`) && Path(`/foo`)", Priority: 100008, RuleSyntax: "v3", @@ -1505,7 +1505,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-default-my-gateway-web-0-wrr": { + "default-http-app-default-my-gateway-web-0-efde1997778109a1f6eb-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1558,14 +1558,14 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-default-my-gateway-web-0-efde1997778109a1f6eb": { EntryPoints: []string{"web"}, - Service: "default-http-app-default-my-gateway-web-0-wrr", + Service: "default-http-app-default-my-gateway-web-0-efde1997778109a1f6eb-wrr", Rule: "Host(`foo.com`) && Path(`/foo`)", Priority: 100008, RuleSyntax: "v3", }, "bar-http-app-bar-my-gateway-web-0-66f5c78d03d948e36597": { EntryPoints: []string{"web"}, - Service: "bar-http-app-bar-my-gateway-web-0-wrr", + Service: "bar-http-app-bar-my-gateway-web-0-66f5c78d03d948e36597-wrr", Rule: "Host(`bar.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -1573,7 +1573,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-default-my-gateway-web-0-wrr": { + "default-http-app-default-my-gateway-web-0-efde1997778109a1f6eb-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1583,7 +1583,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, }, - "bar-http-app-bar-my-gateway-web-0-wrr": { + "bar-http-app-bar-my-gateway-web-0-66f5c78d03d948e36597-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1652,7 +1652,7 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "bar-http-app-bar-my-gateway-web-0-66f5c78d03d948e36597": { EntryPoints: []string{"web"}, - Service: "bar-http-app-bar-my-gateway-web-0-wrr", + Service: "bar-http-app-bar-my-gateway-web-0-66f5c78d03d948e36597-wrr", Rule: "Host(`bar.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -1660,7 +1660,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "bar-http-app-bar-my-gateway-web-0-wrr": { + "bar-http-app-bar-my-gateway-web-0-66f5c78d03d948e36597-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1713,7 +1713,7 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-wrr", Rule: "Host(`example.org`) && PathPrefix(`/`)", Priority: 13, RuleSyntax: "v3", @@ -1730,7 +1730,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1783,7 +1783,7 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-wrr", Rule: "Host(`example.org`) && PathPrefix(`/`)", Priority: 13, RuleSyntax: "v3", @@ -1800,7 +1800,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -1853,7 +1853,7 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-wrr", Rule: "Host(`example.org`) && PathPrefix(`/`)", Priority: 13, RuleSyntax: "v3", @@ -1870,7 +1870,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-wrr": { Weighted: &dynamic.WeightedRoundRobin{}, }, }, @@ -1900,7 +1900,7 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-wrr", Rule: "Host(`example.org`) && PathPrefix(`/`)", Priority: 13, RuleSyntax: "v3", @@ -1917,7 +1917,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-wrr": { Weighted: &dynamic.WeightedRoundRobin{}, }, }, @@ -1947,7 +1947,7 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-wrr", Rule: "Host(`example.com`) && (Path(`/foo`) || PathPrefix(`/foo/`))", RuleSyntax: "v3", Priority: 10412, @@ -1962,7 +1962,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -2015,7 +2015,7 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-wrr", Rule: "Host(`example.com`) && (Path(`/foo`) || PathPrefix(`/foo/`))", RuleSyntax: "v3", Priority: 10412, @@ -2030,7 +2030,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -2083,7 +2083,7 @@ func TestLoadHTTPRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-wrr", Rule: "Host(`example.com`) && (Path(`/foo`) || PathPrefix(`/foo/`))", RuleSyntax: "v3", Priority: 10412, @@ -2100,7 +2100,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -2203,7 +2203,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2211,7 +2211,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -2253,7 +2253,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2261,7 +2261,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -2305,7 +2305,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2313,7 +2313,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -2356,7 +2356,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2364,7 +2364,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -2408,7 +2408,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2416,7 +2416,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -2525,7 +2525,7 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2534,7 +2534,7 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -2591,7 +2591,7 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2602,7 +2602,7 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { "default-my-middleware": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}}, }, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -2931,7 +2931,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, }, { - desc: "Empty caused by multi ports service with wrong TargetPort", + desc: "Router with service in error caused by wrong TargetPort", entryPoints: map[string]Entrypoint{"TCP": { Address: ":8080", }}, @@ -2942,9 +2942,30 @@ func TestLoadTCPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{ + "default-TCP-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb": { + EntryPoints: []string{"TCP"}, + Rule: "HostSNI(`*`)", + RuleSyntax: "v3", + Service: "default-TCP-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb-wrr", + }, + }, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{ + "default-TCP-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb-wrr": { + Weighted: &dynamic.TCPWeightedRoundRobin{ + Services: []dynamic.TCPWRRService{{ + Name: "default-TCP-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb-err-lb", + Weight: ptr.To(1), + }}, + }, + }, + "default-TCP-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb-err-lb": { + LoadBalancer: &dynamic.TCPServersLoadBalancer{ + Servers: []dynamic.TCPServer{}, + }, + }, + }, ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ @@ -2969,16 +2990,16 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-tcp-gateway-tcp": { + "default-tcp-app-1-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-1-my-tcp-gateway-tcp-wrr-0", + Service: "default-tcp-app-1-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-tcp-gateway-tcp-wrr-0": { + "default-tcp-app-1-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3027,22 +3048,22 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-tcp-gateway-tcp-1": { + "default-tcp-app-1-my-tcp-gateway-tcp-1-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp-1"}, - Service: "default-tcp-app-1-my-tcp-gateway-tcp-1-wrr-0", + Service: "default-tcp-app-1-my-tcp-gateway-tcp-1-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "default-tcp-app-2-my-tcp-gateway-tcp-2": { + "default-tcp-app-2-my-tcp-gateway-tcp-2-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp-2"}, - Service: "default-tcp-app-2-my-tcp-gateway-tcp-2-wrr-0", + Service: "default-tcp-app-2-my-tcp-gateway-tcp-2-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-tcp-gateway-tcp-1-wrr-0": { + "default-tcp-app-1-my-tcp-gateway-tcp-1-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3052,7 +3073,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, }, }, - "default-tcp-app-2-my-tcp-gateway-tcp-2-wrr-0": { + "default-tcp-app-2-my-tcp-gateway-tcp-2-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3113,30 +3134,22 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-my-tcp-gateway-tcp-1": { + "default-tcp-app-my-tcp-gateway-tcp-1-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp-1"}, - Service: "default-tcp-app-my-tcp-gateway-tcp-1-wrr", + Service: "default-tcp-app-my-tcp-gateway-tcp-1-0-e3b0c44298fc1c149afb-wrr", + Rule: "HostSNI(`*`)", + RuleSyntax: "v3", + }, + "default-tcp-app-my-tcp-gateway-tcp-1-1-e3b0c44298fc1c149afb": { + EntryPoints: []string{"tcp-1"}, + Service: "default-tcp-app-my-tcp-gateway-tcp-1-1-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-my-tcp-gateway-tcp-1-wrr": { - Weighted: &dynamic.TCPWeightedRoundRobin{ - Services: []dynamic.TCPWRRService{ - { - Name: "default-tcp-app-my-tcp-gateway-tcp-1-wrr-0", - Weight: ptr.To(1), - }, - { - Name: "default-tcp-app-my-tcp-gateway-tcp-1-wrr-1", - Weight: ptr.To(1), - }, - }, - }, - }, - "default-tcp-app-my-tcp-gateway-tcp-1-wrr-0": { + "default-tcp-app-my-tcp-gateway-tcp-1-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3146,7 +3159,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, }, }, - "default-tcp-app-my-tcp-gateway-tcp-1-wrr-1": { + "default-tcp-app-my-tcp-gateway-tcp-1-1-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3205,16 +3218,16 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-gateway-tcp": { + "default-tcp-app-1-my-gateway-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-1-my-gateway-tcp-wrr-0", + Service: "default-tcp-app-1-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-gateway-tcp-wrr-0": { + "default-tcp-app-1-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3265,9 +3278,9 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-gateway-tls": { + "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tcp-app-1-my-gateway-tls-wrr-0", + Service: "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, @@ -3275,7 +3288,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-gateway-tls-wrr-0": { + "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{{ Name: "default-whoamitcp-9000", @@ -3329,16 +3342,16 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-default-my-tcp-gateway-tcp": { + "default-tcp-app-default-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-default-my-tcp-gateway-tcp-wrr-0", + Service: "default-tcp-app-default-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-default-my-tcp-gateway-tcp-wrr-0": { + "default-tcp-app-default-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3385,22 +3398,22 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-default-my-tcp-gateway-tcp": { + "default-tcp-app-default-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-default-my-tcp-gateway-tcp-wrr-0", + Service: "default-tcp-app-default-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "bar-tcp-app-bar-my-tcp-gateway-tcp": { + "bar-tcp-app-bar-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "bar-tcp-app-bar-my-tcp-gateway-tcp-wrr-0", + Service: "bar-tcp-app-bar-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-default-my-tcp-gateway-tcp-wrr-0": { + "default-tcp-app-default-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3410,7 +3423,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, }, }, - "bar-tcp-app-bar-my-tcp-gateway-tcp-wrr-0": { + "bar-tcp-app-bar-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3469,16 +3482,16 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "bar-tcp-app-bar-my-tcp-gateway-tcp": { + "bar-tcp-app-bar-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "bar-tcp-app-bar-my-tcp-gateway-tcp-wrr-0", + Service: "bar-tcp-app-bar-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "bar-tcp-app-bar-my-tcp-gateway-tcp-wrr-0": { + "bar-tcp-app-bar-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3685,7 +3698,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, { - desc: "Empty caused by multi ports service with wrong TargetPort", + desc: "Router with service in error caused by wrong TargetPort", entryPoints: map[string]Entrypoint{"TCP": { Address: ":8080", }}, @@ -3696,9 +3709,31 @@ func TestLoadTLSRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{ + "default-tls-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb": { + EntryPoints: []string{"TCP"}, + Rule: "HostSNI(`*`)", + RuleSyntax: "v3", + Service: "default-tls-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb-wrr", + TLS: &dynamic.RouterTCPTLSConfig{}, + }, + }, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{ + "default-tls-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb-wrr": { + Weighted: &dynamic.TCPWeightedRoundRobin{ + Services: []dynamic.TCPWRRService{{ + Name: "default-tls-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb-err-lb", + Weight: ptr.To(1), + }}, + }, + }, + "default-tls-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb-err-lb": { + LoadBalancer: &dynamic.TCPServersLoadBalancer{ + Servers: []dynamic.TCPServer{}, + }, + }, + }, ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ @@ -3766,9 +3801,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-tls-gateway-tcp": { + "default-tcp-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-1-my-tls-gateway-tcp-wrr-0", + Service: "default-tcp-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, @@ -3776,7 +3811,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-tls-gateway-tcp-wrr-0": { + "default-tcp-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3832,9 +3867,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-tls-gateway-tcp": { + "default-tcp-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-1-my-tls-gateway-tcp-wrr-0", + Service: "default-tcp-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -3844,7 +3879,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-tls-gateway-tcp-wrr-0": { + "default-tcp-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3891,9 +3926,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-1-my-tls-gateway-tcp-f0dd0dd89f82eae1c270": { + "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tls-app-1-my-tls-gateway-tcp-f0dd0dd89f82eae1c270-wrr-0", + Service: "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -3903,7 +3938,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-1-my-tls-gateway-tcp-f0dd0dd89f82eae1c270-wrr-0": { + "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3951,16 +3986,16 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-tls-gateway-tls": { + "default-tcp-app-1-my-tls-gateway-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tcp-app-1-my-tls-gateway-tls-wrr-0", + Service: "default-tcp-app-1-my-tls-gateway-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, }, - "default-tls-app-1-my-tls-gateway-tcp-673acf455cb2dab0b43a": { + "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tls-app-1-my-tls-gateway-tcp-673acf455cb2dab0b43a-wrr-0", + Service: "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -3970,7 +4005,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-tls-gateway-tls-wrr-0": { + "default-tcp-app-1-my-tls-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3980,7 +4015,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, - "default-tls-app-1-my-tls-gateway-tcp-673acf455cb2dab0b43a-wrr-0": { + "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4048,9 +4083,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-gateway-tls": { + "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tcp-app-1-my-gateway-tls-wrr-0", + Service: "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, @@ -4058,7 +4093,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-gateway-tls-wrr-0": { + "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4118,9 +4153,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-1-my-gateway-tls-f0dd0dd89f82eae1c270": { + "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tls-app-1-my-gateway-tls-f0dd0dd89f82eae1c270-wrr-0", + Service: "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -4130,7 +4165,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-1-my-gateway-tls-f0dd0dd89f82eae1c270-wrr-0": { + "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4177,9 +4212,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-1-my-gateway-tls-f0dd0dd89f82eae1c270": { + "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tls-app-1-my-gateway-tls-f0dd0dd89f82eae1c270-wrr-0", + Service: "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -4189,7 +4224,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-1-my-gateway-tls-f0dd0dd89f82eae1c270-wrr-0": { + "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4236,9 +4271,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-1-my-gateway-tls-f0dd0dd89f82eae1c270": { + "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tls-app-1-my-gateway-tls-f0dd0dd89f82eae1c270-wrr-0", + Service: "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -4248,7 +4283,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-1-my-gateway-tls-f0dd0dd89f82eae1c270-wrr-0": { + "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4295,9 +4330,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-1-my-gateway-tls-d5342d75658583f03593": { + "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tls-app-1-my-gateway-tls-d5342d75658583f03593-wrr-0", + Service: "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.example.com`) || HostSNI(`bar.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -4307,7 +4342,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-1-my-gateway-tls-d5342d75658583f03593-wrr-0": { + "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4354,9 +4389,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-default-my-gateway-tls-06ae57dcf13ab4c60ee5": { + "default-tls-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tls-app-default-my-gateway-tls-06ae57dcf13ab4c60ee5-wrr-0", + Service: "default-tls-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.default`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -4366,7 +4401,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-default-my-gateway-tls-06ae57dcf13ab4c60ee5-wrr-0": { + "default-tls-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4413,18 +4448,18 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-default-my-gateway-tls-06ae57dcf13ab4c60ee5": { + "default-tls-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tls-app-default-my-gateway-tls-06ae57dcf13ab4c60ee5-wrr-0", + Service: "default-tls-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.default`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ Passthrough: true, }, }, - "bar-tls-app-bar-my-gateway-tls-2279fe75c5156dc5eb26": { + "bar-tls-app-bar-my-gateway-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "bar-tls-app-bar-my-gateway-tls-2279fe75c5156dc5eb26-wrr-0", + Service: "bar-tls-app-bar-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.bar`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -4434,7 +4469,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-default-my-gateway-tls-06ae57dcf13ab4c60ee5-wrr-0": { + "default-tls-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4444,7 +4479,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, - "bar-tls-app-bar-my-gateway-tls-2279fe75c5156dc5eb26-wrr-0": { + "bar-tls-app-bar-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4503,9 +4538,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "bar-tls-app-bar-my-gateway-tls-2279fe75c5156dc5eb26": { + "bar-tls-app-bar-my-gateway-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "bar-tls-app-bar-my-gateway-tls-2279fe75c5156dc5eb26-wrr-0", + Service: "bar-tls-app-bar-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.bar`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -4515,7 +4550,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "bar-tls-app-bar-my-gateway-tls-2279fe75c5156dc5eb26-wrr-0": { + "bar-tls-app-bar-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4562,9 +4597,18 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-my-gateway-tcp-1-673acf455cb2dab0b43a": { + "default-tls-app-my-gateway-tcp-1-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp-1"}, - Service: "default-tls-app-my-gateway-tcp-1-673acf455cb2dab0b43a-wrr", + Service: "default-tls-app-my-gateway-tcp-1-0-e3b0c44298fc1c149afb-wrr", + Rule: "HostSNI(`*`)", + RuleSyntax: "v3", + TLS: &dynamic.RouterTCPTLSConfig{ + Passthrough: true, + }, + }, + "default-tls-app-my-gateway-tcp-1-1-e3b0c44298fc1c149afb": { + EntryPoints: []string{"tcp-1"}, + Service: "default-tls-app-my-gateway-tcp-1-1-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -4574,21 +4618,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-my-gateway-tcp-1-673acf455cb2dab0b43a-wrr": { - Weighted: &dynamic.TCPWeightedRoundRobin{ - Services: []dynamic.TCPWRRService{ - { - Name: "default-tls-app-my-gateway-tcp-1-673acf455cb2dab0b43a-wrr-0", - Weight: ptr.To(1), - }, - { - Name: "default-tls-app-my-gateway-tcp-1-673acf455cb2dab0b43a-wrr-1", - Weight: ptr.To(1), - }, - }, - }, - }, - "default-tls-app-my-gateway-tcp-1-673acf455cb2dab0b43a-wrr-0": { + "default-tls-app-my-gateway-tcp-1-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4598,7 +4628,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, - "default-tls-app-my-gateway-tcp-1-673acf455cb2dab0b43a-wrr-1": { + "default-tls-app-my-gateway-tcp-1-1-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4809,22 +4839,22 @@ func TestLoadMixedRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-gateway-tcp": { + "default-tcp-app-1-my-gateway-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-1-my-gateway-tcp-wrr-0", + Service: "default-tcp-app-1-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "default-tcp-app-1-my-gateway-tls-1": { + "default-tcp-app-1-my-gateway-tls-1-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-1"}, - Service: "default-tcp-app-1-my-gateway-tls-1-wrr-0", + Service: "default-tcp-app-1-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, }, - "default-tls-app-1-my-gateway-tls-2-59130f7db6718b7700c1": { + "default-tls-app-1-my-gateway-tls-2-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-2"}, - Service: "default-tls-app-1-my-gateway-tls-2-59130f7db6718b7700c1-wrr-0", + Service: "default-tls-app-1-my-gateway-tls-2-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`pass.tls.foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -4834,7 +4864,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-gateway-tcp-wrr-0": { + "default-tcp-app-1-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4844,7 +4874,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-tcp-app-1-my-gateway-tls-1-wrr-0": { + "default-tcp-app-1-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4854,7 +4884,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-tls-app-1-my-gateway-tls-2-59130f7db6718b7700c1-wrr-0": { + "default-tls-app-1-my-gateway-tls-2-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4883,14 +4913,14 @@ func TestLoadMixedRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-1-my-gateway-web-0-a431b128267aabc954fd": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-wrr", + Service: "default-http-app-1-my-gateway-web-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", }, "default-http-app-1-my-gateway-websecure-0-a431b128267aabc954fd": { EntryPoints: []string{"websecure"}, - Service: "default-http-app-1-my-gateway-websecure-0-wrr", + Service: "default-http-app-1-my-gateway-websecure-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", @@ -4899,7 +4929,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-wrr": { + "default-http-app-1-my-gateway-web-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -4909,7 +4939,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-http-app-1-my-gateway-websecure-0-wrr": { + "default-http-app-1-my-gateway-websecure-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -4996,22 +5026,22 @@ func TestLoadMixedRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-default-my-gateway-tcp": { + "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-default-my-gateway-tcp-wrr-0", + Service: "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "default-tcp-app-default-my-gateway-tls-1": { + "default-tcp-app-default-my-gateway-tls-1-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-1"}, - Service: "default-tcp-app-default-my-gateway-tls-1-wrr-0", + Service: "default-tcp-app-default-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, }, - "default-tls-app-default-my-gateway-tls-2-59130f7db6718b7700c1": { + "default-tls-app-default-my-gateway-tls-2-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-2"}, - Service: "default-tls-app-default-my-gateway-tls-2-59130f7db6718b7700c1-wrr-0", + Service: "default-tls-app-default-my-gateway-tls-2-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`pass.tls.foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -5021,7 +5051,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-default-my-gateway-tcp-wrr-0": { + "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5031,7 +5061,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-tcp-app-default-my-gateway-tls-1-wrr-0": { + "default-tcp-app-default-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5041,7 +5071,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-tls-app-default-my-gateway-tls-2-59130f7db6718b7700c1-wrr-0": { + "default-tls-app-default-my-gateway-tls-2-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5070,14 +5100,14 @@ func TestLoadMixedRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd": { EntryPoints: []string{"web"}, - Service: "default-http-app-default-my-gateway-web-0-wrr", + Service: "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", }, "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd": { EntryPoints: []string{"websecure"}, - Service: "default-http-app-default-my-gateway-websecure-0-wrr", + Service: "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", @@ -5086,7 +5116,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-default-my-gateway-web-0-wrr": { + "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -5096,7 +5126,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-http-app-default-my-gateway-websecure-0-wrr": { + "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -5155,37 +5185,37 @@ func TestLoadMixedRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-default-my-gateway-tcp": { + "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-default-my-gateway-tcp-wrr-0", + Service: "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "default-tcp-app-default-my-gateway-tls-1": { + "default-tcp-app-default-my-gateway-tls-1-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-1"}, - Service: "default-tcp-app-default-my-gateway-tls-1-wrr-0", + Service: "default-tcp-app-default-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, }, - "default-tls-app-default-my-gateway-tls-2-59130f7db6718b7700c1": { + "default-tls-app-default-my-gateway-tls-2-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-2"}, - Service: "default-tls-app-default-my-gateway-tls-2-59130f7db6718b7700c1-wrr-0", + Service: "default-tls-app-default-my-gateway-tls-2-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`pass.tls.foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ Passthrough: true, }, }, - "bar-tcp-app-bar-my-gateway-tcp": { + "bar-tcp-app-bar-my-gateway-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "bar-tcp-app-bar-my-gateway-tcp-wrr-0", + Service: "bar-tcp-app-bar-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "bar-tcp-app-bar-my-gateway-tls-1": { + "bar-tcp-app-bar-my-gateway-tls-1-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-1"}, - Service: "bar-tcp-app-bar-my-gateway-tls-1-wrr-0", + Service: "bar-tcp-app-bar-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, @@ -5193,7 +5223,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-default-my-gateway-tcp-wrr-0": { + "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5203,7 +5233,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-tcp-app-default-my-gateway-tls-1-wrr-0": { + "default-tcp-app-default-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5213,7 +5243,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-tls-app-default-my-gateway-tls-2-59130f7db6718b7700c1-wrr-0": { + "default-tls-app-default-my-gateway-tls-2-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5247,7 +5277,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-tcp-app-bar-my-gateway-tcp-wrr-0": { + "bar-tcp-app-bar-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5257,7 +5287,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-tcp-app-bar-my-gateway-tls-1-wrr-0": { + "bar-tcp-app-bar-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5274,14 +5304,14 @@ func TestLoadMixedRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd": { EntryPoints: []string{"web"}, - Service: "default-http-app-default-my-gateway-web-0-wrr", + Service: "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", }, "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd": { EntryPoints: []string{"websecure"}, - Service: "default-http-app-default-my-gateway-websecure-0-wrr", + Service: "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", @@ -5289,14 +5319,14 @@ func TestLoadMixedRoutes(t *testing.T) { }, "bar-http-app-bar-my-gateway-web-0-a431b128267aabc954fd": { EntryPoints: []string{"web"}, - Service: "bar-http-app-bar-my-gateway-web-0-wrr", + Service: "bar-http-app-bar-my-gateway-web-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", }, "bar-http-app-bar-my-gateway-websecure-0-a431b128267aabc954fd": { EntryPoints: []string{"websecure"}, - Service: "bar-http-app-bar-my-gateway-websecure-0-wrr", + Service: "bar-http-app-bar-my-gateway-websecure-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", @@ -5305,7 +5335,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-default-my-gateway-web-0-wrr": { + "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -5315,7 +5345,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-http-app-default-my-gateway-websecure-0-wrr": { + "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -5357,7 +5387,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-http-app-bar-my-gateway-web-0-wrr": { + "bar-http-app-bar-my-gateway-web-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -5367,7 +5397,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-http-app-bar-my-gateway-websecure-0-wrr": { + "bar-http-app-bar-my-gateway-websecure-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -5410,22 +5440,22 @@ func TestLoadMixedRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "bar-tcp-app-bar-my-gateway-tcp": { + "bar-tcp-app-bar-my-gateway-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "bar-tcp-app-bar-my-gateway-tcp-wrr-0", + Service: "bar-tcp-app-bar-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "bar-tcp-app-bar-my-gateway-tls-1": { + "bar-tcp-app-bar-my-gateway-tls-1-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-1"}, - Service: "bar-tcp-app-bar-my-gateway-tls-1-wrr-0", + Service: "bar-tcp-app-bar-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, }, - "bar-tls-app-bar-my-gateway-tls-2-59130f7db6718b7700c1": { + "bar-tls-app-bar-my-gateway-tls-2-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-2"}, - Service: "bar-tls-app-bar-my-gateway-tls-2-59130f7db6718b7700c1-wrr-0", + Service: "bar-tls-app-bar-my-gateway-tls-2-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`pass.tls.foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -5447,7 +5477,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-tcp-app-bar-my-gateway-tcp-wrr-0": { + "bar-tcp-app-bar-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5457,7 +5487,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-tcp-app-bar-my-gateway-tls-1-wrr-0": { + "bar-tcp-app-bar-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5467,7 +5497,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-tls-app-bar-my-gateway-tls-2-59130f7db6718b7700c1-wrr-0": { + "bar-tls-app-bar-my-gateway-tls-2-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5484,14 +5514,14 @@ func TestLoadMixedRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "bar-http-app-bar-my-gateway-web-0-a431b128267aabc954fd": { EntryPoints: []string{"web"}, - Service: "bar-http-app-bar-my-gateway-web-0-wrr", + Service: "bar-http-app-bar-my-gateway-web-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", }, "bar-http-app-bar-my-gateway-websecure-0-a431b128267aabc954fd": { EntryPoints: []string{"websecure"}, - Service: "bar-http-app-bar-my-gateway-websecure-0-wrr", + Service: "bar-http-app-bar-my-gateway-websecure-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", @@ -5516,7 +5546,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-http-app-bar-my-gateway-web-0-wrr": { + "bar-http-app-bar-my-gateway-web-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -5526,7 +5556,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-http-app-bar-my-gateway-websecure-0-wrr": { + "bar-http-app-bar-my-gateway-websecure-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -5568,15 +5598,15 @@ func TestLoadMixedRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-default-my-gateway-tcp": { + "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-default-my-gateway-tcp-wrr-0", + Service: "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "default-tcp-app-default-my-gateway-tls": { + "default-tcp-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tcp-app-default-my-gateway-tls-wrr-0", + Service: "default-tcp-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, @@ -5584,7 +5614,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-default-my-gateway-tcp-wrr-0": { + "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5594,7 +5624,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-tcp-app-default-my-gateway-tls-wrr-0": { + "default-tcp-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5623,14 +5653,14 @@ func TestLoadMixedRoutes(t *testing.T) { Routers: map[string]*dynamic.Router{ "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd": { EntryPoints: []string{"web"}, - Service: "default-http-app-default-my-gateway-web-0-wrr", + Service: "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", }, "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd": { EntryPoints: []string{"websecure"}, - Service: "default-http-app-default-my-gateway-websecure-0-wrr", + Service: "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", @@ -5639,7 +5669,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-default-my-gateway-web-0-wrr": { + "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -5649,7 +5679,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-http-app-default-my-gateway-websecure-0-wrr": { + "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -5851,9 +5881,9 @@ func TestLoadRoutesWithReferenceGrants(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-gateway-tls": { + "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tcp-app-1-my-gateway-tls-wrr-0", + Service: "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, @@ -5861,7 +5891,7 @@ func TestLoadRoutesWithReferenceGrants(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-gateway-tls-wrr-0": { + "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{{ Name: "default-whoamitcp-9000", @@ -6002,14 +6032,14 @@ func TestLoadRoutesWithReferenceGrants(t *testing.T) { "default-http-app-1-my-gateway-http-0-d40286ed9f4652ca2108": { EntryPoints: []string{"http"}, Rule: "Host(`foo.example.com`) && PathPrefix(`/`)", - Service: "default-http-app-1-my-gateway-http-0-wrr", + Service: "default-http-app-1-my-gateway-http-0-d40286ed9f4652ca2108-wrr", RuleSyntax: "v3", Priority: 17, }, }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-http-0-wrr": { + "default-http-app-1-my-gateway-http-0-d40286ed9f4652ca2108-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { diff --git a/pkg/provider/kubernetes/gateway/tcproute.go b/pkg/provider/kubernetes/gateway/tcproute.go index 23e7bcd80..63b2e214c 100644 --- a/pkg/provider/kubernetes/gateway/tcproute.go +++ b/pkg/provider/kubernetes/gateway/tcproute.go @@ -6,6 +6,7 @@ import ( "fmt" "net" "strconv" + "strings" "github.com/rs/zerolog/log" "github.com/traefik/traefik/v3/pkg/config/dynamic" @@ -108,182 +109,241 @@ func (p *Provider) loadTCPRoute(listener gatewayListener, route *gatev1alpha2.TC Reason: string(gatev1.RouteConditionResolvedRefs), } - router := dynamic.TCPRouter{ - Rule: "HostSNI(`*`)", - EntryPoints: []string{listener.EPName}, - RuleSyntax: "v3", - } - - if listener.Protocol == gatev1.TLSProtocolType && listener.TLS != nil { - // TODO support let's encrypt - router.TLS = &dynamic.RouterTCPTLSConfig{ - Passthrough: listener.TLS.Mode != nil && *listener.TLS.Mode == gatev1.TLSModePassthrough, - } - } - - // Adding the gateway desc and the entryPoint desc prevents overlapping of routers build from the same routes. - routerName := provider.Normalize(route.Namespace + "-" + route.Name + "-" + listener.GWName + "-" + listener.EPName) - - var ruleServiceNames []string - for i, rule := range route.Spec.Rules { + for ri, rule := range route.Spec.Rules { if rule.BackendRefs == nil { // Should not happen due to validation. // https://github.com/kubernetes-sigs/gateway-api/blob/v0.4.0/apis/v1alpha2/tcproute_types.go#L76 continue } - wrrService, subServices, err := p.loadTCPServices(route.Namespace, rule.BackendRefs) - if err != nil { - return conf, metav1.Condition{ - Type: string(gatev1.RouteConditionResolvedRefs), - Status: metav1.ConditionFalse, - ObservedGeneration: route.Generation, - LastTransitionTime: metav1.Now(), - Reason: string(gatev1.RouteReasonBackendNotFound), - Message: fmt.Sprintf("Cannot load TCPRoute service %s/%s: %v", route.Namespace, route.Name, err), + router := dynamic.TCPRouter{ + Rule: "HostSNI(`*`)", + EntryPoints: []string{listener.EPName}, + RuleSyntax: "v3", + } + + if listener.Protocol == gatev1.TLSProtocolType && listener.TLS != nil { + router.TLS = &dynamic.RouterTCPTLSConfig{ + Passthrough: listener.TLS.Mode != nil && *listener.TLS.Mode == gatev1.TLSModePassthrough, } } - for svcName, svc := range subServices { - conf.TCP.Services[svcName] = svc + // Adding the gateway desc and the entryPoint desc prevents overlapping of routers build from the same routes. + routeKey := provider.Normalize(fmt.Sprintf("%s-%s-%s-%s-%d", route.Namespace, route.Name, listener.GWName, listener.EPName, ri)) + // Routing criteria should be introduced at some point. + routerName := makeRouterName("", routeKey) + + if len(rule.BackendRefs) == 1 && isInternalService(rule.BackendRefs[0]) { + router.Service = string(rule.BackendRefs[0].Name) + conf.TCP.Routers[routerName] = &router + continue } - serviceName := fmt.Sprintf("%s-wrr-%d", routerName, i) - conf.TCP.Services[serviceName] = wrrService + var serviceCondition *metav1.Condition + router.Service, serviceCondition = p.loadTCPWRRService(conf, routerName, rule.BackendRefs, route) + if serviceCondition != nil { + condition = *serviceCondition + } - ruleServiceNames = append(ruleServiceNames, serviceName) - } - - if len(ruleServiceNames) == 1 { - router.Service = ruleServiceNames[0] conf.TCP.Routers[routerName] = &router - return conf, condition } - routeServiceKey := routerName + "-wrr" - routeService := &dynamic.TCPService{Weighted: &dynamic.TCPWeightedRoundRobin{}} - - for _, name := range ruleServiceNames { - service := dynamic.TCPWRRService{Name: name} - service.SetDefaults() - - routeService.Weighted.Services = append(routeService.Weighted.Services, service) - } - - conf.TCP.Services[routeServiceKey] = routeService - - router.Service = routeServiceKey - conf.TCP.Routers[routerName] = &router - return conf, condition } -// loadTCPServices is generating a WRR service, even when there is only one target. -func (p *Provider) loadTCPServices(namespace string, backendRefs []gatev1.BackendRef) (*dynamic.TCPService, map[string]*dynamic.TCPService, error) { - services := map[string]*dynamic.TCPService{} - - wrrSvc := &dynamic.TCPService{ - Weighted: &dynamic.TCPWeightedRoundRobin{ - Services: []dynamic.TCPWRRService{}, - }, +// loadTCPWRRService is generating a WRR service, even when there is only one target. +func (p *Provider) loadTCPWRRService(conf *dynamic.Configuration, routeKey string, backendRefs []gatev1.BackendRef, route *gatev1alpha2.TCPRoute) (string, *metav1.Condition) { + name := routeKey + "-wrr" + if _, ok := conf.TCP.Services[name]; ok { + return name, nil } + var wrr dynamic.TCPWeightedRoundRobin + var condition *metav1.Condition for _, backendRef := range backendRefs { - if backendRef.Group == nil || backendRef.Kind == nil { - // Should not happen as this is validated by kubernetes + svcName, svc, errCondition := p.loadTCPService(route, backendRef) + weight := ptr.To(int(ptr.Deref(backendRef.Weight, 1))) + + if errCondition != nil { + condition = errCondition + + errName := routeKey + "-err-lb" + conf.TCP.Services[errName] = &dynamic.TCPService{ + LoadBalancer: &dynamic.TCPServersLoadBalancer{ + Servers: []dynamic.TCPServer{}, + }, + } + + wrr.Services = append(wrr.Services, dynamic.TCPWRRService{ + Name: errName, + Weight: weight, + }) continue } - if isInternalService(backendRef) { - return nil, nil, fmt.Errorf("traefik internal service %s is not allowed in a WRR loadbalancer", backendRef.Name) + if svc != nil { + conf.TCP.Services[svcName] = svc } - weight := int(ptr.Deref(backendRef.Weight, 1)) + wrr.Services = append(wrr.Services, dynamic.TCPWRRService{ + Name: svcName, + Weight: weight, + }) + } - if isTraefikService(backendRef) { - wrrSvc.Weighted.Services = append(wrrSvc.Weighted.Services, dynamic.TCPWRRService{Name: string(backendRef.Name), Weight: &weight}) - continue + conf.TCP.Services[name] = &dynamic.TCPService{Weighted: &wrr} + return name, condition +} + +func (p *Provider) loadTCPService(route *gatev1alpha2.TCPRoute, backendRef gatev1.BackendRef) (string, *dynamic.TCPService, *metav1.Condition) { + kind := ptr.Deref(backendRef.Kind, kindService) + + group := groupCore + if backendRef.Group != nil && *backendRef.Group != "" { + group = string(*backendRef.Group) + } + + namespace := route.Namespace + if backendRef.Namespace != nil && *backendRef.Namespace != "" { + namespace = string(*backendRef.Namespace) + } + + serviceName := provider.Normalize(namespace + "-" + string(backendRef.Name)) + + if err := p.isReferenceGranted(kindTCPRoute, route.Namespace, group, string(kind), string(backendRef.Name), namespace); err != nil { + return serviceName, nil, &metav1.Condition{ + Type: string(gatev1.RouteConditionResolvedRefs), + Status: metav1.ConditionFalse, + ObservedGeneration: route.Generation, + LastTransitionTime: metav1.Now(), + Reason: string(gatev1.RouteReasonRefNotPermitted), + Message: fmt.Sprintf("Cannot load TCPRoute BackendRef %s/%s/%s/%s: %s", group, kind, namespace, backendRef.Name, err), } + } - if *backendRef.Group != "" && *backendRef.Group != groupCore && *backendRef.Kind != "Service" { - return nil, nil, fmt.Errorf("unsupported BackendRef %s/%s/%s", *backendRef.Group, *backendRef.Kind, backendRef.Name) - } - - if backendRef.Port == nil { - return nil, nil, errors.New("port is required for Kubernetes Service reference") - } - - service, exists, err := p.client.GetService(namespace, string(backendRef.Name)) + if group != groupCore || kind != kindService { + name, err := p.loadTCPBackendRef(backendRef) if err != nil { - return nil, nil, fmt.Errorf("getting service: %w", err) - } - if !exists { - return nil, nil, errors.New("service not found") + return serviceName, nil, &metav1.Condition{ + Type: string(gatev1.RouteConditionResolvedRefs), + Status: metav1.ConditionFalse, + ObservedGeneration: route.Generation, + LastTransitionTime: metav1.Now(), + Reason: string(gatev1.RouteReasonInvalidKind), + Message: fmt.Sprintf("Cannot load TCPRoute BackendRef %s/%s/%s/%s: %s", group, kind, namespace, backendRef.Name, err), + } } - var svcPort *corev1.ServicePort - for _, p := range service.Spec.Ports { - if p.Port == int32(*backendRef.Port) { - svcPort = &p + return name, nil, nil + } + + port := ptr.Deref(backendRef.Port, gatev1.PortNumber(0)) + if port == 0 { + return serviceName, nil, &metav1.Condition{ + Type: string(gatev1.RouteConditionResolvedRefs), + Status: metav1.ConditionFalse, + ObservedGeneration: route.Generation, + LastTransitionTime: metav1.Now(), + Reason: string(gatev1.RouteReasonUnsupportedProtocol), + Message: fmt.Sprintf("Cannot load TCPRoute BackendRef %s/%s/%s/%s port is required", group, kind, namespace, backendRef.Name), + } + } + + portStr := strconv.FormatInt(int64(port), 10) + serviceName = provider.Normalize(serviceName + "-" + portStr) + + lb, err := p.loadTCPServers(namespace, backendRef) + if err != nil { + return serviceName, nil, &metav1.Condition{ + Type: string(gatev1.RouteConditionResolvedRefs), + Status: metav1.ConditionFalse, + ObservedGeneration: route.Generation, + LastTransitionTime: metav1.Now(), + Reason: string(gatev1.RouteReasonBackendNotFound), + Message: fmt.Sprintf("Cannot load TCPRoute BackendRef %s/%s/%s/%s: %s", group, kind, namespace, backendRef.Name, err), + } + } + + return serviceName, &dynamic.TCPService{LoadBalancer: lb}, nil +} + +func (p *Provider) loadTCPServers(namespace string, backendRef gatev1.BackendRef) (*dynamic.TCPServersLoadBalancer, error) { + if backendRef.Port == nil { + return nil, errors.New("port is required for Kubernetes Service reference") + } + + service, exists, err := p.client.GetService(namespace, string(backendRef.Name)) + if err != nil { + return nil, fmt.Errorf("getting service: %w", err) + } + if !exists { + return nil, errors.New("service not found") + } + + var svcPort *corev1.ServicePort + for _, p := range service.Spec.Ports { + if p.Port == int32(*backendRef.Port) { + svcPort = &p + break + } + } + if svcPort == nil { + return nil, fmt.Errorf("service port %d not found", *backendRef.Port) + } + + endpointSlices, err := p.client.ListEndpointSlicesForService(namespace, string(backendRef.Name)) + if err != nil { + return nil, fmt.Errorf("getting endpointslices: %w", err) + } + if len(endpointSlices) == 0 { + return nil, errors.New("endpointslices not found") + } + + lb := &dynamic.TCPServersLoadBalancer{} + + addresses := map[string]struct{}{} + for _, endpointSlice := range endpointSlices { + var port int32 + for _, p := range endpointSlice.Ports { + if svcPort.Name == *p.Name { + port = *p.Port break } } - if svcPort == nil { - return nil, nil, fmt.Errorf("service port %d not found", *backendRef.Port) + if port == 0 { + continue } - endpointSlices, err := p.client.ListEndpointSlicesForService(namespace, string(backendRef.Name)) - if err != nil { - return nil, nil, fmt.Errorf("getting endpointslices: %w", err) - } - if len(endpointSlices) == 0 { - return nil, nil, errors.New("endpointslices not found") - } - - svc := dynamic.TCPService{LoadBalancer: &dynamic.TCPServersLoadBalancer{}} - - addresses := map[string]struct{}{} - for _, endpointSlice := range endpointSlices { - var port int32 - for _, p := range endpointSlice.Ports { - if svcPort.Name == *p.Name { - port = *p.Port - break - } - } - if port == 0 { + for _, endpoint := range endpointSlice.Endpoints { + if endpoint.Conditions.Ready == nil || !*endpoint.Conditions.Ready { continue } - for _, endpoint := range endpointSlice.Endpoints { - if endpoint.Conditions.Ready == nil || !*endpoint.Conditions.Ready { + for _, address := range endpoint.Addresses { + if _, ok := addresses[address]; ok { continue } - for _, address := range endpoint.Addresses { - if _, ok := addresses[address]; ok { - continue - } - - addresses[address] = struct{}{} - svc.LoadBalancer.Servers = append(svc.LoadBalancer.Servers, dynamic.TCPServer{ - Address: net.JoinHostPort(address, strconv.Itoa(int(port))), - }) - } + addresses[address] = struct{}{} + lb.Servers = append(lb.Servers, dynamic.TCPServer{ + // TODO determine whether the servers needs TLS, from the port? + Address: net.JoinHostPort(address, strconv.Itoa(int(port))), + }) } } - - serviceName := provider.Normalize(service.Namespace + "-" + service.Name + "-" + strconv.Itoa(int(svcPort.Port))) - services[serviceName] = &svc - - wrrSvc.Weighted.Services = append(wrrSvc.Weighted.Services, dynamic.TCPWRRService{Name: serviceName, Weight: &weight}) } - if len(wrrSvc.Weighted.Services) == 0 { - return nil, nil, errors.New("no service has been created") + return lb, nil +} + +func (p *Provider) loadTCPBackendRef(backendRef gatev1.BackendRef) (string, error) { + // Support for cross-provider references (e.g: api@internal). + // This provides the same behavior as for IngressRoutes. + if *backendRef.Kind == "TraefikService" && strings.Contains(string(backendRef.Name), "@") { + return string(backendRef.Name), nil } - return wrrSvc, services, nil + return "", fmt.Errorf("unsupported BackendRef %s/%s/%s", *backendRef.Group, *backendRef.Kind, backendRef.Name) } func mergeTCPConfiguration(from, to *dynamic.Configuration) { diff --git a/pkg/provider/kubernetes/gateway/tlsroute.go b/pkg/provider/kubernetes/gateway/tlsroute.go index b8a853a44..adbff1da5 100644 --- a/pkg/provider/kubernetes/gateway/tlsroute.go +++ b/pkg/provider/kubernetes/gateway/tlsroute.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "regexp" + "strconv" "strings" "github.com/rs/zerolog/log" @@ -11,6 +12,7 @@ import ( "github.com/traefik/traefik/v3/pkg/provider" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ktypes "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" gatev1 "sigs.k8s.io/gateway-api/apis/v1" gatev1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" ) @@ -109,74 +111,159 @@ func (p *Provider) loadTLSRoute(listener gatewayListener, route *gatev1alpha2.TL Reason: string(gatev1.RouteConditionResolvedRefs), } - router := dynamic.TCPRouter{ - RuleSyntax: "v3", - Rule: hostSNIRule(hostnames), - EntryPoints: []string{listener.EPName}, - TLS: &dynamic.RouterTCPTLSConfig{ - Passthrough: listener.TLS != nil && listener.TLS.Mode != nil && *listener.TLS.Mode == gatev1.TLSModePassthrough, - }, - } - - // Adding the gateway desc and the entryPoint desc prevents overlapping of routers build from the same routes. - routeKey := provider.Normalize(route.Namespace + "-" + route.Name + "-" + listener.GWName + "-" + listener.EPName) - routerName := makeRouterName(router.Rule, routeKey) - - var ruleServiceNames []string - for i, routeRule := range route.Spec.Rules { + for ri, routeRule := range route.Spec.Rules { if len(routeRule.BackendRefs) == 0 { // Should not happen due to validation. // https://github.com/kubernetes-sigs/gateway-api/blob/v0.4.0/apis/v1alpha2/tlsroute_types.go#L120 continue } - wrrService, subServices, err := p.loadTCPServices(route.Namespace, routeRule.BackendRefs) + router := dynamic.TCPRouter{ + RuleSyntax: "v3", + Rule: hostSNIRule(hostnames), + EntryPoints: []string{listener.EPName}, + TLS: &dynamic.RouterTCPTLSConfig{ + Passthrough: listener.TLS != nil && listener.TLS.Mode != nil && *listener.TLS.Mode == gatev1.TLSModePassthrough, + }, + } + + // Adding the gateway desc and the entryPoint desc prevents overlapping of routers build from the same routes. + routeKey := provider.Normalize(fmt.Sprintf("%s-%s-%s-%s-%d", route.Namespace, route.Name, listener.GWName, listener.EPName, ri)) + // Routing criteria should be introduced at some point. + routerName := makeRouterName("", routeKey) + + if len(routeRule.BackendRefs) == 1 && isInternalService(routeRule.BackendRefs[0]) { + router.Service = string(routeRule.BackendRefs[0].Name) + conf.TCP.Routers[routerName] = &router + continue + } + + var serviceCondition *metav1.Condition + router.Service, serviceCondition = p.loadTLSWRRService(conf, routerName, routeRule.BackendRefs, route) + if serviceCondition != nil { + condition = *serviceCondition + } + + conf.TCP.Routers[routerName] = &router + } + + return conf, condition +} + +// loadTLSWRRService is generating a WRR service, even when there is only one target. +func (p *Provider) loadTLSWRRService(conf *dynamic.Configuration, routeKey string, backendRefs []gatev1.BackendRef, route *gatev1alpha2.TLSRoute) (string, *metav1.Condition) { + name := routeKey + "-wrr" + if _, ok := conf.TCP.Services[name]; ok { + return name, nil + } + + var wrr dynamic.TCPWeightedRoundRobin + var condition *metav1.Condition + for _, backendRef := range backendRefs { + svcName, svc, errCondition := p.loadTLSService(route, backendRef) + weight := ptr.To(int(ptr.Deref(backendRef.Weight, 1))) + + if errCondition != nil { + condition = errCondition + + errName := routeKey + "-err-lb" + conf.TCP.Services[errName] = &dynamic.TCPService{ + LoadBalancer: &dynamic.TCPServersLoadBalancer{ + Servers: []dynamic.TCPServer{}, + }, + } + + wrr.Services = append(wrr.Services, dynamic.TCPWRRService{ + Name: errName, + Weight: weight, + }) + continue + } + + if svc != nil { + conf.TCP.Services[svcName] = svc + } + + wrr.Services = append(wrr.Services, dynamic.TCPWRRService{ + Name: svcName, + Weight: weight, + }) + } + + conf.TCP.Services[name] = &dynamic.TCPService{Weighted: &wrr} + return name, condition +} + +func (p *Provider) loadTLSService(route *gatev1alpha2.TLSRoute, backendRef gatev1.BackendRef) (string, *dynamic.TCPService, *metav1.Condition) { + kind := ptr.Deref(backendRef.Kind, kindService) + + group := groupCore + if backendRef.Group != nil && *backendRef.Group != "" { + group = string(*backendRef.Group) + } + + namespace := route.Namespace + if backendRef.Namespace != nil && *backendRef.Namespace != "" { + namespace = string(*backendRef.Namespace) + } + + serviceName := provider.Normalize(namespace + "-" + string(backendRef.Name)) + + if err := p.isReferenceGranted(kindTLSRoute, route.Namespace, group, string(kind), string(backendRef.Name), namespace); err != nil { + return serviceName, nil, &metav1.Condition{ + Type: string(gatev1.RouteConditionResolvedRefs), + Status: metav1.ConditionFalse, + ObservedGeneration: route.Generation, + LastTransitionTime: metav1.Now(), + Reason: string(gatev1.RouteReasonRefNotPermitted), + Message: fmt.Sprintf("Cannot load TLSRoute BackendRef %s/%s/%s/%s: %s", group, kind, namespace, backendRef.Name, err), + } + } + + if group != groupCore || kind != kindService { + name, err := p.loadTCPBackendRef(backendRef) if err != nil { - // update "ResolvedRefs" status true with "InvalidBackendRefs" reason - condition = metav1.Condition{ + return serviceName, nil, &metav1.Condition{ Type: string(gatev1.RouteConditionResolvedRefs), Status: metav1.ConditionFalse, ObservedGeneration: route.Generation, LastTransitionTime: metav1.Now(), - Reason: string(gatev1.RouteReasonBackendNotFound), - Message: fmt.Sprintf("Cannot load TLSRoute service %s/%s: %v", route.Namespace, route.Name, err), + Reason: string(gatev1.RouteReasonInvalidKind), + Message: fmt.Sprintf("Cannot load TLSRoute BackendRef %s/%s/%s/%s: %s", group, kind, namespace, backendRef.Name, err), } - continue } - for svcName, svc := range subServices { - conf.TCP.Services[svcName] = svc + return name, nil, nil + } + + port := ptr.Deref(backendRef.Port, gatev1.PortNumber(0)) + if port == 0 { + return serviceName, nil, &metav1.Condition{ + Type: string(gatev1.RouteConditionResolvedRefs), + Status: metav1.ConditionFalse, + ObservedGeneration: route.Generation, + LastTransitionTime: metav1.Now(), + Reason: string(gatev1.RouteReasonUnsupportedProtocol), + Message: fmt.Sprintf("Cannot load TLSRoute BackendRef %s/%s/%s/%s port is required", group, kind, namespace, backendRef.Name), } - - serviceName := fmt.Sprintf("%s-wrr-%d", routerName, i) - conf.TCP.Services[serviceName] = wrrService - - ruleServiceNames = append(ruleServiceNames, serviceName) } - if len(ruleServiceNames) == 1 { - router.Service = ruleServiceNames[0] - conf.TCP.Routers[routerName] = &router + portStr := strconv.FormatInt(int64(port), 10) + serviceName = provider.Normalize(serviceName + "-" + portStr) - return conf, condition + lb, err := p.loadTCPServers(namespace, backendRef) + if err != nil { + return serviceName, nil, &metav1.Condition{ + Type: string(gatev1.RouteConditionResolvedRefs), + Status: metav1.ConditionFalse, + ObservedGeneration: route.Generation, + LastTransitionTime: metav1.Now(), + Reason: string(gatev1.RouteReasonBackendNotFound), + Message: fmt.Sprintf("Cannot load TLSRoute BackendRef %s/%s/%s/%s: %s", group, kind, namespace, backendRef.Name, err), + } } - routeServiceKey := routerName + "-wrr" - routeService := &dynamic.TCPService{Weighted: &dynamic.TCPWeightedRoundRobin{}} - - for _, name := range ruleServiceNames { - service := dynamic.TCPWRRService{Name: name} - service.SetDefaults() - - routeService.Weighted.Services = append(routeService.Weighted.Services, service) - } - - conf.TCP.Services[routeServiceKey] = routeService - - router.Service = routeServiceKey - conf.TCP.Routers[routerName] = &router - - return conf, condition + return serviceName, &dynamic.TCPService{LoadBalancer: lb}, nil } func hostSNIRule(hostnames []gatev1.Hostname) string {