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

fix: ingress rules order is preserved #97

Merged
merged 8 commits into from
Dec 7, 2023

Conversation

mlavacca
Copy link
Member

@mlavacca mlavacca commented Nov 3, 2023

What type of PR is this?

/kind bug

What this PR does / why we need it:

Ingress Rules order needs to be preserved when converting into HTTPRoute rules.

Which issue(s) this PR fixes:

Fixes #91

Does this PR introduce a user-facing change?:

NONE

@k8s-ci-robot k8s-ci-robot added kind/bug Categorizes issue or PR as related to a bug. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Nov 3, 2023
@k8s-ci-robot k8s-ci-robot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Nov 3, 2023
@LiorLieberman
Copy link
Member

@mlavacca I think we want to make sure we dont produce different rule orders other than making the tests pass with different order.
Changing the rule orders have implications. Also it can result in unnecessary update to the API(in case the HTTPRoute is already in the cluster)

@mlavacca
Copy link
Member Author

mlavacca commented Nov 11, 2023

@mlavacca I think we want to make sure we dont produce different rule orders other than making the tests pass with different order. Changing the rule orders have implications. Also it can result in unnecessary update to the API(in case the HTTPRoute is already in the cluster)

yep, I agree that we should preserve the rule orders. I dug a bit into the issue, and the problem is caused by the fact that in the common package we aggregate the ingress rules into a map, and then we iterate that map to create HTTPRoute rules. Since map order is not guaranteed, this can cause flakes. This problem has been surfaced by the new kong test as there were no tests with ingresses having multiple rules previously. We may need to add some logic to fix it. I'll do it in this PR.

@k8s-ci-robot k8s-ci-robot added size/S Denotes a PR that changes 10-29 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Dec 6, 2023
@mlavacca mlavacca changed the title fix: flaky test fix: ingress rules order is preserved Dec 6, 2023
Copy link
Member

@levikobi levikobi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tackling this one @mlavacca!

pkg/i2gw/providers/common/converter.go Outdated Show resolved Hide resolved
The ingress rules order is kept during Ingress to Gateway conversion.

Signed-off-by: Mattia Lavacca <lavacca.mattia@gmail.com>
@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels Dec 7, 2023
Signed-off-by: Mattia Lavacca <lavacca.mattia@gmail.com>
Copy link
Member

@LiorLieberman LiorLieberman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throwing an idea.
Is this helping also achieving what we want?

type orderedPathsByMatchGroup struct {
	keys []pathMatchKey
	data map[pathMatchKey][]ingressPath
}

func (rg *ingressRuleGroup) toHTTPRoute() (gatewayv1beta1.HTTPRoute, field.ErrorList) {
	// pathsByMatchGroup := map[pathMatchKey][]ingressPath{}
	pathsByMatchGroup := &orderedPathsByMatchGroup{
		keys: []pathMatchKey{},
		data: make(map[pathMatchKey][]ingressPath),
	}
	var errors field.ErrorList

	for i, ir := range rg.rules {
		for j, path := range ir.rule.HTTP.Paths {
			ip := ingressPath{ruleIdx: i, pathIdx: j, ruleType: "http", path: path}
			pmKey := getPathMatchKey(ip)
			if _, ok := pathsByMatchGroup.data[pmKey]; !ok {
				pathsByMatchGroup.keys = append(pathsByMatchGroup.keys, pmKey)
			}
			pathsByMatchGroup.data[pmKey] = append(pathsByMatchGroup.data[pmKey], ip)

		}
	}

later in the range:

	for _, pmKey := range pathsByMatchGroup.keys {
		paths := pathsByMatchGroup.data[pmKey]
		path := paths[0]

By keeping only the keys in a slice, we can also retain the order in which the elements were added.
I have not ran this but it feels like it could work

Co-authored-by: Lior Lieberman <liorlieberman@google.com>
Signed-off-by: Mattia Lavacca <lavacca.mattia@gmail.com>
@mlavacca
Copy link
Member Author

mlavacca commented Dec 7, 2023

Throwing an idea. Is this helping also achieving what we want?

type orderedPathsByMatchGroup struct {
	keys []pathMatchKey
	data map[pathMatchKey][]ingressPath
}

func (rg *ingressRuleGroup) toHTTPRoute() (gatewayv1beta1.HTTPRoute, field.ErrorList) {
	// pathsByMatchGroup := map[pathMatchKey][]ingressPath{}
	pathsByMatchGroup := &orderedPathsByMatchGroup{
		keys: []pathMatchKey{},
		data: make(map[pathMatchKey][]ingressPath),
	}
	var errors field.ErrorList

	for i, ir := range rg.rules {
		for j, path := range ir.rule.HTTP.Paths {
			ip := ingressPath{ruleIdx: i, pathIdx: j, ruleType: "http", path: path}
			pmKey := getPathMatchKey(ip)
			if _, ok := pathsByMatchGroup.data[pmKey]; !ok {
				pathsByMatchGroup.keys = append(pathsByMatchGroup.keys, pmKey)
			}
			pathsByMatchGroup.data[pmKey] = append(pathsByMatchGroup.data[pmKey], ip)

		}
	}

later in the range:

	for _, pmKey := range pathsByMatchGroup.keys {
		paths := pathsByMatchGroup.data[pmKey]
		path := paths[0]

By keeping only the keys in a slice, we can also retain the order in which the elements were added. I have not ran this but it feels like it could work

It makes sense, your proposal is more efficient. I've made this change and changed the tests accordingly.

Copy link
Member

@LiorLieberman LiorLieberman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Mattia!

pkg/i2gw/providers/common/utils.go Outdated Show resolved Hide resolved
pkg/i2gw/providers/common/utils.go Outdated Show resolved Hide resolved
pkg/i2gw/providers/common/utils.go Outdated Show resolved Hide resolved
pkg/i2gw/providers/common/converter.go Show resolved Hide resolved
Signed-off-by: Mattia Lavacca <lavacca.mattia@gmail.com>
Signed-off-by: Mattia Lavacca <lavacca.mattia@gmail.com>
pkg/i2gw/providers/common/utils.go Outdated Show resolved Hide resolved
pkg/i2gw/providers/common/converter.go Outdated Show resolved Hide resolved
pkg/i2gw/providers/common/converter.go Outdated Show resolved Hide resolved
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: LiorLieberman, mlavacca

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Dec 7, 2023
Co-authored-by: Lior Lieberman <liorlib7+riskified@gmail.com>
Signed-off-by: Mattia Lavacca <lavacca.mattia@gmail.com>
@LiorLieberman
Copy link
Member

Thanks Mattia!
/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Dec 7, 2023
@k8s-ci-robot k8s-ci-robot merged commit c55e274 into kubernetes-sigs:main Dec 7, 2023
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/bug Categorizes issue or PR as related to a bug. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Flaky tests at Kong ToGateway
4 participants