1
0
Fork 0

Add HTTPUrlRewrite Filter in Gateway API

This commit is contained in:
Manuel Zapf 2024-06-13 17:06:04 +02:00 committed by GitHub
parent 3ca667a3d4
commit a696f7c654
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 754 additions and 110 deletions

View file

@ -301,15 +301,19 @@ 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) {
pm := ptr.Deref(pathMatch, gatev1.HTTPPathMatch{
Type: ptr.To(gatev1.PathMatchPathPrefix),
Value: ptr.To("/"),
})
middlewares := make(map[string]*dynamic.Middleware)
for i, filter := range filters {
name := fmt.Sprintf("%s-%s-%d", routerName, strings.ToLower(string(filter.Type)), i)
switch filter.Type {
case gatev1.HTTPRouteFilterRequestRedirect:
name := fmt.Sprintf("%s-%s-%d", routerName, strings.ToLower(string(filter.Type)), i)
middlewares[name] = createRequestRedirect(filter.RequestRedirect, pathMatch)
middlewares[name] = createRequestRedirect(filter.RequestRedirect, pm)
case gatev1.HTTPRouteFilterRequestHeaderModifier:
name := fmt.Sprintf("%s-%s-%d", routerName, strings.ToLower(string(filter.Type)), i)
middlewares[name] = createRequestHeaderModifier(filter.RequestHeaderModifier)
case gatev1.HTTPRouteFilterExtensionRef:
@ -320,6 +324,14 @@ func (p *Provider) loadMiddlewares(conf *dynamic.Configuration, namespace, route
middlewares[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
default:
// As per the spec: https://gateway-api.sigs.k8s.io/api-types/httproute/#filters-optional
// In all cases where incompatible or unsupported filters are
@ -560,7 +572,7 @@ func createRequestHeaderModifier(filter *gatev1.HTTPHeaderFilter) *dynamic.Middl
}
}
func createRequestRedirect(filter *gatev1.HTTPRequestRedirectFilter, pathMatch *gatev1.HTTPPathMatch) *dynamic.Middleware {
func createRequestRedirect(filter *gatev1.HTTPRequestRedirectFilter, pathMatch gatev1.HTTPPathMatch) *dynamic.Middleware {
var hostname *string
if filter.Hostname != nil {
hostname = ptr.To(string(*filter.Hostname))
@ -599,6 +611,37 @@ func createRequestRedirect(filter *gatev1.HTTPRequestRedirectFilter, pathMatch *
}
}
func createURLRewrite(filter *gatev1.HTTPURLRewriteFilter, pathMatch gatev1.HTTPPathMatch) (*dynamic.Middleware, error) {
if filter.Path == nil && filter.Hostname == nil {
return nil, errors.New("empty configuration")
}
var host *string
if filter.Hostname != nil {
host = ptr.To(string(*filter.Hostname))
}
var path *string
var pathPrefix *string
if filter.Path != nil {
switch filter.Path.Type {
case gatev1.FullPathHTTPPathModifier:
path = filter.Path.ReplaceFullPath
case gatev1.PrefixMatchHTTPPathModifier:
path = filter.Path.ReplacePrefixMatch
pathPrefix = pathMatch.Value
}
}
return &dynamic.Middleware{
URLRewrite: &dynamic.URLRewrite{
Hostname: host,
Path: path,
PathPrefix: pathPrefix,
},
}, nil
}
func getProtocol(portSpec corev1.ServicePort) string {
protocol := "http"
if portSpec.Port == 443 || strings.HasPrefix(portSpec.Name, "https") {