Skip to content

Commit fb2aad0

Browse files
authored
extension: Add stateful session extension (#18207)
Introduce a new stateful session extension. This is a change after #17848 #17290. In #17290, we added a new cross-priority host map for fast host searching. In #17848, we extend `LoadBalancerContext` interface to provide an override host and to select the upstream host by the override host. Finally, in this change, we expand a new API to allow users to extract the state of the session from the request and change the result of load balancing by setting the override host value. Related doc: https://docs.google.com/document/d/1IU4b76AgOXijNa4sew1gfBfSiOMbZNiEt5Dhis8QpYg/edit?usp=sharing. Risk Level: Medium Testing: Added Docs Changes: Added Release Notes: Added Platform-Specific Features: N/A. Signed-off-by: wbpcode <wbphub@live.com>
1 parent d1e91ad commit fb2aad0

51 files changed

Lines changed: 1941 additions & 1 deletion

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CODEOWNERS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ extensions/filters/http/oauth2 @rgs1 @derekargueta @snowp
161161
/*/extensions/filters/common/local_ratelimit @mattklein123 @rgs1
162162
# HTTP Kill Request
163163
/*/extensions/filters/http/kill_request @qqustc @htuch
164+
# HTTP Stateful Session
165+
/*/extensions/filters/http/stateful_session @wbpcode @dio
164166
# Rate limit expression descriptor
165167
/*/extensions/rate_limit_descriptors/expr @kyessenov @lizan
166168
# hash input matcher
@@ -195,6 +197,8 @@ extensions/filters/http/oauth2 @rgs1 @derekargueta @snowp
195197
/*/extensions/matching/input_matchers/ip @aguinet @snowp
196198
# Key Value store
197199
/*/extensions/key_value @alyssawilk @ryantheoptimist
200+
# Stateful session
201+
/*/extensions/http/stateful_session/cookie @wbpcode @dio
198202
# DNS Resolver
199203
/*/extensions/network/dns_resolver/cares @junr03 @yanavlasov
200204
/*/extensions/network/dns_resolver/apple @junr03 @yanavlasov

api/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ proto_library(
171171
"//envoy/extensions/filters/http/rbac/v3:pkg",
172172
"//envoy/extensions/filters/http/router/v3:pkg",
173173
"//envoy/extensions/filters/http/set_metadata/v3:pkg",
174+
"//envoy/extensions/filters/http/stateful_session/v3:pkg",
174175
"//envoy/extensions/filters/http/tap/v3:pkg",
175176
"//envoy/extensions/filters/http/wasm/v3:pkg",
176177
"//envoy/extensions/filters/listener/http_inspector/v3:pkg",
@@ -211,6 +212,7 @@ proto_library(
211212
"//envoy/extensions/http/header_formatters/preserve_case/v3:pkg",
212213
"//envoy/extensions/http/original_ip_detection/custom_header/v3:pkg",
213214
"//envoy/extensions/http/original_ip_detection/xff/v3:pkg",
215+
"//envoy/extensions/http/stateful_session/cookie/v3:pkg",
214216
"//envoy/extensions/internal_redirect/allow_listed_routes/v3:pkg",
215217
"//envoy/extensions/internal_redirect/previous_routes/v3:pkg",
216218
"//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg",
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py.
2+
3+
load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package")
4+
5+
licenses(["notice"]) # Apache 2
6+
7+
api_proto_package(
8+
deps = [
9+
"//envoy/config/core/v3:pkg",
10+
"@com_github_cncf_udpa//udpa/annotations:pkg",
11+
],
12+
)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
syntax = "proto3";
2+
3+
package envoy.extensions.filters.http.stateful_session.v3;
4+
5+
import "envoy/config/core/v3/extension.proto";
6+
7+
import "udpa/annotations/status.proto";
8+
import "validate/validate.proto";
9+
10+
option java_package = "io.envoyproxy.envoy.extensions.filters.http.stateful_session.v3";
11+
option java_outer_classname = "StatefulSessionProto";
12+
option java_multiple_files = true;
13+
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/stateful_session/v3;stateful_sessionv3";
14+
option (udpa.annotations.file_status).package_version_status = ACTIVE;
15+
16+
// [#protodoc-title: Stateful session filter]
17+
// Stateful session :ref:`configuration overview <config_http_filters_stateful_session>`.
18+
// [#extension: envoy.filters.http.stateful_session]
19+
20+
message StatefulSession {
21+
// Specific implementation of session state. This session state will be used to store and
22+
// get address of the upstream host to which the session is assigned.
23+
//
24+
// [#extension-category: envoy.http.stateful_session]
25+
config.core.v3.TypedExtensionConfig session_state = 1
26+
[(validate.rules).message = {required: true}];
27+
}
28+
29+
message StatefulSessionPerRoute {
30+
oneof override {
31+
option (validate.required) = true;
32+
33+
// Disable the stateful session filter for this particular vhost or route. If disabled is
34+
// specified in multiple per-filter-configs, the most specific one will be used.
35+
bool disabled = 1 [(validate.rules).bool = {const: true}];
36+
37+
// Per-route stateful session configuration that can be served by RDS or static route table.
38+
StatefulSession stateful_session = 2;
39+
}
40+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py.
2+
3+
load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package")
4+
5+
licenses(["notice"]) # Apache 2
6+
7+
api_proto_package(
8+
deps = [
9+
"//envoy/type/http/v3:pkg",
10+
"@com_github_cncf_udpa//udpa/annotations:pkg",
11+
],
12+
)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
syntax = "proto3";
2+
3+
package envoy.extensions.http.stateful_session.cookie.v3;
4+
5+
import "envoy/type/http/v3/cookie.proto";
6+
7+
import "udpa/annotations/status.proto";
8+
import "validate/validate.proto";
9+
10+
option java_package = "io.envoyproxy.envoy.extensions.http.stateful_session.cookie.v3";
11+
option java_outer_classname = "CookieProto";
12+
option java_multiple_files = true;
13+
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/http/stateful_session/cookie/v3;cookiev3";
14+
option (udpa.annotations.file_status).package_version_status = ACTIVE;
15+
16+
// [#protodoc-title: Cookie based stateful session extension]
17+
18+
// This extension allows the session state to be tracked via cookies.
19+
//
20+
// This extension first encodes the address of the upstream host selected by the load balancer
21+
// into a `set-cookie` response header with the :ref:`cookie configuration
22+
// <envoy_v3_api_field_extensions.http.stateful_session.cookie.v3.CookieBasedSessionState.cookie>`.
23+
// when new requests are incoming, this extension will try to parse the specific upstream host
24+
// address by the cookie name. If the address parsed from the cookie corresponds to a valid
25+
// upstream host, this upstream host will be selected first. See :ref:`stateful session filter
26+
// <envoy_v3_api_msg_extensions.filters.http.stateful_session.v3.StatefulSession>`.
27+
//
28+
// For example, if the cookie name is set to `sticky-host`, envoy will prefer `1.2.3.4:80`
29+
// as the upstream host when the request contains the following header:
30+
//
31+
// .. code-block:: none
32+
//
33+
// cookie: sticky-host="MS4yLjMuNDo4MA=="
34+
//
35+
// When processing the upstream response, if `1.2.3.4:80` is indeed the final choice the extension
36+
// does nothing. If `1.2.3.4:80` is not the final choice, the new selected host will be used to
37+
// update the cookie (via the `set-cookie` response header).
38+
//
39+
// [#extension: envoy.http.stateful_session.cookie]
40+
message CookieBasedSessionState {
41+
// The cookie configuration used to track session state.
42+
type.http.v3.Cookie cookie = 1 [(validate.rules).message = {required: true}];
43+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
syntax = "proto3";
2+
3+
package envoy.type.http.v3;
4+
5+
import "google/protobuf/duration.proto";
6+
7+
import "udpa/annotations/status.proto";
8+
import "validate/validate.proto";
9+
10+
option java_package = "io.envoyproxy.envoy.type.http.v3";
11+
option java_outer_classname = "CookieProto";
12+
option java_multiple_files = true;
13+
option go_package = "github.com/envoyproxy/go-control-plane/envoy/type/http/v3;httpv3";
14+
option (udpa.annotations.file_status).package_version_status = ACTIVE;
15+
16+
// [#protodoc-title: Http cookie API]
17+
18+
// Cookie defines an API for obtaining or generating HTTP cookie.
19+
message Cookie {
20+
// The name that will be used to obtain cookie value from downstream HTTP request or generate
21+
// new cookie for downstream.
22+
string name = 1 [(validate.rules).string = {min_len: 1}];
23+
24+
// Duration of cookie. This will be used to set the expiry time of a new cookie when it is
25+
// generated. Set this to 0 to use a session cookie.
26+
google.protobuf.Duration ttl = 2 [(validate.rules).duration = {gte {}}];
27+
28+
// Path of cookie. This will be used to set the path of a new cookie when it is generated.
29+
// If no path is specified here, no path will be set for the cookie.
30+
string path = 3;
31+
}

api/versioning/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ proto_library(
109109
"//envoy/extensions/filters/http/rbac/v3:pkg",
110110
"//envoy/extensions/filters/http/router/v3:pkg",
111111
"//envoy/extensions/filters/http/set_metadata/v3:pkg",
112+
"//envoy/extensions/filters/http/stateful_session/v3:pkg",
112113
"//envoy/extensions/filters/http/tap/v3:pkg",
113114
"//envoy/extensions/filters/http/wasm/v3:pkg",
114115
"//envoy/extensions/filters/listener/http_inspector/v3:pkg",
@@ -149,6 +150,7 @@ proto_library(
149150
"//envoy/extensions/http/header_formatters/preserve_case/v3:pkg",
150151
"//envoy/extensions/http/original_ip_detection/custom_header/v3:pkg",
151152
"//envoy/extensions/http/original_ip_detection/xff/v3:pkg",
153+
"//envoy/extensions/http/stateful_session/cookie/v3:pkg",
152154
"//envoy/extensions/internal_redirect/allow_listed_routes/v3:pkg",
153155
"//envoy/extensions/internal_redirect/previous_routes/v3:pkg",
154156
"//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg",

docs/root/api-v3/config/config.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Extensions
3030
request_id/request_id
3131
http/header_formatters
3232
http/original_ip_detection
33+
http/stateful_session
3334
stat_sinks/stat_sinks
3435
quic/quic_extensions
3536
formatter/formatter
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Stateful Session
2+
=====================
3+
4+
.. toctree::
5+
:glob:
6+
:maxdepth: 2
7+
8+
../../extensions/http/stateful_session/*/v3/*

0 commit comments

Comments
 (0)