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

refactor: dedup the route context code using reflection #1502

Merged
merged 9 commits into from
Jun 22, 2023

Conversation

shawnh2
Copy link
Contributor

@shawnh2 shawnh2 commented Jun 7, 2023

What type of PR is this?

What this PR does / why we need it:

Which issue(s) this PR fixes:

Fixes #1252

shawnh2 added 2 commits June 7, 2023 21:06
Signed-off-by: Shawnh2 <[email protected]>
@shawnh2 shawnh2 requested a review from a team as a code owner June 7, 2023 13:18
@codecov
Copy link

codecov bot commented Jun 7, 2023

Codecov Report

Merging #1502 (efd5395) into main (ca36e3f) will increase coverage by 0.00%.
The diff coverage is 84.16%.

@@           Coverage Diff            @@
##             main    #1502    +/-   ##
========================================
  Coverage   61.70%   61.71%            
========================================
  Files          81       81            
  Lines       12131    11967   -164     
========================================
- Hits         7485     7385   -100     
+ Misses       4179     4127    -52     
+ Partials      467      455    -12     
Impacted Files Coverage Δ
internal/gatewayapi/route.go 88.36% <77.27%> (ø)
internal/gatewayapi/contexts.go 84.30% <83.13%> (+8.43%) ⬆️
internal/cmd/egctl/translate.go 82.14% <100.00%> (+0.41%) ⬆️

... and 3 files with indirect coverage changes

// corresponding to the const defined in translator, like KindHTTPRoute,
// KindGRPCRoute, KindTLSRoute, KindTCPRoute, KindUDPRoute
func GetRouteType(route RouteContext) v1beta1.Kind {
rv := reflect.ValueOf(route)
Copy link
Contributor

Choose a reason for hiding this comment

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

do you think reflect is the right package to use here or should we use https://pkg.go.dev/k8s.io/apimachinery/pkg/util/validation/field which is used heavily in upstream gateway api, here an
example

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks for pointing it out, but i think https://pkg.go.dev/k8s.io/apimachinery/pkg/util/validation/field is not suitable for our case.

despite the fact that this package provides several powerful methods, but its intention is for validations only. in our case, we need more than that, we need to write some values for some fields in one struct as well, but this package does not have that kind of ability.

i thought about whether we could replace current validations with the one provided in that package, and turns out we may not. for example, the strings.HasPrefix(*path.Value, "/") use the variable path directly, which has explicit type *gatewayv1b1.HTTPPathMatch. however, in our case, the only variable we can manipulate with is route, which is a interface RouteContext. so we need the ability provided in package reflect, to play with the real type behinds whatever it represents.

so basically, i think relfect is inevitable.

@arkodg
Copy link
Contributor

arkodg commented Jun 7, 2023

thanks for picking this refactor up @shawnh2 !

for i := 0; i < specParentRefs.Len(); i++ {
p := specParentRefs.Index(i).Interface().(v1beta1.ParentReference)
up := p
if !isHTTPRoute {
Copy link
Contributor

Choose a reason for hiding this comment

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

curious why this custom HTTPRoute logic is needed

Copy link
Contributor Author

@shawnh2 shawnh2 Jun 9, 2023

Choose a reason for hiding this comment

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

becasue there are some differences between the implementation of HTTPRoute and other Routes in GetRouteParentContext method.

for example, HTTPRoute is like:

var parentRef *v1beta1.ParentReference
for i, p := range h.Spec.ParentRefs {
if reflect.DeepEqual(p, forParentRef) {
parentRef = &h.Spec.ParentRefs[i]
break
}
}

as for other Route:

var parentRef *v1beta1.ParentReference
for i, p := range u.Spec.ParentRefs {
p := UpgradeParentReference(p)
if reflect.DeepEqual(p, forParentRef) {
upgraded := UpgradeParentReference(u.Spec.ParentRefs[i])
parentRef = &upgraded
break
}
}

so add a if logic to deal with HTTPRoute

@arkodg arkodg requested a review from kflynn June 13, 2023 22:20
func GetRouteType(route RouteContext) v1beta1.Kind {
rv := reflect.ValueOf(route)
rt := rv.Type().String()
return v1beta1.Kind(strings.TrimSuffix(rt, "Context")[strings.LastIndex(rt, ".")+1:])
Copy link
Contributor

Choose a reason for hiding this comment

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

this looks a little intimidating to me, can we use FieldByName here ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sure we can use FieldByName, in that case, we need to add one more field, like type string in struct HTTP/GRPC/.../Context, indicating the type of this struct, and all the value of field type comes from:

KindGRPCRoute = "GRPCRoute"
KindHTTPRoute = "HTTPRoute"
KindNamespace = "Namespace"
KindTLSRoute = "TLSRoute"
KindTCPRoute = "TCPRoute"
KindUDPRoute = "UDPRoute"

@arkodg see if this is ok?

Copy link
Contributor

Choose a reason for hiding this comment

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

or you could also use GetKind() ?
see it being used in other places in the codebase

if res.GetKind() == string(extFilter.Kind) && res.GetName() == string(extFilter.Name) && res.GetNamespace() == filterNs {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks for the heads up!

now we can use FieldByName("Kind"), BTW, I add some TypeMeta for xRoute resources in translate func, nor it will keep getting "".

@arkodg
Copy link
Contributor

arkodg commented Jun 16, 2023

thanks @shawnh2 for addressing the comments, adding a minor comment, else LGTM !

Copy link
Contributor

@arkodg arkodg left a comment

Choose a reason for hiding this comment

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

LGTM thanks !

@arkodg arkodg requested review from a team, chauhanshubham and Xunzhuo and removed request for a team June 21, 2023 18:28
@zirain zirain merged commit 8df2474 into envoyproxy:main Jun 22, 2023
@shawnh2 shawnh2 deleted the rework-route-context branch June 23, 2023 06:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Dedup code pertaining to xRoute using reflection
3 participants