Fix ingress router's rule

Co-authored-by: Mathis Urien <contact.lbf38@gmail.com>
This commit is contained in:
Gina A. 2026-03-17 15:12:05 +01:00 committed by GitHub
parent 154fcf86ae
commit 11d251415a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 119 additions and 119 deletions

View file

@ -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 {

View file

@ -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{},

View file

@ -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 {

View file

@ -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",
},
},

View file

@ -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, " && ")

View file

@ -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"}}},