From 11d251415a6fd935025df5a9dda898e17e3097b2 Mon Sep 17 00:00:00 2001 From: "Gina A." <70909035+gndz07@users.noreply.github.com> Date: Tue, 17 Mar 2026 15:12:05 +0100 Subject: [PATCH] Fix ingress router's rule Co-authored-by: Mathis Urien --- .../kubernetes/ingress-nginx/kubernetes.go | 22 +-- .../ingress-nginx/kubernetes_test.go | 34 ++--- pkg/provider/kubernetes/ingress/kubernetes.go | 16 +-- .../kubernetes/ingress/kubernetes_test.go | 128 +++++++++--------- pkg/provider/kubernetes/knative/kubernetes.go | 6 +- .../kubernetes/knative/kubernetes_test.go | 32 ++--- 6 files changed, 119 insertions(+), 119 deletions(-) diff --git a/pkg/provider/kubernetes/ingress-nginx/kubernetes.go b/pkg/provider/kubernetes/ingress-nginx/kubernetes.go index aff6f8beec..30451e919e 100644 --- a/pkg/provider/kubernetes/ingress-nginx/kubernetes.go +++ b/pkg/provider/kubernetes/ingress-nginx/kubernetes.go @@ -232,7 +232,7 @@ func (p *Provider) loadConfiguration(ctx context.Context) *dynamic.Configuration // Add the default backend service router to the configuration. conf.HTTP.Routers[defaultBackendName] = &dynamic.Router{ - Rule: "PathPrefix(`/`)", + Rule: `PathPrefix("/")`, // "default" stands for the default rule syntax in Traefik v3, i.e. the v3 syntax. RuleSyntax: "default", Priority: math.MinInt32, @@ -240,7 +240,7 @@ func (p *Provider) loadConfiguration(ctx context.Context) *dynamic.Configuration } conf.HTTP.Routers[defaultBackendTLSName] = &dynamic.Router{ - Rule: "PathPrefix(`/`)", + Rule: `PathPrefix("/")`, // "default" stands for the default rule syntax in Traefik v3, i.e. the v3 syntax. RuleSyntax: "default", Priority: math.MinInt32, @@ -309,7 +309,7 @@ func (p *Provider) loadConfiguration(ctx context.Context) *dynamic.Configuration if defaultBackendService != nil && len(ingress.Spec.Rules) == 0 { rt := &dynamic.Router{ - Rule: "PathPrefix(`/`)", + Rule: `PathPrefix("/")`, // "default" stands for the default rule syntax in Traefik v3, i.e. the v3 syntax. RuleSyntax: "default", Priority: math.MinInt32, @@ -323,7 +323,7 @@ func (p *Provider) loadConfiguration(ctx context.Context) *dynamic.Configuration conf.HTTP.Routers[defaultBackendName] = rt rtTLS := &dynamic.Router{ - Rule: "PathPrefix(`/`)", + Rule: `PathPrefix("/")`, // "default" stands for the default rule syntax in Traefik v3, i.e. the v3 syntax. RuleSyntax: "default", Priority: math.MinInt32, @@ -386,7 +386,7 @@ func (p *Provider) loadConfiguration(ctx context.Context) *dynamic.Configuration routerKey := strings.TrimPrefix(provider.Normalize(ingress.Namespace+"-"+ingress.Name+"-"+rule.Host), "-") conf.TCP.Routers[routerKey] = &dynamic.TCPRouter{ - Rule: fmt.Sprintf("HostSNI(`%s`)", rule.Host), + Rule: fmt.Sprintf("HostSNI(%q)", rule.Host), // "default" stands for the default rule syntax in Traefik v3, i.e. the v3 syntax. RuleSyntax: "default", Service: serviceName, @@ -1063,10 +1063,10 @@ func buildRule(host string, pa netv1.HTTPIngressPath, config ingressConfig) stri switch pathType { case netv1.PathTypeExact: - rules = append(rules, fmt.Sprintf("Path(`%s`)", pa.Path)) + rules = append(rules, fmt.Sprintf("Path(%q)", pa.Path)) case netv1.PathTypePrefix: if ptr.Deref(config.UseRegex, false) { - rules = append(rules, fmt.Sprintf("PathRegexp(`^%s`)", pa.Path)) + rules = append(rules, fmt.Sprintf("PathRegexp(%q)", fmt.Sprintf("^%s", pa.Path))) } else { rules = append(rules, buildPrefixRule(pa.Path)) } @@ -1079,10 +1079,10 @@ func buildRule(host string, pa netv1.HTTPIngressPath, config ingressConfig) stri func buildHostRule(host string) string { if strings.HasPrefix(host, "*.") { host = strings.Replace(regexp.QuoteMeta(host), `\*\.`, `[a-zA-Z0-9-]+\.`, 1) - return fmt.Sprintf("HostRegexp(`^%s$`)", host) + return fmt.Sprintf("HostRegexp(%q)", fmt.Sprintf("^%s$", host)) } - return fmt.Sprintf("Host(`%s`)", host) + return fmt.Sprintf("Host(%q)", host) } // buildPrefixRule is a helper function to build a path prefix rule that matches path prefix split by `/`. @@ -1093,11 +1093,11 @@ func buildHostRule(host string) string { // Kubernetes Ingress API. func buildPrefixRule(path string) string { if path == "/" { - return "PathPrefix(`/`)" + return `PathPrefix("/")` } path = strings.TrimSuffix(path, "/") - return fmt.Sprintf("(Path(`%[1]s`) || PathPrefix(`%[1]s/`))", path) + return fmt.Sprintf("(Path(%q) || PathPrefix(%q))", path, fmt.Sprintf("%s/", path)) } func throttleEvents(ctx context.Context, throttleDuration time.Duration, pool *safe.Pool, eventsChan <-chan any) chan any { diff --git a/pkg/provider/kubernetes/ingress-nginx/kubernetes_test.go b/pkg/provider/kubernetes/ingress-nginx/kubernetes_test.go index e13a66edfb..ffea96b564 100644 --- a/pkg/provider/kubernetes/ingress-nginx/kubernetes_test.go +++ b/pkg/provider/kubernetes/ingress-nginx/kubernetes_test.go @@ -62,14 +62,14 @@ func TestLoadIngresses(t *testing.T) { HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ "default-ingress-with-no-annotation-rule-0-path-0": { - Rule: "Host(`whoami.localhost`) && PathPrefix(`/`)", + Rule: `Host("whoami.localhost") && PathPrefix("/")`, RuleSyntax: "default", TLS: &dynamic.RouterTLSConfig{}, Service: "default-ingress-with-no-annotation-whoami-80", }, "default-ingress-with-no-annotation-rule-0-path-0-http": { EntryPoints: []string{"web"}, - Rule: "Host(`whoami.localhost`) && PathPrefix(`/`)", + Rule: `Host("whoami.localhost") && PathPrefix("/")`, RuleSyntax: "default", Middlewares: []string{"default-ingress-with-no-annotation-rule-0-path-0-redirect-scheme"}, Service: "noop@internal", @@ -131,7 +131,7 @@ func TestLoadIngresses(t *testing.T) { HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ "default-ingress-with-basicauth-rule-0-path-0": { - Rule: "Host(`whoami.localhost`) && Path(`/basicauth`)", + Rule: `Host("whoami.localhost") && Path("/basicauth")`, RuleSyntax: "default", Middlewares: []string{"default-ingress-with-basicauth-rule-0-path-0-basic-auth"}, Service: "default-ingress-with-basicauth-whoami-80", @@ -186,7 +186,7 @@ func TestLoadIngresses(t *testing.T) { HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ "default-ingress-with-forwardauth-rule-0-path-0": { - Rule: "Host(`whoami.localhost`) && Path(`/forwardauth`)", + Rule: `Host("whoami.localhost") && Path("/forwardauth")`, RuleSyntax: "default", Middlewares: []string{"default-ingress-with-forwardauth-rule-0-path-0-forward-auth"}, Service: "default-ingress-with-forwardauth-whoami-80", @@ -240,32 +240,32 @@ func TestLoadIngresses(t *testing.T) { HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ "default-ingress-with-ssl-redirect-rule-0-path-0": { - Rule: "Host(`sslredirect.localhost`) && Path(`/`)", + Rule: `Host("sslredirect.localhost") && Path("/")`, RuleSyntax: "default", TLS: &dynamic.RouterTLSConfig{}, Service: "default-ingress-with-ssl-redirect-whoami-80", }, "default-ingress-with-ssl-redirect-rule-0-path-0-http": { EntryPoints: []string{"web"}, - Rule: "Host(`sslredirect.localhost`) && Path(`/`)", + Rule: `Host("sslredirect.localhost") && Path("/")`, RuleSyntax: "default", Middlewares: []string{"default-ingress-with-ssl-redirect-rule-0-path-0-redirect-scheme"}, Service: "noop@internal", }, "default-ingress-without-ssl-redirect-rule-0-path-0-http": { EntryPoints: []string{"web"}, - Rule: "Host(`withoutsslredirect.localhost`) && Path(`/`)", + Rule: `Host("withoutsslredirect.localhost") && Path("/")`, RuleSyntax: "default", Service: "default-ingress-without-ssl-redirect-whoami-80", }, "default-ingress-without-ssl-redirect-rule-0-path-0": { - Rule: "Host(`withoutsslredirect.localhost`) && Path(`/`)", + Rule: `Host("withoutsslredirect.localhost") && Path("/")`, RuleSyntax: "default", TLS: &dynamic.RouterTLSConfig{}, Service: "default-ingress-without-ssl-redirect-whoami-80", }, "default-ingress-with-force-ssl-redirect-rule-0-path-0": { - Rule: "Host(`forcesslredirect.localhost`) && Path(`/`)", + Rule: `Host("forcesslredirect.localhost") && Path("/")`, RuleSyntax: "default", Middlewares: []string{"default-ingress-with-force-ssl-redirect-rule-0-path-0-redirect-scheme"}, Service: "default-ingress-with-force-ssl-redirect-whoami-80", @@ -364,7 +364,7 @@ func TestLoadIngresses(t *testing.T) { TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ "default-ingress-with-ssl-passthrough-passthrough-whoami-localhost": { - Rule: "HostSNI(`passthrough.whoami.localhost`)", + Rule: `HostSNI("passthrough.whoami.localhost")`, RuleSyntax: "default", TLS: &dynamic.RouterTCPTLSConfig{ Passthrough: true, @@ -412,7 +412,7 @@ func TestLoadIngresses(t *testing.T) { HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ "default-ingress-with-sticky-rule-0-path-0": { - Rule: "Host(`sticky.localhost`) && Path(`/`)", + Rule: `Host("sticky.localhost") && Path("/")`, RuleSyntax: "default", Service: "default-ingress-with-sticky-whoami-80", }, @@ -469,7 +469,7 @@ func TestLoadIngresses(t *testing.T) { HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ "default-ingress-with-proxy-ssl-rule-0-path-0": { - Rule: "Host(`proxy-ssl.localhost`) && Path(`/`)", + Rule: `Host("proxy-ssl.localhost") && Path("/")`, RuleSyntax: "default", Service: "default-ingress-with-proxy-ssl-whoami-tls-443", }, @@ -521,7 +521,7 @@ func TestLoadIngresses(t *testing.T) { HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ "default-ingress-with-cors-rule-0-path-0": { - Rule: "Host(`cors.localhost`) && Path(`/`)", + Rule: `Host("cors.localhost") && Path("/")`, RuleSyntax: "default", Middlewares: []string{"default-ingress-with-cors-rule-0-path-0-cors"}, Service: "default-ingress-with-cors-whoami-80", @@ -578,7 +578,7 @@ func TestLoadIngresses(t *testing.T) { HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ "default-ingress-with-service-upstream-rule-0-path-0": { - Rule: "Host(`service-upstream.localhost`) && Path(`/`)", + Rule: `Host("service-upstream.localhost") && Path("/")`, RuleSyntax: "default", Service: "default-ingress-with-service-upstream-whoami-80", }, @@ -620,7 +620,7 @@ func TestLoadIngresses(t *testing.T) { HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ "default-ingress-with-use-regex-rule-0-path-0": { - Rule: "Host(`use-regex.localhost`) && PathRegexp(`^/test(.*)`)", + Rule: `Host("use-regex.localhost") && PathRegexp("^/test(.*)")`, RuleSyntax: "default", Service: "default-ingress-with-use-regex-whoami-80", }, @@ -665,13 +665,13 @@ func TestLoadIngresses(t *testing.T) { HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ "default-backend": { - Rule: "PathPrefix(`/`)", + Rule: `PathPrefix("/")`, RuleSyntax: "default", Priority: math.MinInt32, Service: "default-backend", }, "default-backend-tls": { - Rule: "PathPrefix(`/`)", + Rule: `PathPrefix("/")`, RuleSyntax: "default", Priority: math.MinInt32, TLS: &dynamic.RouterTLSConfig{}, diff --git a/pkg/provider/kubernetes/ingress/kubernetes.go b/pkg/provider/kubernetes/ingress/kubernetes.go index 714aebdfbb..bd8d1f3097 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes.go +++ b/pkg/provider/kubernetes/ingress/kubernetes.go @@ -299,7 +299,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl } rt := &dynamic.Router{ - Rule: "PathPrefix(`/`)", + Rule: `PathPrefix("/")`, // "default" stands for the default rule syntax in Traefik v3, i.e. the v3 syntax. RuleSyntax: "default", Priority: math.MinInt32, @@ -730,19 +730,19 @@ func (p *Provider) loadRouter(rule netv1.IngressRule, pa netv1.HTTPIngressPath, func buildHostRuleV2(host string) string { if strings.HasPrefix(host, "*.") { host = strings.Replace(host, "*.", "{subdomain:[a-zA-Z0-9-]+}.", 1) - return fmt.Sprintf("HostRegexp(`%s`)", host) + return fmt.Sprintf("HostRegexp(%q)", host) } - return fmt.Sprintf("Host(`%s`)", host) + return fmt.Sprintf("Host(%q)", host) } func buildHostRule(host string) string { if strings.HasPrefix(host, "*.") { host = strings.Replace(regexp.QuoteMeta(host), `\*\.`, `[a-zA-Z0-9-]+\.`, 1) - return fmt.Sprintf("HostRegexp(`^%s$`)", host) + return fmt.Sprintf("HostRegexp(%q)", fmt.Sprintf("^%s$", host)) } - return fmt.Sprintf("Host(`%s`)", host) + return fmt.Sprintf("Host(%q)", host) } func getCertificates(ctx context.Context, ingress *netv1.Ingress, k8sClient Client, tlsConfigs map[string]*tls.CertAndStores) error { @@ -883,7 +883,7 @@ func buildRule(strictPrefixMatching bool, matcher string, path string) string { return buildStrictPrefixMatchingRule(path) } - return fmt.Sprintf("%s(`%s`)", matcher, path) + return fmt.Sprintf("%s(%q)", matcher, path) } // buildStrictPrefixMatchingRule is a helper function to build a path prefix rule that matches path prefix split by `/`. @@ -894,11 +894,11 @@ func buildRule(strictPrefixMatching bool, matcher string, path string) string { // Kubernetes Ingress API. func buildStrictPrefixMatchingRule(path string) string { if path == "/" { - return "PathPrefix(`/`)" + return `PathPrefix("/")` } path = strings.TrimSuffix(path, "/") - return fmt.Sprintf("(Path(`%[1]s`) || PathPrefix(`%[1]s/`))", path) + return fmt.Sprintf("(Path(%q) || PathPrefix(%q))", path, fmt.Sprintf("%s/", path)) } func throttleEvents(ctx context.Context, throttleDuration time.Duration, pool *safe.Pool, eventsChan <-chan any) chan any { diff --git a/pkg/provider/kubernetes/ingress/kubernetes_test.go b/pkg/provider/kubernetes/ingress/kubernetes_test.go index b7aac6014c..924e4b4c62 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes_test.go +++ b/pkg/provider/kubernetes/ingress/kubernetes_test.go @@ -71,7 +71,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "PathPrefix(`/bar`)", + Rule: `PathPrefix("/bar")`, Service: "testing-service1-80", }, }, @@ -104,7 +104,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "Path(`/bar`)", + Rule: `Path("/bar")`, EntryPoints: []string{"ep1", "ep2"}, Service: "testing-service1-80", Middlewares: []string{"md1", "md2"}, @@ -170,11 +170,11 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "PathPrefix(`/bar`)", + Rule: `PathPrefix("/bar")`, Service: "testing-service1-80", }, "testing-foo": { - Rule: "PathPrefix(`/foo`)", + Rule: `PathPrefix("/foo")`, Service: "testing-service1-80", }, }, @@ -206,12 +206,12 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { HTTP: &dynamic.HTTPConfiguration{ Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ - "testing-bar-bar-aba9a7d00e9b06a78e16": { - Rule: "HostRegexp(`^[a-zA-Z0-9-]+\\.bar$`) && PathPrefix(`/bar`)", + "testing-bar-bar-97cb2ba265f7a5df4ab9": { + Rule: `HostRegexp("^[a-zA-Z0-9-]+\\.bar$") && PathPrefix("/bar")`, Service: "testing-service1-80", }, - "testing-bar-bar-636bf36c00fedaab3d44": { - Rule: "Host(`bar`) && PathPrefix(`/bar`)", + "testing-bar-bar-605945111a3c9f84dc65": { + Rule: `Host("bar") && PathPrefix("/bar")`, Service: "testing-service1-80", }, }, @@ -243,12 +243,12 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { HTTP: &dynamic.HTTPConfiguration{ Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ - "testing-foo-bar-d0b30949e54d6a7515ca": { - Rule: "PathPrefix(`/foo/bar`)", + "testing-foo-bar-930f0e8b221e60bc7ab7": { + Rule: `PathPrefix("/foo/bar")`, Service: "testing-service1-80", }, - "testing-foo-bar-dcd54bae39a6d7557f48": { - Rule: "PathPrefix(`/foo-bar`)", + "testing-foo-bar-207cc2245cb31ba18e29": { + Rule: `PathPrefix("/foo-bar")`, Service: "testing-service1-80", }, }, @@ -281,11 +281,11 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "PathPrefix(`/bar`)", + Rule: `PathPrefix("/bar")`, Service: "testing-service1-80", }, "testing-foo": { - Rule: "PathPrefix(`/foo`)", + Rule: `PathPrefix("/foo")`, Service: "testing-service1-80", }, }, @@ -318,7 +318,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "testing-service1-80", }, }, @@ -351,7 +351,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-example-com": { - Rule: "Host(`example.com`)", + Rule: `Host("example.com")`, Service: "testing-example-com-80", }, }, @@ -381,11 +381,11 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "testing-service1-80", }, "testing-traefik-tchouk-foo": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/foo`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/foo")`, Service: "testing-service1-80", }, }, @@ -418,11 +418,11 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "testing-service1-80", }, "testing-traefik-courgette-carotte": { - Rule: "Host(`traefik.courgette`) && PathPrefix(`/carotte`)", + Rule: `Host("traefik.courgette") && PathPrefix("/carotte")`, Service: "testing-service1-80", }, }, @@ -455,11 +455,11 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "testing-service1-80", }, "testing-traefik-courgette-carotte": { - Rule: "Host(`traefik.courgette`) && PathPrefix(`/carotte`)", + Rule: `Host("traefik.courgette") && PathPrefix("/carotte")`, Service: "testing-service2-8082", }, }, @@ -510,7 +510,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "testing-service1-80", }, }, @@ -587,7 +587,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "default-router": { - Rule: "PathPrefix(`/`)", + Rule: `PathPrefix("/")`, RuleSyntax: "default", Service: "default-backend", Priority: math.MinInt32, @@ -622,7 +622,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "testing-service1-80", }, }, @@ -655,7 +655,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "testing-service1-tchouk", }, }, @@ -688,7 +688,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "testing-service1-tchouk", }, }, @@ -721,11 +721,11 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "testing-service1-tchouk", }, "testing-traefik-tchouk-foo": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/foo`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/foo")`, Service: "testing-service1-carotte", }, }, @@ -775,7 +775,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "testing-service1-tchouk", }, }, @@ -808,11 +808,11 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "testing-service1-tchouk", }, "toto-toto-traefik-tchouk-bar": { - Rule: "Host(`toto.traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("toto.traefik.tchouk") && PathPrefix("/bar")`, Service: "toto-service1-tchouk", }, }, @@ -882,7 +882,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-traefik-port-port": { - Rule: "Host(`traefik.port`) && PathPrefix(`/port`)", + Rule: `Host("traefik.port") && PathPrefix("/port")`, Service: "testing-service1-8080", }, }, @@ -912,7 +912,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-example-com": { - Rule: "Host(`example.com`)", + Rule: `Host("example.com")`, Service: "testing-example-com-80", TLS: &dynamic.RouterTLSConfig{}, }, @@ -953,7 +953,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "PathPrefix(`/bar`)", + Rule: `PathPrefix("/bar")`, Service: "testing-service1-443", }, }, @@ -986,7 +986,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "PathPrefix(`/bar`)", + Rule: `PathPrefix("/bar")`, Service: "testing-service1-8443", }, }, @@ -1020,7 +1020,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "PathPrefix(`/bar`)", + Rule: `PathPrefix("/bar")`, Service: "testing-service1-8443", }, }, @@ -1053,7 +1053,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "default-router": { - Rule: "PathPrefix(`/`)", + Rule: `PathPrefix("/")`, RuleSyntax: "default", Service: "default-backend", Priority: math.MinInt32, @@ -1088,7 +1088,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "PathPrefix(`/bar`)", + Rule: `PathPrefix("/bar")`, Service: "testing-service1-80", }, }, @@ -1161,7 +1161,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-foobar-com-bar": { - Rule: "HostRegexp(`^[a-zA-Z0-9-]+\\.foobar\\.com$`) && PathPrefix(`/bar`)", + Rule: `HostRegexp("^[a-zA-Z0-9-]+\\.foobar\\.com$") && PathPrefix("/bar")`, Service: "testing-service1-80", }, }, @@ -1194,7 +1194,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-foobar-com-bar": { - Rule: "HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.foobar.com`) && PathPrefix(`/bar`)", + Rule: `HostRegexp("{subdomain:[a-zA-Z0-9-]+}.foobar.com") && PathPrefix("/bar")`, Service: "testing-service1-80", }, }, @@ -1226,11 +1226,11 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-foo": { - Rule: "PathPrefix(`/foo`)", + Rule: `PathPrefix("/foo")`, Service: "testing-service1-80", }, "testing-bar": { - Rule: "PathPrefix(`/bar`)", + Rule: `PathPrefix("/bar")`, Service: "testing-service1-80", }, }, @@ -1261,7 +1261,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-foo": { - Rule: "PathPrefix(`/foo`)", + Rule: `PathPrefix("/foo")`, Service: "testing-service1-80", }, }, @@ -1291,7 +1291,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "PathPrefix(`/bar`)", + Rule: `PathPrefix("/bar")`, Service: "testing-service1-80", }, }, @@ -1321,7 +1321,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "Path(`/bar`)", + Rule: `Path("/bar")`, Service: "testing-service1-80", }, }, @@ -1351,7 +1351,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "Path(`/bar`)", + Rule: `Path("/bar")`, Service: "testing-service1-80", }, }, @@ -1381,7 +1381,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "Path(`/bar`)", + Rule: `Path("/bar")`, Service: "testing-service1-80", }, }, @@ -1411,7 +1411,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "PathPrefix(`/bar`)", + Rule: `PathPrefix("/bar")`, Service: "testing-service1-80", }, }, @@ -1444,7 +1444,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "PathPrefix(`/bar`)", + Rule: `PathPrefix("/bar")`, Service: "testing-service1-80", }, }, @@ -1477,7 +1477,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "PathPrefix(`/bar`)", + Rule: `PathPrefix("/bar")`, Service: "testing-service1-80", }, }, @@ -1507,7 +1507,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "PathPrefix(`/bar`)", + Rule: `PathPrefix("/bar")`, Service: "testing-service1-80", }, }, @@ -1563,7 +1563,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "PathPrefix(`/bar`)", + Rule: `PathPrefix("/bar")`, Service: "testing-service1-foobar", }, }, @@ -1603,7 +1603,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "default-router": { - Rule: "PathPrefix(`/`)", + Rule: `PathPrefix("/")`, RuleSyntax: "default", Priority: math.MinInt32, Service: "default-backend", @@ -1635,7 +1635,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "PathPrefix(`/bar`)", + Rule: `PathPrefix("/bar")`, Service: "testing-service1-80", }, }, @@ -1676,7 +1676,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-bar": { - Rule: "(Path(`/bar`) || PathPrefix(`/bar/`))", + Rule: `(Path("/bar") || PathPrefix("/bar/"))`, Service: "testing-service1-80", }, }, @@ -1750,7 +1750,7 @@ func TestLoadConfigurationFromIngressesWithExternalNameServices(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "testing-service1-8080", }, }, @@ -1780,7 +1780,7 @@ func TestLoadConfigurationFromIngressesWithExternalNameServices(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-example-com-bar": { - Rule: "PathPrefix(`/bar`)", + Rule: `PathPrefix("/bar")`, Service: "testing-service-bar-8080", }, }, @@ -1811,7 +1811,7 @@ func TestLoadConfigurationFromIngressesWithExternalNameServices(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-example-com-foo": { - Rule: "PathPrefix(`/foo`)", + Rule: `PathPrefix("/foo")`, Service: "testing-service-foo-8080", }, }, @@ -1864,7 +1864,7 @@ func TestLoadConfigurationFromIngressesWithNativeLB(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "testing-service1-8080", }, }, @@ -1914,7 +1914,7 @@ func TestLoadConfigurationFromIngressesWithNodePortLB(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "testing-service1-8080", }, }, @@ -2152,7 +2152,7 @@ func TestLoadConfigurationFromIngressesWithNativeLBByDefault(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "testing-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "testing-service1-8080", }, }, @@ -2180,7 +2180,7 @@ func TestLoadConfigurationFromIngressesWithNativeLBByDefault(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "default-global-native-lb-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "default-service1-8080", }, }, @@ -2208,7 +2208,7 @@ func TestLoadConfigurationFromIngressesWithNativeLBByDefault(t *testing.T) { Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ "default-global-native-lb-traefik-tchouk-bar": { - Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Rule: `Host("traefik.tchouk") && PathPrefix("/bar")`, Service: "default-native-disabled-svc-web", }, }, diff --git a/pkg/provider/kubernetes/knative/kubernetes.go b/pkg/provider/kubernetes/knative/kubernetes.go index a7842a6e00..4ebad6d20b 100644 --- a/pkg/provider/kubernetes/knative/kubernetes.go +++ b/pkg/provider/kubernetes/knative/kubernetes.go @@ -452,7 +452,7 @@ func buildRule(hosts []string, headers map[string]knativenetworkingv1alpha1.Head if len(hosts) > 0 { var hostRules []string for _, host := range hosts { - hostRules = append(hostRules, fmt.Sprintf("Host(`%v`)", host)) + hostRules = append(hostRules, fmt.Sprintf("Host(%q)", host)) } operands = append(operands, fmt.Sprintf("(%s)", strings.Join(hostRules, " || "))) } @@ -463,13 +463,13 @@ func buildRule(hosts []string, headers map[string]knativenetworkingv1alpha1.Head var headerRules []string for _, key := range headerKeys { - headerRules = append(headerRules, fmt.Sprintf("Header(`%s`,`%s`)", key, headers[key].Exact)) + headerRules = append(headerRules, fmt.Sprintf("Header(%q,%q)", key, headers[key].Exact)) } operands = append(operands, fmt.Sprintf("(%s)", strings.Join(headerRules, " && "))) } if len(path) > 0 { - operands = append(operands, fmt.Sprintf("PathPrefix(`%s`)", path)) + operands = append(operands, fmt.Sprintf("PathPrefix(%q)", path)) } return strings.Join(operands, " && ") diff --git a/pkg/provider/kubernetes/knative/kubernetes_test.go b/pkg/provider/kubernetes/knative/kubernetes_test.go index 08ea0e2c35..453cff79f4 100644 --- a/pkg/provider/kubernetes/knative/kubernetes_test.go +++ b/pkg/provider/kubernetes/knative/kubernetes_test.go @@ -55,7 +55,7 @@ func Test_loadConfiguration(t *testing.T) { "default-helloworld-go-rule-0-path-0": { EntryPoints: []string{"priv-http", "priv-https"}, Service: "default-helloworld-go-rule-0-path-0-wrr", - Rule: "(Host(`helloworld-go.default`) || Host(`helloworld-go.default.svc`) || Host(`helloworld-go.default.svc.cluster.local`))", + Rule: `(Host("helloworld-go.default") || Host("helloworld-go.default.svc") || Host("helloworld-go.default.svc.cluster.local"))`, Middlewares: []string{}, }, }, @@ -125,7 +125,7 @@ func Test_loadConfiguration(t *testing.T) { "default-helloworld-go-rule-0-path-0": { EntryPoints: []string{"http", "https"}, Service: "default-helloworld-go-rule-0-path-0-wrr", - Rule: "(Host(`helloworld-go.default`) || Host(`helloworld-go.default.svc`) || Host(`helloworld-go.default.svc.cluster.local`))", + Rule: `(Host("helloworld-go.default") || Host("helloworld-go.default.svc") || Host("helloworld-go.default.svc.cluster.local"))`, Middlewares: []string{}, }, }, @@ -195,13 +195,13 @@ func Test_loadConfiguration(t *testing.T) { "default-helloworld-go-rule-0-path-0": { EntryPoints: []string{"http", "https"}, Service: "default-helloworld-go-rule-0-path-0-wrr", - Rule: "(Host(`helloworld-go.default`) || Host(`helloworld-go.default.svc`) || Host(`helloworld-go.default.svc.cluster.local`))", + Rule: `(Host("helloworld-go.default") || Host("helloworld-go.default.svc") || Host("helloworld-go.default.svc.cluster.local"))`, Middlewares: []string{}, }, "default-helloworld-go-rule-0-path-0-tls": { EntryPoints: []string{"http", "https"}, Service: "default-helloworld-go-rule-0-path-0-wrr", - Rule: "(Host(`helloworld-go.default`) || Host(`helloworld-go.default.svc`) || Host(`helloworld-go.default.svc.cluster.local`))", + Rule: `(Host("helloworld-go.default") || Host("helloworld-go.default.svc") || Host("helloworld-go.default.svc.cluster.local"))`, Middlewares: []string{}, TLS: &dynamic.RouterTLSConfig{}, }, @@ -307,12 +307,12 @@ func Test_buildRule(t *testing.T) { { desc: "single host, no headers, no path", hosts: []string{"example.com"}, - want: "(Host(`example.com`))", + want: `(Host("example.com"))`, }, { desc: "multiple hosts, no headers, no path", hosts: []string{"example.com", "foo.com"}, - want: "(Host(`example.com`) || Host(`foo.com`))", + want: `(Host("example.com") || Host("foo.com"))`, }, { desc: "single host, single header, no path", @@ -320,7 +320,7 @@ func Test_buildRule(t *testing.T) { headers: map[string]knativenetworkingv1alpha1.HeaderMatch{ "X-Header": {Exact: "value"}, }, - want: "(Host(`example.com`)) && (Header(`X-Header`,`value`))", + want: `(Host("example.com")) && (Header("X-Header","value"))`, }, { desc: "single host, multiple headers, no path", @@ -329,7 +329,7 @@ func Test_buildRule(t *testing.T) { "X-Header": {Exact: "value"}, "X-Header2": {Exact: "value2"}, }, - want: "(Host(`example.com`)) && (Header(`X-Header`,`value`) && Header(`X-Header2`,`value2`))", + want: `(Host("example.com")) && (Header("X-Header","value") && Header("X-Header2","value2"))`, }, { desc: "single host, multiple headers, with path", @@ -339,13 +339,13 @@ func Test_buildRule(t *testing.T) { "X-Header2": {Exact: "value2"}, }, path: "/foo", - want: "(Host(`example.com`)) && (Header(`X-Header`,`value`) && Header(`X-Header2`,`value2`)) && PathPrefix(`/foo`)", + want: `(Host("example.com")) && (Header("X-Header","value") && Header("X-Header2","value2")) && PathPrefix("/foo")`, }, { desc: "single host, no headers, with path", hosts: []string{"example.com"}, path: "/foo", - want: "(Host(`example.com`)) && PathPrefix(`/foo`)", + want: `(Host("example.com")) && PathPrefix("/foo")`, }, } @@ -370,7 +370,7 @@ func Test_mergeHTTPConfigs(t *testing.T) { configs: []*dynamic.HTTPConfiguration{ { Routers: map[string]*dynamic.Router{ - "router1": {Rule: "Host(`example.com`)"}, + "router1": {Rule: `Host("example.com")`}, }, Middlewares: map[string]*dynamic.Middleware{ "middleware1": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"X-Test": "value"}}}, @@ -387,7 +387,7 @@ func Test_mergeHTTPConfigs(t *testing.T) { }, want: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "router1": {Rule: "Host(`example.com`)"}, + "router1": {Rule: `Host("example.com")`}, }, Middlewares: map[string]*dynamic.Middleware{ "middleware1": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"X-Test": "value"}}}, @@ -402,7 +402,7 @@ func Test_mergeHTTPConfigs(t *testing.T) { configs: []*dynamic.HTTPConfiguration{ { Routers: map[string]*dynamic.Router{ - "router1": {Rule: "Host(`example.com`)"}, + "router1": {Rule: `Host("example.com")`}, }, Middlewares: map[string]*dynamic.Middleware{ "middleware1": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"X-Test": "value"}}}, @@ -413,7 +413,7 @@ func Test_mergeHTTPConfigs(t *testing.T) { }, { Routers: map[string]*dynamic.Router{ - "router2": {Rule: "PathPrefix(`/test`)"}, + "router2": {Rule: `PathPrefix("/test")`}, }, Middlewares: map[string]*dynamic.Middleware{ "middleware2": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"X-Test": "value"}}}, @@ -425,8 +425,8 @@ func Test_mergeHTTPConfigs(t *testing.T) { }, want: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "router1": {Rule: "Host(`example.com`)"}, - "router2": {Rule: "PathPrefix(`/test`)"}, + "router1": {Rule: `Host("example.com")`}, + "router2": {Rule: `PathPrefix("/test")`}, }, Middlewares: map[string]*dynamic.Middleware{ "middleware1": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"X-Test": "value"}}},