Basic Rewrite target fails as namespace is appended to middleware name

Here's my config for a simple re-direction. I want to be able to access / on /watch
I converted the ingress to ingressroute using the migration tool. This is the original ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: traefik
    traefik.ingress.kubernetes.io/rewrite-target: /
  name: watch-service
spec:
  rules:
  - host: video-service.b2b
    http:
      paths:
      - backend:
          serviceName: video-service
          servicePort: 8080
        path: /watch

And here's the converted ingress to ingressroute:

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  annotations:
    kubernetes.io/ingress.class: traefik
  name: watch-service
spec:
  entryPoints: []
  routes:
  - kind: Rule
    match: Host(`video-service.b2b`) && PathPrefix(`/watch`)
    middlewares:
    - name: replace-path-video-service.b2b-watch
      namespace: b2b
    priority: 0
    services:
    - kind: Service
      name: video-service
      namespace:  b2b
      port: 8080
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  creationTimestamp: null
  name: replace-path-video-service.b2b-watch
spec:
  replacePathRegex:
    regex: ^/watch(.*)
    replacement: $1

However i get this error:
traefik-ingress-controller-t984s traefik time="2021-05-13T07:42:41Z" level=error msg="middleware \"b2b-replace-path-video-service.b2b-watch@kubernetescrd\" does not exist" routerName=b2b-watch-service-65c6965abc6fe32a9e21@kubernetescrd entryPointName=https

It seems to have appeneded my namespace to the routername it claims it can't find. So replace-path-video-service.b2b-watch now becomes b2b-replace-path-video-service.b2b-watch I can't makes sense of this because the middleware has been created.

Hey @trafficker
The name will be created using the following pattern:

<namespace>-<middleware-name>@provider

where:

  • namespace, the name of the namespace where middleware has been created
  • middleware - it is middleware name :wink:
  • provider, can be e.g. file

In your case I would try to add middleware using the name:

defualt-replace-path-video-service.b2b-watch@kubernetescrd

I assume that you have created middleware in the namespace default.

Thank you

@jakubhajek

I'm a little confused. Are you saying that I need to do this instead? I am also creating the middle as part of the deployment. The middleware is created in the b2b namespace not default.

---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  creationTimestamp: null
  name: `b2b-replace-path-video-service.b2b-watch@kubernetescrd`
spec:
  replacePathRegex:
    regex: ^/watch(.*)
    replacement: $1

And of course that can't work because

Invalid value: "b2b-replace-path-video-service.b2b-watch@kubernetescrd": a DNS-1123 subdomain must consist of lower case alphanumeric characters,

@jakubhajek
I found this link here which seems to make sense, however even after adding the annotation it still doesn't work for me. Note the new annotation in the IngressRoute ....perhaps it only works for Ingress resource?
How to configure middleware with kubernetes-ingress? (middleware "xyz" does not exist)
Here's my config.

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  annotations:
    traefik.ingress.kubernetes.io/router.middlewares: b2b-video-service.b2b-watch@kubernetescrd
    kubernetes.io/ingress.class: traefik
  name: watch-service
spec:
  entryPoints: []
  routes:
  - kind: Rule
    match: Host(`video-service.b2b`) && PathPrefix(`/watch`)
    middlewares:
    - name: video-service.b2b-watch
      namespace: b2b
    priority: 0
    services:
    - kind: Service
      name: video-service
      namespace:  b2b
      port: 8080
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: video-service.b2b-watch
  namespace: b2b
spec:
  replacePathRegex:
    regex: ^/watch(.*)
    replacement: $1

Hey @trafficker

Leave the middleware name in the middleware object as it is, just a simple name e.g. b2b-replace-path is enough.
In the object IngressRoute when you add middleway you can use the name according the pattern:
-@provider - this is what I recommended.

here are more details concerning that, please see Kubernetes Namespace provider.

The annotation you are trying to add is not needed as it is used in Kubernetes Ingress implementation. If you use Ingressroute, you are just using middleware spec.routes.middleware

You can have a look on my latest workshop Getting stated with Traefik on Kubernetes where I am explaining all those aspects.

Thank you,