Preserve HTTPRoute filters order

This commit is contained in:
Kevin Pollet 2024-10-21 09:54:04 +02:00 committed by GitHub
parent ef5aa129c7
commit eeb99c3536
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 46 additions and 19 deletions

View file

@ -54,4 +54,9 @@ spec:
extensionRef:
group: traefik.io
kind: Middleware
name: my-middleware
name: my-first-middleware
- type: ExtensionRef
extensionRef:
group: traefik.io
kind: Middleware
name: my-second-middleware

View file

@ -301,36 +301,52 @@ func (p *Provider) loadHTTPBackendRef(namespace string, backendRef gatev1.HTTPBa
}
func (p *Provider) loadMiddlewares(conf *dynamic.Configuration, namespace, routerName string, filters []gatev1.HTTPRouteFilter, pathMatch *gatev1.HTTPPathMatch) ([]string, error) {
type namedMiddleware struct {
Name string
Config *dynamic.Middleware
}
pm := ptr.Deref(pathMatch, gatev1.HTTPPathMatch{
Type: ptr.To(gatev1.PathMatchPathPrefix),
Value: ptr.To("/"),
})
middlewares := make(map[string]*dynamic.Middleware)
var middlewares []namedMiddleware
for i, filter := range filters {
name := fmt.Sprintf("%s-%s-%d", routerName, strings.ToLower(string(filter.Type)), i)
switch filter.Type {
case gatev1.HTTPRouteFilterRequestRedirect:
middlewares[name] = createRequestRedirect(filter.RequestRedirect, pm)
middlewares = append(middlewares, namedMiddleware{
name,
createRequestRedirect(filter.RequestRedirect, pm),
})
case gatev1.HTTPRouteFilterRequestHeaderModifier:
middlewares[name] = createRequestHeaderModifier(filter.RequestHeaderModifier)
middlewares = append(middlewares, namedMiddleware{
name,
createRequestHeaderModifier(filter.RequestHeaderModifier),
})
case gatev1.HTTPRouteFilterExtensionRef:
name, middleware, err := p.loadHTTPRouteFilterExtensionRef(namespace, filter.ExtensionRef)
if err != nil {
return nil, fmt.Errorf("loading ExtensionRef filter %s: %w", filter.Type, err)
}
middlewares[name] = middleware
middlewares = append(middlewares, namedMiddleware{
name,
middleware,
})
case gatev1.HTTPRouteFilterURLRewrite:
var err error
middleware, err := createURLRewrite(filter.URLRewrite, pm)
if err != nil {
return nil, fmt.Errorf("invalid filter %s: %w", filter.Type, err)
}
middlewares[name] = middleware
middlewares = append(middlewares, namedMiddleware{
name,
middleware,
})
default:
// As per the spec: https://gateway-api.sigs.k8s.io/api-types/httproute/#filters-optional
@ -342,12 +358,11 @@ func (p *Provider) loadMiddlewares(conf *dynamic.Configuration, namespace, route
}
var middlewareNames []string
for name, middleware := range middlewares {
if middleware != nil {
conf.HTTP.Middlewares[name] = middleware
for _, m := range middlewares {
if m.Config != nil {
conf.HTTP.Middlewares[m.Name] = m.Config
}
middlewareNames = append(middlewareNames, name)
middlewareNames = append(middlewareNames, m.Name)
}
return middlewareNames, nil

View file

@ -2431,7 +2431,7 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) {
entryPoints map[string]Entrypoint
}{
{
desc: "HTTPRoute with ExtensionRef filter",
desc: "ExtensionRef filter",
groupKindFilterFuncs: map[string]map[string]BuildFilterFunc{
traefikv1alpha1.GroupName: {"Middleware": func(name, namespace string) (string, *dynamic.Middleware, error) {
return namespace + "-" + name, nil, nil
@ -2459,7 +2459,10 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) {
Rule: "Host(`foo.com`) && Path(`/bar`)",
Priority: 100008,
RuleSyntax: "v3",
Middlewares: []string{"default-my-middleware"},
Middlewares: []string{
"default-my-first-middleware",
"default-my-second-middleware",
},
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -2497,7 +2500,7 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) {
},
},
{
desc: "HTTPRoute with ExtensionRef filter and create middleware",
desc: "ExtensionRef filter with middleware creation",
groupKindFilterFuncs: map[string]map[string]BuildFilterFunc{
traefikv1alpha1.GroupName: {"Middleware": func(name, namespace string) (string, *dynamic.Middleware, error) {
return namespace + "-" + name, &dynamic.Middleware{Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}}, nil
@ -2525,11 +2528,15 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) {
Rule: "Host(`foo.com`) && Path(`/bar`)",
Priority: 100008,
RuleSyntax: "v3",
Middlewares: []string{"default-my-middleware"},
Middlewares: []string{
"default-my-first-middleware",
"default-my-second-middleware",
},
},
},
Middlewares: map[string]*dynamic.Middleware{
"default-my-middleware": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}},
"default-my-first-middleware": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}},
"default-my-second-middleware": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}},
},
Services: map[string]*dynamic.Service{
"default-http-app-1-my-gateway-web-0-wrr": {
@ -2565,7 +2572,7 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) {
},
},
{
desc: "ExtensionRef filter: Unknown",
desc: "Unknown ExtensionRef filter",
entryPoints: map[string]Entrypoint{"web": {
Address: ":80",
}},