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

API: HTTP Filter ordering #2993

Merged
merged 31 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
6d7b9dc
add filter ordering API
zhaohuabing Mar 21, 2024
e4e11cc
envoy HTTP filter ordering API
zhaohuabing Mar 21, 2024
fd26a09
add validation
zhaohuabing Mar 21, 2024
93e88d0
remove router
zhaohuabing Mar 21, 2024
59b4cc4
remove maxItem
zhaohuabing Mar 25, 2024
913a159
address comments
zhaohuabing Mar 25, 2024
ccc5180
Merge branch 'main' into filter-order
zhaohuabing Mar 25, 2024
dcc1063
fix json tag
zhaohuabing Mar 25, 2024
5ff23ef
fix gen
zhaohuabing Mar 25, 2024
50caf0a
Merge branch 'main' into filter-order
zhaohuabing Mar 25, 2024
8afa438
Merge branch 'main' into filter-order
zirain Mar 25, 2024
0956189
fix gen
zhaohuabing Mar 26, 2024
87748b9
address comments
zhaohuabing Mar 26, 2024
f9d315d
minor wording
zhaohuabing Mar 26, 2024
3780166
minor wording
zhaohuabing Mar 26, 2024
1d0e35d
Merge branch 'main' into filter-order
zhaohuabing Mar 26, 2024
e405951
fix gen
zhaohuabing Mar 26, 2024
f42aaa5
fix gen
zhaohuabing Mar 26, 2024
7371b69
minor wording
zhaohuabing Mar 26, 2024
11ab05a
fix gen
zhaohuabing Mar 26, 2024
a99b413
address comments
zhaohuabing Mar 26, 2024
73688ca
fix gent
zhaohuabing Mar 26, 2024
0a53710
Merge branch 'main' into filter-order
zhaohuabing Mar 26, 2024
0d76bfc
Merge branch 'main' into filter-order
zhaohuabing Mar 26, 2024
b2ba887
address comments
zhaohuabing Apr 12, 2024
9a12f9f
Merge branch 'main' into filter-order
zhaohuabing Apr 12, 2024
ade4707
kube gen
zhaohuabing Apr 12, 2024
e8291a0
Merge remote-tracking branch 'upstream/main' into filter-order
zhaohuabing Apr 16, 2024
d68ee22
address comments
zhaohuabing Apr 16, 2024
321b5ab
address comments
zhaohuabing Apr 17, 2024
7673385
Merge branch 'main' into filter-order
zirain Apr 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions api/v1alpha1/envoyproxy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,92 @@ type EnvoyProxySpec struct {
//
// +optional
Shutdown *ShutdownConfig `json:"shutdown,omitempty"`

// FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain.
// If unspecified, the default filter order is applied.
// Default filter order is:
//
// - envoy.filters.http.fault
//
// - envoy.filters.http.cors
//
// - envoy.filters.http.ext_authz
//
// - envoy.filters.http.basic_authn
//
// - envoy.filters.http.oauth2
//
// - envoy.filters.http.jwt_authn
//
// - envoy.filters.http.ext_proc
//
// - envoy.filters.http.wasm
//
// - envoy.filters.http.local_ratelimit
//
// - envoy.filters.http.ratelimit
//
// - envoy.filters.http.router
//
// +optional
// +notImplementedHide
FilterOrder []FilterPosition `json:"filterOrder,omitempty"`
}

// FilterPosition defines the position of an Envoy HTTP filter in the filter chain.
// +kubebuilder:validation:XValidation:rule="(has(self.before) || has(self.after))",message="one of before or after must be specified"
// +kubebuilder:validation:XValidation:rule="(has(self.before) && !has(self.after)) || (!has(self.before) && has(self.after))",message="only one of before or after can be specified"
type FilterPosition struct {
// Name of the filter.
Name EnvoyFilter `json:"filter"`

// Before defines the filter that should come before the filter.
// Only one of Before or After must be set.
Before *EnvoyFilter `json:"before,omitempty"`
zhaohuabing marked this conversation as resolved.
Show resolved Hide resolved

// After defines the filter that should come after the filter.
// Only one of Before or After must be set.
After *EnvoyFilter `json:"after,omitempty"`
}

// EnvoyFilter defines the type of Envoy HTTP filter.
// +kubebuilder:validation:Enum=envoy.filters.http.cors;envoy.filters.http.ext_authz;envoy.filters.http.basic_authn;envoy.filters.http.oauth2;envoy.filters.http.jwt_authn;envoy.filters.http.fault;envoy.filters.http.local_ratelimit;envoy.filters.http.ratelimit;envoy.filters.http.wasm;envoy.filters.http.ext_proc
zhaohuabing marked this conversation as resolved.
Show resolved Hide resolved
type EnvoyFilter string
zhaohuabing marked this conversation as resolved.
Show resolved Hide resolved

