diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware_multiple_hyphens.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware_multiple_hyphens.yml new file mode 100644 index 000000000..dc66091c2 --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware_multiple_hyphens.yml @@ -0,0 +1,29 @@ +apiVersion: traefik.containo.us/v1alpha1 +kind: MiddlewareTCP +metadata: + name: multiple---hyphens + namespace: default +spec: + ipWhiteList: + sourceRange: + - 127.0.0.1/32 + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRouteTCP +metadata: + name: test.route + namespace: default + +spec: + entryPoints: + - foo + + routes: + - match: HostSNI(`foo.com`) + services: + - name: whoamitcp + port: 8000 + + middlewares: + - name: multiple---hyphens diff --git a/pkg/provider/kubernetes/crd/fixtures/with_middleware_multiple_hyphens.yml b/pkg/provider/kubernetes/crd/fixtures/with_middleware_multiple_hyphens.yml new file mode 100644 index 000000000..cee835136 --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/with_middleware_multiple_hyphens.yml @@ -0,0 +1,31 @@ +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: multiple---hyphens + namespace: default + +spec: + stripPrefix: + prefixes: + - /tobestripped + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: test2.route + namespace: default + +spec: + entryPoints: + - web + + routes: + - match: Host(`foo.com`) && PathPrefix(`/tobestripped`) + priority: 12 + kind: Rule + services: + - name: whoami + port: 80 + middlewares: + - name: multiple---hyphens diff --git a/pkg/provider/kubernetes/crd/kubernetes_http.go b/pkg/provider/kubernetes/crd/kubernetes_http.go index b78d14c31..b95a6679a 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_http.go +++ b/pkg/provider/kubernetes/crd/kubernetes_http.go @@ -183,7 +183,7 @@ func (p *Provider) makeMiddlewareKeys(ctx context.Context, ingRouteNamespace str ns = mi.Namespace } - mds = append(mds, makeID(ns, name)) + mds = append(mds, provider.Normalize(makeID(ns, name))) } return mds, nil diff --git a/pkg/provider/kubernetes/crd/kubernetes_tcp.go b/pkg/provider/kubernetes/crd/kubernetes_tcp.go index 187020a2d..37c584e17 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_tcp.go +++ b/pkg/provider/kubernetes/crd/kubernetes_tcp.go @@ -10,6 +10,7 @@ import ( "github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/log" + "github.com/traefik/traefik/v2/pkg/provider" "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" "github.com/traefik/traefik/v2/pkg/tls" corev1 "k8s.io/api/core/v1" @@ -162,7 +163,7 @@ func (p *Provider) makeMiddlewareTCPKeys(ctx context.Context, ingRouteTCPNamespa ns = mi.Namespace } - mds = append(mds, makeID(ns, mi.Name)) + mds = append(mds, provider.Normalize(makeID(ns, mi.Name))) } return mds, nil diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go index dafa56653..310ae48bd 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_test.go +++ b/pkg/provider/kubernetes/crd/kubernetes_test.go @@ -149,6 +149,54 @@ func TestLoadIngressRouteTCPs(t *testing.T) { TLS: &dynamic.TLSConfiguration{}, }, }, + { + desc: "Middlewares in ingress route config are normalized", + paths: []string{"tcp/services.yml", "tcp/with_middleware_multiple_hyphens.yml"}, + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{}, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{}, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + TCP: &dynamic.TCPConfiguration{ + Routers: map[string]*dynamic.TCPRouter{ + "default-test.route-fdd3e9338e47a45efefc": { + EntryPoints: []string{"foo"}, + Service: "default-test.route-fdd3e9338e47a45efefc", + Middlewares: []string{"default-multiple-hyphens"}, + Rule: "HostSNI(`foo.com`)", + }, + }, + Middlewares: map[string]*dynamic.TCPMiddleware{ + "default-multiple-hyphens": { + IPWhiteList: &dynamic.TCPIPWhiteList{ + SourceRange: []string{"127.0.0.1/32"}, + }, + }, + }, + Services: map[string]*dynamic.TCPService{ + "default-test.route-fdd3e9338e47a45efefc": { + LoadBalancer: &dynamic.TCPServersLoadBalancer{ + Servers: []dynamic.TCPServer{ + { + Address: "10.10.0.1:8000", + }, + { + Address: "10.10.0.2:8000", + }, + }, + }, + }, + }, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, { desc: "Simple Ingress Route, with foo entrypoint and crossprovider middleware", paths: []string{"tcp/services.yml", "tcp/with_middleware_crossprovider.yml"}, @@ -1456,6 +1504,57 @@ func TestLoadIngressRoutes(t *testing.T) { TLS: &dynamic.TLSConfiguration{}, }, }, + { + desc: "Middlewares in ingress route config are normalized", + AllowCrossNamespace: true, + paths: []string{"services.yml", "with_middleware_multiple_hyphens.yml"}, + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + TCP: &dynamic.TCPConfiguration{ + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{ + "default-test2-route-23c7f4c450289ee29016": { + EntryPoints: []string{"web"}, + Service: "default-test2-route-23c7f4c450289ee29016", + Rule: "Host(`foo.com`) && PathPrefix(`/tobestripped`)", + Priority: 12, + Middlewares: []string{"default-multiple-hyphens"}, + }, + }, + Middlewares: map[string]*dynamic.Middleware{ + "default-multiple-hyphens": { + StripPrefix: &dynamic.StripPrefix{ + Prefixes: []string{"/tobestripped"}, + }, + }, + }, + Services: map[string]*dynamic.Service{ + "default-test2-route-23c7f4c450289ee29016": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:80", + }, + { + URL: "http://10.10.0.2:80", + }, + }, + PassHostHeader: Bool(true), + }, + }, + }, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, { desc: "Simple Ingress Route with middleware crossprovider", AllowCrossNamespace: true, diff --git a/pkg/provider/kubernetes/k8s/parser.go b/pkg/provider/kubernetes/k8s/parser.go index f7336c5bd..16941be7c 100644 --- a/pkg/provider/kubernetes/k8s/parser.go +++ b/pkg/provider/kubernetes/k8s/parser.go @@ -14,7 +14,7 @@ import ( func MustParseYaml(content []byte) []runtime.Object { acceptedK8sTypes := regexp.MustCompile(`^(Deployment|Endpoints|Service|Ingress|IngressRoute|IngressRouteTCP|IngressRouteUDP|Middleware|MiddlewareTCP|Secret|TLSOption|TLSStore|TraefikService|IngressClass|ServersTransport|GatewayClass|Gateway|HTTPRoute|TCPRoute|TLSRoute)$`) - files := strings.Split(string(content), "---") + files := strings.Split(string(content), "---\n") retVal := make([]runtime.Object, 0, len(files)) for _, file := range files { if file == "\n" || file == "" {