Skip to content

Commit

Permalink
update tests and changelog
Browse files Browse the repository at this point in the history
  • Loading branch information
randmonkey committed Dec 10, 2024
1 parent caaeac9 commit df6e670
Show file tree
Hide file tree
Showing 7 changed files with 685 additions and 73 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ Adding a new version? You'll need three changes:
where `<hash>` is the hash result of the calculated name, like
`httproute.default.svc.default.a-long-long-long-service-name.80_combined.00001111222233334444aaaabbbbcccc`.
[#6711](https://github.com/Kong/kubernetes-ingress-controller/pull/6711)
[#6766](https://github.com/Kong/kubernetes-ingress-controller/pull/6766)
- The new tag `k8s-named-route-rule` is added to a Kong Route, in the case when mapped `HTTPRoute`, `GRPCRoute`,
`TCPRoute`, `TLSRoute` or `UDPRoute` has one or many route rules named (filled `spec.rules[*].name` field),
those names will be propagated to one or many instances of aforementioned tag.
Expand All @@ -224,7 +225,6 @@ Adding a new version? You'll need three changes:
This can reduce the memory usage in scenarios with a large number of giant secrets.
[#6795](https://github.com/Kong/kubernetes-ingress-controller/pull/6795)


## [3.3.1]

> Release date: 2024-08-28
Expand Down
41 changes: 8 additions & 33 deletions internal/dataplane/translator/subtranslator/httproute.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ type HTTPRoutesTranslationResult struct {
HTTPRouteNameToTranslationErrors map[k8stypes.NamespacedName][]error
}

type splitHTTPRouteMatchesWithPrioritiesGroupedByRule map[string][]SplitHTTPRouteMatchToKongRoutePriority

// TranslateHTTPRoutesToKongstateServices translates a set of HTTPRoutes to kongstate services,
// and collect the translation errors in the process of translating.
func TranslateHTTPRoutesToKongstateServices(
Expand All @@ -65,20 +67,12 @@ func TranslateHTTPRoutesToKongstateServices(
) HTTPRoutesTranslationResult {
serviceNameToRules := groupRulesFromHTTPRoutesByKongServiceName(routes, combinedServicesFromDifferentHTTPRoutes)

// first, split HTTPRoutes by hostnames and matches.
ruleToSplitMatchesWithPriorities := make(map[string][]SplitHTTPRouteMatchToKongRoutePriority)
// When feature flag expression routes is enabled, we need first split the matches and assign priorities to them
// to set proper priorities to the translated Kong routes for satisfying the specification of priorities of HTTPRoute matches:
// https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteRule
ruleToSplitMatchesWithPriorities := make(splitHTTPRouteMatchesWithPrioritiesGroupedByRule)
if expressionRoutes {
splitHTTPRouteMatches := []SplitHTTPRouteMatch{}
for _, route := range routes {
splitHTTPRouteMatches = append(splitHTTPRouteMatches, SplitHTTPRoute(route)...)
}
// assign priorities to split HTTPRoutes.
splitHTTPRouteMatchesWithPriorities := AssignRoutePriorityToSplitHTTPRouteMatches(logger, splitHTTPRouteMatches)
for _, matchWithPriority := range splitHTTPRouteMatchesWithPriorities {
sourceRoute := matchWithPriority.Match.Source
ruleKey := fmt.Sprintf("%s/%s.%d", sourceRoute.Namespace, sourceRoute.Name, matchWithPriority.Match.RuleIndex)
ruleToSplitMatchesWithPriorities[ruleKey] = append(ruleToSplitMatchesWithPriorities[ruleKey], matchWithPriority)
}
ruleToSplitMatchesWithPriorities = groupHTTPRouteMatchesWithPrioritiesByRule(logger, routes)
}

kongstateServiceCache := map[string]kongstate.Service{}
Expand Down Expand Up @@ -274,7 +268,7 @@ func translateHTTPRouteRulesMetaToKongstateService(
}

if expressionRoutes {
routes, err := translateHTTPRouteRulesMetaToKongstateRoutesWithExpression(matchesWithPriorities)
routes, err := translateSplitHTTPRouteMatchesToKongstateRoutesWithExpression(matchesWithPriorities)
if err != nil {
return kongstate.Service{}, err
}
Expand Down Expand Up @@ -401,24 +395,6 @@ func translateHTTPRouteRulesMetaToKongstateRoutes(
return routes, nil
}

func translateHTTPRouteRulesMetaToKongstateRoutesWithExpression(
matchesWithPriorities []SplitHTTPRouteMatchToKongRoutePriority,
) ([]kongstate.Route, error) {
routes := []kongstate.Route{}
for _, matchWithPriority := range matchesWithPriorities {
// Since each match is assigned a deterministic priority, we have to generate one route for each split match
// because every match have a different priority.
// TODO: update the algorithm to assign priorities to matches to make it possible to consilidate some matches.
// For example, we can assign the same priority to multiple matches from the same rule if they tie on the priority from the fixed fields.
route, err := KongExpressionRouteFromHTTPRouteMatchWithPriority(matchWithPriority)
if err != nil {
return []kongstate.Route{}, err
}
routes = append(routes, *route)
}
return routes, nil
}

// extractUniqueHTTPRoutes extracts unique HTTPRoutes in a grouped list of HTTPRouteRuleMeta.
func extractUniqueHTTPRoutes(rulesMeta []httpRouteRuleMeta) []*gatewayapi.HTTPRoute {
routes := lo.Map(rulesMeta, func(m httpRouteRuleMeta, _ int) *gatewayapi.HTTPRoute {
Expand Down Expand Up @@ -558,7 +534,6 @@ func (m httpRouteRuleMeta) getKongServiceNameByBackendRefs() string {
hash := sha256.Sum256([]byte(name))
// We have already returned when there are no backends in the rule, so it is safe to use backendNames[0].
trimmedName := fmt.Sprintf("httproute.%s.svc.%s_combined.%x", m.parentRoute.Namespace, backendNames[0], hash)
// REVIEW: should we emit a log here to tell that the name is trimmed? And should we record the original long name?
return trimmedName
}
return name
Expand Down
62 changes: 43 additions & 19 deletions internal/dataplane/translator/subtranslator/httproute_atc.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,14 +451,14 @@ func (t HTTPRoutePriorityTraits) EncodeToPriority() RoutePriorityType {
return priority
}

// AssignRoutePriorityToSplitHTTPRouteMatches assigns priority to
// assignRoutePriorityToSplitHTTPRouteMatches assigns priority to
// ALL split matches from ALL HTTPRoutes in the cache.
// Firstly assign "fixed" bits by the following fields of the match:
// hostname, path type, path length, method match, number of header matches, number of query param matches.
// If ties exists in the first step, where multiple matches has the same priority
// calculated from the fields, we run a sort for the matches in the tie
// and assign the bits for "relative order" according to the sorting result of these matches.
func AssignRoutePriorityToSplitHTTPRouteMatches(
func assignRoutePriorityToSplitHTTPRouteMatches(
logger logr.Logger,
splitHTTPRouteMatches []SplitHTTPRouteMatch,
) []SplitHTTPRouteMatchToKongRoutePriority {
Expand Down Expand Up @@ -541,9 +541,9 @@ func compareSplitHTTPRouteMatchesRelativePriority(match1, match2 SplitHTTPRouteM
return true
}

// KongExpressionRouteFromHTTPRouteMatchWithPriority translates a split HTTPRoute match into expression
// kongExpressionRouteFromHTTPRouteMatchWithPriority translates a split HTTPRoute match into expression
// based kong route with assigned priority.
func KongExpressionRouteFromHTTPRouteMatchWithPriority(
func kongExpressionRouteFromHTTPRouteMatchWithPriority(
httpRouteMatchWithPriority SplitHTTPRouteMatchToKongRoutePriority,
) (*kongstate.Route, error) {
match := httpRouteMatchWithPriority.Match
Expand Down Expand Up @@ -607,20 +607,44 @@ func KongExpressionRouteFromHTTPRouteMatchWithPriority(
return r, nil
}

// KongServiceNameFromSplitHTTPRouteMatch generates service name from split HTTPRoute match.
// since one HTTPRoute may be split by hostname and rule, the service name will be generated
// in the format "httproute.<namespace>.<name>.<hostname>.<rule index>".
// For example: `httproute.default.example.foo.com.0`.
func KongServiceNameFromSplitHTTPRouteMatch(match SplitHTTPRouteMatch) string {
httproute := match.Source
hostname := "_"
if len(match.Hostname) > 0 {
hostname = strings.ReplaceAll(match.Hostname, "*", "_")
// groupHTTPRouteMatchesWithPrioritiesByRule groups split HTTPRoute matches that has priorities assigned by the source HTTPRoute rule,.
func groupHTTPRouteMatchesWithPrioritiesByRule(
logger logr.Logger, routes []*gatewayapi.HTTPRoute,
) splitHTTPRouteMatchesWithPrioritiesGroupedByRule {
//
splitHTTPRouteMatches := []SplitHTTPRouteMatch{}
for _, route := range routes {
splitHTTPRouteMatches = append(splitHTTPRouteMatches, SplitHTTPRoute(route)...)
}
// assign priorities to split HTTPRoutes.
splitHTTPRouteMatchesWithPriorities := assignRoutePriorityToSplitHTTPRouteMatches(logger, splitHTTPRouteMatches)

// group the matches with priorities by its source HTTPRoute rule.
ruleToSplitMatchesWithPriorities := splitHTTPRouteMatchesWithPrioritiesGroupedByRule{}
for _, matchWithPriority := range splitHTTPRouteMatchesWithPriorities {
sourceRoute := matchWithPriority.Match.Source
ruleKey := fmt.Sprintf("%s/%s.%d", sourceRoute.Namespace, sourceRoute.Name, matchWithPriority.Match.RuleIndex)
ruleToSplitMatchesWithPriorities[ruleKey] = append(ruleToSplitMatchesWithPriorities[ruleKey], matchWithPriority)
}
return ruleToSplitMatchesWithPriorities
}

// translateSplitHTTPRouteMatchesToKongstateRoutesWithExpression translates a list of split HTTPRoute matches with assigned priorities
// that are poiting to the same service to list of kongstate route with expressions.
func translateSplitHTTPRouteMatchesToKongstateRoutesWithExpression(
matchesWithPriorities []SplitHTTPRouteMatchToKongRoutePriority,
) ([]kongstate.Route, error) {
routes := []kongstate.Route{}
for _, matchWithPriority := range matchesWithPriorities {
// Since each match is assigned a deterministic priority, we have to generate one route for each split match
// because every match have a different priority.
// TODO: update the algorithm to assign priorities to matches to make it possible to consolidate some matches.
// For example, we can assign the same priority to multiple matches from the same rule if they tie on the priority from the fixed fields.
route, err := kongExpressionRouteFromHTTPRouteMatchWithPriority(matchWithPriority)
if err != nil {
return []kongstate.Route{}, err
}
routes = append(routes, *route)
}
return fmt.Sprintf("httproute.%s.%s.%s.%d",
httproute.Namespace,
httproute.Name,
hostname,
match.RuleIndex,
)
return routes, nil
}
Loading

0 comments on commit df6e670

Please sign in to comment.