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
Implementing GEPs 726 and 922: Rewrites + Experimental CRDs #945
Implementing GEPs 726 and 922: Rewrites + Experimental CRDs #945
Conversation
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: robscott 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 |
This is a big PR, adding a hold until we have consensus on the approach. /hold |
d56d28c
to
7821e4e
Compare
Although I'd like to improve the reference docs, the rendering with this change actually isn't as bad as I'd originally expected. Search for "gateway:experimental" in the deploy preview to take a look. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This LGTM overall, with just a couple of small queries.
// Substitution defines the HTTP path value to substitute. An empty value | ||
// ("") indicates that the portion of the path to be changed should be | ||
// removed from the resulting path. For example, a request to "/foo/bar" | ||
// with a prefix match of "/foo" would be modified to "/bar". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit hesitant about empty fields, especially string semantics. They are not usually the most intuitive, even more so in kube land.
Have we considered another "Type": "RemovePrefixMatch"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if explicitly a NULL is the substitution value for the remove case? Something explicit in the value as opposed to an additional type (too many types, while explicit to implement can cause usability issues and API friction)
Also, many JSON parsers and automation tools drop an empty value - thus preventing passing an empty value in a document through a tool chain, and YAML empty value = NULL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hbagdi We discussed this at the community meeting yesterday. I suggested something similar to what @brianehlert said above, essentially trying to ensure that users had to specify at least something here, even if that was just "". I tested the current CRDs out with the following YAML in a redirect filter:
path:
type: ReplacePrefixMatch
That resulted in the following error:
error validating data: ValidationError(HTTPRoute.spec.rules[0].filters[0].requestRedirect.path): missing required field "substitution" in io.k8s.networking.gateway.v1alpha2.HTTPRoute.spec.rules.filters.requestRedirect.path
That error could be avoided by specifying an empty string:
path:
type: ReplacePrefixMatch
substitution: ""
I think that ends up being pretty clear.
The other key point that came up in the community meeting was that "replace with nothing" is a fairly common way to represent "remove" in a wide variety of tooling. Although I agree that we need to be careful about inferring meaning from unspecified values, I think we're safely avoiding that by requiring user input.
With all that said, my personal preference is to avoid an additional unique filter type here and instead move forward with the ability to replace a prefix match with nothing.
The generated YAML has nothing that indicates that those fields are experimental: gateway-api/config/crd/experimental/gateway.networking.k8s.io_httproutes.yaml Lines 977 to 1014 in 7821e4e
Can we not strip out the experimental tags from the YAML? |
7821e4e
to
963f6f3
Compare
963f6f3
to
0d40986
Compare
Good call, updated to leave them in place. |
Thanks for the great feedback on this @hbagdi and @youngnick! I think I've addressed everything now, PTAL. |
/lgtm I think the docs followup is a great idea. Thanks @robscott! |
|
||
// HTTPPathModifier defines configuration for path modifiers. | ||
// <gateway:experimental> | ||
type HTTPPathModifier struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to clarify that path doesn't include query string?
I think this may be a potential source of confusion. Not a blocker.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, that's a good point. I'll add that in a follow up.
Great work Rob! |
Thanks for the reviews! /hold cancel |
What type of PR is this?
/kind feature
What this PR does / why we need it:
This is a huge PR that implements GEP #726 and #922. These are bundled because they're difficult to do independently. To add new features to Gateway API, they need to be experimental. To understand how to generate experimental CRDs, we needed to have some kind of experimental feature to test with.
A big thanks to @jpeach for the inspiration here for CRD generation and showing this kind of custom approach was relatively straightforward.
I spent a non-trivial amount of time trying to get these field level annotations to work as "markers" like the other kubebuilder tags. Unfortunately I could not make that work, so chose a different syntax
<>
so these values would still be parseable after crdgen was complete. If anyone wants to experiment with better approaches here, I'd be very open.Alternatives I'd considered here:
Although this approach is not perfect, I think it's preferable to either of the above.
Which issue(s) this PR fixes:
This implements both #726 and #922, but both still require documentation updates. I'm leaving that out of this PR because it's already so big.
Does this PR introduce a user-facing change?: