1
0
Fork 0

Update routing syntax

Co-authored-by: Tom Moulard <tom.moulard@traefik.io>
This commit is contained in:
Antoine 2022-11-28 15:48:05 +01:00 committed by GitHub
parent b93141992e
commit 4d86668af3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 2484 additions and 2085 deletions

View file

@ -101,7 +101,7 @@ func patchDynamicConfiguration(cfg *dynamic.Configuration, ep string, port int,
cfg.HTTP.Routers["traefik-hub-agent-service"] = &dynamic.Router{
EntryPoints: []string{ep},
Service: "traefik-hub-agent-service",
Rule: "Host(`proxy.traefik`) && PathPrefix(`/config`, `/discover-ip`, `/state`)",
Rule: "Host(`proxy.traefik`) && (PathPrefix(`/config`) || PathPrefix(`/discover-ip`) || PathPrefix(`/state`))",
}
cfg.HTTP.Services["traefik-hub-agent-service"] = &dynamic.Service{

View file

@ -7,6 +7,7 @@ import (
"fmt"
"net"
"os"
"regexp"
"sort"
"strconv"
"strings"
@ -1163,8 +1164,7 @@ func getRouteBindingSelectorNamespace(client Client, gatewayNamespace string, ro
}
func hostRule(hostnames []v1alpha2.Hostname) (string, error) {
var hostNames []string
var hostRegexNames []string
var rules []string
for _, hostname := range hostnames {
host := string(hostname)
@ -1177,7 +1177,7 @@ func hostRule(hostnames []v1alpha2.Hostname) (string, error) {
wildcard := strings.Count(host, "*")
if wildcard == 0 {
hostNames = append(hostNames, host)
rules = append(rules, fmt.Sprintf("Host(`%s`)", host))
continue
}
@ -1186,25 +1186,18 @@ func hostRule(hostnames []v1alpha2.Hostname) (string, error) {
return "", fmt.Errorf("invalid rule: %q", host)
}
hostRegexNames = append(hostRegexNames, strings.Replace(host, "*.", "{subdomain:[a-zA-Z0-9-]+}.", 1))
host = strings.Replace(regexp.QuoteMeta(host), `\*\.`, `[a-zA-Z0-9-]+\.`, 1)
rules = append(rules, fmt.Sprintf("HostRegexp(`^%s$`)", host))
}
var res string
if len(hostNames) > 0 {
res = "Host(`" + strings.Join(hostNames, "`, `") + "`)"
switch len(rules) {
case 0:
return "", nil
case 1:
return rules[0], nil
default:
return fmt.Sprintf("(%s)", strings.Join(rules, " || ")), nil
}
if len(hostRegexNames) == 0 {
return res, nil
}
hostRegexp := "HostRegexp(`" + strings.Join(hostRegexNames, "`, `") + "`)"
if len(res) > 0 {
return "(" + res + " || " + hostRegexp + ")", nil
}
return hostRegexp, nil
}
func hostSNIRule(hostnames []v1alpha2.Hostname) (string, error) {
@ -1227,15 +1220,18 @@ func hostSNIRule(hostnames []v1alpha2.Hostname) (string, error) {
return "", fmt.Errorf("wildcard hostname is not supported: %q", h)
}
matchers = append(matchers, "`"+h+"`")
matchers = append(matchers, fmt.Sprintf("HostSNI(`%s`)", h))
uniqHostnames[hostname] = struct{}{}
}
if len(matchers) == 0 {
switch len(matchers) {
case 0:
return "HostSNI(`*`)", nil
case 1:
return matchers[0], nil
default:
return fmt.Sprintf("(%s)", strings.Join(matchers, " || ")), nil
}
return "HostSNI(" + strings.Join(matchers, ",") + ")", nil
}
func extractRule(routeRule v1alpha2.HTTPRouteRule, hostRule string) (string, error) {

View file

@ -744,15 +744,15 @@ func TestLoadHTTPRoutes(t *testing.T) {
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"default-http-app-1-my-gateway-web-75dd1ad561e42725558a": {
"default-http-app-1-my-gateway-web-66e726cd8903b49727ae": {
EntryPoints: []string{"web"},
Service: "default-http-app-1-my-gateway-web-75dd1ad561e42725558a-wrr",
Rule: "Host(`foo.com`, `bar.com`) && PathPrefix(`/`)",
Service: "default-http-app-1-my-gateway-web-66e726cd8903b49727ae-wrr",
Rule: "(Host(`foo.com`) || Host(`bar.com`)) && PathPrefix(`/`)",
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"default-http-app-1-my-gateway-web-75dd1ad561e42725558a-wrr": {
"default-http-app-1-my-gateway-web-66e726cd8903b49727ae-wrr": {
Weighted: &dynamic.WeightedRoundRobin{
Services: []dynamic.WRRService{
{
@ -802,15 +802,15 @@ func TestLoadHTTPRoutes(t *testing.T) {
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"default-http-app-1-my-gateway-web-2dbd7883f5537db39bca": {
"default-http-app-1-my-gateway-web-3b78e2feb3295ddd87f0": {
EntryPoints: []string{"web"},
Service: "default-http-app-1-my-gateway-web-2dbd7883f5537db39bca-wrr",
Rule: "(Host(`foo.com`) || HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.bar.com`)) && PathPrefix(`/`)",
Service: "default-http-app-1-my-gateway-web-3b78e2feb3295ddd87f0-wrr",
Rule: "(Host(`foo.com`) || HostRegexp(`^[a-zA-Z0-9-]+\\.bar\\.com$`)) && PathPrefix(`/`)",
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"default-http-app-1-my-gateway-web-2dbd7883f5537db39bca-wrr": {
"default-http-app-1-my-gateway-web-3b78e2feb3295ddd87f0-wrr": {
Weighted: &dynamic.WeightedRoundRobin{
Services: []dynamic.WRRService{
{
@ -860,15 +860,15 @@ func TestLoadHTTPRoutes(t *testing.T) {
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"default-http-app-1-my-gateway-web-eb1490f180299bf5ed29": {
"default-http-app-1-my-gateway-web-b0521a61fb43068694b4": {
EntryPoints: []string{"web"},
Service: "default-http-app-1-my-gateway-web-eb1490f180299bf5ed29-wrr",
Rule: "(Host(`foo.com`) || HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.foo.com`)) && PathPrefix(`/`)",
Service: "default-http-app-1-my-gateway-web-b0521a61fb43068694b4-wrr",
Rule: "(Host(`foo.com`) || HostRegexp(`^[a-zA-Z0-9-]+\\.foo\\.com$`)) && PathPrefix(`/`)",
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"default-http-app-1-my-gateway-web-eb1490f180299bf5ed29-wrr": {
"default-http-app-1-my-gateway-web-b0521a61fb43068694b4-wrr": {
Weighted: &dynamic.WeightedRoundRobin{
Services: []dynamic.WRRService{
{
@ -3011,10 +3011,10 @@ func TestLoadTLSRoutes(t *testing.T) {
},
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{
"default-tls-app-1-my-gateway-tls-339184c3296a9c2c39fa": {
"default-tls-app-1-my-gateway-tls-dfc5c7506ac1b172c8b7": {
EntryPoints: []string{"tls"},
Service: "default-tls-app-1-my-gateway-tls-339184c3296a9c2c39fa-wrr-0",
Rule: "HostSNI(`foo.example.com`,`bar.example.com`)",
Service: "default-tls-app-1-my-gateway-tls-dfc5c7506ac1b172c8b7-wrr-0",
Rule: "(HostSNI(`foo.example.com`) || HostSNI(`bar.example.com`))",
TLS: &dynamic.RouterTCPTLSConfig{
Passthrough: true,
},
@ -3022,7 +3022,7 @@ func TestLoadTLSRoutes(t *testing.T) {
},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{
"default-tls-app-1-my-gateway-tls-339184c3296a9c2c39fa-wrr-0": {
"default-tls-app-1-my-gateway-tls-dfc5c7506ac1b172c8b7-wrr-0": {
Weighted: &dynamic.TCPWeightedRoundRobin{
Services: []dynamic.TCPWRRService{
{
@ -4362,7 +4362,7 @@ func Test_hostRule(t *testing.T) {
"Bar",
"Bir",
},
expectedRule: "Host(`Foo`, `Bar`, `Bir`)",
expectedRule: "(Host(`Foo`) || Host(`Bar`) || Host(`Bir`))",
},
{
desc: "Multiple Hosts with empty one",
@ -4389,14 +4389,14 @@ func Test_hostRule(t *testing.T) {
"bar.foo",
"foo.foo",
},
expectedRule: "(Host(`bar.foo`, `foo.foo`) || HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.bar.foo`))",
expectedRule: "(HostRegexp(`^[a-zA-Z0-9-]+\\.bar\\.foo$`) || Host(`bar.foo`) || Host(`foo.foo`))",
},
{
desc: "Host with wildcard",
hostnames: []v1alpha2.Hostname{
"*.bar.foo",
},
expectedRule: "HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.bar.foo`)",
expectedRule: "HostRegexp(`^[a-zA-Z0-9-]+\\.bar\\.foo$`)",
},
{
desc: "Alone wildcard",
@ -4708,7 +4708,7 @@ func Test_hostSNIRule(t *testing.T) {
{
desc: "Some empty hostnames",
hostnames: []v1alpha2.Hostname{"foo", "", "bar"},
expectedRule: "HostSNI(`foo`,`bar`)",
expectedRule: "(HostSNI(`foo`) || HostSNI(`bar`))",
},
{
desc: "Valid hostname",
@ -4718,12 +4718,12 @@ func Test_hostSNIRule(t *testing.T) {
{
desc: "Multiple valid hostnames",
hostnames: []v1alpha2.Hostname{"foo", "bar"},
expectedRule: "HostSNI(`foo`,`bar`)",
expectedRule: "(HostSNI(`foo`) || HostSNI(`bar`))",
},
{
desc: "Multiple overlapping hostnames",
hostnames: []v1alpha2.Hostname{"foo", "bar", "foo", "baz"},
expectedRule: "HostSNI(`foo`,`bar`,`baz`)",
expectedRule: "(HostSNI(`foo`) || HostSNI(`bar`) || HostSNI(`baz`))",
},
}

View file

@ -8,6 +8,7 @@ import (
"math"
"net"
"os"
"regexp"
"sort"
"strconv"
"strings"
@ -400,10 +401,11 @@ func (p *Provider) shouldProcessIngress(ingress *networkingv1.Ingress, ingressCl
func buildHostRule(host string) string {
if strings.HasPrefix(host, "*.") {
return "HostRegexp(`" + strings.Replace(host, "*.", "{subdomain:[a-zA-Z0-9-]+}.", 1) + "`)"
host = strings.Replace(regexp.QuoteMeta(host), `\*\.`, `[a-zA-Z0-9-]+\.`, 1)
return fmt.Sprintf("HostRegexp(`^%s$`)", host)
}
return "Host(`" + host + "`)"
return fmt.Sprintf("Host(`%s`)", host)
}
func getCertificates(ctx context.Context, ingress *networkingv1.Ingress, k8sClient Client, tlsConfigs map[string]*tls.CertAndStores) error {

View file

@ -189,8 +189,8 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Middlewares: map[string]*dynamic.Middleware{},
Routers: map[string]*dynamic.Router{
"testing-bar-bar-3be6cfd7daba66cf2fdd": {
Rule: "HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.bar`) && PathPrefix(`/bar`)",
"testing-bar-bar-aba9a7d00e9b06a78e16": {
Rule: "HostRegexp(`^[a-zA-Z0-9-]+\\.bar$`) && PathPrefix(`/bar`)",
Service: "testing-service1-80",
},
"testing-bar-bar-636bf36c00fedaab3d44": {
@ -1104,7 +1104,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(`^[a-zA-Z0-9-]+\\.foobar\\.com$`) && PathPrefix(`/bar`)",
Service: "testing-service1-80",
},
},

View file

@ -9,7 +9,7 @@
"redirect-web-to-websecure"
],
"service": "noop@internal",
"rule": "HostRegexp(`{host:.+}`)"
"rule": "HostRegexp(`^.+$`)"
}
},
"middlewares": {
@ -27,4 +27,4 @@
},
"tcp": {},
"tls": {}
}
}

View file

@ -9,7 +9,7 @@
"redirect-web-to-443"
],
"service": "noop@internal",
"rule": "HostRegexp(`{host:.+}`)"
"rule": "HostRegexp(`^.+$`)"
}
},
"middlewares": {
@ -27,4 +27,4 @@
},
"tcp": {},
"tls": {}
}
}

View file

@ -9,7 +9,7 @@
"redirect-web-to-websecure"
],
"service": "noop@internal",
"rule": "HostRegexp(`{host:.+}`)"
"rule": "HostRegexp(`^.+$`)"
}
},
"middlewares": {
@ -27,4 +27,4 @@
},
"tcp": {},
"tls": {}
}
}

View file

@ -137,7 +137,7 @@ func (i *Provider) redirection(ctx context.Context, cfg *dynamic.Configuration)
mdName := "redirect-" + rtName
rt := &dynamic.Router{
Rule: "HostRegexp(`{host:.+}`)",
Rule: "HostRegexp(`^.+$`)",
EntryPoints: []string{name},
Middlewares: []string{mdName},
Service: "noop@internal",