-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
[WIP] Admission Control Filter #10230
Changes from all commits
991d39f
84c1b51
d3e80e0
668040d
3727a6d
b91335f
871fe70
cd1d879
b768ad1
7a4678e
d5278b8
34144fd
f3ec7f7
5e3d1ed
5654fa2
10472c0
a15ad6e
7f30f79
fa3cd1c
29478b0
6b69513
48043b6
d0b8c50
5358a78
6bf90d1
fbecc7f
c31da84
a9b9f8b
e01eda5
5e97619
fc666b7
d639d37
167133d
598fc5f
bafb45e
17fa361
3bde611
0d6dc11
e416db7
2748f16
0fa0905
72cd42d
8340a73
65c9773
dde5ea2
74a35a3
dbd2d88
0359eb4
5bb2747
762b131
a29c9eb
c83b8fd
c562c65
b420460
935e672
cddd71e
eab6c0f
6b893f6
1379ac5
9921663
9cb2499
80c219a
43d479b
20f6036
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# DO NOT EDIT. This file is generated by tools/proto_sync.py. | ||
|
||
load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") | ||
|
||
licenses(["notice"]) # Apache 2 | ||
|
||
api_proto_package( | ||
deps = [ | ||
"//envoy/api/v2/core:pkg", | ||
"//envoy/type/grpc/v2:pkg", | ||
"@com_github_cncf_udpa//udpa/annotations:pkg", | ||
], | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
syntax = "proto3"; | ||
|
||
package envoy.config.filter.http.admission_control.v2alpha; | ||
|
||
import "envoy/api/v2/core/base.proto"; | ||
import "envoy/type/grpc/v2/grpc_status.proto"; | ||
|
||
import "google/api/annotations.proto"; | ||
import "google/protobuf/duration.proto"; | ||
import "google/protobuf/wrappers.proto"; | ||
import "google/rpc/status.proto"; | ||
|
||
import "udpa/annotations/migrate.proto"; | ||
import "validate/validate.proto"; | ||
|
||
option java_package = "io.envoyproxy.envoy.config.filter.http.admission_control.v2alpha"; | ||
option java_outer_classname = "AdmissionControlProto"; | ||
option java_multiple_files = true; | ||
option (udpa.annotations.file_migrate).move_to_package = | ||
"envoy.extensions.filters.http.admission_control.v3alpha"; | ||
|
||
// [#protodoc-title: Admission Control] | ||
// Admission Control :ref:`configuration overview | ||
// <config_http_filters_admission_control>`. | ||
// [#extension: envoy.filters.http.admission_control] | ||
|
||
message AdmissionControl { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In terms of how to define/configure what success means, here is my suggestion: I would define a oneof which contains a required message which defines how a request is considered successful. I think this will give us future flexibility to potentially add pluggable success criteria. In the near term I would have a message called something like DefaultSuccessCriteria which can be used to configure things like 5xx, gRPC, etc. Maybe let's try that type of shape and have a look at whether we feel it will be extensible enough or not? |
||
enum HttpStatusRange { | ||
Http1xx = 0; | ||
Http2xx = 1; | ||
Http3xx = 2; | ||
Http4xx = 3; | ||
Http5xx = 4; | ||
} | ||
|
||
// Default method of specifying what constitutes a successful request. All status codes that | ||
// indicate a successful request must be explicitly specified if not relying on the default | ||
// values. | ||
message DefaultSuccessCriteria { | ||
// If HTTP statuses are unspecified, defaults to 2xx. | ||
repeated HttpStatusRange http_status = 1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I would make this an actual numeric range for flexibility. See |
||
|
||
// GRPC status codes to consider as request successes. If unspecified, defaults to "OK". | ||
repeated type.grpc.v2.GrpcStatus grpc_status = 2; | ||
} | ||
|
||
// If set to false, the admission control filter will operate as a pass-through filter. If the | ||
// message is unspecified, the filter will be enabled. | ||
api.v2.core.RuntimeFeatureFlag enabled = 1; | ||
|
||
// Defines how a request is considered a success/failure. | ||
oneof success_criteria { | ||
option (validate.required) = true; | ||
|
||
DefaultSuccessCriteria default_success_criteria = 2; | ||
} | ||
|
||
// The time window over which the success rate is calculated. The window is rounded to the nearest | ||
// second. Defaults to 120s. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW this seems super long. Also, naively I would think we would want a rolling window? Can you clarify how this works in terms of rolling vs. static windows, etc.? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this is a sliding window. Each second, we're popping off the success rate information from 121s ago and replacing it with the SR data from 1s ago. If I understood the first question correctly, we both want the same thing w.r.t. the windows. There are no tumbling windows. I just went with 120s because that's what was mentioned in the SRE handbook. I can run some experiments with different window sizes for the same traffic profile to get a better handle on what most people would want. I can put a TODO in code to make sure we're not stuck with an insane default. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes that makes sense, I would just update the docs to make that a bit more clear. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: I would still clarify that this is a sliding window at 1s granularity, etc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bump still needs more verbiage to talk about sliding, etc. |
||
google.protobuf.Duration sampling_window = 3; | ||
|
||
// Rejection probability is defined by the formula:: | ||
// | ||
// max(0, (rq_count - aggression_coefficient * rq_success_count) / (rq_count + 1)) | ||
// | ||
// The coefficient dictates how aggressively the admission controller will throttle requests as | ||
// the success rate drops. Lower values will cause throttling to kick in at higher success rates | ||
// and result in more aggressive throttling. Any values less than 1.0, will be set to 1.0. If the | ||
// message is unspecified, the coefficient is 2.0. | ||
api.v2.core.RuntimeDouble aggression_coefficient = 4; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# DO NOT EDIT. This file is generated by tools/proto_sync.py. | ||
|
||
load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") | ||
|
||
licenses(["notice"]) # Apache 2 | ||
|
||
api_proto_package( | ||
deps = [ | ||
"//envoy/config/core/v3:pkg", | ||
"//envoy/config/filter/http/admission_control/v2alpha:pkg", | ||
"//envoy/type/grpc/v3:pkg", | ||
"@com_github_cncf_udpa//udpa/annotations:pkg", | ||
], | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
syntax = "proto3"; | ||
|
||
package envoy.extensions.filters.http.admission_control.v3alpha; | ||
|
||
import "envoy/config/core/v3/base.proto"; | ||
import "envoy/type/grpc/v3/grpc_status.proto"; | ||
|
||
import "google/api/annotations.proto"; | ||
import "google/protobuf/duration.proto"; | ||
import "google/protobuf/wrappers.proto"; | ||
import "google/rpc/status.proto"; | ||
|
||
import "udpa/annotations/versioning.proto"; | ||
|
||
import "validate/validate.proto"; | ||
|
||
option java_package = "io.envoyproxy.envoy.extensions.filters.http.admission_control.v3alpha"; | ||
option java_outer_classname = "AdmissionControlProto"; | ||
option java_multiple_files = true; | ||
|
||
// [#protodoc-title: Admission Control] | ||
// Admission Control :ref:`configuration overview | ||
// <config_http_filters_admission_control>`. | ||
// [#extension: envoy.filters.http.admission_control] | ||
|
||
message AdmissionControl { | ||
option (udpa.annotations.versioning).previous_message_type = | ||
"envoy.config.filter.http.admission_control.v2alpha.AdmissionControl"; | ||
|
||
enum HttpStatusRange { | ||
Http1xx = 0; | ||
Http2xx = 1; | ||
Http3xx = 2; | ||
Http4xx = 3; | ||
Http5xx = 4; | ||
} | ||
|
||
// Default method of specifying what constitutes a successful request. All status codes that | ||
// indicate a successful request must be explicitly specified if not relying on the default | ||
// values. | ||
message DefaultSuccessCriteria { | ||
option (udpa.annotations.versioning).previous_message_type = | ||
"envoy.config.filter.http.admission_control.v2alpha.AdmissionControl." | ||
"DefaultSuccessCriteria"; | ||
|
||
// If HTTP statuses are unspecified, defaults to 2xx. | ||
repeated HttpStatusRange http_status = 1; | ||
|
||
// GRPC status codes to consider as request successes. If unspecified, defaults to "OK". | ||
repeated type.grpc.v3.GrpcStatus grpc_status = 2; | ||
} | ||
|
||
// If set to false, the admission control filter will operate as a pass-through filter. If the | ||
// message is unspecified, the filter will be enabled. | ||
config.core.v3.RuntimeFeatureFlag enabled = 1; | ||
|
||
// Defines how a request is considered a success/failure. | ||
oneof success_criteria { | ||
option (validate.required) = true; | ||
|
||
DefaultSuccessCriteria default_success_criteria = 2; | ||
} | ||
|
||
// The time window over which the success rate is calculated. The window is rounded to the nearest | ||
// second. Defaults to 120s. | ||
google.protobuf.Duration sampling_window = 3; | ||
|
||
// Rejection probability is defined by the formula:: | ||
// | ||
// max(0, (rq_count - aggression_coefficient * rq_success_count) / (rq_count + 1)) | ||
// | ||
// The coefficient dictates how aggressively the admission controller will throttle requests as | ||
// the success rate drops. Lower values will cause throttling to kick in at higher success rates | ||
// and result in more aggressive throttling. Any values less than 1.0, will be set to 1.0. If the | ||
// message is unspecified, the coefficient is 2.0. | ||
config.core.v3.RuntimeDouble aggression_coefficient = 4; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# DO NOT EDIT. This file is generated by tools/proto_sync.py. | ||
|
||
load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") | ||
|
||
licenses(["notice"]) # Apache 2 | ||
|
||
api_proto_package( | ||
deps = ["@com_github_cncf_udpa//udpa/annotations:pkg"], | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
syntax = "proto3"; | ||
|
||
package envoy.type.grpc.v2; | ||
|
||
import "udpa/annotations/migrate.proto"; | ||
import "validate/validate.proto"; | ||
|
||
option java_package = "io.envoyproxy.envoy.type.grpc.v2"; | ||
option java_outer_classname = "GrpcStatusProto"; | ||
option java_multiple_files = true; | ||
option (udpa.annotations.file_migrate).move_to_package = "envoy.type.grpc.v3"; | ||
|
||
// [#protodoc-title: GRPC status codes] | ||
|
||
// GRPC response codes supported. | ||
enum Status { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lizan does this exist anywhere else? Any thoughts on defining this in our API? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No this doesn't exist. I don't think we should define this as enum but just as |
||
OK = 0; | ||
CANCELED = 1; | ||
UNKNOWN = 2; | ||
INVALID_ARGUMENT = 3; | ||
DEADLINE_EXCEEDED = 4; | ||
NOT_FOUND = 5; | ||
ALREADY_EXISTS = 6; | ||
PERMISSION_DENIED = 7; | ||
RESOURCE_EXHAUSTED = 8; | ||
FAILED_PRECONDITION = 9; | ||
ABORTED = 10; | ||
OUT_OF_RANGE = 11; | ||
UNIMPLEMENTED = 12; | ||
INTERNAL = 13; | ||
UNAVAILABLE = 14; | ||
DATA_LOSS = 15; | ||
UNAUTHENTICATED = 16; | ||
} | ||
|
||
// GRPC status. | ||
message GrpcStatus { | ||
// Supplies GRPC response code. | ||
Status status = 1 [(validate.rules).enum = {defined_only: true not_in: 0}]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does the not_in 0 do? |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# DO NOT EDIT. This file is generated by tools/proto_sync.py. | ||
|
||
load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") | ||
|
||
licenses(["notice"]) # Apache 2 | ||
|
||
api_proto_package( | ||
deps = [ | ||
"//envoy/type/grpc/v2:pkg", | ||
"@com_github_cncf_udpa//udpa/annotations:pkg", | ||
], | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
syntax = "proto3"; | ||
|
||
package envoy.type.grpc.v3; | ||
|
||
import "udpa/annotations/versioning.proto"; | ||
|
||
import "validate/validate.proto"; | ||
|
||
option java_package = "io.envoyproxy.envoy.type.grpc.v3"; | ||
option java_outer_classname = "GrpcStatusProto"; | ||
option java_multiple_files = true; | ||
|
||
// [#protodoc-title: GRPC status codes] | ||
|
||
// GRPC response codes supported. | ||
enum Status { | ||
OK = 0; | ||
CANCELED = 1; | ||
UNKNOWN = 2; | ||
INVALID_ARGUMENT = 3; | ||
DEADLINE_EXCEEDED = 4; | ||
NOT_FOUND = 5; | ||
ALREADY_EXISTS = 6; | ||
PERMISSION_DENIED = 7; | ||
RESOURCE_EXHAUSTED = 8; | ||
FAILED_PRECONDITION = 9; | ||
ABORTED = 10; | ||
OUT_OF_RANGE = 11; | ||
UNIMPLEMENTED = 12; | ||
INTERNAL = 13; | ||
UNAVAILABLE = 14; | ||
DATA_LOSS = 15; | ||
UNAUTHENTICATED = 16; | ||
} | ||
|
||
// GRPC status. | ||
message GrpcStatus { | ||
option (udpa.annotations.versioning).previous_message_type = "envoy.type.grpc.v2.GrpcStatus"; | ||
|
||
// Supplies GRPC response code. | ||
Status status = 1 [(validate.rules).enum = {defined_only: true not_in: 0}]; | ||
} |
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.
Since this PR is so large please split this and associated tests into a different PR (if there is anything else that can be split out please do so)