const (
// EnvoyFilterFault defines the Envoy HTTP fault filter.
EnvoyFilterFault EnvoyFilter = "envoy.filters.http.fault"
// EnvoyFilterCORS defines the Envoy HTTP CORS filter.
EnvoyFilterCORS EnvoyFilter = "envoy.filters.http.cors"

// EnvoyFilterExtAuthz defines the Envoy HTTP external authorization filter.
EnvoyFilterExtAuthz EnvoyFilter = "envoy.filters.http.ext_authz"

// EnvoyFilterBasicAuthn defines the Envoy HTTP basic authentication filter.
EnvoyFilterBasicAuthn EnvoyFilter = "envoy.filters.http.basic_authn"

// EnvoyFilterOAuth2 defines the Envoy HTTP OAuth2 filter.
EnvoyFilterOAuth2 EnvoyFilter = "envoy.filters.http.oauth2"

// EnvoyFilterJWTAuthn defines the Envoy HTTP JWT authentication filter.
EnvoyFilterJWTAuthn EnvoyFilter = "envoy.filters.http.jwt_authn"

// EnvoyFilterExtProc defines the Envoy HTTP external process filter.
EnvoyFilterExtProc EnvoyFilter = "envoy.filters.http.ext_proc"

// EnvoyFilterWasm defines the Envoy HTTP WebAssembly filter.
EnvoyFilterWasm EnvoyFilter = "envoy.filters.http.wasm"

// EnvoyFilterLocalRateLimit defines the Envoy HTTP local rate limit filter.
EnvoyFilterLocalRateLimit EnvoyFilter = "envoy.filters.http.local_ratelimit"

// EnvoyFilterRateLimit defines the Envoy HTTP rate limit filter.
EnvoyFilterRateLimit EnvoyFilter = "envoy.filters.http.ratelimit"

// EnvoyFilterRouter defines the Envoy HTTP router filter.
EnvoyFilterRouter EnvoyFilter = "envoy.filters.http.router"
)

