Conversation
Signed-off-by: wbpcode/wangbaiping <wbphub@gmail.com>
|
CC @envoyproxy/api-shepherds: Your approval is needed for changes made to |
Signed-off-by: wbpcode/wangbaiping <wbphub@gmail.com>
|
I like it, CI are all green. |
adisuissa
left a comment
There was a problem hiding this comment.
Thanks.
Left a few high-level comments.
This should probably be reviewed by the rest of the api shepherds.
cc @markdroth
api/envoy/extensions/filters/http/filter_chain/v3/filter_chain.proto
Outdated
Show resolved
Hide resolved
|
|
||
| // Map of named filter chains. The key is an arbitrary name assigned to the filter chain. | ||
| // These named filter chains can be referenced by the per-route configuration using | ||
| // the filter_chain_name field in FilterChainConfigPerRoute. |
There was a problem hiding this comment.
I think there's an implementation detail that should be highlighted here:
all the filters (in all the chains) will be initialized even if not used.
This will cause some confusion especially as some filters of the same type that appear in two different chains will not have a shared state.
There was a problem hiding this comment.
I will update the comment to make it more clear.
| // Each filter in the chain will process the request/response in sequence. | ||
| // At least one filter must be specified. | ||
| // [#extension-category: envoy.filters.http] | ||
| repeated config.core.v3.TypedExtensionConfig filters = 1 |
There was a problem hiding this comment.
As this is a filter chain, what were the design tradeoffs between typed-extension and Filter types here?
There was a problem hiding this comment.
Sorry, what you mean by Filter types? We prefer to use the TypedExtensionConfig in most cases I think?
There was a problem hiding this comment.
@wbpcode I think Adi is proposing using the HttpFilter type:
Note that this HttpFilter type is slightly more flexible, as it allows graceful failure if the Filter Type config is not built into the Envoy, and it allows for easy per route enabling and disabling of filters and for config discovery.
There was a problem hiding this comment.
Hello, @paul-r-gall, thanks for the explanation. I see. Actually, it's by design to use TypedExtension rather then HttpFilter. Because:
- this filter_chain filter is designed to provide better solution for per route level filter chain. That's say, in this new solution, we needn't previous
disabledflag inHttpFilterto enable or disable a filter. - the
is_optionalofHttpFilterflag actually should be part of TypedExtension in the future if necessary because more and more extensions are configured with TypedExtension. - the filter_chain now could be updated based on RDS, it reduced sense of ECDS support. So, to keep it simple, we prefer to keep the ECDS be part of main http filter chain only. So, the
config_discoveryfield is also unnecessary.
So, finally, we choose to use the general API of extensions (TypedExtensionConfig) rather then HttpFilter.
api/envoy/extensions/filters/http/filter_chain/v3/filter_chain.proto
Outdated
Show resolved
Hide resolved
api/envoy/extensions/filters/http/filter_chain/v3/filter_chain.proto
Outdated
Show resolved
Hide resolved
Signed-off-by: wbpcode <wbphub@gmail.com>
… dev-new-filter-chain-filter
Signed-off-by: wbpcode <wbphub@gmail.com>
Signed-off-by: wbpcode <wbphub@gmail.com>
agrawroh
left a comment
There was a problem hiding this comment.
LGTM, Thank You for this awesome change!
Signed-off-by: code <wbphub@gmail.com>
adisuissa
left a comment
There was a problem hiding this comment.
In general I like the idea of naming filters.
I'm not sure if filter-chain and named-filters should be coupled together, seems to me that chaining is one feature and named-filters is another.
/assign @markdroth
From implementation perspective, should probably validate that modifying the filter-chain contents (essentially ensuring that all the referenced filters are still alive mid-request and don't go away if the list changes) isn't problematic.
api/envoy/extensions/filters/http/filter_chain/v3/filter_chain.proto
Outdated
Show resolved
Hide resolved
The used filters list will be cached by the stream and never change when initializing the filter chain. And after that, we don't care the chain update for single request and every filter instance will cache related filter configuration. |
Hmm, i think there may be an information gap. we actual have no named-filters support here but a named-chains support? In the map, the key is unique key, the value must be a chain? It's designed to avoid we configure same chain at every route again and again. We treat the chain as the minimum unit and it's similar to named lua scripts, named route cluster specifier and so on. BTW, we don't support to configure a |
Composite‘s filter chain cannot works well in Envoy actually. Because composite works as a wrapper. From main filter chain's perspective, it's only one single filter. Because this reason, if any filters return a non-continue status, there would be a problem. That's say the composite filter chain could only be used for cases where all sub filters only return continue. It will bring huge complexity to refactor the composite or filter chain to make composite filter chain works well in Envoy. And because inherent design of composite filter implementation, it's no way to let composite works like this new filter. This new L7 filter (this PR) is much simple and easy to maintain, designed for per route filter chain natively. although they have similar API, but they actually have completely different underlying mechanism. |
I'm not super familiar with Envoy's filter API itself. What does "continue" mean in this context? Can you give me an example of a situation in which a filter might return a non-continue status? I'm trying to understand what limitations of the composite filter we're trying to overcome here in terms of practical examples.
This argument seems to be about Envoy's implementation, not about xDS as a multi-data plane API. From an API perspective, it seems extremely undesirable to have two different APIs to do essentially the same thing. I would strongly prefer to find a way to allow the existing API to do what you need here. For example, perhaps we can modify the composite filter implementation in Envoy such that if the matcher has only an |
|
@markdroth @wbpcode Thanks for the thoughtful discussion on this one. I think the verbosity problem with Composite filters is very real. With the current matcher API, there are 3-4 levels of As @markdroth you noted, the I think that having both APIs isn't duplication but layering which provides a simple API for the 80% of the use cases, and a powerful API for rest 20% who need conditional logic. As @wbpcode mentioned, Envoy Gateway has been using similar patterns (the |
|
I also think that the inline matcher simplification that @wbpcode proposed here is in the right direction. It'll allow Composite Filter to directly include the matcher field and would help eliminate the |
|
I am still unhappy with having two different filters that do the same thing. How about a compromise: We simplify the composite filter as @wbpcode is doing in #43227, and we also add a top-level filter chain field to the config, which can be set instead of the matcher. That way, we're still providing two APIs, but at least they're both in the same filter, so it will be clear to users that that's the right filter to use to solve that problem. |
|
Thanks so much @markdroth. With that way, then at least we can configure per route filter chain in easier way, that will make big sense for Envoy based gateway products 🙇 🎉 . Some points I am thinking about your proposed way (open for discussion):
Anyway, my core point is always that we should be open to new extensions if they have explicit target scenarios and maintainers are willing to maintain. As @zirain said, we already have different filters could so similar things, and if we check Kong Gateway plugin hub (popular gateway product based on Nginx and OpenResty), there are more similar but different plugins in their community. A rich library of extensions and extensibility are the lifeblood of gateway/proxy. As an engineer need to support consumers from various different companies, I only hear complain about why Envoy doesn't support this or that, but I never hear a complain about why there are three different rate limits, or why there are two different cache filters. So, we may needn't to worry too much for adding Also cc @agrawroh for thoughts from perspective of both user and maintainer. |
|
As Envoy Gateway maintainer, I would like to see a simpler API to enchane the per route level filter. xref: compisite filter
If |
|
@markdroth Thanks for being open to finding a middle ground here. I do want to echo some of @wbpcode's points though. One thing that comes to mind is the xDS multi-data-plane story. If we fold this into composite, data planes like gRPC that only care about conditional matching would still need to understand or explicitly ignore the filter-chain-only mode. Keeping them separate lets each data plane adopt what's relevant. gRPC can just ignore There's also a discoverability aspect. Users looking for "simple per-route filter chain" might not intuitively reach for something called "composite" as the name itself implies certain complexity. A separate filter with a clear name does signal the intent immediately. We already do this with That said, I do understand the concern about API surface area. If the consensus lands on keeping them in one filter, I think that's workable as long as we have clear documentation guiding users to the right pattern for their use case. Not to mention that internally 8/10 people who I spoke to find Composite and the Matchers API in general too complicated to use. |
Completely same experience when I worked at NetEase 🤣 . I used ~40 min to explain everything to PM and gateway teams, then they said, I think these work background and feedbacks from others make me always think the composite and generic matcher is expert-only tool for tricky scenarios and not a handy solution for non-expert users. And in most cases, it's these non-expert engineers to distribute and support Envoy in various different companies. Also this background makes me want to separate them independent extensions for different scenarios to avoid additional mental burden for non-expert engineers. And, TBH, I didn't get an obvious side effect of keeping independent extensions. 😂 |
Signed-off-by: code <wbphub@gmail.com>
|
adding some more history from Envoy Gateway
|
|
+1 on a simpler per-route API. Even though Envoy is mostly configured via the control plane, I still need to look at the Envoy configuration from time to time when troubleshooting. A more intuitive per-route API would really help 🙂 |
| // At least one filter must be specified. | ||
| // | ||
| // .. warning:: | ||
| // Please do not configure the ``filter_chain`` filter itself within this list recursively |
There was a problem hiding this comment.
This should be a validation check in the filter config and not rely on a warning message.
Co-authored-by: phlax <phlax@users.noreply.github.com> Signed-off-by: code <wbphub@gmail.com>
… dev-new-filter-chain-filter
phlax
left a comment
There was a problem hiding this comment.
thanks for fixing xds/api include - hopefully this will remove my request change
Take it easy. This is still waiting a LGTM from api shepherd |
|
Gently ping for another check or LGTM cc @adisuissa @markdroth I think Envoy maintainers and Envoy gateway maintainers here are all good to continue with this new extension? Especially this not change any core API (route/listener/cluster/HCM/TCP), we may shouldn't stop here? |
Signed-off-by: wbpcode/wangbaiping <wbphub@gmail.com>
|
Sorry, I still don't understand why it's better to have a second filter for this, rather than just add a new field to the composite filter's config to set the filter chain without a matcher. I think that from an API perspective, the important thing that users are going to be thinking about is "I need to configure a separate filter chain", not how the filter chain is specified. I think it's going to cause confusion if we need to explain to everyone how to decide which of the two filters to use. I think the story is much easier to understand if we say that the composite filter is the one place to do this, and it has a few knobs for how the nested filter chain can be selected. Can someone please tell me what use-case wouldn't be handled by that approach? Because as far as I can see, it would provide exactly the same functionality as would be provided here. |
|
BTW, there is no multi-data-plane issue here: gRPC is free to support or not support the new non-matcher filter chain field, and that's true regardless of whether it's a new field in the composite filter config or a new filter. |
Thanks for the response, Mark. All things are about to make API more friendly (which is I strongly think is very very important from practices and user feedbacks). Our understanding is:
The new extension should make most people happy (Maintainers, EG maintainers, most non-expert users). |
I think Rohit meant, combining APIs will result in that gRPC or similar clients will need to ignore specific fields in a supported extension rather than to ignore the whole extension. This may brings additional cognitive burden. Completely ignoring an extension should be much better to support an extension partially. This is not a very core point anyway 🤣. |
|
I hear what you're saying, but I just don't agree. I think that having a second filter to do the same thing is going to cause a lot more confusion than simply adding a new field to the composite filter. I don't think the composite filter has to be only an "expert" filter. Once we have the new API in #43227, if we add a config field that allows the composite filter to set a filter chain without a matcher, then from the API perspective, it's exactly the same as what you're proposing here. Users who don't need to select the filter chain conditionally can just set the hard-coded filter chain field without a matcher, and they still don't need to know or care about the matcher. I agree that "composite" may not be the best name for this filter, but I don't think that's a good justification for adding a second filter to do the same thing. Stepping back a bit, I think we've gotten to the point in this discussion where we're both just repeating what we've already said and not actually offering any new arguments, and I don't think that's a productive use of either of our time. I have heard your argument, and I believe that you have heard mine, and I don't think we're going to agree. So we need to figure out how to move forward. I still don't really think any of this is necessary, since essentially the same thing can be achieved via the composite filter with a matcher that matches everything. But I've offered a compromise of adding a new field to the composite filter to set the filter chain without a matcher, which I think addresses the main concern here. Like any compromise, it's not perfect, but I think it's something we can all live with. Can we agree to disagree and move forward with that compromise? |
FWIW, there are already lots of cases where gRPC doesn't support every field in a given extension, and there are even a few cases where Envoy doesn't support a field that gRPC has added. So this really isn't anything new. |
|
This pull request has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
Commit Message: http: new filter chain filter
Additional Description:
This PR gives the actual per route level filter chain support. We only need to ensure most filters could support the
createFilterFactoryFromProtoWithServerContext.This filter is a little similar to composite, but with following difference:
Risk Level: low. new filter.
Testing: unit/integration.
Docs Changes: added.
Release Notes: added.
Platform Specific Features: n/a.