diff --git a/build.gradle b/build.gradle index 7d731579893..4c8c919ebdc 100644 --- a/build.gradle +++ b/build.gradle @@ -149,6 +149,7 @@ subprojects { opencensus_contrib_grpc_metrics: "io.opencensus:opencensus-contrib-grpc-metrics:${opencensusVersion}", opencensus_impl: "io.opencensus:opencensus-impl:${opencensusVersion}", opencensus_impl_lite: "io.opencensus:opencensus-impl-lite:${opencensusVersion}", + opencensus_proto: "io.opencensus:opencensus-proto:0.2.0", instrumentation_api: 'com.google.instrumentation:instrumentation-api:0.4.3', perfmark: 'io.perfmark:perfmark-api:0.19.0', protobuf: "com.google.protobuf:protobuf-java:${protobufVersion}", diff --git a/xds/build.gradle b/xds/build.gradle index 94371ed37d3..f2918389055 100644 --- a/xds/build.gradle +++ b/xds/build.gradle @@ -23,7 +23,8 @@ dependencies { project(':grpc-stub'), project(':grpc-core'), project(':grpc-services'), - project(path: ':grpc-alts', configuration: 'shadow') + project(path: ':grpc-alts', configuration: 'shadow'), + libraries.opencensus_proto def nettyDependency = compile project(':grpc-netty') compile (libraries.protobuf_util) { diff --git a/xds/src/test/java/io/grpc/xds/XdsClientTestHelper.java b/xds/src/test/java/io/grpc/xds/XdsClientTestHelper.java index 2090c3af339..6522c087183 100644 --- a/xds/src/test/java/io/grpc/xds/XdsClientTestHelper.java +++ b/xds/src/test/java/io/grpc/xds/XdsClientTestHelper.java @@ -149,6 +149,7 @@ static Cluster buildSecureCluster(String clusterName, @Nullable String edsServic return clusterBuilder.build(); } + @SuppressWarnings("deprecation") static ClusterLoadAssignment buildClusterLoadAssignment(String clusterName, List localityLbEndpoints, List dropOverloads) { diff --git a/xds/third_party/envoy/import.sh b/xds/third_party/envoy/import.sh index ccc50b3522c..0d5d5a63ffd 100755 --- a/xds/third_party/envoy/import.sh +++ b/xds/third_party/envoy/import.sh @@ -18,7 +18,7 @@ set -e BRANCH=master # import VERSION from one of the google internal CLs -VERSION=c0ab3a4374144728c1e193fc2d43951ed36ccdb7 +VERSION=b16ce6d5ea0d2da73e764d145623e7367dc59ed3 GIT_REPO="https://github.com/envoyproxy/envoy.git" GIT_BASE_DIR=envoy SOURCE_PROTO_BASE_DIR=envoy/api @@ -33,12 +33,14 @@ envoy/api/v2/cluster/circuit_breaker.proto envoy/api/v2/cluster/filter.proto envoy/api/v2/cluster/outlier_detection.proto envoy/api/v2/core/address.proto +envoy/api/v2/core/backoff.proto envoy/api/v2/core/base.proto envoy/api/v2/core/config_source.proto envoy/api/v2/core/grpc_service.proto envoy/api/v2/core/health_check.proto envoy/api/v2/core/http_uri.proto envoy/api/v2/core/protocol.proto +envoy/api/v2/core/socket_option.proto envoy/api/v2/discovery.proto envoy/api/v2/eds.proto envoy/api/v2/endpoint.proto @@ -59,6 +61,7 @@ envoy/api/v2/srds.proto envoy/config/filter/accesslog/v2/accesslog.proto envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto envoy/config/listener/v2/api_listener.proto +envoy/config/trace/v2/trace.proto envoy/service/discovery/v2/ads.proto envoy/service/discovery/v2/sds.proto envoy/service/load_stats/v2/lrs.proto diff --git a/xds/third_party/envoy/src/main/proto/envoy/api/v2/auth/cert.proto b/xds/third_party/envoy/src/main/proto/envoy/api/v2/auth/cert.proto index 52e5e29a839..cdb6a3d168b 100644 --- a/xds/third_party/envoy/src/main/proto/envoy/api/v2/auth/cert.proto +++ b/xds/third_party/envoy/src/main/proto/envoy/api/v2/auth/cert.proto @@ -296,8 +296,8 @@ message CertificateValidationContext { // // .. code-block:: yaml // - // match_subject_alt_names: - // exact: "api.example.com" + // match_subject_alt_names: + // exact: "api.example.com" // // .. attention:: // diff --git a/xds/third_party/envoy/src/main/proto/envoy/api/v2/cluster.proto b/xds/third_party/envoy/src/main/proto/envoy/api/v2/cluster.proto index 2d61ef3f22b..55324ff6006 100644 --- a/xds/third_party/envoy/src/main/proto/envoy/api/v2/cluster.proto +++ b/xds/third_party/envoy/src/main/proto/envoy/api/v2/cluster.proto @@ -643,9 +643,6 @@ message Cluster { // other than :ref:`STRICT_DNS` and // :ref:`LOGICAL_DNS` this setting is // ignored. - // - // Note: Currently, DNS failures and empty DNS responses are not treated differently and this - // configuration is applied in both situations. RefreshRate dns_failure_refresh_rate = 44; // Optional configuration for setting cluster's DNS refresh rate. If the value is set to true, @@ -734,7 +731,7 @@ message Cluster { // cluster. It can be used for stats, logging, and varying filter behavior. // Fields should use reverse DNS notation to denote which entity within Envoy // will need the information. For instance, if the metadata is intended for - // the Router filter, the filter name should be specified as *envoy.router*. + // the Router filter, the filter name should be specified as *envoy.filters.http.router*. core.Metadata metadata = 25; // Determines how Envoy selects the protocol used to speak to upstream hosts. diff --git a/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/address.proto b/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/address.proto index d2e2b653900..e5c1f1c9d48 100644 --- a/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/address.proto +++ b/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/address.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package envoy.api.v2.core; -import "envoy/api/v2/core/base.proto"; +import "envoy/api/v2/core/socket_option.proto"; import "google/protobuf/wrappers.proto"; @@ -82,7 +82,7 @@ message TcpKeepalive { // The number of seconds a connection needs to be idle before keep-alive probes // start being sent. Default is to use the OS level configuration (unless - // overridden, Linux defaults to 7200s (ie 2 hours.) + // overridden, Linux defaults to 7200s (i.e., 2 hours.) google.protobuf.UInt32Value keepalive_time = 2; // The number of seconds between keep-alive probes. Default is to use the OS diff --git a/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/backoff.proto b/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/backoff.proto new file mode 100644 index 00000000000..b4679150029 --- /dev/null +++ b/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/backoff.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; + +package envoy.api.v2.core; + +import "google/protobuf/duration.proto"; + +import "udpa/annotations/migrate.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.api.v2.core"; +option java_outer_classname = "BackoffProto"; +option java_multiple_files = true; +option (udpa.annotations.file_migrate).move_to_package = "envoy.config.core.v3"; + +// [#protodoc-title: Backoff Strategy] + +// Configuration defining a jittered exponential back off strategy. +message BackoffStrategy { + // The base interval to be used for the next back off computation. It should + // be greater than zero and less than or equal to :ref:`max_interval + // `. + google.protobuf.Duration base_interval = 1 [(validate.rules).duration = { + required: true + gte {nanos: 1000000} + }]; + + // Specifies the maximum interval between retries. This parameter is optional, + // but must be greater than or equal to the :ref:`base_interval + // ` if set. The default + // is 10 times the :ref:`base_interval + // `. + google.protobuf.Duration max_interval = 2 [(validate.rules).duration = {gt {}}]; +} diff --git a/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/base.proto b/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/base.proto index 67a97dd6e25..d10163b3bdf 100644 --- a/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/base.proto +++ b/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/base.proto @@ -2,17 +2,22 @@ syntax = "proto3"; package envoy.api.v2.core; +import "envoy/api/v2/core/address.proto"; +import "envoy/api/v2/core/backoff.proto"; import "envoy/api/v2/core/http_uri.proto"; import "envoy/type/percent.proto"; import "envoy/type/semantic_version.proto"; import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; import "udpa/annotations/migrate.proto"; import "validate/validate.proto"; +import public "envoy/api/v2/core/socket_option.proto"; + option java_package = "io.envoyproxy.envoy.api.v2.core"; option java_outer_classname = "BaseProto"; option java_multiple_files = true; @@ -94,7 +99,7 @@ message BuildVersion { // [#next-free-field: 6] message Extension { // This is the name of the Envoy filter as specified in the Envoy - // configuration, e.g. envoy.router, com.acme.widget. + // configuration, e.g. envoy.filters.http.router, com.acme.widget. string name = 1; // Category of the extension. @@ -121,7 +126,7 @@ message Extension { // Identifies a specific Envoy instance. The node identifier is presented to the // management server, which may use this identifier to distinguish per Envoy // configuration for serving. -// [#next-free-field: 11] +// [#next-free-field: 12] message Node { // An opaque node identifier for the Envoy node. This also provides the local // service node name. It should be set if any of the following features are @@ -180,6 +185,12 @@ message Node { // See :ref:`the list of features ` that xDS client may // support. repeated string client_features = 10; + + // Known listening ports on the node as a generic hint to the management server + // for filtering :ref:`listeners ` to be returned. For example, + // if there is a listener bound to port 80, the list can optionally contain the + // SocketAddress `(0.0.0.0,80)`. The field is optional and just a hint. + repeated Address listening_addresses = 11; } // Metadata provides additional inputs to filters based on matched listeners, @@ -233,14 +244,18 @@ message RuntimeFeatureFlag { // Header name/value pair. message HeaderValue { // Header name. - string key = 1 [(validate.rules).string = {min_bytes: 1 max_bytes: 16384}]; + string key = 1 + [(validate.rules).string = + {min_bytes: 1 max_bytes: 16384 well_known_regex: HTTP_HEADER_NAME strict: false}]; // Header value. // // The same :ref:`format specifier ` as used for // :ref:`HTTP access logging ` applies here, however // unknown header values are replaced with the empty string instead of `-`. - string value = 2 [(validate.rules).string = {max_bytes: 16384}]; + string value = 2 [ + (validate.rules).string = {max_bytes: 16384 well_known_regex: HTTP_HEADER_VALUE strict: false} + ]; } // Header name/value pair plus option to control append behavior. @@ -274,6 +289,18 @@ message DataSource { } } +// The message specifies the retry policy of remote data source when fetching fails. +message RetryPolicy { + // Specifies parameters that control :ref:`retry backoff strategy `. + // This parameter is optional, in which case the default base interval is 1000 milliseconds. The + // default maximum interval is 10 times the base interval. + BackoffStrategy retry_back_off = 1; + + // Specifies the allowed number of retries. This parameter is optional and + // defaults to 1. + google.protobuf.UInt32Value num_retries = 2; +} + // The message specifies how to fetch data from remote and how to verify it. message RemoteDataSource { // The HTTP URI to fetch the remote data. @@ -281,6 +308,9 @@ message RemoteDataSource { // SHA256 string for verifying data. string sha256 = 2 [(validate.rules).string = {min_bytes: 1}]; + + // Retry policy for fetching remote data. + RetryPolicy retry_policy = 3; } // Async data source which support async data fetch. @@ -314,46 +344,6 @@ message TransportSocket { } } -// Generic socket option message. This would be used to set socket options that -// might not exist in upstream kernels or precompiled Envoy binaries. -// [#next-free-field: 7] -message SocketOption { - enum SocketState { - // Socket options are applied after socket creation but before binding the socket to a port - STATE_PREBIND = 0; - - // Socket options are applied after binding the socket to a port but before calling listen() - STATE_BOUND = 1; - - // Socket options are applied after calling listen() - STATE_LISTENING = 2; - } - - // An optional name to give this socket option for debugging, etc. - // Uniqueness is not required and no special meaning is assumed. - string description = 1; - - // Corresponding to the level value passed to setsockopt, such as IPPROTO_TCP - int64 level = 2; - - // The numeric name as passed to setsockopt - int64 name = 3; - - oneof value { - option (validate.required) = true; - - // Because many sockopts take an int value. - int64 int_value = 4; - - // Otherwise it's a byte buffer. - bytes buf_value = 5; - } - - // The state in which the option will be applied. When used in BindConfig - // STATE_PREBIND is currently the only valid value. - SocketState state = 6 [(validate.rules).enum = {defined_only: true}]; -} - // Runtime derived FractionalPercent with defaults for when the numerator or denominator is not // specified via a runtime key. // diff --git a/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/grpc_service.proto b/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/grpc_service.proto index 17f769b14e8..6fda81e3a20 100644 --- a/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/grpc_service.proto +++ b/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/grpc_service.proto @@ -221,6 +221,6 @@ message GrpcService { // Additional metadata to include in streams initiated to the GrpcService. // This can be used for scenarios in which additional ad hoc authorization - // headers (e.g. `x-foo-bar: baz-key`) are to be injected. + // headers (e.g. ``x-foo-bar: baz-key``) are to be injected. repeated HeaderValue initial_metadata = 5; } diff --git a/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/protocol.proto b/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/protocol.proto index 53b6ae87467..c8cfcf8260a 100644 --- a/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/protocol.proto +++ b/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/protocol.proto @@ -59,6 +59,12 @@ message HttpProtocolOptions { // maximum number of request headers allowed is 100. Requests that exceed this limit will receive // a 431 response for HTTP/1.x and cause a stream reset for HTTP/2. google.protobuf.UInt32Value max_headers_count = 2 [(validate.rules).uint32 = {gte: 1}]; + + // Total duration to keep alive an HTTP request/response stream. If the time limit is reached the stream will be + // reset independent of any other timeouts. If not specified, this value is not set. + // The current implementation implements this timeout on downstream connections only. + // [#comment:TODO(shikugawa): add this functionality to upstream.] + google.protobuf.Duration max_stream_duration = 4; } // [#next-free-field: 6] @@ -112,8 +118,21 @@ message Http1ProtocolOptions { bool enable_trailers = 5; } -// [#next-free-field: 13] +// [#next-free-field: 14] message Http2ProtocolOptions { + // Defines a parameter to be sent in the SETTINGS frame. + // See `RFC7540, sec. 6.5.1 `_ for details. + message SettingsParameter { + // The 16 bit parameter identifier. + google.protobuf.UInt32Value identifier = 1 [ + (validate.rules).uint32 = {lte: 65536 gte: 1}, + (validate.rules).message = {required: true} + ]; + + // The 32 bit parameter value. + google.protobuf.UInt32Value value = 2 [(validate.rules).message = {required: true}]; + } + // `Maximum table size `_ // (in octets) that the encoder is permitted to use for the dynamic HPACK table. Valid values // range from 0 to 4294967295 (2^32 - 1) and defaults to 4096. 0 effectively disables header @@ -216,6 +235,34 @@ message Http2ProtocolOptions { // // See `RFC7540, sec. 8.1 `_ for details. bool stream_error_on_invalid_http_messaging = 12; + + // [#not-implemented-hide:] + // Specifies SETTINGS frame parameters to be sent to the peer, with two exceptions: + // + // 1. SETTINGS_ENABLE_PUSH (0x2) is not configurable as HTTP/2 server push is not supported by + // Envoy. + // + // 2. SETTINGS_ENABLE_CONNECT_PROTOCOL (0x8) is only configurable through the named field + // 'allow_connect'. + // + // Note that custom parameters specified through this field can not also be set in the + // corresponding named parameters: + // + // .. code-block:: text + // + // ID Field Name + // ---------------- + // 0x1 hpack_table_size + // 0x3 max_concurrent_streams + // 0x4 initial_stream_window_size + // + // Collisions will trigger config validation failure on load/update. Likewise, inconsistencies + // between custom parameters with the same identifier will trigger a failure. + // + // See `IANA HTTP/2 Settings + // `_ for + // standardized identifiers. + repeated SettingsParameter custom_settings_parameters = 13; } // [#not-implemented-hide:] diff --git a/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/socket_option.proto b/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/socket_option.proto new file mode 100644 index 00000000000..9a044d1a9eb --- /dev/null +++ b/xds/third_party/envoy/src/main/proto/envoy/api/v2/core/socket_option.proto @@ -0,0 +1,53 @@ +syntax = "proto3"; + +package envoy.api.v2.core; + +import "udpa/annotations/migrate.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.api.v2.core"; +option java_outer_classname = "SocketOptionProto"; +option java_multiple_files = true; +option (udpa.annotations.file_migrate).move_to_package = "envoy.config.core.v3"; + +// [#protodoc-title: Socket Option ] + +// Generic socket option message. This would be used to set socket options that +// might not exist in upstream kernels or precompiled Envoy binaries. +// [#next-free-field: 7] +message SocketOption { + enum SocketState { + // Socket options are applied after socket creation but before binding the socket to a port + STATE_PREBIND = 0; + + // Socket options are applied after binding the socket to a port but before calling listen() + STATE_BOUND = 1; + + // Socket options are applied after calling listen() + STATE_LISTENING = 2; + } + + // An optional name to give this socket option for debugging, etc. + // Uniqueness is not required and no special meaning is assumed. + string description = 1; + + // Corresponding to the level value passed to setsockopt, such as IPPROTO_TCP + int64 level = 2; + + // The numeric name as passed to setsockopt + int64 name = 3; + + oneof value { + option (validate.required) = true; + + // Because many sockopts take an int value. + int64 int_value = 4; + + // Otherwise it's a byte buffer. + bytes buf_value = 5; + } + + // The state in which the option will be applied. When used in BindConfig + // STATE_PREBIND is currently the only valid value. + SocketState state = 6 [(validate.rules).enum = {defined_only: true}]; +} diff --git a/xds/third_party/envoy/src/main/proto/envoy/api/v2/endpoint.proto b/xds/third_party/envoy/src/main/proto/envoy/api/v2/endpoint.proto index d800c6d19e5..87d8713e8e1 100644 --- a/xds/third_party/envoy/src/main/proto/envoy/api/v2/endpoint.proto +++ b/xds/third_party/envoy/src/main/proto/envoy/api/v2/endpoint.proto @@ -94,9 +94,8 @@ message ClusterLoadAssignment { // localities as endpoints become unhealthy. Otherwise Envoy will perform // graceful failover as :ref:`overprovisioning factor // ` suggests. - // [#next-major-version: Unify with overprovisioning config as a single message.] // [#not-implemented-hide:] - bool disable_overprovisioning = 5; + bool disable_overprovisioning = 5 [deprecated = true]; } // Name of the cluster. This will be the :ref:`service_name diff --git a/xds/third_party/envoy/src/main/proto/envoy/api/v2/listener.proto b/xds/third_party/envoy/src/main/proto/envoy/api/v2/listener.proto index 3fbb10070d0..5873380db80 100644 --- a/xds/third_party/envoy/src/main/proto/envoy/api/v2/listener.proto +++ b/xds/third_party/envoy/src/main/proto/envoy/api/v2/listener.proto @@ -4,6 +4,7 @@ package envoy.api.v2; import "envoy/api/v2/core/address.proto"; import "envoy/api/v2/core/base.proto"; +import "envoy/api/v2/core/socket_option.proto"; import "envoy/api/v2/listener/listener_components.proto"; import "envoy/api/v2/listener/udp_listener_config.proto"; import "envoy/config/listener/v2/api_listener.proto"; diff --git a/xds/third_party/envoy/src/main/proto/envoy/api/v2/listener/listener_components.proto b/xds/third_party/envoy/src/main/proto/envoy/api/v2/listener/listener_components.proto index d9c8cfbfcb9..ec889d7f4f4 100644 --- a/xds/third_party/envoy/src/main/proto/envoy/api/v2/listener/listener_components.proto +++ b/xds/third_party/envoy/src/main/proto/envoy/api/v2/listener/listener_components.proto @@ -136,7 +136,7 @@ message FilterChainMatch { // Suggested values include: // // * ``raw_buffer`` - default, used when no transport protocol is detected, - // * ``tls`` - set by :ref:`envoy.listener.tls_inspector ` + // * ``tls`` - set by :ref:`envoy.filters.listener.tls_inspector ` // when TLS protocol is detected. string transport_protocol = 9; @@ -146,9 +146,9 @@ message FilterChainMatch { // // Suggested values include: // - // * ``http/1.1`` - set by :ref:`envoy.listener.tls_inspector + // * ``http/1.1`` - set by :ref:`envoy.filters.listener.tls_inspector // `, - // * ``h2`` - set by :ref:`envoy.listener.tls_inspector ` + // * ``h2`` - set by :ref:`envoy.filters.listener.tls_inspector ` // // .. attention:: // diff --git a/xds/third_party/envoy/src/main/proto/envoy/api/v2/route.proto b/xds/third_party/envoy/src/main/proto/envoy/api/v2/route.proto index 11ae686239d..87374611d80 100644 --- a/xds/third_party/envoy/src/main/proto/envoy/api/v2/route.proto +++ b/xds/third_party/envoy/src/main/proto/envoy/api/v2/route.proto @@ -43,7 +43,9 @@ message RouteConfiguration { // will consider to be internal only. If they are found on external requests they will be cleaned // prior to filter invocation. See :ref:`config_http_conn_man_headers_x-envoy-internal` for more // information. - repeated string internal_only_headers = 3; + repeated string internal_only_headers = 3 [ + (validate.rules).repeated = {items {string {well_known_regex: HTTP_HEADER_NAME strict: false}}} + ]; // Specifies a list of HTTP headers that should be added to each response that // the connection manager encodes. Headers specified at this level are applied @@ -56,7 +58,9 @@ message RouteConfiguration { // Specifies a list of HTTP headers that should be removed from each response // that the connection manager encodes. - repeated string response_headers_to_remove = 5; + repeated string response_headers_to_remove = 5 [ + (validate.rules).repeated = {items {string {well_known_regex: HTTP_HEADER_NAME strict: false}}} + ]; // Specifies a list of HTTP headers that should be added to each request // routed by the HTTP connection manager. Headers specified at this level are @@ -69,7 +73,9 @@ message RouteConfiguration { // Specifies a list of HTTP headers that should be removed from each request // routed by the HTTP connection manager. - repeated string request_headers_to_remove = 8; + repeated string request_headers_to_remove = 8 [ + (validate.rules).repeated = {items {string {well_known_regex: HTTP_HEADER_NAME strict: false}}} + ]; // By default, headers that should be added/removed are evaluated from most to least specific: // diff --git a/xds/third_party/envoy/src/main/proto/envoy/api/v2/route/route_components.proto b/xds/third_party/envoy/src/main/proto/envoy/api/v2/route/route_components.proto index f5e6bae79a3..2ae4ee75ef3 100644 --- a/xds/third_party/envoy/src/main/proto/envoy/api/v2/route/route_components.proto +++ b/xds/third_party/envoy/src/main/proto/envoy/api/v2/route/route_components.proto @@ -32,7 +32,7 @@ option (udpa.annotations.file_migrate).move_to_package = "envoy.config.route.v3" // host header. This allows a single listener to service multiple top level domain path trees. Once // a virtual host is selected based on the domain, the routes are processed in order to see which // upstream cluster to route to or whether to perform a redirect. -// [#next-free-field: 19] +// [#next-free-field: 21] message VirtualHost { enum TlsRequirementType { // No TLS requirement for the virtual host. @@ -69,7 +69,12 @@ message VirtualHost { // The longest wildcards match first. // Only a single virtual host in the entire route configuration can match on ``*``. A domain // must be unique across all virtual hosts or the config will fail to load. - repeated string domains = 2 [(validate.rules).repeated = {min_items: 1}]; + // + // Domains cannot contain control characters. This is validated by the well_known_regex HTTP_HEADER_VALUE. + repeated string domains = 2 [(validate.rules).repeated = { + min_items: 1 + items {string {well_known_regex: HTTP_HEADER_VALUE strict: false}} + }]; // The list of routes that will be matched, in order, for incoming requests. // The first route that matches will be used. @@ -118,14 +123,14 @@ message VirtualHost { // The per_filter_config field can be used to provide virtual host-specific // configurations for filters. The key should match the filter name, such as - // *envoy.buffer* for the HTTP buffer filter. Use of this field is filter + // *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter // specific; see the :ref:`HTTP filter documentation ` // for if and how it is utilized. map per_filter_config = 12 [deprecated = true]; // The per_filter_config field can be used to provide virtual host-specific // configurations for filters. The key should match the filter name, such as - // *envoy.buffer* for the HTTP buffer filter. Use of this field is filter + // *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter // specific; see the :ref:`HTTP filter documentation ` // for if and how it is utilized. map typed_per_filter_config = 15; @@ -138,13 +143,32 @@ message VirtualHost { // This header is unaffected by the // :ref:`suppress_envoy_headers // ` flag. + // + // [#next-major-version: rename to include_attempt_count_in_request.] bool include_request_attempt_count = 14; + // Decides whether the :ref:`x-envoy-attempt-count + // ` header should be included + // in the downstream response. Setting this option will cause the router to override any existing header + // value, so in the case of two Envoys on the request path with this option enabled, the downstream + // will see the attempt count as perceived by the Envoy closest upstream from itself. Defaults to false. + // This header is unaffected by the + // :ref:`suppress_envoy_headers + // ` flag. + bool include_attempt_count_in_response = 19; + // Indicates the retry policy for all routes in this virtual host. Note that setting a // route level entry will take precedence over this config and it'll be treated // independently (e.g.: values are not inherited). RetryPolicy retry_policy = 16; + // [#not-implemented-hide:] + // Specifies the configuration for retry policy extension. Note that setting a route level entry + // will take precedence over this config and it'll be treated independently (e.g.: values are not + // inherited). :ref:`Retry policy ` should not be + // set if this field is used. + google.protobuf.Any retry_policy_typed_config = 20; + // Indicates the hedge policy for all routes in this virtual host. Note that setting a // route level entry will take precedence over this config and it'll be treated // independently (e.g.: values are not inherited). @@ -200,7 +224,7 @@ message Route { // about the route. It can be used for configuration, stats, and logging. // The metadata should go under the filter namespace that will need it. // For instance, if the metadata is intended for the Router filter, - // the filter name should be specified as *envoy.router*. + // the filter name should be specified as *envoy.filters.http.router*. core.Metadata metadata = 4; // Decorator for the matched route. @@ -208,14 +232,14 @@ message Route { // The per_filter_config field can be used to provide route-specific // configurations for filters. The key should match the filter name, such as - // *envoy.buffer* for the HTTP buffer filter. Use of this field is filter + // *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter // specific; see the :ref:`HTTP filter documentation ` for // if and how it is utilized. map per_filter_config = 8 [deprecated = true]; - // The per_filter_config field can be used to provide route-specific + // The typed_per_filter_config field can be used to provide route-specific // configurations for filters. The key should match the filter name, such as - // *envoy.buffer* for the HTTP buffer filter. Use of this field is filter + // *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter // specific; see the :ref:`HTTP filter documentation ` for // if and how it is utilized. map typed_per_filter_config = 13; @@ -314,14 +338,14 @@ message WeightedCluster { // The per_filter_config field can be used to provide weighted cluster-specific // configurations for filters. The key should match the filter name, such as - // *envoy.buffer* for the HTTP buffer filter. Use of this field is filter + // *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter // specific; see the :ref:`HTTP filter documentation ` // for if and how it is utilized. map per_filter_config = 8 [deprecated = true]; // The per_filter_config field can be used to provide weighted cluster-specific // configurations for filters. The key should match the filter name, such as - // *envoy.buffer* for the HTTP buffer filter. Use of this field is filter + // *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter // specific; see the :ref:`HTTP filter documentation ` // for if and how it is utilized. map typed_per_filter_config = 10; @@ -530,7 +554,7 @@ message CorsPolicy { core.RuntimeFractionalPercent shadow_enabled = 10; } -// [#next-free-field: 32] +// [#next-free-field: 34] message RouteAction { enum ClusterNotFoundResponseCode { // HTTP status code - 503 Service Unavailable. @@ -588,16 +612,21 @@ message RouteAction { // number is <= the value of the numerator N, or if the key is not present, the default // value, the request will be mirrored. core.RuntimeFractionalPercent runtime_fraction = 3; + + // Determines if the trace span should be sampled. Defaults to true. + google.protobuf.BoolValue trace_sampled = 4; } // Specifies the route's hashing policy if the upstream cluster uses a hashing :ref:`load balancer // `. - // [#next-free-field: 6] + // [#next-free-field: 7] message HashPolicy { message Header { // The name of the request header that will be used to obtain the hash // key. If the request header is not present, no hash will be produced. - string header_name = 1 [(validate.rules).string = {min_bytes: 1}]; + string header_name = 1 [ + (validate.rules).string = {min_bytes: 1 well_known_regex: HTTP_HEADER_NAME strict: false} + ]; } // Envoy supports two types of cookie affinity: @@ -642,6 +671,13 @@ message RouteAction { string name = 1 [(validate.rules).string = {min_bytes: 1}]; } + message FilterState { + // The name of the Object in the per-request filterState, which is an + // Envoy::Http::Hashable object. If there is no data associated with the key, + // or the stored object is not Envoy::Http::Hashable, no hash will be produced. + string key = 1 [(validate.rules).string = {min_bytes: 1}]; + } + oneof policy_specifier { option (validate.required) = true; @@ -656,6 +692,9 @@ message RouteAction { // Query parameter hash policy. QueryParameter query_parameter = 5; + + // Filter state hash policy. + FilterState filter_state = 6; } // The flag that short-circuits the hash computing. This field provides a @@ -690,7 +729,8 @@ message RouteAction { // The case-insensitive name of this upgrade, e.g. "websocket". // For each upgrade type present in upgrade_configs, requests with // Upgrade: [upgrade_type] will be proxied upstream. - string upgrade_type = 1; + string upgrade_type = 1 + [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}]; // Determines if upgrades are available on this route. Defaults to true. google.protobuf.BoolValue enabled = 2; @@ -714,7 +754,8 @@ message RouteAction { // // Internally, Envoy always uses the HTTP/2 *:authority* header to represent the HTTP/1 // *Host* header. Thus, if attempting to match on *Host*, match on *:authority* instead. - string cluster_header = 2 [(validate.rules).string = {min_bytes: 1}]; + string cluster_header = 2 + [(validate.rules).string = {min_bytes: 1 well_known_regex: HTTP_HEADER_NAME strict: false}]; // Multiple upstream clusters can be specified for a given route. The // request is routed to one of the upstream clusters based on weights @@ -742,6 +783,10 @@ message RouteAction { // place the original path before rewrite into the :ref:`x-envoy-original-path // ` header. // + // Only one of *prefix_rewrite* or + // :ref:`regex_rewrite ` + // may be specified. + // // .. attention:: // // Pay careful attention to the use of trailing slashes in the @@ -763,12 +808,46 @@ message RouteAction { // // Having above entries in the config, requests to */prefix* will be stripped to */*, while // requests to */prefix/etc* will be stripped to */etc*. - string prefix_rewrite = 5; + string prefix_rewrite = 5 + [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}]; + + // Indicates that during forwarding, portions of the path that match the + // pattern should be rewritten, even allowing the substitution of capture + // groups from the pattern into the new path as specified by the rewrite + // substitution string. This is useful to allow application paths to be + // rewritten in a way that is aware of segments with variable content like + // identifiers. The router filter will place the original path as it was + // before the rewrite into the :ref:`x-envoy-original-path + // ` header. + // + // Only one of :ref:`prefix_rewrite ` + // or *regex_rewrite* may be specified. + // + // Examples using Google's `RE2 `_ engine: + // + // * The path pattern ``^/service/([^/]+)(/.*)$`` paired with a substitution + // string of ``\2/instance/\1`` would transform ``/service/foo/v1/api`` + // into ``/v1/api/instance/foo``. + // + // * The pattern ``one`` paired with a substitution string of ``two`` would + // transform ``/xxx/one/yyy/one/zzz`` into ``/xxx/two/yyy/two/zzz``. + // + // * The pattern ``^(.*?)one(.*)$`` paired with a substitution string of + // ``\1two\2`` would replace only the first occurrence of ``one``, + // transforming path ``/xxx/one/yyy/one/zzz`` into ``/xxx/two/yyy/one/zzz``. + // + // * The pattern ``(?i)/xxx/`` paired with a substitution string of ``/yyy/`` + // would do a case-insensitive match and transform path ``/aaa/XxX/bbb`` to + // ``/aaa/yyy/bbb``. + type.matcher.RegexMatchAndSubstitute regex_rewrite = 32; oneof host_rewrite_specifier { // Indicates that during forwarding, the host header will be swapped with // this value. - string host_rewrite = 6 [(udpa.annotations.field_migrate).rename = "host_rewrite_literal"]; + string host_rewrite = 6 [ + (validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}, + (udpa.annotations.field_migrate).rename = "host_rewrite_literal" + ]; // Indicates that during forwarding, the host header will be swapped with // the hostname of the upstream host chosen by the cluster manager. This @@ -785,8 +864,10 @@ message RouteAction { // // Pay attention to the potential security implications of using this option. Provided header // must come from trusted source. - string auto_host_rewrite_header = 29 - [(udpa.annotations.field_migrate).rename = "host_rewrite_header"]; + string auto_host_rewrite_header = 29 [ + (validate.rules).string = {well_known_regex: HTTP_HEADER_NAME strict: false}, + (udpa.annotations.field_migrate).rename = "host_rewrite_header" + ]; } // Specifies the upstream timeout for the route. If not specified, the default is 15s. This @@ -827,6 +908,13 @@ message RouteAction { // (e.g.: policies are not merged, most internal one becomes the enforced policy). RetryPolicy retry_policy = 9; + // [#not-implemented-hide:] + // Specifies the configuration for retry policy extension. Note that if this is set, it'll take + // precedence over the virtual host level retry policy entirely (e.g.: policies are not merged, + // most internal one becomes the enforced policy). :ref:`Retry policy ` + // should not be set if this field is used. + google.protobuf.Any retry_policy_typed_config = 33; + // Indicates that the route has a request mirroring policy. // // .. attention:: @@ -877,6 +965,15 @@ message RouteAction { // :ref:`timeout ` or its default. // This can be used to prevent unexpected upstream request timeouts due to potentially long // time gaps between gRPC request and response in gRPC streaming mode. + // + // .. note:: + // + // If a timeout is specified using :ref:`config_http_filters_router_x-envoy-upstream-rq-timeout-ms`, it takes + // precedence over `grpc-timeout header `_, when + // both are present. See also + // :ref:`config_http_filters_router_x-envoy-upstream-rq-timeout-ms`, + // :ref:`config_http_filters_router_x-envoy-upstream-rq-per-try-timeout-ms`, and the + // :ref:`retry overview `. google.protobuf.Duration max_grpc_timeout = 23; // If present, Envoy will adjust the timeout provided by the `grpc-timeout` header by subtracting @@ -1070,14 +1167,16 @@ message RedirectAction { } // The host portion of the URL will be swapped with this value. - string host_redirect = 1; + string host_redirect = 1 + [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}]; // The port value of the URL will be swapped with this value. uint32 port_redirect = 8; oneof path_rewrite_specifier { // The path portion of the URL will be swapped with this value. - string path_redirect = 2; + string path_redirect = 2 + [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}]; // Indicates that during redirection, the matched prefix (or path) // should be swapped with this value. This option allows redirect URLs be dynamically created @@ -1087,7 +1186,8 @@ message RedirectAction { // // Pay attention to the use of trailing slashes as mentioned in // :ref:`RouteAction's prefix_rewrite `. - string prefix_rewrite = 5; + string prefix_rewrite = 5 + [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}]; } // The HTTP status code to use in the redirect response. The default response @@ -1263,7 +1363,9 @@ message RateLimit { // The header name to be queried from the request headers. The header’s // value is used to populate the value of the descriptor entry for the // descriptor_key. - string header_name = 1 [(validate.rules).string = {min_bytes: 1}]; + string header_name = 1 [ + (validate.rules).string = {min_bytes: 1 well_known_regex: HTTP_HEADER_NAME strict: false} + ]; // The key to use in the descriptor entry. string descriptor_key = 2 [(validate.rules).string = {min_bytes: 1}]; @@ -1384,7 +1486,8 @@ message HeaderMatcher { reserved 2, 3; // Specifies the name of the header in the request. - string name = 1 [(validate.rules).string = {min_bytes: 1}]; + string name = 1 + [(validate.rules).string = {min_bytes: 1 well_known_regex: HTTP_HEADER_NAME strict: false}]; // Specifies how the header match will be performed to route the request. oneof header_match_specifier { diff --git a/xds/third_party/envoy/src/main/proto/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto b/xds/third_party/envoy/src/main/proto/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto index 13dc6ffaec1..35fd122c06b 100644 --- a/xds/third_party/envoy/src/main/proto/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto +++ b/xds/third_party/envoy/src/main/proto/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto @@ -7,6 +7,7 @@ import "envoy/api/v2/core/protocol.proto"; import "envoy/api/v2/route.proto"; import "envoy/api/v2/scoped_route.proto"; import "envoy/config/filter/accesslog/v2/accesslog.proto"; +import "envoy/config/trace/v2/trace.proto"; import "envoy/type/percent.proto"; import "envoy/type/tracing/v2/custom_tag.proto"; @@ -89,7 +90,7 @@ message HttpConnectionManager { ALWAYS_FORWARD_ONLY = 4; } - // [#next-free-field: 9] + // [#next-free-field: 10] message Tracing { enum OperationName { // The HTTP listener is used for ingress/incoming requests. @@ -156,6 +157,12 @@ message HttpConnectionManager { // A list of custom tags with unique tag name to create tags for the active span. repeated type.tracing.v2.CustomTag custom_tags = 8; + + // Configuration for an external tracing provider. + // If not specified, Envoy will fall back to using tracing provider configuration + // from the bootstrap config. + // [#not-implemented-hide:] + trace.v2.Tracing.Http provider = 9; } message InternalAddressConfig { diff --git a/xds/third_party/envoy/src/main/proto/envoy/config/trace/v2/trace.proto b/xds/third_party/envoy/src/main/proto/envoy/config/trace/v2/trace.proto new file mode 100644 index 00000000000..420e4aa28ff --- /dev/null +++ b/xds/third_party/envoy/src/main/proto/envoy/config/trace/v2/trace.proto @@ -0,0 +1,224 @@ +syntax = "proto3"; + +package envoy.config.trace.v2; + +import "envoy/api/v2/core/grpc_service.proto"; + +import "google/protobuf/any.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/wrappers.proto"; + +import "opencensus/proto/trace/v1/trace_config.proto"; + +import "envoy/annotations/deprecation.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.config.trace.v2"; +option java_outer_classname = "TraceProto"; +option java_multiple_files = true; + +// [#protodoc-title: Tracing] +// Tracing :ref:`architecture overview `. + +// The tracing configuration specifies global +// settings for the HTTP tracer used by Envoy. The configuration is defined by +// the :ref:`Bootstrap ` :ref:`tracing +// ` field. Envoy may support other tracers +// in the future, but right now the HTTP tracer is the only one supported. +message Tracing { + message Http { + // The name of the HTTP trace driver to instantiate. The name must match a + // supported HTTP trace driver. Built-in trace drivers: + // + // - *envoy.tracers.lightstep* + // - *envoy.tracers.zipkin* + // - *envoy.tracers.dynamic_ot* + // - *envoy.tracers.datadog* + // - *envoy.tracers.opencensus* + // - *envoy.tracers.xray* + string name = 1 [(validate.rules).string = {min_bytes: 1}]; + + // Trace driver specific configuration which depends on the driver being instantiated. + // See the trace drivers for examples: + // + // - :ref:`LightstepConfig ` + // - :ref:`ZipkinConfig ` + // - :ref:`DynamicOtConfig ` + // - :ref:`DatadogConfig ` + // - :ref:`OpenCensusConfig ` + // - :ref:`AWS X-Ray ` + oneof config_type { + google.protobuf.Struct config = 2 [deprecated = true]; + + google.protobuf.Any typed_config = 3; + } + } + + // Provides configuration for the HTTP tracer. + Http http = 1; +} + +// Configuration for the LightStep tracer. +// [#extension: envoy.tracers.lightstep] +message LightstepConfig { + // The cluster manager cluster that hosts the LightStep collectors. + string collector_cluster = 1 [(validate.rules).string = {min_bytes: 1}]; + + // File containing the access token to the `LightStep + // `_ API. + string access_token_file = 2 [(validate.rules).string = {min_bytes: 1}]; +} + +// Configuration for the Zipkin tracer. +// [#extension: envoy.tracers.zipkin] +// [#next-free-field: 6] +message ZipkinConfig { + // Available Zipkin collector endpoint versions. + enum CollectorEndpointVersion { + // Zipkin API v1, JSON over HTTP. + // [#comment: The default implementation of Zipkin client before this field is added was only v1 + // and the way user configure this was by not explicitly specifying the version. Consequently, + // before this is added, the corresponding Zipkin collector expected to receive v1 payload. + // Hence the motivation of adding HTTP_JSON_V1 as the default is to avoid a breaking change when + // user upgrading Envoy with this change. Furthermore, we also immediately deprecate this field, + // since in Zipkin realm this v1 version is considered to be not preferable anymore.] + HTTP_JSON_V1 = 0 [deprecated = true, (envoy.annotations.disallowed_by_default_enum) = true]; + + // Zipkin API v2, JSON over HTTP. + HTTP_JSON = 1; + + // Zipkin API v2, protobuf over HTTP. + HTTP_PROTO = 2; + + // [#not-implemented-hide:] + GRPC = 3; + } + + // The cluster manager cluster that hosts the Zipkin collectors. Note that the + // Zipkin cluster must be defined in the :ref:`Bootstrap static cluster + // resources `. + string collector_cluster = 1 [(validate.rules).string = {min_bytes: 1}]; + + // The API endpoint of the Zipkin service where the spans will be sent. When + // using a standard Zipkin installation, the API endpoint is typically + // /api/v1/spans, which is the default value. + string collector_endpoint = 2 [(validate.rules).string = {min_bytes: 1}]; + + // Determines whether a 128bit trace id will be used when creating a new + // trace instance. The default value is false, which will result in a 64 bit trace id being used. + bool trace_id_128bit = 3; + + // Determines whether client and server spans will share the same span context. + // The default value is true. + google.protobuf.BoolValue shared_span_context = 4; + + // Determines the selected collector endpoint version. By default, the ``HTTP_JSON_V1`` will be + // used. + CollectorEndpointVersion collector_endpoint_version = 5; +} + +// DynamicOtConfig is used to dynamically load a tracer from a shared library +// that implements the `OpenTracing dynamic loading API +// `_. +// [#extension: envoy.tracers.dynamic_ot] +message DynamicOtConfig { + // Dynamic library implementing the `OpenTracing API + // `_. + string library = 1 [(validate.rules).string = {min_bytes: 1}]; + + // The configuration to use when creating a tracer from the given dynamic + // library. + google.protobuf.Struct config = 2; +} + +// Configuration for the Datadog tracer. +// [#extension: envoy.tracers.datadog] +message DatadogConfig { + // The cluster to use for submitting traces to the Datadog agent. + string collector_cluster = 1 [(validate.rules).string = {min_bytes: 1}]; + + // The name used for the service when traces are generated by envoy. + string service_name = 2 [(validate.rules).string = {min_bytes: 1}]; +} + +// Configuration for the OpenCensus tracer. +// [#next-free-field: 15] +// [#extension: envoy.tracers.opencensus] +message OpenCensusConfig { + enum TraceContext { + // No-op default, no trace context is utilized. + NONE = 0; + + // W3C Trace-Context format "traceparent:" header. + TRACE_CONTEXT = 1; + + // Binary "grpc-trace-bin:" header. + GRPC_TRACE_BIN = 2; + + // "X-Cloud-Trace-Context:" header. + CLOUD_TRACE_CONTEXT = 3; + + // X-B3-* headers. + B3 = 4; + } + + reserved 7; + + // Configures tracing, e.g. the sampler, max number of annotations, etc. + opencensus.proto.trace.v1.TraceConfig trace_config = 1; + + // Enables the stdout exporter if set to true. This is intended for debugging + // purposes. + bool stdout_exporter_enabled = 2; + + // Enables the Stackdriver exporter if set to true. The project_id must also + // be set. + bool stackdriver_exporter_enabled = 3; + + // The Cloud project_id to use for Stackdriver tracing. + string stackdriver_project_id = 4; + + // (optional) By default, the Stackdriver exporter will connect to production + // Stackdriver. If stackdriver_address is non-empty, it will instead connect + // to this address, which is in the gRPC format: + // https://github.com/grpc/grpc/blob/master/doc/naming.md + string stackdriver_address = 10; + + // (optional) The gRPC server that hosts Stackdriver tracing service. Only + // Google gRPC is supported. If :ref:`target_uri ` + // is not provided, the default production Stackdriver address will be used. + api.v2.core.GrpcService stackdriver_grpc_service = 13; + + // Enables the Zipkin exporter if set to true. The url and service name must + // also be set. + bool zipkin_exporter_enabled = 5; + + // The URL to Zipkin, e.g. "http://127.0.0.1:9411/api/v2/spans" + string zipkin_url = 6; + + // Enables the OpenCensus Agent exporter if set to true. The ocagent_address or + // ocagent_grpc_service must also be set. + bool ocagent_exporter_enabled = 11; + + // The address of the OpenCensus Agent, if its exporter is enabled, in gRPC + // format: https://github.com/grpc/grpc/blob/master/doc/naming.md + // [#comment:TODO: deprecate this field] + string ocagent_address = 12; + + // (optional) The gRPC server hosted by the OpenCensus Agent. Only Google gRPC is supported. + // This is only used if the ocagent_address is left empty. + api.v2.core.GrpcService ocagent_grpc_service = 14; + + // List of incoming trace context headers we will accept. First one found + // wins. + repeated TraceContext incoming_trace_context = 8; + + // List of outgoing trace context headers we will produce. + repeated TraceContext outgoing_trace_context = 9; +} + +// Configuration structure. +message TraceServiceConfig { + // The upstream gRPC cluster that hosts the metrics service. + api.v2.core.GrpcService grpc_service = 1 [(validate.rules).message = {required: true}]; +} diff --git a/xds/third_party/envoy/src/main/proto/envoy/type/matcher/regex.proto b/xds/third_party/envoy/src/main/proto/envoy/type/matcher/regex.proto index 2dd5bbe047c..2be13845fc0 100644 --- a/xds/third_party/envoy/src/main/proto/envoy/type/matcher/regex.proto +++ b/xds/third_party/envoy/src/main/proto/envoy/type/matcher/regex.proto @@ -35,3 +35,29 @@ message RegexMatcher { // The regex match string. The string must be supported by the configured engine. string regex = 2 [(validate.rules).string = {min_bytes: 1}]; } + +// Describes how to match a string and then produce a new string using a regular +// expression and a substitution string. +message RegexMatchAndSubstitute { + // The regular expression used to find portions of a string (hereafter called + // the "subject string") that should be replaced. When a new string is + // produced during the substitution operation, the new string is initially + // the same as the subject string, but then all matches in the subject string + // are replaced by the substitution string. If replacing all matches isn't + // desired, regular expression anchors can be used to ensure a single match, + // so as to replace just one occurrence of a pattern. Capture groups can be + // used in the pattern to extract portions of the subject string, and then + // referenced in the substitution string. + RegexMatcher pattern = 1; + + // The string that should be substituted into matching portions of the + // subject string during a substitution operation to produce a new string. + // Capture groups in the pattern can be referenced in the substitution + // string. Note, however, that the syntax for referring to capture groups is + // defined by the chosen regular expression engine. Google's `RE2 + // `_ regular expression engine uses a + // backslash followed by the capture group number to denote a numbered + // capture group. E.g., ``\1`` refers to capture group 1, and ``\2`` refers + // to capture group 2. + string substitution = 2; +} diff --git a/xds/third_party/envoy/src/main/proto/envoy/type/tracing/v2/custom_tag.proto b/xds/third_party/envoy/src/main/proto/envoy/type/tracing/v2/custom_tag.proto index 683a5c53677..750c07f7994 100644 --- a/xds/third_party/envoy/src/main/proto/envoy/type/tracing/v2/custom_tag.proto +++ b/xds/third_party/envoy/src/main/proto/envoy/type/tracing/v2/custom_tag.proto @@ -35,7 +35,8 @@ message CustomTag { // Header type custom tag with header name and default value. message Header { // Header name to obtain the value to populate the tag value. - string name = 1 [(validate.rules).string = {min_bytes: 1}]; + string name = 1 + [(validate.rules).string = {min_bytes: 1 well_known_regex: HTTP_HEADER_NAME strict: false}]; // When the header does not exist, // the tag value will be populated with this default value if specified,