type ProxyTelemetry struct {
// AccessLogs defines accesslog parameters for managed proxies.
// If unspecified, will send default format to stdout.
Expand Down
32 changes: 32 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,104 @@ spec:
items:
type: string
type: array
filterOrder:
description: |-
FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain.
If unspecified, the default filter order is applied.
Default filter order is:


- envoy.filters.http.fault


- envoy.filters.http.cors


- envoy.filters.http.ext_authz


- envoy.filters.http.basic_authn


- envoy.filters.http.oauth2


- envoy.filters.http.jwt_authn


- envoy.filters.http.ext_proc


- envoy.filters.http.wasm


- envoy.filters.http.local_ratelimit


- envoy.filters.http.ratelimit


- envoy.filters.http.router
items:
description: FilterPosition defines the position of an Envoy HTTP
filter in the filter chain.
properties:
after:
description: |-
After defines the filter that should come after the filter.
Only one of Before or After must be set.
enum:
- envoy.filters.http.cors
- envoy.filters.http.ext_authz
- envoy.filters.http.basic_authn
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
- envoy.filters.http.fault
- envoy.filters.http.local_ratelimit
- envoy.filters.http.ratelimit
- envoy.filters.http.wasm
- envoy.filters.http.ext_proc
type: string
before:
description: |-
Before defines the filter that should come before the filter.
Only one of Before or After must be set.
enum:
- envoy.filters.http.cors
- envoy.filters.http.ext_authz
- envoy.filters.http.basic_authn
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
- envoy.filters.http.fault
- envoy.filters.http.local_ratelimit
- envoy.filters.http.ratelimit
- envoy.filters.http.wasm
- envoy.filters.http.ext_proc
type: string
filter:
description: Name of the filter.
enum:
- envoy.filters.http.cors
- envoy.filters.http.ext_authz
- envoy.filters.http.basic_authn
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
- envoy.filters.http.fault
- envoy.filters.http.local_ratelimit
- envoy.filters.http.ratelimit
- envoy.filters.http.wasm
- envoy.filters.http.ext_proc
type: string
required:
- filter
type: object
x-kubernetes-validations:
- message: one of before or after must be specified
rule: (has(self.before) || has(self.after))
- message: only one of before or after can be specified
rule: (has(self.before) && !has(self.after)) || (!has(self.before)
&& has(self.after))
type: array
logging:
default:
level:
Expand Down
40 changes: 40 additions & 0 deletions site/content/en/latest/api/extension_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,30 @@ _Appears in:_
| `extProc` | _[ExtProc](#extproc) array_ | true | ExtProc is an ordered list of external processing filters<br />that should added to the envoy filter chain |


#### EnvoyFilter

_Underlying type:_ _string_

EnvoyFilter defines the type of Envoy HTTP filter.

_Appears in:_
- [FilterPosition](#filterposition)

| Value | Description |
| ----- | ----------- |
| `envoy.filters.http.fault` | EnvoyFilterFault defines the Envoy HTTP fault filter.<br /> |
| `envoy.filters.http.cors` | EnvoyFilterCORS defines the Envoy HTTP CORS filter.<br /> |
| `envoy.filters.http.ext_authz` | EnvoyFilterExtAuthz defines the Envoy HTTP external authorization filter.<br /> |
| `envoy.filters.http.basic_authn` | EnvoyFilterBasicAuthn defines the Envoy HTTP basic authentication filter.<br /> |
| `envoy.filters.http.oauth2` | EnvoyFilterOAuth2 defines the Envoy HTTP OAuth2 filter.<br /> |
| `envoy.filters.http.jwt_authn` | EnvoyFilterJWTAuthn defines the Envoy HTTP JWT authentication filter.<br /> |
| `envoy.filters.http.ext_proc` | EnvoyFilterExtProc defines the Envoy HTTP external process filter.<br /> |
| `envoy.filters.http.wasm` | EnvoyFilterWasm defines the Envoy HTTP WebAssembly filter.<br /> |
| `envoy.filters.http.local_ratelimit` | EnvoyFilterLocalRateLimit defines the Envoy HTTP local rate limit filter.<br /> |
| `envoy.filters.http.ratelimit` | EnvoyFilterRateLimit defines the Envoy HTTP rate limit filter.<br /> |
| `envoy.filters.http.router` | EnvoyFilterRouter defines the Envoy HTTP router filter.<br /> |


#### EnvoyGateway


Expand Down Expand Up @@ -1302,6 +1326,22 @@ _Appears in:_
| `path` | _string_ | true | Path defines the file path used to expose envoy access log(e.g. /dev/stdout). |


#### FilterPosition



FilterPosition defines the position of an Envoy HTTP filter in the filter chain.

_Appears in:_
- [EnvoyProxySpec](#envoyproxyspec)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `filter` | _[EnvoyFilter](#envoyfilter)_ | true | Name of the filter. |
| `before` | _[EnvoyFilter](#envoyfilter)_ | true | Before defines the filter that should come before the filter.<br />Only one of Before or After must be set. |
| `after` | _[EnvoyFilter](#envoyfilter)_ | true | After defines the filter that should come after the filter.<br />Only one of Before or After must be set. |


#### GRPCExtAuthService


Expand Down
58 changes: 57 additions & 1 deletion test/cel-validation/envoyproxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,62 @@ func TestEnvoyProxyProvider(t *testing.T) {
}
},
},
{
desc: "ProxyFilterOrder-with-before-and-after",
mutate: func(envoy *egv1a1.EnvoyProxy) {
envoy.Spec = egv1a1.EnvoyProxySpec{
FilterOrder: []egv1a1.FilterPosition{
{
Name: egv1a1.EnvoyFilterRateLimit,
Before: ptr.To(egv1a1.EnvoyFilterCORS),
After: ptr.To(egv1a1.EnvoyFilterBasicAuthn),
},
},
}
},
wantErrors: []string{"only one of before or after can be specified"},
},
{
desc: "ProxyFilterOrder-without-before-or-after",
mutate: func(envoy *egv1a1.EnvoyProxy) {
envoy.Spec = egv1a1.EnvoyProxySpec{
FilterOrder: []egv1a1.FilterPosition{
{
Name: egv1a1.EnvoyFilterRateLimit,
},
},
}
},
wantErrors: []string{"one of before or after must be specified"},
},
{
desc: "ProxyFilterOrder-with-before",
mutate: func(envoy *egv1a1.EnvoyProxy) {
envoy.Spec = egv1a1.EnvoyProxySpec{
FilterOrder: []egv1a1.FilterPosition{
{
Name: egv1a1.EnvoyFilterRateLimit,
Before: ptr.To(egv1a1.EnvoyFilterCORS),
},
},
}
},
wantErrors: []string{},
},
{
desc: "ProxyFilterOrder-with-after",
mutate: func(envoy *egv1a1.EnvoyProxy) {
envoy.Spec = egv1a1.EnvoyProxySpec{
FilterOrder: []egv1a1.FilterPosition{
{
Name: egv1a1.EnvoyFilterRateLimit,
After: ptr.To(egv1a1.EnvoyFilterBasicAuthn),
},
},
}
},
wantErrors: []string{},
},
}

for _, tc := range cases {
Expand All @@ -1237,7 +1293,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
}

if (len(tc.wantErrors) != 0) != (err != nil) {
t.Fatalf("Unexpected response while creating EnvoyProxy; got err=\n%v\n;want error=%v", err, tc.wantErrors != nil)
t.Fatalf("Unexpected response while creating EnvoyProxy; got err=\n%v\n;want error=%v", err, tc.wantErrors)
}

var missingErrorStrings []string
Expand Down