diff --git a/internal/dataplane/parser/translate_httproute.go b/internal/dataplane/parser/translate_httproute.go index 45a6080cd2..848080a949 100644 --- a/internal/dataplane/parser/translate_httproute.go +++ b/internal/dataplane/parser/translate_httproute.go @@ -264,8 +264,7 @@ func generateKongRoutesFromHTTPRouteMatches( // if the redirect filter has not been set, we still need to set the route plugins if !hasRedirectFilter { - plugins := translators.GeneratePluginsFromHTTPRouteFilters(filters, "", tags) - r.Plugins = append(r.Plugins, plugins...) + translators.ConvertFiltersToPlugins(&r, filters, "", tags) routes = []kongstate.Route{r} } @@ -314,8 +313,7 @@ func getRoutesFromMatches(matches []gatewayapi.HTTPRouteMatch, } // generate kong plugins from rule.filters - plugins := translators.GeneratePluginsFromHTTPRouteFilters(filters, path, tags) - matchRoute.Plugins = append(matchRoute.Plugins, plugins...) + translators.ConvertFiltersToPlugins(matchRoute, filters, path, tags) routes = append(routes, *route) } else { diff --git a/internal/dataplane/parser/translators/httproute.go b/internal/dataplane/parser/translators/httproute.go index cd7a78ff9c..b905a250cc 100644 --- a/internal/dataplane/parser/translators/httproute.go +++ b/internal/dataplane/parser/translators/httproute.go @@ -9,6 +9,8 @@ import ( "github.com/kong/go-kong/kong" + "github.com/kong/kubernetes-ingress-controller/v2/internal/annotations" + "github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane/kongstate" "github.com/kong/kubernetes-ingress-controller/v2/internal/gatewayapi" ) @@ -350,14 +352,35 @@ func mustMarshalJSON[T any](val T) string { return string(key) } -// GeneratePluginsFromHTTPRouteFilters converts HTTPRouteFilter into Kong plugins. +func ConvertFiltersToPlugins(route *kongstate.Route, filters []gatewayapi.HTTPRouteFilter, path string, tags []*string) { + plugins, pluginAnnotation := generatePluginsFromHTTPRouteFilters(filters, "", tags) + if route.Plugins == nil { + route.Plugins = make([]kong.Plugin, 0) + } + route.Plugins = append(route.Plugins, plugins...) + if len(pluginAnnotation) > 0 { + if route.Ingress.Annotations == nil { + route.Ingress.Annotations = make(map[string]string) + } + if _, ok := route.Ingress.Annotations[annotations.AnnotationPrefix+annotations.PluginsKey]; !ok { + route.Ingress.Annotations[annotations.AnnotationPrefix+annotations.PluginsKey] = pluginAnnotation + } else { + route.Ingress.Annotations[annotations.AnnotationPrefix+annotations.PluginsKey] = fmt.Sprintf("%s,%s", + route.Ingress.Annotations[annotations.AnnotationPrefix+annotations.PluginsKey], + pluginAnnotation) + } + } +} + +// generatePluginsFromHTTPRouteFilters converts HTTPRouteFilter into Kong plugins. // path is the parameter to be used by the redirect plugin, to perform redirection. -func GeneratePluginsFromHTTPRouteFilters(filters []gatewayapi.HTTPRouteFilter, path string, tags []*string) []kong.Plugin { +func generatePluginsFromHTTPRouteFilters(filters []gatewayapi.HTTPRouteFilter, path string, tags []*string) ([]kong.Plugin, string) { kongPlugins := make([]kong.Plugin, 0) if len(filters) == 0 { - return kongPlugins + return kongPlugins, "" } + var pluginsAnnotation string for _, filter := range filters { switch filter.Type { case gatewayapi.HTTPRouteFilterRequestHeaderModifier: @@ -369,8 +392,15 @@ func GeneratePluginsFromHTTPRouteFilters(filters []gatewayapi.HTTPRouteFilter, p case gatewayapi.HTTPRouteFilterResponseHeaderModifier: kongPlugins = append(kongPlugins, generateResponseHeaderModifierKongPlugin(filter.ResponseHeaderModifier)) - case gatewayapi.HTTPRouteFilterExtensionRef, - gatewayapi.HTTPRouteFilterRequestMirror, + case gatewayapi.HTTPRouteFilterExtensionRef: + plugin := generateExtensionRefKongPlugin(filter.ExtensionRef) + if len(pluginsAnnotation) > 0 { + pluginsAnnotation = fmt.Sprintf("%s,%s", pluginsAnnotation, plugin) + } else { + pluginsAnnotation = plugin + } + + case gatewayapi.HTTPRouteFilterRequestMirror, gatewayapi.HTTPRouteFilterURLRewrite: // not supported } @@ -381,7 +411,7 @@ func GeneratePluginsFromHTTPRouteFilters(filters []gatewayapi.HTTPRouteFilter, p p.Tags = tags } - return kongPlugins + return kongPlugins, pluginsAnnotation } // generateRequestRedirectKongPlugin generates configurations of plugins to satisfy the specification @@ -429,6 +459,10 @@ func generateRequestRedirectKongPlugin(modifier *gatewayapi.HTTPRequestRedirectF return plugins } +func generateExtensionRefKongPlugin(modifier *gatewayapi.LocalObjectReference) string { + return string(modifier.Name) +} + // generateRequestHeaderModifierKongPlugin converts a gatewayapi.HTTPRequestHeaderFilter into a // kong.Plugin of type request-transformer. func generateRequestHeaderModifierKongPlugin(modifier *gatewayapi.HTTPHeaderFilter) kong.Plugin { diff --git a/internal/dataplane/parser/translators/httproute_atc.go b/internal/dataplane/parser/translators/httproute_atc.go index 31bb4f4e18..fd8c924318 100644 --- a/internal/dataplane/parser/translators/httproute_atc.go +++ b/internal/dataplane/parser/translators/httproute_atc.go @@ -66,8 +66,7 @@ func GenerateKongExpressionRoutesFromHTTPRouteMatches( atc.ApplyExpression(&r.Route, routeMatcher, 1) // generate plugins. - plugins := GeneratePluginsFromHTTPRouteFilters(translation.Filters, "", tags) - r.Plugins = plugins + ConvertFiltersToPlugins(&r, translation.Filters, "", tags) return []kongstate.Route{r}, nil } @@ -104,9 +103,7 @@ func generateKongExpressionRoutesWithRequestRedirectFilter( if match.Path != nil && match.Path.Value != nil { path = *match.Path.Value } - plugins := GeneratePluginsFromHTTPRouteFilters(translation.Filters, path, tags) - matchRoute.Plugins = plugins - + ConvertFiltersToPlugins(&matchRoute, translation.Filters, path, tags) routes = append(routes, matchRoute) } return routes, nil @@ -561,8 +558,7 @@ func KongExpressionRouteFromHTTPRouteMatchWithPriority( path = *match.Match.Path.Value } - plugins := GeneratePluginsFromHTTPRouteFilters(rule.Filters, path, tags) - r.Plugins = plugins + ConvertFiltersToPlugins(&r, rule.Filters, path, tags) } return r diff --git a/internal/dataplane/parser/translators/httproute_test.go b/internal/dataplane/parser/translators/httproute_test.go index 0451222818..535ae61f63 100644 --- a/internal/dataplane/parser/translators/httproute_test.go +++ b/internal/dataplane/parser/translators/httproute_test.go @@ -157,7 +157,7 @@ func TestGeneratePluginsFromHTTPRouteFilters(t *testing.T) { for _, tc := range testCases { tc := tc - plugins := GeneratePluginsFromHTTPRouteFilters(tc.filters, tc.path, nil) + plugins := generatePluginsFromHTTPRouteFilters(tc.filters, tc.path, nil) t.Run(tc.name, func(t *testing.T) { require.Equal(t, tc.expectedPlugins, plugins) }) diff --git a/internal/gatewayapi/aliases.go b/internal/gatewayapi/aliases.go index fda3ce9efe..d7966907e2 100644 --- a/internal/gatewayapi/aliases.go +++ b/internal/gatewayapi/aliases.go @@ -47,6 +47,7 @@ type ( ListenerConditionReason = gatewayv1beta1.ListenerConditionReason ListenerConditionType = gatewayv1beta1.ListenerConditionType ListenerStatus = gatewayv1beta1.ListenerStatus + LocalObjectReference = gatewayv1beta1.LocalObjectReference Namespace = gatewayv1beta1.Namespace ObjectName = gatewayv1beta1.ObjectName ParentReference = gatewayv1beta1.ParentReference