Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature(parser): consolidation of multiple HTTPRouteMatch objects into single kong.Route #3060

Merged
merged 2 commits into from
Oct 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,31 @@ Adding a new version? You'll need three changes:
### Added

- Added `HTTPRoute` support for `CombinedRoutes` feature. When enabled,
this changes how `HTTPRoute` resources are translated so that `HTTPRouteRule`
resources are combined when they have same backends references. This change
does not functionally impact routing: requests that went to a given Service
using the original method still go to the same Service in the new method.
`HTTPRoute.HTTPRouteRule` objects with identical `backendRefs` generate a
single Kong service instead of a service per rule, and
`HTTPRouteRule.HTTPRouteMatche` objects using the same `backendRefs` can be
consolidated into a single Kong route instead of always creating a route per
match, reducing configuration size.
The following limitations apply:
- `HTTPRouteRule` objects cannot be consolidated into a single Kong Service
if they belong to different `HTTPRoute`.
- `HTTPRouteRule` objects cannot be consolidated into a single Kong Service
if they have different `HTTPRouteRule.HTTPBackendRef[]` objects. The order
of the backend references is not important.
- `HTTPRouteMatch` objects cannot be consolidated into a single Kong Route
if parent `HTTPRouteRule` objects cannot be consolidated into a single Kong Service.
- `HTTPRouteMatch` objects cannot be consolidated into a single Kong Route
if parent `HTTPRouteRule` objects have different `HTTPRouteRule.HTTPRouteFilter[]` filters.
- `HTTPRouteMatch` objects cannot be consolidated into a single Kong Route
if they have different matching spec (`HTTPHeaderMatch.Headers`, `HTTPHeaderMatch.QueryParams`,
`HTTPHeaderMatch.Method`). Different `HTTPHeaderMatch.Path` paths between
`HTTPRouteMatch[]` objects does not prevent consolidation.
This change does not functionally impact routing: requests that went to a given Service
using the original method still go to the same Service when `CombinedRoutes` is enabled.
[#3008](https://github.com/Kong/kubernetes-ingress-controller/pull/3008)
- Added `--cache-sync-timeout` flag allowing to change the default controllers'
cache synchronisation timeout.
[#3060]https://github.com/Kong/kubernetes-ingress-controller/pull/3060)
- Added `--cache-sync-timeout` flag allowing to change the default controllers'
cache synchronisation timeout.
[#3013](https://github.com/Kong/kubernetes-ingress-controller/pull/3013)
- Secrets validation introduced: CA certificates won't be synchronized
to Kong if the certificate is expired.
Expand Down
40 changes: 31 additions & 9 deletions internal/dataplane/parser/translate_httproute.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,27 +78,25 @@ func (p *Parser) ingressRulesFromHTTPRoute(result *ingressRules, httproute *gate
// ingressRulesFromHTTPRouteWithCombinedServiceRoutes generates a set of proto-Kong routes (ingress rules) from an HTTPRoute.
// If multiple rules in the HTTPRoute use the same Service, it combines them into a single Kong route.
func (p *Parser) ingressRulesFromHTTPRouteWithCombinedServiceRoutes(httproute *gatewayv1beta1.HTTPRoute, result *ingressRules) error {
for _, translationMeta := range translators.TranslateHTTPRoute(httproute) {
for _, kongServiceTranslation := range translators.TranslateHTTPRoute(httproute) {
// HTTPRoute uses a wrapper HTTPBackendRef to add optional filters to its BackendRefs
backendRefs := httpBackendRefsToBackendRefs(translationMeta.BackendRefs)
backendRefs := httpBackendRefsToBackendRefs(kongServiceTranslation.BackendRefs)

// use the original index of the first rule that uses this service as the rule number
firstCombinedRuleNum := translationMeta.RulesNumbers[0]
serviceName := kongServiceTranslation.Name

// create a service and attach the routes to it
service, err := generateKongServiceFromBackendRefWithRuleNumber(p.logger, p.storer, result, httproute, firstCombinedRuleNum, "http", backendRefs...)
service, err := generateKongServiceFromBackendRefWithName(p.logger, p.storer, result, serviceName, httproute, "http", backendRefs...)
if err != nil {
return err
}

// generate the routes for the service and attach them to the service
for j, rule := range translationMeta.Rules {
ruleNumber := translationMeta.RulesNumbers[j]
routes, err := generateKongRoutesFromHTTPRouteRule(httproute, ruleNumber, rule, p.flagEnabledRegexPathPrefix)
for _, kongRouteTranslation := range kongServiceTranslation.KongRoutes {
route, err := generateKongRouteFromTranslation(httproute, kongRouteTranslation, p.flagEnabledRegexPathPrefix)
if err != nil {
return err
}
service.Routes = append(service.Routes, routes...)
service.Routes = append(service.Routes, route)
}

// cache the service to avoid duplicates in further loop iterations
Expand Down Expand Up @@ -219,6 +217,30 @@ func generateKongRoutesFromHTTPRouteRule(
return routes, nil
}

func generateKongRouteFromTranslation(
httproute *gatewayv1beta1.HTTPRoute,
translation translators.KongRouteTranslation,
addRegexPrefix bool,
) (kongstate.Route, error) {
// gather the k8s object information and hostnames from the httproute
objectInfo := util.FromK8sObject(httproute)

// get the hostnames from the HTTPRoute
hostnames := getHTTPRouteHostnamesAsSliceOfStringPointers(httproute)

// generate kong plugins from rule.filters
plugins := generatePluginsFromHTTPRouteFilters(translation.Filters)

return generateKongRouteFromHTTPRouteMatches(
translation.Name,
translation.Matches,
objectInfo,
hostnames,
plugins,
addRegexPrefix,
)
}

// generateKongRouteFromHTTPRouteMatches converts an HTTPRouteMatches to a Kong Route object.
// This function assumes that the HTTPRouteMatches share the query params, headers and methods.
func generateKongRouteFromHTTPRouteMatches(
Expand Down
Loading