diff --git a/api/src/main/proto/cel/expr/checked.proto b/api/src/main/proto/cel/expr/checked.proto new file mode 100644 index 000000000..e327db9b2 --- /dev/null +++ b/api/src/main/proto/cel/expr/checked.proto @@ -0,0 +1,344 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package cel.expr; + +import "cel/expr/syntax.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/struct.proto"; + +option cc_enable_arenas = true; +option go_package = "cel.dev/expr"; +option java_multiple_files = true; +option java_outer_classname = "DeclProto"; +option java_package = "dev.cel.expr"; + +// Protos for representing CEL declarations and typed checked expressions. + +// A CEL expression which has been successfully type checked. +message CheckedExpr { + // A map from expression ids to resolved references. + // + // The following entries are in this table: + // + // - An Ident or Select expression is represented here if it resolves to a + // declaration. For instance, if `a.b.c` is represented by + // `select(select(id(a), b), c)`, and `a.b` resolves to a declaration, + // while `c` is a field selection, then the reference is attached to the + // nested select expression (but not to the id or or the outer select). + // In turn, if `a` resolves to a declaration and `b.c` are field selections, + // the reference is attached to the ident expression. + // - Every Call expression has an entry here, identifying the function being + // called. + // - Every CreateStruct expression for a message has an entry, identifying + // the message. + map reference_map = 2; + + // A map from expression ids to types. + // + // Every expression node which has a type different than DYN has a mapping + // here. If an expression has type DYN, it is omitted from this map to save + // space. + map type_map = 3; + + // The source info derived from input that generated the parsed `expr` and + // any optimizations made during the type-checking pass. + SourceInfo source_info = 5; + + // The expr version indicates the major / minor version number of the `expr` + // representation. + // + // The most common reason for a version change will be to indicate to the CEL + // runtimes that transformations have been performed on the expr during static + // analysis. In some cases, this will save the runtime the work of applying + // the same or similar transformations prior to evaluation. + string expr_version = 6; + + // The checked expression. Semantically equivalent to the parsed `expr`, but + // may have structural differences. + Expr expr = 4; +} + +// Represents a CEL type. +message Type { + // List type with typed elements, e.g. `list`. + message ListType { + // The element type. + Type elem_type = 1; + } + + // Map type with parameterized key and value types, e.g. `map`. + message MapType { + // The type of the key. + Type key_type = 1; + + // The type of the value. + Type value_type = 2; + } + + // Function type with result and arg types. + message FunctionType { + // Result type of the function. + Type result_type = 1; + + // Argument types of the function. + repeated Type arg_types = 2; + } + + // Application defined abstract type. + message AbstractType { + // The fully qualified name of this abstract type. + string name = 1; + + // Parameter types for this abstract type. + repeated Type parameter_types = 2; + } + + // CEL primitive types. + enum PrimitiveType { + // Unspecified type. + PRIMITIVE_TYPE_UNSPECIFIED = 0; + + // Boolean type. + BOOL = 1; + + // Int64 type. + // + // 32-bit integer values are widened to int64. + INT64 = 2; + + // Uint64 type. + // + // 32-bit unsigned integer values are widened to uint64. + UINT64 = 3; + + // Double type. + // + // 32-bit float values are widened to double values. + DOUBLE = 4; + + // String type. + STRING = 5; + + // Bytes type. + BYTES = 6; + } + + // Well-known protobuf types treated with first-class support in CEL. + enum WellKnownType { + // Unspecified type. + WELL_KNOWN_TYPE_UNSPECIFIED = 0; + + // Well-known protobuf.Any type. + // + // Any types are a polymorphic message type. During type-checking they are + // treated like `DYN` types, but at runtime they are resolved to a specific + // message type specified at evaluation time. + ANY = 1; + + // Well-known protobuf.Timestamp type, internally referenced as `timestamp`. + TIMESTAMP = 2; + + // Well-known protobuf.Duration type, internally referenced as `duration`. + DURATION = 3; + } + + // The kind of type. + oneof type_kind { + // Dynamic type. + google.protobuf.Empty dyn = 1; + + // Null value. + google.protobuf.NullValue null = 2; + + // Primitive types: `true`, `1u`, `-2.0`, `'string'`, `b'bytes'`. + PrimitiveType primitive = 3; + + // Wrapper of a primitive type, e.g. `google.protobuf.Int64Value`. + PrimitiveType wrapper = 4; + + // Well-known protobuf type such as `google.protobuf.Timestamp`. + WellKnownType well_known = 5; + + // Parameterized list with elements of `list_type`, e.g. `list`. + ListType list_type = 6; + + // Parameterized map with typed keys and values. + MapType map_type = 7; + + // Function type. + FunctionType function = 8; + + // Protocol buffer message type. + // + // The `message_type` string specifies the qualified message type name. For + // example, `google.type.PhoneNumber`. + string message_type = 9; + + // Type param type. + // + // The `type_param` string specifies the type parameter name, e.g. `list` + // would be a `list_type` whose element type was a `type_param` type + // named `E`. + string type_param = 10; + + // Type type. + // + // The `type` value specifies the target type. e.g. int is type with a + // target type of `Primitive.INT64`. + Type type = 11; + + // Error type. + // + // During type-checking if an expression is an error, its type is propagated + // as the `ERROR` type. This permits the type-checker to discover other + // errors present in the expression. + google.protobuf.Empty error = 12; + + // Abstract, application defined type. + // + // An abstract type has no accessible field names, and it can only be + // inspected via helper / member functions. + AbstractType abstract_type = 14; + } +} + +// Represents a declaration of a named value or function. +// +// A declaration is part of the contract between the expression, the agent +// evaluating that expression, and the caller requesting evaluation. +message Decl { + // Identifier declaration which specifies its type and optional `Expr` value. + // + // An identifier without a value is a declaration that must be provided at + // evaluation time. An identifier with a value should resolve to a constant, + // but may be used in conjunction with other identifiers bound at evaluation + // time. + message IdentDecl { + // Required. The type of the identifier. + Type type = 1; + + // The constant value of the identifier. If not specified, the identifier + // must be supplied at evaluation time. + Constant value = 2; + + // Documentation string for the identifier. + string doc = 3; + } + + // Function declaration specifies one or more overloads which indicate the + // function's parameter types and return type. + // + // Functions have no observable side-effects (there may be side-effects like + // logging which are not observable from CEL). + message FunctionDecl { + // An overload indicates a function's parameter types and return type, and + // may optionally include a function body described in terms of + // [Expr][cel.expr.Expr] values. + // + // Functions overloads are declared in either a function or method + // call-style. For methods, the `params[0]` is the expected type of the + // target receiver. + // + // Overloads must have non-overlapping argument types after erasure of all + // parameterized type variables (similar as type erasure in Java). + message Overload { + // Required. Globally unique overload name of the function which reflects + // the function name and argument types. + // + // This will be used by a [Reference][cel.expr.Reference] to + // indicate the `overload_id` that was resolved for the function `name`. + string overload_id = 1; + + // List of function parameter [Type][cel.expr.Type] values. + // + // Param types are disjoint after generic type parameters have been + // replaced with the type `DYN`. Since the `DYN` type is compatible with + // any other type, this means that if `A` is a type parameter, the + // function types `int` and `int` are not disjoint. Likewise, + // `map` is not disjoint from `map`. + // + // When the `result_type` of a function is a generic type param, the + // type param name also appears as the `type` of on at least one params. + repeated Type params = 2; + + // The type param names associated with the function declaration. + // + // For example, `function ex(K key, map map) : V` would yield + // the type params of `K, V`. + repeated string type_params = 3; + + // Required. The result type of the function. For example, the operator + // `string.isEmpty()` would have `result_type` of `kind: BOOL`. + Type result_type = 4; + + // Whether the function is to be used in a method call-style `x.f(...)` + // of a function call-style `f(x, ...)`. + // + // For methods, the first parameter declaration, `params[0]` is the + // expected type of the target receiver. + bool is_instance_function = 5; + + // Documentation string for the overload. + string doc = 6; + } + + // Required. List of function overloads, must contain at least one overload. + repeated Overload overloads = 1; + } + + // The fully qualified name of the declaration. + // + // Declarations are organized in containers and this represents the full path + // to the declaration in its container, as in `cel.expr.Decl`. + // + // Declarations used as + // [FunctionDecl.Overload][cel.expr.Decl.FunctionDecl.Overload] + // parameters may or may not have a name depending on whether the overload is + // function declaration or a function definition containing a result + // [Expr][cel.expr.Expr]. + string name = 1; + + // Required. The declaration kind. + oneof decl_kind { + // Identifier declaration. + IdentDecl ident = 2; + + // Function declaration. + FunctionDecl function = 3; + } +} + +// Describes a resolved reference to a declaration. +message Reference { + // The fully qualified name of the declaration. + string name = 1; + + // For references to functions, this is a list of `Overload.overload_id` + // values which match according to typing rules. + // + // If the list has more than one element, overload resolution among the + // presented candidates must happen at runtime because of dynamic types. The + // type checker attempts to narrow down this list as much as possible. + // + // Empty if this is not a reference to a + // [Decl.FunctionDecl][cel.expr.Decl.FunctionDecl]. + repeated string overload_id = 3; + + // For references to constants, this may contain the value of the + // constant if known at compile time. + Constant value = 4; +} diff --git a/api/src/main/proto/cel/expr/conformance/conformance_service.proto b/api/src/main/proto/cel/expr/conformance/conformance_service.proto new file mode 100644 index 000000000..0b4740b37 --- /dev/null +++ b/api/src/main/proto/cel/expr/conformance/conformance_service.proto @@ -0,0 +1,180 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package cel.expr.conformance; + +import "cel/expr/checked.proto"; +import "cel/expr/eval.proto"; +import "cel/expr/syntax.proto"; +import "google/rpc/status.proto"; + +option cc_enable_arenas = true; +option go_package = "cel.dev/expr/conformance"; +option java_multiple_files = true; +option java_outer_classname = "ConformanceServiceProto"; +option java_package = "dev.cel.expr.conformance"; + +// Access a CEL implementation from another process or machine. +// A CEL implementation is decomposed as a parser, a static checker, +// and an evaluator. Every CEL implementation is expected to provide +// a server for this API. The API will be used for conformance testing +// and other utilities. +service ConformanceService { + // Transforms CEL source text into a parsed representation. + rpc Parse(ParseRequest) returns (ParseResponse) { + } + + // Runs static checks on a parsed CEL representation and return + // an annotated representation, or a set of issues. + rpc Check(CheckRequest) returns (CheckResponse) { + } + + // Evaluates a parsed or annotation CEL representation given + // values of external bindings. + rpc Eval(EvalRequest) returns (EvalResponse) { + } +} + +// Request message for the Parse method. +message ParseRequest { + // Required. Source text in CEL syntax. + string cel_source = 1; + + // Tag for version of CEL syntax, for future use. + string syntax_version = 2; + + // File or resource for source text, used in [SourceInfo][google.api.SourceInfo]. + string source_location = 3; + + // Prevent macro expansion. See "Macros" in Language Defiinition. + bool disable_macros = 4; +} + +// Response message for the Parse method. +message ParseResponse { + // The parsed representation, or unset if parsing failed. + cel.expr.ParsedExpr parsed_expr = 1; + + // Any number of issues with [StatusDetails][] as the details. + repeated google.rpc.Status issues = 2; +} + +// Request message for the Check method. +message CheckRequest { + // Required. The parsed representation of the CEL program. + cel.expr.ParsedExpr parsed_expr = 1; + + // Declarations of types for external variables and functions. + // Required if program uses external variables or functions + // not in the default environment. + repeated cel.expr.Decl type_env = 2; + + // The protocol buffer context. See "Name Resolution" in the + // Language Definition. + string container = 3; + + // If true, use only the declarations in [type_env][google.api.expr.conformance.v1alpha1.CheckRequest.type_env]. If false (default), + // add declarations for the standard definitions to the type environment. See + // "Standard Definitions" in the Language Definition. + bool no_std_env = 4; +} + +// Response message for the Check method. +message CheckResponse { + // The annotated representation, or unset if checking failed. + cel.expr.CheckedExpr checked_expr = 1; + + // Any number of issues with [StatusDetails][] as the details. + repeated google.rpc.Status issues = 2; +} + +// Request message for the Eval method. +message EvalRequest { + // Required. Either the parsed or annotated representation of the CEL program. + oneof expr_kind { + // Evaluate based on the parsed representation. + cel.expr.ParsedExpr parsed_expr = 1; + + // Evaluate based on the checked representation. + cel.expr.CheckedExpr checked_expr = 2; + } + + // Bindings for the external variables. The types SHOULD be compatible + // with the type environment in [CheckRequest][google.api.expr.conformance.v1alpha1.CheckRequest], if checked. + map bindings = 3; + + // SHOULD be the same container as used in [CheckRequest][google.api.expr.conformance.v1alpha1.CheckRequest], if checked. + string container = 4; +} + +// Response message for the Eval method. +message EvalResponse { + // The execution result, or unset if execution couldn't start. + cel.expr.ExprValue result = 1; + + // Any number of issues with [StatusDetails][] as the details. + // Note that CEL execution errors are reified into [ExprValue][]. + // Nevertheless, we'll allow out-of-band issues to be raised, + // which also makes the replies more regular. + repeated google.rpc.Status issues = 2; +} + +// A specific position in source. +message SourcePosition { + // The source location name (e.g. file name). + string location = 1; + + // The UTF-8 code unit offset. + int32 offset = 2; + + // The 1-based index of the starting line in the source text + // where the issue occurs, or 0 if unknown. + int32 line = 3; + + // The 0-based index of the starting position within the line of source text + // where the issue occurs. Only meaningful if line is nonzero. + int32 column = 4; +} + +// Warnings or errors in service execution are represented by +// [google.rpc.Status][google.rpc.Status] messages, with the following message +// in the details field. +message IssueDetails { + // Severities of issues. + enum Severity { + // An unspecified severity. + SEVERITY_UNSPECIFIED = 0; + + // Deprecation issue for statements and method that may no longer be + // supported or maintained. + DEPRECATION = 1; + + // Warnings such as: unused variables. + WARNING = 2; + + // Errors such as: unmatched curly braces or variable redefinition. + ERROR = 3; + } + + // The severity of the issue. + Severity severity = 1; + + // Position in the source, if known. + SourcePosition position = 2; + + // Expression ID from [Expr][], 0 if unknown. + int64 id = 3; +} diff --git a/api/src/main/proto/cel/expr/conformance/envcheck.proto b/api/src/main/proto/cel/expr/conformance/envcheck.proto new file mode 100644 index 000000000..93585c67d --- /dev/null +++ b/api/src/main/proto/cel/expr/conformance/envcheck.proto @@ -0,0 +1,37 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Tests for runtime support of standard functions. + +syntax = "proto3"; + +package cel.expr.conformance; + +import "cel/expr/checked.proto"; + +option cc_enable_arenas = true; +option go_package = "cel.dev/expr/conformance"; +option java_multiple_files = true; +option java_outer_classname = "EnvcheckProto"; +option java_package = "dev.cel.expr.conformance"; + +// The format of a standard environment, i.e. a collection of declarations +// for the checker. +message Env { + // Required. The name of the environment. + string name = 1; + + // The declarations in this environment. + repeated cel.expr.Decl decl = 2; +} diff --git a/api/src/main/proto/cel/expr/conformance/proto2/test_all_types.proto b/api/src/main/proto/cel/expr/conformance/proto2/test_all_types.proto new file mode 100644 index 000000000..737ca3ab7 --- /dev/null +++ b/api/src/main/proto/cel/expr/conformance/proto2/test_all_types.proto @@ -0,0 +1,307 @@ +syntax = "proto2"; + +package cel.expr.conformance.proto2; + +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/wrappers.proto"; + +option cc_enable_arenas = true; +option go_package = "cel.dev/expr/conformance/proto2"; +option java_multiple_files = true; +option java_outer_classname = "TestAllTypesProto"; +option java_package = "dev.cel.expr.conformance.proto2"; + +// This proto includes every type of field in both singular and repeated +// forms. +message TestAllTypes { + message NestedMessage { + // The field name "b" fails to compile in proto1 because it conflicts with + // a local variable named "b" in one of the generated methods. + // This file needs to compile in proto1 to test backwards-compatibility. + optional int32 bb = 1; + } + + enum NestedEnum { + FOO = 0; + BAR = 1; + BAZ = 2; + } + + // Singular + optional int32 single_int32 = 1 [default = -32]; + optional int64 single_int64 = 2 [default = -64]; + optional uint32 single_uint32 = 3 [default = 32]; + optional uint64 single_uint64 = 4 [default = 64]; + optional sint32 single_sint32 = 5; + optional sint64 single_sint64 = 6; + optional fixed32 single_fixed32 = 7; + optional fixed64 single_fixed64 = 8; + optional sfixed32 single_sfixed32 = 9; + optional sfixed64 single_sfixed64 = 10; + optional float single_float = 11 [default = 3.0]; + optional double single_double = 12 [default = 6.4]; + optional bool single_bool = 13 [default = true]; + optional string single_string = 14 [default = "empty"]; + optional bytes single_bytes = 15 [default = "none"]; + + // Wellknown. + optional google.protobuf.Any single_any = 100; + optional google.protobuf.Duration single_duration = 101; + optional google.protobuf.Timestamp single_timestamp = 102; + optional google.protobuf.Struct single_struct = 103; + optional google.protobuf.Value single_value = 104; + optional google.protobuf.Int64Value single_int64_wrapper = 105; + optional google.protobuf.Int32Value single_int32_wrapper = 106; + optional google.protobuf.DoubleValue single_double_wrapper = 107; + optional google.protobuf.FloatValue single_float_wrapper = 108; + optional google.protobuf.UInt64Value single_uint64_wrapper = 109; + optional google.protobuf.UInt32Value single_uint32_wrapper = 110; + optional google.protobuf.StringValue single_string_wrapper = 111; + optional google.protobuf.BoolValue single_bool_wrapper = 112; + optional google.protobuf.BytesValue single_bytes_wrapper = 113; + optional google.protobuf.ListValue list_value = 114; + optional google.protobuf.NullValue null_value = 115; + optional google.protobuf.NullValue optional_null_value = 116; + + // Nested messages + oneof nested_type { + NestedMessage single_nested_message = 21; + NestedEnum single_nested_enum = 22 [default = BAR]; + } + optional NestedMessage standalone_message = 23; + optional NestedEnum standalone_enum = 24; + + // Repeated + repeated int32 repeated_int32 = 31; + repeated int64 repeated_int64 = 32; + repeated uint32 repeated_uint32 = 33; + repeated uint64 repeated_uint64 = 34; + repeated sint32 repeated_sint32 = 35; + repeated sint64 repeated_sint64 = 36; + repeated fixed32 repeated_fixed32 = 37; + repeated fixed64 repeated_fixed64 = 38; + repeated sfixed32 repeated_sfixed32 = 39; + repeated sfixed64 repeated_sfixed64 = 40; + repeated float repeated_float = 41; + repeated double repeated_double = 42; + repeated bool repeated_bool = 43; + repeated string repeated_string = 44; + repeated bytes repeated_bytes = 45; + + // Repeated and nested + repeated NestedMessage repeated_nested_message = 51; + repeated NestedEnum repeated_nested_enum = 52; + repeated string repeated_string_piece = 53 [ctype = STRING_PIECE]; + repeated string repeated_cord = 54 [ctype = CORD]; + repeated NestedMessage repeated_lazy_message = 55 [lazy = true]; + + // Repeated wellknown. + repeated google.protobuf.Any repeated_any = 120; + repeated google.protobuf.Duration repeated_duration = 121; + repeated google.protobuf.Timestamp repeated_timestamp = 122; + repeated google.protobuf.Struct repeated_struct = 123; + repeated google.protobuf.Value repeated_value = 124; + repeated google.protobuf.Int64Value repeated_int64_wrapper = 125; + repeated google.protobuf.Int32Value repeated_int32_wrapper = 126; + repeated google.protobuf.DoubleValue repeated_double_wrapper = 127; + repeated google.protobuf.FloatValue repeated_float_wrapper = 128; + repeated google.protobuf.UInt64Value repeated_uint64_wrapper = 129; + repeated google.protobuf.UInt32Value repeated_uint32_wrapper = 130; + repeated google.protobuf.StringValue repeated_string_wrapper = 131; + repeated google.protobuf.BoolValue repeated_bool_wrapper = 132; + repeated google.protobuf.BytesValue repeated_bytes_wrapper = 133; + repeated google.protobuf.ListValue repeated_list_value = 134; + repeated google.protobuf.NullValue repeated_null_value = 135; + + // Map + map map_int64_nested_type = 62; + + map map_bool_bool = 63; + map map_bool_string = 64; + map map_bool_bytes = 65; + map map_bool_int32 = 66; + map map_bool_int64 = 67; + map map_bool_uint32 = 68; + map map_bool_uint64 = 69; + map map_bool_float = 70; + map map_bool_double = 71; + map map_bool_enum = 72; + map map_bool_message = 73; + map map_bool_duration = 228; + map map_bool_timestamp = 229; + map map_bool_null_value = 230; + map map_bool_any = 246; + map map_bool_struct = 247; + map map_bool_value = 248; + map map_bool_list_value = 249; + map map_bool_int64_wrapper = 250; + map map_bool_int32_wrapper = 251; + map map_bool_double_wrapper = 252; + map map_bool_float_wrapper = 253; + map map_bool_uint64_wrapper = 254; + map map_bool_uint32_wrapper = 255; + map map_bool_string_wrapper = 256; + map map_bool_bool_wrapper = 257; + map map_bool_bytes_wrapper = 258; + + map map_int32_bool = 74; + map map_int32_string = 75; + map map_int32_bytes = 76; + map map_int32_int32 = 77; + map map_int32_int64 = 78; + map map_int32_uint32 = 79; + map map_int32_uint64 = 80; + map map_int32_float = 81; + map map_int32_double = 82; + map map_int32_enum = 83; + map map_int32_message = 84; + map map_int32_duration = 231; + map map_int32_timestamp = 232; + map map_int32_null_value = 233; + map map_int32_any = 259; + map map_int32_struct = 260; + map map_int32_value = 261; + map map_int32_list_value = 262; + map map_int32_int64_wrapper = 263; + map map_int32_int32_wrapper = 264; + map map_int32_double_wrapper = 265; + map map_int32_float_wrapper = 266; + map map_int32_uint64_wrapper = 267; + map map_int32_uint32_wrapper = 268; + map map_int32_string_wrapper = 269; + map map_int32_bool_wrapper = 270; + map map_int32_bytes_wrapper = 271; + + map map_int64_bool = 85; + map map_int64_string = 86; + map map_int64_bytes = 87; + map map_int64_int32 = 88; + map map_int64_int64 = 89; + map map_int64_uint32 = 90; + map map_int64_uint64 = 91; + map map_int64_float = 92; + map map_int64_double = 93; + map map_int64_enum = 94; + map map_int64_message = 95; + map map_int64_duration = 234; + map map_int64_timestamp = 235; + map map_int64_null_value = 236; + map map_int64_any = 272; + map map_int64_struct = 273; + map map_int64_value = 274; + map map_int64_list_value = 275; + map map_int64_int64_wrapper = 276; + map map_int64_int32_wrapper = 277; + map map_int64_double_wrapper = 278; + map map_int64_float_wrapper = 279; + map map_int64_uint64_wrapper = 280; + map map_int64_uint32_wrapper = 281; + map map_int64_string_wrapper = 282; + map map_int64_bool_wrapper = 283; + map map_int64_bytes_wrapper = 284; + + map map_uint32_bool = 96; + map map_uint32_string = 97; + map map_uint32_bytes = 98; + map map_uint32_int32 = 99; + map map_uint32_int64 = 200; + map map_uint32_uint32 = 201; + map map_uint32_uint64 = 202; + map map_uint32_float = 203; + map map_uint32_double = 204; + map map_uint32_enum = 205; + map map_uint32_message = 206; + map map_uint32_duration = 237; + map map_uint32_timestamp = 238; + map map_uint32_null_value = 239; + map map_uint32_any = 285; + map map_uint32_struct = 286; + map map_uint32_value = 287; + map map_uint32_list_value = 288; + map map_uint32_int64_wrapper = 289; + map map_uint32_int32_wrapper = 290; + map map_uint32_double_wrapper = 291; + map map_uint32_float_wrapper = 292; + map map_uint32_uint64_wrapper = 293; + map map_uint32_uint32_wrapper = 294; + map map_uint32_string_wrapper = 295; + map map_uint32_bool_wrapper = 296; + map map_uint32_bytes_wrapper = 297; + + map map_uint64_bool = 207; + map map_uint64_string = 208; + map map_uint64_bytes = 209; + map map_uint64_int32 = 210; + map map_uint64_int64 = 211; + map map_uint64_uint32 = 212; + map map_uint64_uint64 = 213; + map map_uint64_float = 214; + map map_uint64_double = 215; + map map_uint64_enum = 216; + map map_uint64_message = 217; + map map_uint64_duration = 240; + map map_uint64_timestamp = 241; + map map_uint64_null_value = 242; + map map_uint64_any = 298; + map map_uint64_struct = 299; + map map_uint64_value = 300; + map map_uint64_list_value = 301; + map map_uint64_int64_wrapper = 302; + map map_uint64_int32_wrapper = 303; + map map_uint64_double_wrapper = 304; + map map_uint64_float_wrapper = 305; + map map_uint64_uint64_wrapper = 306; + map map_uint64_uint32_wrapper = 307; + map map_uint64_string_wrapper = 308; + map map_uint64_bool_wrapper = 309; + map map_uint64_bytes_wrapper = 310; + + map map_string_bool = 218; + map map_string_string = 61; + map map_string_bytes = 219; + map map_string_int32 = 220; + map map_string_int64 = 221; + map map_string_uint32 = 222; + map map_string_uint64 = 223; + map map_string_float = 224; + map map_string_double = 225; + map map_string_enum = 226; + map map_string_message = 227; + map map_string_duration = 243; + map map_string_timestamp = 244; + map map_string_null_value = 245; + map map_string_any = 311; + map map_string_struct = 312; + map map_string_value = 313; + map map_string_list_value = 314; + map map_string_int64_wrapper = 315; + map map_string_int32_wrapper = 316; + map map_string_double_wrapper = 317; + map map_string_float_wrapper = 318; + map map_string_uint64_wrapper = 319; + map map_string_uint32_wrapper = 320; + map map_string_string_wrapper = 321; + map map_string_bool_wrapper = 322; + map map_string_bytes_wrapper = 323; +} + +// This proto includes a recursively nested message. +message NestedTestAllTypes { + optional NestedTestAllTypes child = 1; + optional TestAllTypes payload = 2; +} + +// This proto has a required field. +message TestRequired { + required int32 required_int32 = 1; +} + +// This proto tests that global enums are resolved correctly. +enum GlobalEnum { + GOO = 0; + GAR = 1; + GAZ = 2; +} diff --git a/api/src/main/proto/cel/expr/conformance/proto3/test_all_types.proto b/api/src/main/proto/cel/expr/conformance/proto3/test_all_types.proto new file mode 100644 index 000000000..c904868ab --- /dev/null +++ b/api/src/main/proto/cel/expr/conformance/proto3/test_all_types.proto @@ -0,0 +1,302 @@ +syntax = "proto3"; + +package cel.expr.conformance.proto3; + +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/wrappers.proto"; + +option cc_enable_arenas = true; +option go_package = "cel.dev/expr/conformance/proto3"; +option java_multiple_files = true; +option java_outer_classname = "TestAllTypesProto"; +option java_package = "dev.cel.expr.conformance.proto3"; + +// This proto includes every type of field in both singular and repeated +// forms. +message TestAllTypes { + message NestedMessage { + // The field name "b" fails to compile in proto1 because it conflicts with + // a local variable named "b" in one of the generated methods. + // This file needs to compile in proto1 to test backwards-compatibility. + int32 bb = 1; + } + + enum NestedEnum { + FOO = 0; + BAR = 1; + BAZ = 2; + } + + // Singular + int32 single_int32 = 1; + int64 single_int64 = 2; + uint32 single_uint32 = 3; + uint64 single_uint64 = 4; + sint32 single_sint32 = 5; + sint64 single_sint64 = 6; + fixed32 single_fixed32 = 7; + fixed64 single_fixed64 = 8; + sfixed32 single_sfixed32 = 9; + sfixed64 single_sfixed64 = 10; + float single_float = 11; + double single_double = 12; + bool single_bool = 13; + string single_string = 14; + bytes single_bytes = 15; + + // Wellknown. + google.protobuf.Any single_any = 100; + google.protobuf.Duration single_duration = 101; + google.protobuf.Timestamp single_timestamp = 102; + google.protobuf.Struct single_struct = 103; + google.protobuf.Value single_value = 104; + google.protobuf.Int64Value single_int64_wrapper = 105; + google.protobuf.Int32Value single_int32_wrapper = 106; + google.protobuf.DoubleValue single_double_wrapper = 107; + google.protobuf.FloatValue single_float_wrapper = 108; + google.protobuf.UInt64Value single_uint64_wrapper = 109; + google.protobuf.UInt32Value single_uint32_wrapper = 110; + google.protobuf.StringValue single_string_wrapper = 111; + google.protobuf.BoolValue single_bool_wrapper = 112; + google.protobuf.BytesValue single_bytes_wrapper = 113; + google.protobuf.ListValue list_value = 114; + google.protobuf.NullValue null_value = 115; + optional google.protobuf.NullValue optional_null_value = 116; + + // Nested messages + oneof nested_type { + NestedMessage single_nested_message = 21; + NestedEnum single_nested_enum = 22; + } + NestedMessage standalone_message = 23; + NestedEnum standalone_enum = 24; + + // Repeated + repeated int32 repeated_int32 = 31; + repeated int64 repeated_int64 = 32; + repeated uint32 repeated_uint32 = 33; + repeated uint64 repeated_uint64 = 34; + repeated sint32 repeated_sint32 = 35; + repeated sint64 repeated_sint64 = 36; + repeated fixed32 repeated_fixed32 = 37; + repeated fixed64 repeated_fixed64 = 38; + repeated sfixed32 repeated_sfixed32 = 39; + repeated sfixed64 repeated_sfixed64 = 40; + repeated float repeated_float = 41; + repeated double repeated_double = 42; + repeated bool repeated_bool = 43; + repeated string repeated_string = 44; + repeated bytes repeated_bytes = 45; + + // Repeated and nested + repeated NestedMessage repeated_nested_message = 51; + repeated NestedEnum repeated_nested_enum = 52; + repeated string repeated_string_piece = 53 [ctype = STRING_PIECE]; + repeated string repeated_cord = 54 [ctype = CORD]; + repeated NestedMessage repeated_lazy_message = 55 [lazy = true]; + + // Repeated wellknown. + repeated google.protobuf.Any repeated_any = 120; + repeated google.protobuf.Duration repeated_duration = 121; + repeated google.protobuf.Timestamp repeated_timestamp = 122; + repeated google.protobuf.Struct repeated_struct = 123; + repeated google.protobuf.Value repeated_value = 124; + repeated google.protobuf.Int64Value repeated_int64_wrapper = 125; + repeated google.protobuf.Int32Value repeated_int32_wrapper = 126; + repeated google.protobuf.DoubleValue repeated_double_wrapper = 127; + repeated google.protobuf.FloatValue repeated_float_wrapper = 128; + repeated google.protobuf.UInt64Value repeated_uint64_wrapper = 129; + repeated google.protobuf.UInt32Value repeated_uint32_wrapper = 130; + repeated google.protobuf.StringValue repeated_string_wrapper = 131; + repeated google.protobuf.BoolValue repeated_bool_wrapper = 132; + repeated google.protobuf.BytesValue repeated_bytes_wrapper = 133; + repeated google.protobuf.ListValue repeated_list_value = 134; + repeated google.protobuf.NullValue repeated_null_value = 135; + + // Map + map map_int64_nested_type = 62; + + map map_bool_bool = 63; + map map_bool_string = 64; + map map_bool_bytes = 65; + map map_bool_int32 = 66; + map map_bool_int64 = 67; + map map_bool_uint32 = 68; + map map_bool_uint64 = 69; + map map_bool_float = 70; + map map_bool_double = 71; + map map_bool_enum = 72; + map map_bool_message = 73; + map map_bool_duration = 228; + map map_bool_timestamp = 229; + map map_bool_null_value = 230; + map map_bool_any = 246; + map map_bool_struct = 247; + map map_bool_value = 248; + map map_bool_list_value = 249; + map map_bool_int64_wrapper = 250; + map map_bool_int32_wrapper = 251; + map map_bool_double_wrapper = 252; + map map_bool_float_wrapper = 253; + map map_bool_uint64_wrapper = 254; + map map_bool_uint32_wrapper = 255; + map map_bool_string_wrapper = 256; + map map_bool_bool_wrapper = 257; + map map_bool_bytes_wrapper = 258; + + map map_int32_bool = 74; + map map_int32_string = 75; + map map_int32_bytes = 76; + map map_int32_int32 = 77; + map map_int32_int64 = 78; + map map_int32_uint32 = 79; + map map_int32_uint64 = 80; + map map_int32_float = 81; + map map_int32_double = 82; + map map_int32_enum = 83; + map map_int32_message = 84; + map map_int32_duration = 231; + map map_int32_timestamp = 232; + map map_int32_null_value = 233; + map map_int32_any = 259; + map map_int32_struct = 260; + map map_int32_value = 261; + map map_int32_list_value = 262; + map map_int32_int64_wrapper = 263; + map map_int32_int32_wrapper = 264; + map map_int32_double_wrapper = 265; + map map_int32_float_wrapper = 266; + map map_int32_uint64_wrapper = 267; + map map_int32_uint32_wrapper = 268; + map map_int32_string_wrapper = 269; + map map_int32_bool_wrapper = 270; + map map_int32_bytes_wrapper = 271; + + map map_int64_bool = 85; + map map_int64_string = 86; + map map_int64_bytes = 87; + map map_int64_int32 = 88; + map map_int64_int64 = 89; + map map_int64_uint32 = 90; + map map_int64_uint64 = 91; + map map_int64_float = 92; + map map_int64_double = 93; + map map_int64_enum = 94; + map map_int64_message = 95; + map map_int64_duration = 234; + map map_int64_timestamp = 235; + map map_int64_null_value = 236; + map map_int64_any = 272; + map map_int64_struct = 273; + map map_int64_value = 274; + map map_int64_list_value = 275; + map map_int64_int64_wrapper = 276; + map map_int64_int32_wrapper = 277; + map map_int64_double_wrapper = 278; + map map_int64_float_wrapper = 279; + map map_int64_uint64_wrapper = 280; + map map_int64_uint32_wrapper = 281; + map map_int64_string_wrapper = 282; + map map_int64_bool_wrapper = 283; + map map_int64_bytes_wrapper = 284; + + map map_uint32_bool = 96; + map map_uint32_string = 97; + map map_uint32_bytes = 98; + map map_uint32_int32 = 99; + map map_uint32_int64 = 200; + map map_uint32_uint32 = 201; + map map_uint32_uint64 = 202; + map map_uint32_float = 203; + map map_uint32_double = 204; + map map_uint32_enum = 205; + map map_uint32_message = 206; + map map_uint32_duration = 237; + map map_uint32_timestamp = 238; + map map_uint32_null_value = 239; + map map_uint32_any = 285; + map map_uint32_struct = 286; + map map_uint32_value = 287; + map map_uint32_list_value = 288; + map map_uint32_int64_wrapper = 289; + map map_uint32_int32_wrapper = 290; + map map_uint32_double_wrapper = 291; + map map_uint32_float_wrapper = 292; + map map_uint32_uint64_wrapper = 293; + map map_uint32_uint32_wrapper = 294; + map map_uint32_string_wrapper = 295; + map map_uint32_bool_wrapper = 296; + map map_uint32_bytes_wrapper = 297; + + map map_uint64_bool = 207; + map map_uint64_string = 208; + map map_uint64_bytes = 209; + map map_uint64_int32 = 210; + map map_uint64_int64 = 211; + map map_uint64_uint32 = 212; + map map_uint64_uint64 = 213; + map map_uint64_float = 214; + map map_uint64_double = 215; + map map_uint64_enum = 216; + map map_uint64_message = 217; + map map_uint64_duration = 240; + map map_uint64_timestamp = 241; + map map_uint64_null_value = 242; + map map_uint64_any = 298; + map map_uint64_struct = 299; + map map_uint64_value = 300; + map map_uint64_list_value = 301; + map map_uint64_int64_wrapper = 302; + map map_uint64_int32_wrapper = 303; + map map_uint64_double_wrapper = 304; + map map_uint64_float_wrapper = 305; + map map_uint64_uint64_wrapper = 306; + map map_uint64_uint32_wrapper = 307; + map map_uint64_string_wrapper = 308; + map map_uint64_bool_wrapper = 309; + map map_uint64_bytes_wrapper = 310; + + map map_string_bool = 218; + map map_string_string = 61; + map map_string_bytes = 219; + map map_string_int32 = 220; + map map_string_int64 = 221; + map map_string_uint32 = 222; + map map_string_uint64 = 223; + map map_string_float = 224; + map map_string_double = 225; + map map_string_enum = 226; + map map_string_message = 227; + map map_string_duration = 243; + map map_string_timestamp = 244; + map map_string_null_value = 245; + map map_string_any = 311; + map map_string_struct = 312; + map map_string_value = 313; + map map_string_list_value = 314; + map map_string_int64_wrapper = 315; + map map_string_int32_wrapper = 316; + map map_string_double_wrapper = 317; + map map_string_float_wrapper = 318; + map map_string_uint64_wrapper = 319; + map map_string_uint32_wrapper = 320; + map map_string_string_wrapper = 321; + map map_string_bool_wrapper = 322; + map map_string_bytes_wrapper = 323; +} + +// This proto includes a recursively nested message. +message NestedTestAllTypes { + NestedTestAllTypes child = 1; + TestAllTypes payload = 2; +} + +// This proto tests that global enums are resolved correctly. +enum GlobalEnum { + GOO = 0; + GAR = 1; + GAZ = 2; +} diff --git a/api/src/main/proto/cel/expr/conformance/simple.proto b/api/src/main/proto/cel/expr/conformance/simple.proto new file mode 100644 index 000000000..8b4ab8020 --- /dev/null +++ b/api/src/main/proto/cel/expr/conformance/simple.proto @@ -0,0 +1,127 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Simple end-to-end conformance tests. + +syntax = "proto3"; + +package cel.expr.conformance; + +import "cel/expr/checked.proto"; +import "cel/expr/eval.proto"; +import "cel/expr/value.proto"; + +option cc_enable_arenas = true; +option go_package = "cel.dev/expr/conformance"; +option java_multiple_files = true; +option java_outer_classname = "SimpleProto"; +option java_package = "dev.cel.expr.conformance"; + +// The format of a simple test file, expected to be stored in text format. +// A file is the unit of granularity for selecting conformance tests, +// so tests of optional features should be segregated into separate files. +message SimpleTestFile { + // Required. The name of the file. Should match the filename. + string name = 1; + + // A description of the file. + string description = 2; + + // The contained sections. + repeated SimpleTestSection section = 3; +} + +// A collection of related SimpleTests. +// +// The section is the unit of organization within a test file, and should +// guide where new tests are added. +message SimpleTestSection { + // Required. The name of the section. + string name = 1; + + // A description of the section. + string description = 2; + + // The contained tests. + repeated SimpleTest test = 3; +} + +// A test which should run the given CEL program through parsing, +// optionally through checking, then evaluation, with the results +// of the pipeline validated by the given result matcher. +message SimpleTest { + // Required. The name of the test, which should be unique in the test file. + string name = 1; + + // A description of the test. + string description = 2; + + // Required. The text of the CEL expression. + string expr = 3; + + // Disables all macro expansion in parsing. + bool disable_macros = 4; + + // Disables the check phase. + bool disable_check = 5; + + // The type environment to use for the check phase. + repeated cel.expr.Decl type_env = 6; + + // The container for name resolution. + string container = 13; + + // The locale to use for the evaluation phase. + string locale = 14; + + // Variable bindings to use for the eval phase. + map bindings = 7; + + // An unspecified result defaults to a matcher for the true boolean value. + oneof result_matcher { + // A normal value, which must match the evaluation result exactly + // via value equality semantics. This coincides with proto equality, + // except for: + // * maps are order-agnostic. + // * a floating point NaN should match any NaN. + cel.expr.Value value = 8; + + // Matches error evaluation results. + cel.expr.ErrorSet eval_error = 9; + + // Matches one of several error results. + // (Using explicit message since oneof can't handle repeated.) + ErrorSetMatcher any_eval_errors = 10; + + // Matches unknown evaluation results. + cel.expr.UnknownSet unknown = 11; + + // Matches one of several unknown results. + // (Using explicit message since oneof can't handle repeated.) + UnknownSetMatcher any_unknowns = 12; + } + // Next is 15. +} + +// Matches error results from Eval. +message ErrorSetMatcher { + // Success if we match any of these sets. + repeated cel.expr.ErrorSet errors = 1; +} + +// Matches unknown results from Eval. +message UnknownSetMatcher { + // Success if we match any of these sets. + repeated cel.expr.UnknownSet unknowns = 1; +} diff --git a/api/src/main/proto/cel/expr/eval.proto b/api/src/main/proto/cel/expr/eval.proto new file mode 100644 index 000000000..3f76f5761 --- /dev/null +++ b/api/src/main/proto/cel/expr/eval.proto @@ -0,0 +1,116 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package cel.expr; + +import "cel/expr/value.proto"; +import "google/rpc/status.proto"; + +option cc_enable_arenas = true; +option go_package = "cel.dev/expr"; +option java_multiple_files = true; +option java_outer_classname = "EvalProto"; +option java_package = "dev.cel.expr"; + +// The state of an evaluation. +// +// Can represent an initial, partial, or completed state of evaluation. +message EvalState { + // A single evaluation result. + message Result { + // The id of the expression this result if for. + int64 expr = 1; + + // The index in `values` of the resulting value. + int64 value = 2; + } + + // The unique values referenced in this message. + repeated ExprValue values = 1; + + // An ordered list of results. + // + // Tracks the flow of evaluation through the expression. + // May be sparse. + repeated Result results = 3; +} + +// The value of an evaluated expression. +message ExprValue { + // An expression can resolve to a value, error or unknown. + oneof kind { + Value value = 1; + + // The set of errors in the critical path of evaluation. + // + // Only errors in the critical path are included. For example, + // `( || true) && ` will only result in ``, + // while ` || ` will result in both `` and + // ``. + // + // Errors cause by the presence of other errors are not included in the + // set. For example `.foo`, `foo()`, and ` + 1` will + // only result in ``. + // + // Multiple errors *might* be included when evaluation could result + // in different errors. For example ` + ` and + // `foo(, )` may result in ``, `` or both. + // The exact subset of errors included for this case is unspecified and + // depends on the implementation details of the evaluator. + ErrorSet error = 2; + + // The set of unknowns in the critical path of evaluation. + // + // Unknown behaves identically to Error with regards to propagation. + // Specifically, only unknowns in the critical path are included, unknowns + // caused by the presence of other unknowns are not included, and multiple + // unknowns *might* be included when evaluation could result in + // different unknowns. For example: + // + // ( || true) && -> + // || -> + // .foo -> + // foo() -> + // + -> or + // + // Unknown takes precedence over Error in cases where a `Value` can short + // circuit the result: + // + // || -> + // && -> + // + // Errors take precedence in all other cases: + // + // + -> + // foo(, ) -> + UnknownSet unknown = 3; + } +} + +// A set of errors. +// +// The errors included depend on the context. See `ExprValue.error`. +message ErrorSet { + repeated google.rpc.Status errors = 1; +} + +// A set of expressions for which the value is unknown. +// +// The unknowns included depend on the context. See `ExprValue.unknown`. +message UnknownSet { + // The ids of the expressions with unknown values. + repeated int64 exprs = 1; +} diff --git a/api/src/main/proto/cel/expr/explain.proto b/api/src/main/proto/cel/expr/explain.proto new file mode 100644 index 000000000..aa4ba940f --- /dev/null +++ b/api/src/main/proto/cel/expr/explain.proto @@ -0,0 +1,52 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package cel.expr; + +import "cel/expr/value.proto"; + +option cc_enable_arenas = true; +option go_package = "cel.dev/expr"; +option java_multiple_files = true; +option java_outer_classname = "ExplainProto"; +option java_package = "dev.cel.expr"; + +// Values of intermediate expressions produced when evaluating expression. +message Explain { + option deprecated = true; + + // ID and value index of one step. + message ExprStep { + // ID of corresponding Expr node. + int64 id = 1; + + // Index of the value in the values list. + int32 value_index = 2; + } + + // All of the observed values. + // + // The field value_index is an index in the values list. + // Separating values from steps is needed to remove redundant values. + repeated Value values = 1; + + // List of steps. + // + // Repeated evaluations of the same expression generate new ExprStep + // instances. The order of such ExprStep instances matches the order of + // elements returned by Comprehension.iter_range. + repeated ExprStep expr_steps = 2; +} diff --git a/api/src/main/proto/cel/expr/syntax.proto b/api/src/main/proto/cel/expr/syntax.proto new file mode 100644 index 000000000..ed124a743 --- /dev/null +++ b/api/src/main/proto/cel/expr/syntax.proto @@ -0,0 +1,393 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package cel.expr; + +import "google/protobuf/duration.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; + +option cc_enable_arenas = true; +option go_package = "cel.dev/expr"; +option java_multiple_files = true; +option java_outer_classname = "SyntaxProto"; +option java_package = "dev.cel.expr"; + +// A representation of the abstract syntax of the Common Expression Language. + +// An expression together with source information as returned by the parser. +message ParsedExpr { + // The parsed expression. + Expr expr = 2; + + // The source info derived from input that generated the parsed `expr`. + SourceInfo source_info = 3; +} + +// An abstract representation of a common expression. +// +// Expressions are abstractly represented as a collection of identifiers, +// select statements, function calls, literals, and comprehensions. All +// operators with the exception of the '.' operator are modelled as function +// calls. This makes it easy to represent new operators into the existing AST. +// +// All references within expressions must resolve to a +// [Decl][cel.expr.Decl] provided at type-check for an expression to be +// valid. A reference may either be a bare identifier `name` or a qualified +// identifier `google.api.name`. References may either refer to a value or a +// function declaration. +// +// For example, the expression `google.api.name.startsWith('expr')` references +// the declaration `google.api.name` within a +// [Expr.Select][cel.expr.Expr.Select] expression, and the function +// declaration `startsWith`. +message Expr { + // An identifier expression. e.g. `request`. + message Ident { + // Required. Holds a single, unqualified identifier, possibly preceded by a + // '.'. + // + // Qualified names are represented by the + // [Expr.Select][cel.expr.Expr.Select] expression. + string name = 1; + } + + // A field selection expression. e.g. `request.auth`. + message Select { + // Required. The target of the selection expression. + // + // For example, in the select expression `request.auth`, the `request` + // portion of the expression is the `operand`. + Expr operand = 1; + + // Required. The name of the field to select. + // + // For example, in the select expression `request.auth`, the `auth` portion + // of the expression would be the `field`. + string field = 2; + + // Whether the select is to be interpreted as a field presence test. + // + // This results from the macro `has(request.auth)`. + bool test_only = 3; + } + + // A call expression, including calls to predefined functions and operators. + // + // For example, `value == 10`, `size(map_value)`. + message Call { + // The target of an method call-style expression. For example, `x` in + // `x.f()`. + Expr target = 1; + + // Required. The name of the function or method being called. + string function = 2; + + // The arguments. + repeated Expr args = 3; + } + + // A list creation expression. + // + // Lists may either be homogenous, e.g. `[1, 2, 3]`, or heterogeneous, e.g. + // `dyn([1, 'hello', 2.0])` + message CreateList { + // The elements part of the list. + repeated Expr elements = 1; + + // The indices within the elements list which are marked as optional + // elements. + // + // When an optional-typed value is present, the value it contains + // is included in the list. If the optional-typed value is absent, the list + // element is omitted from the CreateList result. + repeated int32 optional_indices = 2; + } + + // A map or message creation expression. + // + // Maps are constructed as `{'key_name': 'value'}`. Message construction is + // similar, but prefixed with a type name and composed of field ids: + // `types.MyType{field_id: 'value'}`. + message CreateStruct { + // Represents an entry. + message Entry { + // Required. An id assigned to this node by the parser which is unique + // in a given expression tree. This is used to associate type + // information and other attributes to the node. + int64 id = 1; + + // The `Entry` key kinds. + oneof key_kind { + // The field key for a message creator statement. + string field_key = 2; + + // The key expression for a map creation statement. + Expr map_key = 3; + } + + // Required. The value assigned to the key. + // + // If the optional_entry field is true, the expression must resolve to an + // optional-typed value. If the optional value is present, the key will be + // set; however, if the optional value is absent, the key will be unset. + Expr value = 4; + + // Whether the key-value pair is optional. + bool optional_entry = 5; + } + + // The type name of the message to be created, empty when creating map + // literals. + string message_name = 1; + + // The entries in the creation expression. + repeated Entry entries = 2; + } + + // A comprehension expression applied to a list or map. + // + // Comprehensions are not part of the core syntax, but enabled with macros. + // A macro matches a specific call signature within a parsed AST and replaces + // the call with an alternate AST block. Macro expansion happens at parse + // time. + // + // The following macros are supported within CEL: + // + // Aggregate type macros may be applied to all elements in a list or all keys + // in a map: + // + // * `all`, `exists`, `exists_one` - test a predicate expression against + // the inputs and return `true` if the predicate is satisfied for all, + // any, or only one value `list.all(x, x < 10)`. + // * `filter` - test a predicate expression against the inputs and return + // the subset of elements which satisfy the predicate: + // `payments.filter(p, p > 1000)`. + // * `map` - apply an expression to all elements in the input and return the + // output aggregate type: `[1, 2, 3].map(i, i * i)`. + // + // The `has(m.x)` macro tests whether the property `x` is present in struct + // `m`. The semantics of this macro depend on the type of `m`. For proto2 + // messages `has(m.x)` is defined as 'defined, but not set`. For proto3, the + // macro tests whether the property is set to its default. For map and struct + // types, the macro tests whether the property `x` is defined on `m`. + // + // Comprehension evaluation can be best visualized as the following + // pseudocode: + // + // ``` + // let `accu_var` = `accu_init` + // for (let `iter_var` in `iter_range`) { + // if (!`loop_condition`) { + // break + // } + // `accu_var` = `loop_step` + // } + // return `result` + // ``` + message Comprehension { + // The name of the iteration variable. + string iter_var = 1; + + // The range over which var iterates. + Expr iter_range = 2; + + // The name of the variable used for accumulation of the result. + string accu_var = 3; + + // The initial value of the accumulator. + Expr accu_init = 4; + + // An expression which can contain iter_var and accu_var. + // + // Returns false when the result has been computed and may be used as + // a hint to short-circuit the remainder of the comprehension. + Expr loop_condition = 5; + + // An expression which can contain iter_var and accu_var. + // + // Computes the next value of accu_var. + Expr loop_step = 6; + + // An expression which can contain accu_var. + // + // Computes the result. + Expr result = 7; + } + + // Required. An id assigned to this node by the parser which is unique in a + // given expression tree. This is used to associate type information and other + // attributes to a node in the parse tree. + int64 id = 2; + + // Required. Variants of expressions. + oneof expr_kind { + // A constant expression. + Constant const_expr = 3; + + // An identifier expression. + Ident ident_expr = 4; + + // A field selection expression, e.g. `request.auth`. + Select select_expr = 5; + + // A call expression, including calls to predefined functions and operators. + Call call_expr = 6; + + // A list creation expression. + CreateList list_expr = 7; + + // A map or message creation expression. + CreateStruct struct_expr = 8; + + // A comprehension expression. + Comprehension comprehension_expr = 9; + } +} + +// Represents a primitive literal. +// +// Named 'Constant' here for backwards compatibility. +// +// This is similar as the primitives supported in the well-known type +// `google.protobuf.Value`, but richer so it can represent CEL's full range of +// primitives. +// +// Lists and structs are not included as constants as these aggregate types may +// contain [Expr][cel.expr.Expr] elements which require evaluation and +// are thus not constant. +// +// Examples of constants include: `"hello"`, `b'bytes'`, `1u`, `4.2`, `-2`, +// `true`, `null`. +message Constant { + // Required. The valid constant kinds. + oneof constant_kind { + // null value. + google.protobuf.NullValue null_value = 1; + + // boolean value. + bool bool_value = 2; + + // int64 value. + int64 int64_value = 3; + + // uint64 value. + uint64 uint64_value = 4; + + // double value. + double double_value = 5; + + // string value. + string string_value = 6; + + // bytes value. + bytes bytes_value = 7; + + // protobuf.Duration value. + // + // Deprecated: duration is no longer considered a builtin cel type. + google.protobuf.Duration duration_value = 8 [deprecated = true]; + + // protobuf.Timestamp value. + // + // Deprecated: timestamp is no longer considered a builtin cel type. + google.protobuf.Timestamp timestamp_value = 9 [deprecated = true]; + } +} + +// Source information collected at parse time. +message SourceInfo { + // The syntax version of the source, e.g. `cel1`. + string syntax_version = 1; + + // The location name. All position information attached to an expression is + // relative to this location. + // + // The location could be a file, UI element, or similar. For example, + // `acme/app/AnvilPolicy.cel`. + string location = 2; + + // Monotonically increasing list of code point offsets where newlines + // `\n` appear. + // + // The line number of a given position is the index `i` where for a given + // `id` the `line_offsets[i] < id_positions[id] < line_offsets[i+1]`. The + // column may be derived from `id_positions[id] - line_offsets[i]`. + repeated int32 line_offsets = 3; + + // A map from the parse node id (e.g. `Expr.id`) to the code point offset + // within the source. + map positions = 4; + + // A map from the parse node id where a macro replacement was made to the + // call `Expr` that resulted in a macro expansion. + // + // For example, `has(value.field)` is a function call that is replaced by a + // `test_only` field selection in the AST. Likewise, the call + // `list.exists(e, e > 10)` translates to a comprehension expression. The key + // in the map corresponds to the expression id of the expanded macro, and the + // value is the call `Expr` that was replaced. + map macro_calls = 5; + + // A list of tags for extensions that were used while parsing or type checking + // the source expression. For example, optimizations that require special + // runtime support may be specified. + // + // These are used to check feature support between components in separate + // implementations. This can be used to either skip redundant work or + // report an error if the extension is unsupported. + repeated Extension extensions = 6; + + // An extension that was requested for the source expression. + message Extension { + // Version + message Version { + // Major version changes indicate different required support level from + // the required components. + int64 major = 1; + // Minor version changes must not change the observed behavior from + // existing implementations, but may be provided informationally. + int64 minor = 2; + } + + // CEL component specifier. + enum Component { + // Unspecified, default. + COMPONENT_UNSPECIFIED = 0; + // Parser. Converts a CEL string to an AST. + COMPONENT_PARSER = 1; + // Type checker. Checks that references in an AST are defined and types + // agree. + COMPONENT_TYPE_CHECKER = 2; + // Runtime. Evaluates a parsed and optionally checked CEL AST against a + // context. + COMPONENT_RUNTIME = 3; + } + + // Identifier for the extension. Example: constant_folding + string id = 1; + + // If set, the listed components must understand the extension for the + // expression to evaluate correctly. + // + // This field has set semantics, repeated values should be deduplicated. + repeated Component affected_components = 2; + + // Version info. May be skipped if it isn't meaningful for the extension. + // (for example constant_folding might always be v0.0). + Version version = 3; + } +} diff --git a/api/src/main/proto/cel/expr/value.proto b/api/src/main/proto/cel/expr/value.proto new file mode 100644 index 000000000..8315c2c4b --- /dev/null +++ b/api/src/main/proto/cel/expr/value.proto @@ -0,0 +1,114 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package cel.expr; + +import "google/protobuf/any.proto"; +import "google/protobuf/struct.proto"; + +option cc_enable_arenas = true; +option go_package = "cel.dev/expr"; +option java_multiple_files = true; +option java_outer_classname = "ValueProto"; +option java_package = "dev.cel.expr"; + +// Contains representations for CEL runtime values. + +// Represents a CEL value. +// +// This is similar to `google.protobuf.Value`, but can represent CEL's full +// range of values. +message Value { + // Required. The valid kinds of values. + oneof kind { + // Null value. + google.protobuf.NullValue null_value = 1; + + // Boolean value. + bool bool_value = 2; + + // Signed integer value. + int64 int64_value = 3; + + // Unsigned integer value. + uint64 uint64_value = 4; + + // Floating point value. + double double_value = 5; + + // UTF-8 string value. + string string_value = 6; + + // Byte string value. + bytes bytes_value = 7; + + // An enum value. + EnumValue enum_value = 9; + + // The proto message backing an object value. + google.protobuf.Any object_value = 10; + + // Map value. + MapValue map_value = 11; + + // List value. + ListValue list_value = 12; + + // Type value. + string type_value = 15; + } +} + +// An enum value. +message EnumValue { + // The fully qualified name of the enum type. + string type = 1; + + // The value of the enum. + int32 value = 2; +} + +// A list. +// +// Wrapped in a message so 'not set' and empty can be differentiated, which is +// required for use in a 'oneof'. +message ListValue { + // The ordered values in the list. + repeated Value values = 1; +} + +// A map. +// +// Wrapped in a message so 'not set' and empty can be differentiated, which is +// required for use in a 'oneof'. +message MapValue { + message Entry { + // The key. + // + // Must be unique with in the map. + // Currently only boolean, int, uint, and string values can be keys. + Value key = 1; + + // The value. + Value value = 2; + } + + // The set of map entries. + // + // CEL has fewer restrictions on keys, so a protobuf map representation + // cannot be used. + repeated Entry entries = 1; +} diff --git a/api/src/main/proto/envoy/admin/v3/server_info.proto b/api/src/main/proto/envoy/admin/v3/server_info.proto index b623f7fea..58bbedf2e 100644 --- a/api/src/main/proto/envoy/admin/v3/server_info.proto +++ b/api/src/main/proto/envoy/admin/v3/server_info.proto @@ -59,7 +59,7 @@ message ServerInfo { config.core.v3.Node node = 7; } -// [#next-free-field: 39] +// [#next-free-field: 40] message CommandLineOptions { option (udpa.annotations.versioning).previous_message_type = "envoy.admin.v2alpha.CommandLineOptions"; @@ -98,6 +98,9 @@ message CommandLineOptions { // See :option:`--use-dynamic-base-id` for details. bool use_dynamic_base_id = 31; + // See :option:`--skip-hot-restart-on-no-parent` for details. + bool skip_hot_restart_on_no_parent = 39; + // See :option:`--base-id-path` for details. string base_id_path = 32; diff --git a/api/src/main/proto/envoy/config/accesslog/v3/accesslog.proto b/api/src/main/proto/envoy/config/accesslog/v3/accesslog.proto index fe3ba2bc9..5599f8082 100644 --- a/api/src/main/proto/envoy/config/accesslog/v3/accesslog.proto +++ b/api/src/main/proto/envoy/config/accesslog/v3/accesslog.proto @@ -256,6 +256,7 @@ message ResponseFlagFilter { in: "OM" in: "DF" in: "DO" + in: "DR" } } }]; diff --git a/api/src/main/proto/envoy/config/cluster/v3/cluster.proto b/api/src/main/proto/envoy/config/cluster/v3/cluster.proto index 9b847a331..775f37d92 100644 --- a/api/src/main/proto/envoy/config/cluster/v3/cluster.proto +++ b/api/src/main/proto/envoy/config/cluster/v3/cluster.proto @@ -1236,6 +1236,26 @@ message UpstreamConnectionOptions { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.UpstreamConnectionOptions"; + enum FirstAddressFamilyVersion { + // respect the native ranking of destination ip addresses returned from dns + // resolution + DEFAULT = 0; + + V4 = 1; + + V6 = 2; + } + + message HappyEyeballsConfig { + // Specify the IP address family to attempt connection first in happy + // eyeballs algorithm according to RFC8305#section-4. + FirstAddressFamilyVersion first_address_family_version = 1; + + // Specify the number of addresses of the first_address_family_version being + // attempted for connection before the other address family. + google.protobuf.UInt32Value first_address_family_count = 2 [(validate.rules).uint32 = {gte: 1}]; + } + // If set then set SO_KEEPALIVE on the socket to enable TCP Keepalives. core.v3.TcpKeepalive tcp_keepalive = 1; @@ -1243,6 +1263,11 @@ message UpstreamConnectionOptions { // This can be used by extensions during processing of requests. The association mechanism is // implementation specific. Defaults to false due to performance concerns. bool set_local_interface_name_on_upstream_connections = 2; + + // Configurations for happy eyeballs algorithm. + // Add configs for first_address_family_version and first_address_family_count + // when sorting destination ip addresses. + HappyEyeballsConfig happy_eyeballs_config = 3; } message TrackClusterStats { diff --git a/api/src/main/proto/envoy/config/cluster/v3/outlier_detection.proto b/api/src/main/proto/envoy/config/cluster/v3/outlier_detection.proto index 11289e26b..622486e41 100644 --- a/api/src/main/proto/envoy/config/cluster/v3/outlier_detection.proto +++ b/api/src/main/proto/envoy/config/cluster/v3/outlier_detection.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package envoy.config.cluster.v3; +import "envoy/config/core/v3/extension.proto"; + import "google/protobuf/duration.proto"; import "google/protobuf/wrappers.proto"; @@ -19,7 +21,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // See the :ref:`architecture overview ` for // more information on outlier detection. -// [#next-free-field: 24] +// [#next-free-field: 25] message OutlierDetection { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.cluster.OutlierDetection"; @@ -167,4 +169,8 @@ message OutlierDetection { // To change this default behavior set this config to ``false`` where active health checking will not uneject the host. // Defaults to true. google.protobuf.BoolValue successful_active_health_check_uneject_host = 23; + + // Set of host's passive monitors. + // [#not-implemented-hide:] + repeated core.v3.TypedExtensionConfig monitors = 24; } diff --git a/api/src/main/proto/envoy/config/core/v3/base.proto b/api/src/main/proto/envoy/config/core/v3/base.proto index 97131e4b8..b5897721f 100644 --- a/api/src/main/proto/envoy/config/core/v3/base.proto +++ b/api/src/main/proto/envoy/config/core/v3/base.proto @@ -245,7 +245,8 @@ message Metadata { // :ref:`typed_filter_metadata ` // fields are present in the metadata with same keys, // only ``typed_filter_metadata`` field will be parsed. - map filter_metadata = 1; + map filter_metadata = 1 + [(validate.rules).map = {keys {string {min_len: 1}}}]; // Key is the reverse DNS filter name, e.g. com.acme.widget. The ``envoy.*`` // namespace is reserved for Envoy's built-in filters. @@ -253,7 +254,8 @@ message Metadata { // If both :ref:`filter_metadata ` // and ``typed_filter_metadata`` fields are present in the metadata with same keys, // only ``typed_filter_metadata`` field will be parsed. - map typed_filter_metadata = 2; + map typed_filter_metadata = 2 + [(validate.rules).map = {keys {string {min_len: 1}}}]; } // Runtime derived uint32 with a default when not specified. @@ -430,9 +432,28 @@ message DataSource { } // The message specifies the retry policy of remote data source when fetching fails. +// [#next-free-field: 7] message RetryPolicy { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.core.RetryPolicy"; + // See :ref:`RetryPriority `. + message RetryPriority { + string name = 1 [(validate.rules).string = {min_len: 1}]; + + oneof config_type { + google.protobuf.Any typed_config = 2; + } + } + + // See :ref:`RetryHostPredicate `. + message RetryHostPredicate { + string name = 1 [(validate.rules).string = {min_len: 1}]; + + oneof config_type { + google.protobuf.Any typed_config = 2; + } + } + // 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. @@ -442,6 +463,18 @@ message RetryPolicy { // defaults to 1. google.protobuf.UInt32Value num_retries = 2 [(udpa.annotations.field_migrate).rename = "max_retries"]; + + // For details, see :ref:`retry_on `. + string retry_on = 3; + + // For details, see :ref:`retry_priority `. + RetryPriority retry_priority = 4; + + // For details, see :ref:`RetryHostPredicate `. + repeated RetryHostPredicate retry_host_predicate = 5; + + // For details, see :ref:`host_selection_retry_max_attempts `. + int64 host_selection_retry_max_attempts = 6; } // The message specifies how to fetch data from remote and how to verify it. diff --git a/api/src/main/proto/envoy/config/core/v3/grpc_service.proto b/api/src/main/proto/envoy/config/core/v3/grpc_service.proto index f266c7bce..471f9165b 100644 --- a/api/src/main/proto/envoy/config/core/v3/grpc_service.proto +++ b/api/src/main/proto/envoy/config/core/v3/grpc_service.proto @@ -25,7 +25,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // gRPC service configuration. This is used by :ref:`ApiConfigSource // ` and filter configurations. -// [#next-free-field: 6] +// [#next-free-field: 7] message GrpcService { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.core.GrpcService"; @@ -49,6 +49,12 @@ message GrpcService { // Currently only supported for xDS gRPC streams. // If not set, xDS gRPC streams default base interval:500ms, maximum interval:30s will be applied. RetryPolicy retry_policy = 3; + + // Maximum gRPC message size that is allowed to be received. + // If a message over this limit is received, the gRPC stream is terminated with the RESOURCE_EXHAUSTED error. + // This limit is applied to individual messages in the streaming response and not the total size of streaming response. + // Defaults to 0, which means unlimited. + google.protobuf.UInt32Value max_receive_message_length = 4; } // [#next-free-field: 9] @@ -300,4 +306,8 @@ message GrpcService { // documentation on :ref:`custom request headers // `. repeated HeaderValue initial_metadata = 5; + + // Optional default retry policy for streams toward the service. + // If an async stream doesn't have retry policy configured in its stream options, this retry policy is used. + RetryPolicy retry_policy = 6; } diff --git a/api/src/main/proto/envoy/config/core/v3/health_check.proto b/api/src/main/proto/envoy/config/core/v3/health_check.proto index 2ec258d8a..41cde41af 100644 --- a/api/src/main/proto/envoy/config/core/v3/health_check.proto +++ b/api/src/main/proto/envoy/config/core/v3/health_check.proto @@ -62,7 +62,7 @@ message HealthStatusSet { [(validate.rules).repeated = {items {enum {defined_only: true}}}]; } -// [#next-free-field: 26] +// [#next-free-field: 27] message HealthCheck { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.core.HealthCheck"; @@ -95,12 +95,11 @@ message HealthCheck { // left empty (default value), the name of the cluster this health check is associated // with will be used. The host header can be customized for a specific endpoint by setting the // :ref:`hostname ` field. - string host = 1 [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}]; + string host = 1 [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE}]; // Specifies the HTTP path that will be requested during health checking. For example // ``/healthcheck``. - string path = 2 - [(validate.rules).string = {min_len: 1 well_known_regex: HTTP_HEADER_VALUE strict: false}]; + string path = 2 [(validate.rules).string = {min_len: 1 well_known_regex: HTTP_HEADER_VALUE}]; // [#not-implemented-hide:] HTTP specific payload. Payload send = 3; @@ -392,6 +391,11 @@ message HealthCheck { // The default value is false. bool always_log_health_check_failures = 19; + // If set to true, health check success events will always be logged. If set to false, only host addition event will be logged + // if it is the first successful health check, or if the healthy threshold is reached. + // The default value is false. + bool always_log_health_check_success = 26; + // This allows overriding the cluster TLS settings, just for health check connections. TlsOptions tls_options = 21; diff --git a/api/src/main/proto/envoy/config/core/v3/protocol.proto b/api/src/main/proto/envoy/config/core/v3/protocol.proto index d128dc6d9..70af4851b 100644 --- a/api/src/main/proto/envoy/config/core/v3/protocol.proto +++ b/api/src/main/proto/envoy/config/core/v3/protocol.proto @@ -56,7 +56,7 @@ message QuicKeepAliveSettings { } // QUIC protocol options which apply to both downstream and upstream connections. -// [#next-free-field: 8] +// [#next-free-field: 9] message QuicProtocolOptions { // Maximum number of streams that the client can negotiate per connection. 100 // if not specified. @@ -64,7 +64,7 @@ message QuicProtocolOptions { // `Initial stream-level flow-control receive window // `_ size. Valid values range from - // 1 to 16777216 (2^24, maximum supported by QUICHE) and defaults to 65536 (2^16). + // 1 to 16777216 (2^24, maximum supported by QUICHE) and defaults to 16777216 (16 * 1024 * 1024). // // NOTE: 16384 (2^14) is the minimum window size supported in Google QUIC. If configured smaller than it, we will use 16384 instead. // QUICHE IETF Quic implementation supports 1 bytes window. We only support increasing the default window size now, so it's also the minimum. @@ -76,8 +76,8 @@ message QuicProtocolOptions { [(validate.rules).uint32 = {lte: 16777216 gte: 1}]; // Similar to ``initial_stream_window_size``, but for connection-level - // flow-control. Valid values rage from 1 to 25165824 (24MB, maximum supported by QUICHE) and defaults to 65536 (2^16). - // window. Currently, this has the same minimum/default as ``initial_stream_window_size``. + // flow-control. Valid values rage from 1 to 25165824 (24MB, maximum supported by QUICHE) and defaults + // to 25165824 (24 * 1024 * 1024). // // NOTE: 16384 (2^14) is the minimum window size supported in Google QUIC. We only support increasing the default // window size now, so it's also the minimum. @@ -102,6 +102,15 @@ message QuicProtocolOptions { // A comma-separated list of strings representing QUIC client connection options defined in // `QUICHE `_ and to be sent by upstream connections. string client_connection_options = 7; + + // The duration that a QUIC connection stays idle before it closes itself. If this field is not present, QUICHE + // default 600s will be applied. + // For internal corporate network, a long timeout is often fine. + // But for client facing network, 30s is usually a good choice. + google.protobuf.Duration idle_network_timeout = 8 [(validate.rules).duration = { + lte {seconds: 600} + gte {seconds: 1} + }]; } message UpstreamHttpProtocolOptions { @@ -477,10 +486,10 @@ message Http2ProtocolOptions { // Allows proxying Websocket and other upgrades over H2 connect. bool allow_connect = 5; - // [#not-implemented-hide:] Hiding until envoy has full metadata support. + // [#not-implemented-hide:] Hiding until Envoy has full metadata support. // Still under implementation. DO NOT USE. // - // Allows metadata. See [metadata + // Allows sending and receiving HTTP/2 METADATA frames. See [metadata // docs](https://github.com/envoyproxy/envoy/blob/main/source/docs/h2_metadata.md) for more // information. bool allow_metadata = 6; @@ -609,7 +618,7 @@ message GrpcProtocolOptions { } // A message which allows using HTTP/3. -// [#next-free-field: 6] +// [#next-free-field: 7] message Http3ProtocolOptions { QuicProtocolOptions quic_protocol_options = 1; @@ -628,6 +637,14 @@ message Http3ProtocolOptions { // `_ // Note that HTTP/3 CONNECT is not yet an RFC. bool allow_extended_connect = 5 [(xds.annotations.v3.field_status).work_in_progress = true]; + + // [#not-implemented-hide:] Hiding until Envoy has full metadata support. + // Still under implementation. DO NOT USE. + // + // Allows sending and receiving HTTP/3 METADATA frames. See [metadata + // docs](https://github.com/envoyproxy/envoy/blob/main/source/docs/h2_metadata.md) for more + // information. + bool allow_metadata = 6; } // A message to control transformations to the :scheme header diff --git a/api/src/main/proto/envoy/config/listener/v3/quic_config.proto b/api/src/main/proto/envoy/config/listener/v3/quic_config.proto index 3a8ce2cd0..bd6327d41 100644 --- a/api/src/main/proto/envoy/config/listener/v3/quic_config.proto +++ b/api/src/main/proto/envoy/config/listener/v3/quic_config.proto @@ -24,7 +24,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: QUIC listener config] // Configuration specific to the UDP QUIC listener. -// [#next-free-field: 10] +// [#next-free-field: 11] message QuicProtocolOptions { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.listener.QuicProtocolOptions"; @@ -72,9 +72,13 @@ message QuicProtocolOptions { core.v3.TypedExtensionConfig connection_id_generator_config = 8; // Configure the server's preferred address to advertise so that client can migrate to it. See :ref:`example ` which configures a pair of v4 and v6 preferred addresses. - // The current QUICHE implementation will advertise only one of the preferred IPv4 and IPv6 addresses based on the address family the client initially connects with, and only if the client is also QUICHE-based. + // The current QUICHE implementation will advertise only one of the preferred IPv4 and IPv6 addresses based on the address family the client initially connects with. // If not specified, Envoy will not advertise any server's preferred address. // [#extension-category: envoy.quic.server_preferred_address] core.v3.TypedExtensionConfig server_preferred_address_config = 9 [(xds.annotations.v3.field_status).work_in_progress = true]; + + // Configure the server to send transport parameter `disable_active_migration `_. + // Defaults to false (do not send this transport parameter). + google.protobuf.BoolValue send_disable_active_migration = 10; } diff --git a/api/src/main/proto/envoy/config/rbac/v3/rbac.proto b/api/src/main/proto/envoy/config/rbac/v3/rbac.proto index 3a9271c00..8d98fd715 100644 --- a/api/src/main/proto/envoy/config/rbac/v3/rbac.proto +++ b/api/src/main/proto/envoy/config/rbac/v3/rbac.proto @@ -194,7 +194,7 @@ message Policy { } // Permission defines an action (or actions) that a principal can take. -// [#next-free-field: 13] +// [#next-free-field: 14] message Permission { option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Permission"; @@ -270,6 +270,10 @@ message Permission { // Extension for configuring custom matchers for RBAC. // [#extension-category: envoy.rbac.matchers] core.v3.TypedExtensionConfig matcher = 12; + + // URI template path matching. + // [#extension-category: envoy.path.match] + core.v3.TypedExtensionConfig uri_template = 13; } } diff --git a/api/src/main/proto/envoy/config/route/v3/route_components.proto b/api/src/main/proto/envoy/config/route/v3/route_components.proto index 1e2b486d2..69d3e8a5e 100644 --- a/api/src/main/proto/envoy/config/route/v3/route_components.proto +++ b/api/src/main/proto/envoy/config/route/v3/route_components.proto @@ -673,7 +673,7 @@ message RouteMatch { // :ref:`CorsPolicy in filter extension ` // as as alternative. // -// [#next-free-field: 13] +// [#next-free-field: 14] message CorsPolicy { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.CorsPolicy"; @@ -727,6 +727,10 @@ message CorsPolicy { // // More details refer to https://developer.chrome.com/blog/private-network-access-preflight. google.protobuf.BoolValue allow_private_network_access = 12; + + // Specifies if preflight requests not matching the configured allowed origin should be forwarded + // to the upstream. Default is true. + google.protobuf.BoolValue forward_not_matching_preflights = 13; } // [#next-free-field: 42] @@ -1211,7 +1215,6 @@ message RouteAction { // :ref:`host_rewrite_path_regex `) // causes the original value of the host header, if any, to be appended to the // :ref:`config_http_conn_man_headers_x-forwarded-host` HTTP header if it is different to the last value appended. - // This can be disabled by setting the runtime guard ``envoy_reloadable_features_append_xfh_idempotent`` to false. bool append_x_forwarded_host = 38; // Specifies the upstream timeout for the route. If not specified, the default is 15s. This diff --git a/api/src/main/proto/envoy/config/trace/v3/dynamic_ot.proto b/api/src/main/proto/envoy/config/trace/v3/dynamic_ot.proto index 35971f30d..d2664ef71 100644 --- a/api/src/main/proto/envoy/config/trace/v3/dynamic_ot.proto +++ b/api/src/main/proto/envoy/config/trace/v3/dynamic_ot.proto @@ -33,11 +33,15 @@ message DynamicOtConfig { string library = 1 [ deprecated = true, (validate.rules).string = {min_len: 1}, - (envoy.annotations.deprecated_at_minor_version) = "3.0" + (envoy.annotations.deprecated_at_minor_version) = "3.0", + (envoy.annotations.disallowed_by_default) = true ]; // The configuration to use when creating a tracer from the given dynamic // library. - google.protobuf.Struct config = 2 - [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; + google.protobuf.Struct config = 2 [ + deprecated = true, + (envoy.annotations.deprecated_at_minor_version) = "3.0", + (envoy.annotations.disallowed_by_default) = true + ]; } diff --git a/api/src/main/proto/envoy/config/trace/v3/zipkin.proto b/api/src/main/proto/envoy/config/trace/v3/zipkin.proto index a9aefef0c..2d8f3195c 100644 --- a/api/src/main/proto/envoy/config/trace/v3/zipkin.proto +++ b/api/src/main/proto/envoy/config/trace/v3/zipkin.proto @@ -82,5 +82,10 @@ message ZipkinConfig { // If this is set to true, then the // :ref:`start_child_span of router ` // SHOULD be set to true also to ensure the correctness of trace chain. - bool split_spans_for_request = 7; + // + // Both this field and ``start_child_span`` are deprecated by the + // :ref:`spawn_upstream_span `. + // Please use that ``spawn_upstream_span`` field to control the span creation. + bool split_spans_for_request = 7 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; } diff --git a/api/src/main/proto/envoy/data/accesslog/v3/accesslog.proto b/api/src/main/proto/envoy/data/accesslog/v3/accesslog.proto index a247c08df..2e02f1eb4 100644 --- a/api/src/main/proto/envoy/data/accesslog/v3/accesslog.proto +++ b/api/src/main/proto/envoy/data/accesslog/v3/accesslog.proto @@ -271,7 +271,7 @@ message AccessLogCommon { } // Flags indicating occurrences during request/response processing. -// [#next-free-field: 28] +// [#next-free-field: 29] message ResponseFlags { option (udpa.annotations.versioning).previous_message_type = "envoy.data.accesslog.v2.ResponseFlags"; @@ -372,6 +372,9 @@ message ResponseFlags { // Indicates a DNS resolution failed. bool dns_resolution_failure = 27; + + // Indicates a downstream remote codec level reset was received on the stream + bool downstream_remote_reset = 28; } // Properties of a negotiated TLS connection. diff --git a/api/src/main/proto/envoy/data/core/v3/health_check_event.proto b/api/src/main/proto/envoy/data/core/v3/health_check_event.proto index 17e78ea5e..2f8c32d92 100644 --- a/api/src/main/proto/envoy/data/core/v3/health_check_event.proto +++ b/api/src/main/proto/envoy/data/core/v3/health_check_event.proto @@ -35,7 +35,7 @@ enum HealthCheckerType { THRIFT = 4; } -// [#next-free-field: 12] +// [#next-free-field: 13] message HealthCheckEvent { option (udpa.annotations.versioning).previous_message_type = "envoy.data.core.v2alpha.HealthCheckEvent"; @@ -55,6 +55,12 @@ message HealthCheckEvent { // Host addition. HealthCheckAddHealthy add_healthy_event = 5; + // A health check was successful. Note: a host will be considered healthy either if it is + // the first ever health check, or if the healthy threshold is reached. This kind of event + // indicate that a health check was successful, but does not indicates that the host is + // considered healthy. A host is considered healthy if HealthCheckAddHealthy kind of event is sent. + HealthCheckSuccessful successful_health_check_event = 12; + // Host failure. HealthCheckFailure health_check_failure_event = 7; @@ -93,6 +99,9 @@ message HealthCheckAddHealthy { bool first_check = 1; } +message HealthCheckSuccessful { +} + message HealthCheckFailure { option (udpa.annotations.versioning).previous_message_type = "envoy.data.core.v2alpha.HealthCheckFailure"; diff --git a/api/src/main/proto/envoy/extensions/access_loggers/fluentd/v3/fluentd.proto b/api/src/main/proto/envoy/extensions/access_loggers/fluentd/v3/fluentd.proto new file mode 100644 index 000000000..dab04fb59 --- /dev/null +++ b/api/src/main/proto/envoy/extensions/access_loggers/fluentd/v3/fluentd.proto @@ -0,0 +1,94 @@ +syntax = "proto3"; + +package envoy.extensions.access_loggers.fluentd.v3; + +import "envoy/config/core/v3/backoff.proto"; +import "envoy/config/core/v3/extension.proto"; + +import "google/protobuf/duration.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/wrappers.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.access_loggers.fluentd.v3"; +option java_outer_classname = "FluentdProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/access_loggers/fluentd/v3;fluentdv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Fluentd access log] + +// Configuration for the *envoy.access_loggers.fluentd* :ref:`AccessLog `. +// This access log extension will send the emitted access logs over a TCP connection to an upstream that is accepting +// the Fluentd Forward Protocol as described in: `Fluentd Forward Protocol Specification +// `_. +// [#extension: envoy.access_loggers.fluentd] +// [#next-free-field: 9] +message FluentdAccessLogConfig { + message RetryOptions { + // The number of times the logger will attempt to connect to the upstream during reconnects. + // By default, there is no limit. The logger will attempt to reconnect to the upstream each time + // connecting to the upstream failed or the upstream connection had been closed for any reason. + google.protobuf.UInt32Value max_connect_attempts = 1; + + // Sets the backoff strategy. If this value is not set, the default base backoff interval is 500 + // milliseconds and the default max backoff interval is 5 seconds (10 times the base interval). + config.core.v3.BackoffStrategy backoff_options = 2; + } + + // The upstream cluster to connect to for streaming the Fluentd messages. + string cluster = 1 [(validate.rules).string = {min_len: 1}]; + + // A tag is a string separated with '.' (e.g. log.type) to categorize events. + // See: https://github.com/fluent/fluentd/wiki/Forward-Protocol-Specification-v1#message-modes + string tag = 2 [(validate.rules).string = {min_len: 1}]; + + // The prefix to use when emitting :ref:`statistics `. + string stat_prefix = 3 [(validate.rules).string = {min_len: 1}]; + + // Interval for flushing access logs to the TCP stream. Logger will flush requests every time + // this interval is elapsed, or when batch size limit is hit, whichever comes first. Defaults to + // 1 second. + google.protobuf.Duration buffer_flush_interval = 4 [(validate.rules).duration = {gt {}}]; + + // Soft size limit in bytes for access log entries buffer. The logger will buffer requests until + // this limit it hit, or every time flush interval is elapsed, whichever comes first. When the buffer + // limit is hit, the logger will immediately flush the buffer contents. Setting it to zero effectively + // disables the batching. Defaults to 16384. + google.protobuf.UInt32Value buffer_size_bytes = 5; + + // A struct that represents the record that is sent for each log entry. + // https://github.com/fluent/fluentd/wiki/Forward-Protocol-Specification-v1#entry + // Values are rendered as strings, numbers, or boolean values as appropriate. + // Nested JSON objects may be produced by some command operators (e.g. FILTER_STATE or DYNAMIC_METADATA). + // See :ref:`format string` documentation for a specific command operator details. + // + // .. validated-code-block:: yaml + // :type-name: envoy.extensions.access_loggers.fluentd.v3.FluentdAccessLogConfig + // + // record: + // status: "%RESPONSE_CODE%" + // message: "%LOCAL_REPLY_BODY%" + // + // The following msgpack record would be created: + // + // .. code-block:: json + // + // { + // "status": 500, + // "message": "My error message" + // } + google.protobuf.Struct record = 6 [(validate.rules).message = {required: true}]; + + // Optional retry, in case upstream connection has failed. If this field is not set, the default values will be applied, + // as specified in the :ref:`RetryOptions ` + // configuration. + RetryOptions retry_options = 7; + + // Specifies a collection of Formatter plugins that can be called from the access log configuration. + // See the formatters extensions documentation for details. + // [#extension-category: envoy.formatter] + repeated config.core.v3.TypedExtensionConfig formatters = 8; +} diff --git a/api/src/main/proto/envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.proto b/api/src/main/proto/envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.proto index d8f9b717f..eae3b8f74 100644 --- a/api/src/main/proto/envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.proto +++ b/api/src/main/proto/envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.proto @@ -67,9 +67,9 @@ message DnsCacheConfig { // The minimum rate that DNS resolution will occur. Per ``dns_refresh_rate``, once a host is // resolved, the DNS TTL will be used, with a minimum set by ``dns_min_refresh_rate``. - // ``dns_min_refresh_rate`` defaults to 5s and must also be >= 5s. + // ``dns_min_refresh_rate`` defaults to 5s and must also be >= 1s. google.protobuf.Duration dns_min_refresh_rate = 14 - [(validate.rules).duration = {gte {seconds: 5}}]; + [(validate.rules).duration = {gte {seconds: 1}}]; // The TTL for hosts that are unused. Hosts that have not been used in the configured time // interval will be purged. If not specified defaults to 5m. diff --git a/api/src/main/proto/envoy/extensions/filters/http/aws_lambda/v3/aws_lambda.proto b/api/src/main/proto/envoy/extensions/filters/http/aws_lambda/v3/aws_lambda.proto index 5268550c0..b5d7e2a27 100644 --- a/api/src/main/proto/envoy/extensions/filters/http/aws_lambda/v3/aws_lambda.proto +++ b/api/src/main/proto/envoy/extensions/filters/http/aws_lambda/v3/aws_lambda.proto @@ -17,6 +17,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#extension: envoy.filters.http.aws_lambda] // AWS Lambda filter config +// [#next-free-field: 6] message Config { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.aws_lambda.v2alpha.Config"; @@ -42,6 +43,25 @@ message Config { // Determines the way to invoke the Lambda function. InvocationMode invocation_mode = 3 [(validate.rules).enum = {defined_only: true}]; + + // Indicates that before signing headers, the host header will be swapped with + // this value. If not set or empty, the original host header value + // will be used and no rewrite will happen. + // + // Note: this rewrite affects both signing and host header forwarding. However, this + // option shouldn't be used with + // :ref:`HCM host rewrite ` given that the + // value set here would be used for signing whereas the value set in the HCM would be used + // for host header forwarding which is not the desired outcome. + // Changing the value of the host header can result in a different route to be selected + // if an HTTP filter after AWS lambda re-evaluates the route (clears route cache). + string host_rewrite = 4; + + // Specifies the credentials profile to be used from the AWS credentials file. + // This parameter is optional. If set, it will override the value set in the AWS_PROFILE env variable and + // the provider chain is limited to the AWS credentials file Provider. + // Other providers are ignored + string credentials_profile = 5; } // Per-route configuration for AWS Lambda. This can be useful when invoking a different Lambda function or a different diff --git a/api/src/main/proto/envoy/extensions/filters/http/aws_request_signing/v3/aws_request_signing.proto b/api/src/main/proto/envoy/extensions/filters/http/aws_request_signing/v3/aws_request_signing.proto index 05ea85e2a..5729d7f50 100644 --- a/api/src/main/proto/envoy/extensions/filters/http/aws_request_signing/v3/aws_request_signing.proto +++ b/api/src/main/proto/envoy/extensions/filters/http/aws_request_signing/v3/aws_request_signing.proto @@ -4,6 +4,8 @@ package envoy.extensions.filters.http.aws_request_signing.v3; import "envoy/type/matcher/v3/string.proto"; +import "google/protobuf/duration.proto"; + import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; import "validate/validate.proto"; @@ -19,7 +21,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#extension: envoy.filters.http.aws_request_signing] // Top level configuration for the AWS request signing filter. -// [#next-free-field: 7] +// [#next-free-field: 8] message AwsRequestSigning { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.aws_request_signing.v2alpha.AwsRequestSigning"; @@ -32,6 +34,16 @@ message AwsRequestSigning { AWS_SIGV4A = 1; } + message QueryString { + // Optional expiration time for the query string parameters. As query string parameter based requests are replayable, in effect representing + // an API call that has already been authenticated, it is recommended to keep this expiration time as short as feasible. + // This value will default to 5 seconds and has a maximum value of 3600 seconds (1 hour). + google.protobuf.Duration expiration_time = 1 [(validate.rules).duration = { + lte {seconds: 3600} + gte {seconds: 1} + }]; + } + // The `service namespace // `_ // of the HTTP endpoint. @@ -39,6 +51,9 @@ message AwsRequestSigning { // Example: s3 string service_name = 1 [(validate.rules).string = {min_len: 1}]; + // Optional region string. If region is not provided, the region will be retrieved from the environment + // or AWS configuration files. See :ref:`config_http_filters_aws_request_signing_region` for more details. + // // When signing_algorithm is set to ``AWS_SIGV4`` the region is a standard AWS `region `_ string for the service // hosting the HTTP endpoint. // @@ -51,9 +66,9 @@ message AwsRequestSigning { // // Example: '*' // - // By configuring a region set, a sigv4a signed request can be sent to multiple regions, rather than being + // By configuring a region set, a SigV4A signed request can be sent to multiple regions, rather than being // valid for only a single region destination. - string region = 2 [(validate.rules).string = {min_len: 1}]; + string region = 2; // Indicates that before signing headers, the host header will be swapped with // this value. If not set or empty, the original host header value @@ -84,6 +99,14 @@ message AwsRequestSigning { // Optional Signing algorithm specifier, either ``AWS_SIGV4`` or ``AWS_SIGV4A``, defaulting to ``AWS_SIGV4``. SigningAlgorithm signing_algorithm = 6; + + // If set, use the query string to store output of SigV4 or SigV4A calculation, rather than HTTP headers. The ``Authorization`` header will not be modified if ``query_string`` + // is configured. + // + // Example: + // query_string: {} + // + QueryString query_string = 7; } message AwsRequestSigningPerRoute { diff --git a/api/src/main/proto/envoy/extensions/filters/http/basic_auth/v3/basic_auth.proto b/api/src/main/proto/envoy/extensions/filters/http/basic_auth/v3/basic_auth.proto index df23868a4..995d2c3bc 100644 --- a/api/src/main/proto/envoy/extensions/filters/http/basic_auth/v3/basic_auth.proto +++ b/api/src/main/proto/envoy/extensions/filters/http/basic_auth/v3/basic_auth.proto @@ -6,6 +6,7 @@ import "envoy/config/core/v3/base.proto"; import "udpa/annotations/sensitive.proto"; import "udpa/annotations/status.proto"; +import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.filters.http.basic_auth.v3"; option java_outer_classname = "BasicAuthProto"; @@ -33,4 +34,19 @@ message BasicAuth { // The value needs to be the htpasswd format. // Reference to https://httpd.apache.org/docs/2.4/programs/htpasswd.html config.core.v3.DataSource users = 1 [(udpa.annotations.sensitive) = true]; + + // This field specifies the header name to forward a successfully authenticated user to + // the backend. The header will be added to the request with the username as the value. + // + // If it is not specified, the username will not be forwarded. + string forward_username_header = 2 + [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME strict: false}]; +} + +// Extra settings that may be added to per-route configuration for +// a virtual host or a cluster. +message BasicAuthPerRoute { + // Username-password pairs for this route. + config.core.v3.DataSource users = 1 + [(validate.rules).message = {required: true}, (udpa.annotations.sensitive) = true]; } diff --git a/api/src/main/proto/envoy/extensions/filters/http/composite/v3/composite.proto b/api/src/main/proto/envoy/extensions/filters/http/composite/v3/composite.proto index a6132b704..8ea4f2a43 100644 --- a/api/src/main/proto/envoy/extensions/filters/http/composite/v3/composite.proto +++ b/api/src/main/proto/envoy/extensions/filters/http/composite/v3/composite.proto @@ -53,8 +53,7 @@ message ExecuteFilterAction { config.core.v3.TypedExtensionConfig typed_config = 1 [(udpa.annotations.field_migrate).oneof_promotion = "config_type"]; - // Dynamic configuration of filter obtained via extension configuration discovery - // service. + // Dynamic configuration of filter obtained via extension configuration discovery service. // Only one of ``typed_config`` or ``dynamic_config`` can be set. DynamicConfig dynamic_config = 2 [(udpa.annotations.field_migrate).oneof_promotion = "config_type"]; diff --git a/api/src/main/proto/envoy/extensions/filters/http/cors/v3/cors.proto b/api/src/main/proto/envoy/extensions/filters/http/cors/v3/cors.proto index 7e49dc8e6..11ce91015 100644 --- a/api/src/main/proto/envoy/extensions/filters/http/cors/v3/cors.proto +++ b/api/src/main/proto/envoy/extensions/filters/http/cors/v3/cors.proto @@ -33,7 +33,7 @@ message Cors { // Per route configuration for the CORS filter. This configuration should be configured in the ``RouteConfiguration`` as ``typed_per_filter_config`` at some level to // make the filter work. -// [#next-free-field: 10] +// [#next-free-field: 11] message CorsPolicy { // Specifies string patterns that match allowed origins. An origin is allowed if any of the // string matchers match. @@ -79,4 +79,8 @@ message CorsPolicy { // // More details refer to https://developer.chrome.com/blog/private-network-access-preflight. google.protobuf.BoolValue allow_private_network_access = 9; + + // Specifies if preflight requests not matching the configured allowed origin should be forwarded + // to the upstream. Default is true. + google.protobuf.BoolValue forward_not_matching_preflights = 10; } diff --git a/api/src/main/proto/envoy/extensions/filters/http/credential_injector/v3/credential_injector.proto b/api/src/main/proto/envoy/extensions/filters/http/credential_injector/v3/credential_injector.proto index efa16d3ac..5dc8e82b5 100644 --- a/api/src/main/proto/envoy/extensions/filters/http/credential_injector/v3/credential_injector.proto +++ b/api/src/main/proto/envoy/extensions/filters/http/credential_injector/v3/credential_injector.proto @@ -17,7 +17,6 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; option (xds.annotations.v3.file_status).work_in_progress = true; // [#protodoc-title: Credential Injector] -// [#not-implemented-hide:] // Credential Injector :ref:`configuration overview `. // [#extension: envoy.filters.http.credential_injector] @@ -25,7 +24,8 @@ option (xds.annotations.v3.file_status).work_in_progress = true; // they can be requested through the OAuth2 client credential grant. The credentials obtained are then injected into the Authorization header // of the proxied HTTP requests, utilizing either the Basic or Bearer scheme. // -// If the credential is not present, the request will fail with 401 Unauthorized if fail_if_not_present is set to true. +// If the credential is not present or there was a failure injecting the credential, the request will fail with ``401 Unauthorized`` unless +// ``allow_request_without_credential`` is set to ``true``. // // Notice: This filter is intended to be used for workload authentication, which means that the identity associated with the inserted credential // is considered as the identity of the workload behind the envoy proxy(in this case, envoy is typically deployed as a sidecar alongside that @@ -33,14 +33,13 @@ option (xds.annotations.v3.file_status).work_in_progress = true; // // Here is an example of CredentialInjector configuration with Generic credential, which injects an HTTP Basic Auth credential into the proxied requests. // -// .. code-block:: yaml +// .. code-block:: yaml // // overwrite: true -// fail_if_not_present: true // credential: // name: generic_credential // typed_config: -// "@type": type.googleapis.com/envoy.extensions.injected_credentials.generic.v3.Generic +// "@type": type.googleapis.com/envoy.extensions.http.injected_credentials.generic.v3.Generic // credential: // name: credential // sds_config: @@ -49,7 +48,8 @@ option (xds.annotations.v3.file_status).work_in_progress = true; // header: Authorization // // credential.yaml for Basic Auth: -// .. code-block:: yaml +// +// .. code-block:: yaml // // resources: // - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret" @@ -59,8 +59,10 @@ option (xds.annotations.v3.file_status).work_in_progress = true; // inline_string: "Basic base64EncodedUsernamePassword" // // It can also be configured to inject a Bearer token into the proxied requests. +// // credential.yaml for Bearer Token: -// .. code-block:: yaml +// +// .. code-block:: yaml // // resources: // - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret" @@ -74,12 +76,15 @@ message CredentialInjector { // Value defaults to false. bool overwrite = 1; - // Whether to fail the request if the credential is not present. - // Value defaults to false. - // If set to true, the request will fail with 401 Unauthorized if the credential is not present. - bool fail_if_not_present = 2; + // Whether to send the request to upstream if the credential is not present or if the credential injection + // to the request fails. + // + // By default, a request will fail with ``401 Unauthorized`` if the + // credential is not present or the injection of the credential to the request fails. + // If set to true, the request will be sent to upstream without the credential. + bool allow_request_without_credential = 2; // The credential to inject into the proxied requests - // TODO add extension-category + // [#extension-category: envoy.http.injected_credentials] config.core.v3.TypedExtensionConfig credential = 3 [(validate.rules).message = {required: true}]; } diff --git a/api/src/main/proto/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto b/api/src/main/proto/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto index ea40112a9..60cd96fd9 100644 --- a/api/src/main/proto/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto +++ b/api/src/main/proto/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto @@ -28,7 +28,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // External Authorization :ref:`configuration overview `. // [#extension: envoy.filters.http.ext_authz] -// [#next-free-field: 23] +// [#next-free-field: 24] message ExtAuthz { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.ext_authz.v2.ExtAuthz"; @@ -215,6 +215,28 @@ message ExtAuthz { // Whether to increment cluster statistics (e.g. cluster..upstream_rq_*) on authorization failure. // Defaults to true. google.protobuf.BoolValue charge_cluster_response_stats = 20; + + // Whether to encode the raw headers (i.e. unsanitized values & unconcatenated multi-line headers) + // in authentication request. Works with both HTTP and GRPC clients. + // + // When this is set to true, header values are not sanitized. Headers with the same key will also + // not be combined into a single, comma-separated header. + // Requests to GRPC services will populate the field + // :ref:`header_map`. + // Requests to HTTP services will be constructed with the unsanitized header values and preserved + // multi-line headers with the same key. + // + // If this field is set to false, header values will be sanitized, with any non-UTF-8-compliant + // bytes replaced with '!'. Headers with the same key will have their values concatenated into a + // single comma-separated header value. + // Requests to GRPC services will populate the field + // :ref:`headers`. + // Requests to HTTP services will have their header values sanitized and will not preserve + // multi-line headers with the same key. + // + // It's recommended you set this to true unless you already rely on the old behavior. False is the + // default only for backwards compatibility. + bool encode_raw_headers = 23; } // Configuration for buffering the request data. diff --git a/api/src/main/proto/envoy/extensions/filters/http/ext_proc/v3/ext_proc.proto b/api/src/main/proto/envoy/extensions/filters/http/ext_proc/v3/ext_proc.proto index c9500486a..c32b74a3d 100644 --- a/api/src/main/proto/envoy/extensions/filters/http/ext_proc/v3/ext_proc.proto +++ b/api/src/main/proto/envoy/extensions/filters/http/ext_proc/v3/ext_proc.proto @@ -3,6 +3,7 @@ syntax = "proto3"; package envoy.extensions.filters.http.ext_proc.v3; import "envoy/config/common/mutation_rules/v3/mutation_rules.proto"; +import "envoy/config/core/v3/base.proto"; import "envoy/config/core/v3/grpc_service.proto"; import "envoy/extensions/filters/http/ext_proc/v3/processing_mode.proto"; import "envoy/type/matcher/v3/string.proto"; @@ -28,8 +29,6 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // **Current Implementation Status:** // All options and processing modes are implemented except for the following: // -// * Request and response attributes are not sent and not processed. -// * Dynamic metadata in responses from the external processor is ignored. // * "async mode" is not implemented. // The filter communicates with an external gRPC service called an "external processor" @@ -98,8 +97,12 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // ` object in a namespace matching the filter // name. // -// [#next-free-field: 16] +// [#next-free-field: 18] message ExternalProcessor { + reserved 4; + + reserved "async_mode"; + // Configuration for the gRPC service that the filter will communicate with. // The filter supports both the "Envoy" and "Google" gRPC clients. config.core.v3.GrpcService grpc_service = 1 [(validate.rules).message = {required: true}]; @@ -117,15 +120,6 @@ message ExternalProcessor { // sent. See ProcessingMode for details. ProcessingMode processing_mode = 3; - // [#not-implemented-hide:] - // If true, send each part of the HTTP request or response specified by ProcessingMode - // asynchronously -- in other words, send the message on the gRPC stream and then continue - // filter processing. If false, which is the default, suspend filter execution after - // each message is sent to the remote service and wait up to "message_timeout" - // for a reply. - bool async_mode = 4; - - // [#not-implemented-hide:] // Envoy provides a number of :ref:`attributes ` // for expressive policies. Each attribute name provided in this field will be // matched against that list and populated in the request_headers message. @@ -133,7 +127,6 @@ message ExternalProcessor { // for the list of supported attributes and their types. repeated string request_attributes = 5; - // [#not-implemented-hide:] // Envoy provides a number of :ref:`attributes ` // for expressive policies. Each attribute name provided in this field will be // matched against that list and populated in the response_headers message. @@ -206,6 +199,59 @@ message ExternalProcessor { // Instead, the stream to the external processor will be closed. There will be no // more external processing for this stream from now on. bool disable_immediate_response = 15; + + // Options related to the sending and receiving of dynamic metadata. + MetadataOptions metadata_options = 16; + + // If true, send each part of the HTTP request or response specified by ProcessingMode + // without pausing on filter chain iteration. It is "Send and Go" mode that can be used + // by external processor to observe Envoy data and status. In this mode: + // + // 1. Only STREAMED body processing mode is supported and any other body processing modes will be + // ignored. NONE mode(i.e., skip body processing) will still work as expected. + // + // 2. External processor should not send back processing response, as any responses will be ignored. + // This also means that + // :ref:`message_timeout ` + // restriction doesn't apply to this mode. + // + // 3. External processor may still close the stream to indicate that no more messages are needed. + // + // .. warning:: + // + // Flow control is necessary mechanism to prevent the fast sender (either downstream client or upstream server) + // from overwhelming the external processor when its processing speed is slower. + // This protective measure is being explored and developed but has not been ready yet, so please use your own + // discretion when enabling this feature. + // This work is currently tracked under https://github.com/envoyproxy/envoy/issues/33319. + // + bool observability_mode = 17; +} + +// The MetadataOptions structure defines options for the sending and receiving of +// dynamic metadata. Specifically, which namespaces to send to the server, whether +// metadata returned by the server may be written, and how that metadata may be written. +message MetadataOptions { + message MetadataNamespaces { + // Specifies a list of metadata namespaces whose values, if present, + // will be passed to the ext_proc service as an opaque *protobuf::Struct*. + repeated string untyped = 1; + + // Specifies a list of metadata namespaces whose values, if present, + // will be passed to the ext_proc service as a *protobuf::Any*. This allows + // envoy and the external processing server to share the protobuf message + // definition for safe parsing. + repeated string typed = 2; + } + + // Describes which typed or untyped dynamic metadata namespaces to forward to + // the external processing server. + MetadataNamespaces forwarding_namespaces = 1; + + // Describes which typed or untyped dynamic metadata namespaces to accept from + // the external processing server. Set to empty or leave unset to disallow writing + // any received dynamic metadata. Receiving of typed metadata is not supported. + MetadataNamespaces receiving_namespaces = 2; } // The HeaderForwardingRules structure specifies what headers are @@ -248,7 +294,7 @@ message ExtProcPerRoute { } // Overrides that may be set on a per-route basis -// [#next-free-field: 6] +// [#next-free-field: 8] message ExtProcOverrides { // Set a different processing mode for this route than the default. ProcessingMode processing_mode = 1; @@ -269,4 +315,17 @@ message ExtProcOverrides { // Set a different gRPC service for this route than the default. config.core.v3.GrpcService grpc_service = 5; + + // Options related to the sending and receiving of dynamic metadata. + // Lists of forwarding and receiving namespaces will be overridden in their entirety, + // meaning the most-specific config that specifies this override will be the final + // config used. It is the prerogative of the control plane to ensure this + // most-specific config contains the correct final overrides. + MetadataOptions metadata_options = 6; + + // Additional metadata to include into streams initiated to the ext_proc gRPC + // service. This can be used for scenarios in which additional ad hoc + // authorization headers (e.g. ``x-foo-bar: baz-key``) are to be injected or + // when a route needs to partially override inherited metadata. + repeated config.core.v3.HeaderValue grpc_initial_metadata = 7; } diff --git a/api/src/main/proto/envoy/extensions/filters/http/json_to_metadata/v3/json_to_metadata.proto b/api/src/main/proto/envoy/extensions/filters/http/json_to_metadata/v3/json_to_metadata.proto index 8d7b53d1c..82bf67e25 100644 --- a/api/src/main/proto/envoy/extensions/filters/http/json_to_metadata/v3/json_to_metadata.proto +++ b/api/src/main/proto/envoy/extensions/filters/http/json_to_metadata/v3/json_to_metadata.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package envoy.extensions.filters.http.json_to_metadata.v3; +import "envoy/type/matcher/v3/regex.proto"; + import "google/protobuf/struct.proto"; import "udpa/annotations/status.proto"; @@ -87,7 +89,7 @@ message JsonToMetadata { // The value in the KeyValuePair must be set. KeyValuePair on_missing = 3; - // If the body is too large or fail to parse, apply this metadata KeyValuePair. + // If the body is too large or fail to parse or content-type is mismatched, apply this metadata KeyValuePair. // // The value in the KeyValuePair must be set. KeyValuePair on_error = 4; @@ -108,6 +110,10 @@ message JsonToMetadata { // Allowed empty content-type for json to metadata transformation. // Default to false. bool allow_empty_content_type = 3; + + // Allowed content-type by regex match for json to metadata transformation. + // This can be used in parallel with ``allow_content_types``. + type.matcher.v3.RegexMatcher allow_content_types_regex = 4; } // At least one of request_rules and response_rules must be provided. diff --git a/api/src/main/proto/envoy/extensions/filters/http/jwt_authn/v3/config.proto b/api/src/main/proto/envoy/extensions/filters/http/jwt_authn/v3/config.proto index 7d5ae25a0..3db921a94 100644 --- a/api/src/main/proto/envoy/extensions/filters/http/jwt_authn/v3/config.proto +++ b/api/src/main/proto/envoy/extensions/filters/http/jwt_authn/v3/config.proto @@ -5,6 +5,7 @@ package envoy.extensions.filters.http.jwt_authn.v3; import "envoy/config/core/v3/base.proto"; import "envoy/config/core/v3/http_uri.proto"; import "envoy/config/route/v3/route_components.proto"; +import "envoy/type/matcher/v3/string.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/empty.proto"; @@ -53,7 +54,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // cache_duration: // seconds: 300 // -// [#next-free-field: 19] +// [#next-free-field: 22] message JwtProvider { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.jwt_authn.v2alpha.JwtProvider"; @@ -104,6 +105,48 @@ message JwtProvider { // repeated string audiences = 2; + // Restrict the `subjects `_ + // that the JwtProvider can assert. For instance, this could implement JWT-SVID + // `subject restrictions `_. + // If not specified, will not check subjects in the token. + // + // Example: + // + // .. code-block:: yaml + // + // subjects: + // prefix: spiffe://spiffe.example.com/ + // + type.matcher.v3.StringMatcher subjects = 19; + + // Requires that the credential contains an `expiration `_. + // For instance, this could implement JWT-SVID + // `expiration restrictions `_. + // Unlike ``max_lifetime``, this only requires that expiration is present, where ``max_lifetime`` also checks the value. + // + // Example: + // + // .. code-block:: yaml + // + // require_expiration: true + // + bool require_expiration = 20; + + // Restrict the maximum remaining lifetime of a credential from the JwtProvider. Credential lifetime + // is the difference between the current time and the expiration of the credential. For instance, + // the following example will reject credentials that have a lifetime longer than 24 hours. If not set, + // expiration checking still occurs, but there is no limit on credential lifetime. If set, takes precedence + // over ``require_expiration``. + // + // Example: + // + // .. code-block:: yaml + // + // max_lifetime: + // seconds: 86400 + // + google.protobuf.Duration max_lifetime = 21; + // `JSON Web Key Set (JWKS) `_ is needed to // validate signature of a JWT. This field specifies where to fetch JWKS. oneof jwks_source_specifier { @@ -311,6 +354,7 @@ message JwtProvider { // Add JWT claim to HTTP Header // Specify the claim name you want to copy in which HTTP header. For examples, following config: // The claim must be of type; string, int, double, bool. Array type claims are not supported + // // .. code-block:: yaml // // claim_to_headers: diff --git a/api/src/main/proto/envoy/extensions/filters/http/oauth2/v3/oauth.proto b/api/src/main/proto/envoy/extensions/filters/http/oauth2/v3/oauth.proto index 666ebab58..aa5f70b28 100644 --- a/api/src/main/proto/envoy/extensions/filters/http/oauth2/v3/oauth.proto +++ b/api/src/main/proto/envoy/extensions/filters/http/oauth2/v3/oauth.proto @@ -74,7 +74,7 @@ message OAuth2Credentials { // OAuth config // -// [#next-free-field: 14] +// [#next-free-field: 16] message OAuth2Config { enum AuthType { // The ``client_id`` and ``client_secret`` will be sent in the URL encoded request body. @@ -137,6 +137,18 @@ message OAuth2Config { // If this value is not set, it will default to ``0s``. In this case, the expiry must be set by // the authorization server or the OAuth flow will fail. google.protobuf.Duration default_expires_in = 13; + + // Any request that matches any of the provided matchers won't be redirected to OAuth server when tokens are not valid. + // Automatic access token refresh will be performed for these requests, if enabled. + // This behavior can be useful for AJAX requests. + repeated config.route.v3.HeaderMatcher deny_redirect_matcher = 14; + + // The default lifetime in seconds of the refresh token, if the exp (expiration time) claim is omitted in the refresh token or the refresh token is not JWT. + // + // If this value is not set, it will default to ``604800s``. In this case, the cookie with the refresh token will be expired + // in a week. + // This setting is only considered if ``use_refresh_token`` is set to true, otherwise the authorization server expiration or ``defaul_expires_in`` is used. + google.protobuf.Duration default_refresh_token_expires_in = 15; } // Filter config. diff --git a/api/src/main/proto/envoy/extensions/filters/http/proto_message_logging/v3/config.proto b/api/src/main/proto/envoy/extensions/filters/http/proto_message_logging/v3/config.proto new file mode 100644 index 000000000..5b57e9c7d --- /dev/null +++ b/api/src/main/proto/envoy/extensions/filters/http/proto_message_logging/v3/config.proto @@ -0,0 +1,255 @@ +syntax = "proto3"; + +package envoy.extensions.filters.http.proto_message_logging.v3; + +import "envoy/config/core/v3/base.proto"; + +import "xds/annotations/v3/status.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.http.proto_message_logging.v3"; +option java_outer_classname = "ConfigProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/proto_message_logging/v3;proto_message_loggingv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; +option (xds.annotations.v3.file_status).work_in_progress = true; + +// [#not-implemented-hide:] +// [#protodoc-title: Proto Message Logging] +// Proto Message Logging :ref:`configuration overview +// `. +// [#extension: envoy.filters.http.proto_message_logging] +// +// ProtoMessageLogging filter supports logging scrubbed gRPC requests/responses(proto messages) +// as google.protobuf.Struct and storing results +// in the dynamic metadata `envoy.filters.http.proto_message_logging` for later access. +// +// # Assumptions +// This filter assumes it is only applicable for gRPC with Protobuf as payload. +// +// # Process Flow +// On the request path, it will check +// +// 1. if the incoming gRPC request is configured, the filter tries to: +// +// a. buffer the incoming data to complete protobuf messages +// b. log individual protobuf messages according to directives +// c. write the result into the dynamic metadata. +// d. pass through the request data +// +// 2. otherwise, pass through the request. +// +// On the response path, it will check +// +// 1. if the incoming gRPC request is configured, the filter tries to: +// +// a. buffer the incoming data to complete protobuf messages +// b. log individual protobuf messages according to directives +// c. write the result into the dynamic metadata. +// d. pass through the response data +// +// 2. otherwise, pass through the response. +// +// # Config Requirements +// Here are config requirements +// +// 1. the log target field should be among the following primitive types: `string`, `uint32`, `uint64`, `int32`, `int64`, `sint32`, `sint64`, `fixed32`, `fixed64`, `sfixed32`, `sfixed64`, `float`, `double`. +// +// 2. the target field could be repeated. +// +// 3. the intermediate type could also be repeated. +// +// # Output Format +// The logged requests and responses will be will be added in the dynamic ``metadata`` with the same layout of the message. +// +// For the default `FIRST_AND_LAST` mode, it will be like: +// { +// "requests":{ +// "first":{ +// "foo": "val_foo1", +// ... +// } +// "last":{ +// "foo": "val_foo3", +// ... +// } +// }, +// "responses":{ +// "first":{ +// "baz": "val_baz1", +// ... +// } +// "last":{ +// "baz": "val_foo3", +// ... +// } +// } +// } +// +// +// # Example for `FIRST_AND_LAST` mode +// Let's say we have the following definition for the bi-streaming request +// `pkg.svc.Method`. +// +// .. code-block:: proto +// +// message MethodRequest { +// string foo = 1; +// Nested nested = 2; +// Msg redacted = 3; +// ... +// } +// +// message MethodResponse { +// string baz = 1; +// } +// +// message Nested { +// Msg double_nested = 2; +// } +// +// message Msg { +// string bar = 1; +// string not_logged = 2; +// } +// +// This is the filter config in JSON. +// +// .. code-block:: json +// +// { +// "descriptor_set":{}, +// "mode": "FIRST_AND_LAST", +// "logging_by_method":{ +// "pkg.svc.Method":{ +// "request_logging_by_field":{ +// "foo":"LOG", +// "nested.doubled_nested.bar":"LOG", +// "redacted":"LOG_REDACT" +// }, +// "response_logging_by_field":{ +// "bar":"LOG", +// } +// } +// } +// } +// +// During runtime, the filter receives the following `MethodRequest` message in +// JSON. +// +// .. code-block:: json +// +// { +// "foo": "val_foo1", +// "nested": { "double_nested": {"bar": "val_bar1", "not_logged": "val_not_logged1"}, +// "redacted": { "bar": "val_redacted_bar1"} +// } +// { +// "foo": "val_foo2", +// "nested": { "double_nested": {"bar": "val_bar2", "not_logged": "val_not_logged2"}, +// "redacted": { "bar": "val_redacted_bar2"} +// } +// { +// "foo": "val_foo3", +// "nested": { "double_nested": {"bar": "val_bar3", "not_logged": "val_not_logged3"}, +// "redacted": { "bar": "val_redacted_bar3"} +// } +// +// the filter receives the following `MethodResponse` message in +// JSON. +// +// .. code-block:: json +// +// { +// "baz": "val_baz1", +// } +// { +// "baz": "val_baz2", +// } +// { +// "baz": "val_baz3", +// } +// +// The filter will write the following dynamic +// metadata(`envoy.filters.http.proto_message_logging`) in JSON. +// +// .. code-block:: json +// +// { +// "requests":{ +// "first":{ +// "foo": "val_foo1", +// "nested": { "double_nested": {"bar": "val_bar1"}}, +// "redacted": {} +// } +// "last":{ +// "foo": "val_foo3", +// "nested": { "double_nested": {"bar": "val_bar3"}}, +// "redacted": {} +// } +// }, +// "responses":{ +// "first":{ +// "baz": "val_baz1" +// } +// "last":{ +// "baz": "val_foo3" +// } +// } +// } + +message ProtoMessageLoggingConfig { + enum LogMode { + LogMode_UNSPECIFIED = 0; + + // The filter will log the first and the last message for + // for streaming cases, containing + // client-side streaming, server-side streaming or bi-directional streaming. + FIRST_AND_LAST = 1; + } + + // The proto descriptor set binary for the gRPC services. + oneof descriptor_set { + // It could be passed by a local file through ``Datasource.filename`` or + // embedded in the ``Datasource.inline_bytes``. + config.core.v3.DataSource data_source = 1; + + // Unimplemented, the key of proto descriptor TypedMetadata. + // Among filters depending on the proto descriptor, we can have a TypedMetadata + // for proto descriptors, so that these filters can share one copy of proto + // descriptor in memory. + string proto_descriptor_typed_metadata = 2; + } + + LogMode mode = 3; + + // Specify the message logging info. + // The key is the fully qualified gRPC method name. + // ``${package}.${Service}.${Method}``, like + // ``endpoints.examples.bookstore.BookStore.GetShelf`` + // + // The value is the message logging information for individual gRPC methods. + map logging_by_method = 4; +} + +// This message can be used to support per route config approach later even +// though the Istio doesn't support that so far. +message MethodLogging { + enum LogDirective { + LogDirective_UNSPECIFIED = 0; + + // The value of this field will be logged. + LOG = 1; + + // It should be only annotated on Message type fields so if the field isn't + // empty, an empty Struct will be logged. + LOG_REDACT = 2; + } + + // The mapping of field path to its LogDirective for request messages + map request_logging_by_field = 2; + + // The mapping of field path to its LogDirective for response messages + map response_logging_by_field = 3; +} diff --git a/api/src/main/proto/envoy/extensions/filters/http/rbac/v3/rbac.proto b/api/src/main/proto/envoy/extensions/filters/http/rbac/v3/rbac.proto index eeb505a17..649869a25 100644 --- a/api/src/main/proto/envoy/extensions/filters/http/rbac/v3/rbac.proto +++ b/api/src/main/proto/envoy/extensions/filters/http/rbac/v3/rbac.proto @@ -22,7 +22,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#extension: envoy.filters.http.rbac] // RBAC filter config. -// [#next-free-field: 6] +// [#next-free-field: 8] message RBAC { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.rbac.v2.RBAC"; @@ -34,6 +34,11 @@ message RBAC { config.rbac.v3.RBAC rules = 1 [(udpa.annotations.field_migrate).oneof_promotion = "rules_specifier"]; + // If specified, rules will emit stats with the given prefix. + // This is useful to distinguish the stat when there are more than 1 RBAC filter configured with + // rules. + string rules_stat_prefix = 6; + // The match tree to use when resolving RBAC action for incoming requests. Requests do not // match any matcher will be denied. // If absent, no enforcing RBAC matcher will be applied. @@ -62,6 +67,9 @@ message RBAC { // This is useful to distinguish the stat when there are more than 1 RBAC filter configured with // shadow rules. string shadow_rules_stat_prefix = 3; + + // If track_per_rule_stats is true, counters will be published for each rule and shadow rule. + bool track_per_rule_stats = 7; } message RBACPerRoute { diff --git a/api/src/main/proto/envoy/extensions/filters/listener/proxy_protocol/v3/proxy_protocol.proto b/api/src/main/proto/envoy/extensions/filters/listener/proxy_protocol/v3/proxy_protocol.proto index 4431d5463..31ca8a695 100644 --- a/api/src/main/proto/envoy/extensions/filters/listener/proxy_protocol/v3/proxy_protocol.proto +++ b/api/src/main/proto/envoy/extensions/filters/listener/proxy_protocol/v3/proxy_protocol.proto @@ -70,4 +70,19 @@ message ProxyProtocol { // :ref:`core.v3.ProxyProtocolConfig.pass_through_tlvs `, // which controls pass-through for the upstream. config.core.v3.ProxyProtocolPassThroughTLVs pass_through_tlvs = 3; + + // The PROXY protocol versions that won't be matched. Useful to limit the scope and attack surface of the filter. + // + // When the filter receives PROXY protocol data that is disallowed, it will reject the connection. + // By default, the filter will match all PROXY protocol versions. + // See https://www.haproxy.org/download/2.1/doc/proxy-protocol.txt for details. + // + // .. attention:: + // + // When used in conjunction with the :ref:`allow_requests_without_proxy_protocol `, + // the filter will not attempt to match signatures for the disallowed versions. + // For example, when ``disallowed_versions=V2``, ``allow_requests_without_proxy_protocol=true``, + // and an incoming request matches the V2 signature, the filter will allow the request through without any modification. + // The filter treats this request as if it did not have any PROXY protocol information. + repeated config.core.v3.ProxyProtocolConfig.Version disallowed_versions = 4; } diff --git a/api/src/main/proto/envoy/extensions/filters/network/ext_authz/v3/ext_authz.proto b/api/src/main/proto/envoy/extensions/filters/network/ext_authz/v3/ext_authz.proto index 19d428379..afd0197de 100644 --- a/api/src/main/proto/envoy/extensions/filters/network/ext_authz/v3/ext_authz.proto +++ b/api/src/main/proto/envoy/extensions/filters/network/ext_authz/v3/ext_authz.proto @@ -25,7 +25,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // gRPC Authorization API defined by // :ref:`CheckRequest `. // A failed check will cause this filter to close the TCP connection. -// [#next-free-field: 8] +// [#next-free-field: 9] message ExtAuthz { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.network.ext_authz.v2.ExtAuthz"; @@ -62,4 +62,10 @@ message ExtAuthz { // :ref:`destination`. // The labels will be read from :ref:`metadata` with the specified key. string bootstrap_metadata_labels_key = 7; + + // Specifies if the TLS session level details like SNI are sent to the external service. + // + // When this field is true, Envoy will include the SNI name used for TLSClientHello, if available, in the + // :ref:`tls_session`. + bool include_tls_session = 8; } diff --git a/api/src/main/proto/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/src/main/proto/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 7a92259eb..9e7274daa 100644 --- a/api/src/main/proto/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/src/main/proto/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -37,7 +37,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // HTTP connection manager :ref:`configuration overview `. // [#extension: envoy.filters.network.http_connection_manager] -// [#next-free-field: 57] +// [#next-free-field: 58] message HttpConnectionManager { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager"; @@ -887,6 +887,10 @@ message HttpConnectionManager { // will be ignored if the ``x-forwarded-port`` header has been set by any trusted proxy in front of Envoy. bool append_x_forwarded_port = 51; + // Append the :ref:`config_http_conn_man_headers_x-envoy-local-overloaded` HTTP header in the scenario where + // the Overload Manager has been triggered. + bool append_local_overload = 57; + // Whether the HCM will add ProxyProtocolFilterState to the Connection lifetime filter state. Defaults to ``true``. // This should be set to ``false`` in cases where Envoy's view of the downstream address may not correspond to the // actual client address, for example, if there's another proxy in front of the Envoy. diff --git a/api/src/main/proto/envoy/extensions/filters/network/tcp_proxy/v3/tcp_proxy.proto b/api/src/main/proto/envoy/extensions/filters/network/tcp_proxy/v3/tcp_proxy.proto index d9f0db325..b0f7602a8 100644 --- a/api/src/main/proto/envoy/extensions/filters/network/tcp_proxy/v3/tcp_proxy.proto +++ b/api/src/main/proto/envoy/extensions/filters/network/tcp_proxy/v3/tcp_proxy.proto @@ -184,6 +184,8 @@ message TcpProxy { // is defined as the period in which there are no bytes sent or received on either // the upstream or downstream connection. If not set, the default idle timeout is 1 hour. If set // to 0s, the timeout will be disabled. + // It is possible to dynamically override this configuration by setting a per-connection filter + // state object for the key ``envoy.tcp_proxy.per_connection_idle_timeout_ms``. // // .. warning:: // Disabling this timeout has a highly likelihood of yielding connection leaks due to lost TCP diff --git a/api/src/main/proto/envoy/extensions/injected_credentials/generic/v3/generic.proto b/api/src/main/proto/envoy/extensions/http/injected_credentials/generic/v3/generic.proto similarity index 51% rename from api/src/main/proto/envoy/extensions/injected_credentials/generic/v3/generic.proto rename to api/src/main/proto/envoy/extensions/http/injected_credentials/generic/v3/generic.proto index 5519ec10f..f81a146f6 100644 --- a/api/src/main/proto/envoy/extensions/injected_credentials/generic/v3/generic.proto +++ b/api/src/main/proto/envoy/extensions/http/injected_credentials/generic/v3/generic.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -package envoy.extensions.injected_credentials.generic.v3; +package envoy.extensions.http.injected_credentials.generic.v3; import "envoy/extensions/transport_sockets/tls/v3/secret.proto"; @@ -9,58 +9,19 @@ import "xds/annotations/v3/status.proto"; import "udpa/annotations/status.proto"; import "validate/validate.proto"; -option java_package = "io.envoyproxy.envoy.extensions.injected_credentials.generic.v3"; +option java_package = "io.envoyproxy.envoy.extensions.http.injected_credentials.generic.v3"; option java_outer_classname = "GenericProto"; option java_multiple_files = true; -option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/injected_credentials/generic/v3;genericv3"; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/http/injected_credentials/generic/v3;genericv3"; option (udpa.annotations.file_status).package_version_status = ACTIVE; option (xds.annotations.v3.file_status).work_in_progress = true; // [#protodoc-title: Generic Credential] -// [#not-implemented-hide:] -// [#extension: envoy.injected_credentials.generic] +// [#extension: envoy.http.injected_credentials.generic] // Generic extension can be used to inject HTTP Basic Auth, Bearer Token, or any arbitrary credential // into the proxied requests. // The credential will be injected into the specified HTTP request header. -// Example: -// -// .. code-block:: yaml -// -// credential: -// name: generic_credential -// typed_config: -// "@type": type.googleapis.com/envoy.extensions.injected_credentials.generic.v3.Generic -// credential: -// name: credential -// sds_config: -// path_config_source: -// path: credential.yaml -// header: Authorization -// -// credential.yaml for Basic Auth: -// -// .. code-block:: yaml -// -// resources: -// - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret" -// name: credential -// generic_secret: -// secret: -// inline_string: "Basic base64EncodedUsernamePassword" -// -// Refer to [RFC 7617: The 'Basic' HTTP Authentication Scheme](https://www.rfc-editor.org/rfc/rfc7617) for details. -// -// credential.yaml for Bearer Token: -// -// .. code-block:: yaml -// resources: -// - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret" -// name: credential -// generic_secret: -// secret: -// inline_string: "Bearer myToken" -// // Refer to [RFC 6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://www.rfc-editor.org/rfc/rfc6750) for details. // message Generic { diff --git a/api/src/main/proto/envoy/extensions/injected_credentials/oauth2/v3/oauth2.proto b/api/src/main/proto/envoy/extensions/http/injected_credentials/oauth2/v3/oauth2.proto similarity index 91% rename from api/src/main/proto/envoy/extensions/injected_credentials/oauth2/v3/oauth2.proto rename to api/src/main/proto/envoy/extensions/http/injected_credentials/oauth2/v3/oauth2.proto index bf8989336..becf44108 100644 --- a/api/src/main/proto/envoy/extensions/injected_credentials/oauth2/v3/oauth2.proto +++ b/api/src/main/proto/envoy/extensions/http/injected_credentials/oauth2/v3/oauth2.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -package envoy.extensions.injected_credentials.oauth2.v3; +package envoy.extensions.http.injected_credentials.oauth2.v3; import "envoy/config/core/v3/http_uri.proto"; import "envoy/extensions/transport_sockets/tls/v3/secret.proto"; @@ -10,16 +10,16 @@ import "xds/annotations/v3/status.proto"; import "udpa/annotations/status.proto"; import "validate/validate.proto"; -option java_package = "io.envoyproxy.envoy.extensions.injected_credentials.oauth2.v3"; +option java_package = "io.envoyproxy.envoy.extensions.http.injected_credentials.oauth2.v3"; option java_outer_classname = "Oauth2Proto"; option java_multiple_files = true; -option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/injected_credentials/oauth2/v3;oauth2v3"; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/http/injected_credentials/oauth2/v3;oauth2v3"; option (udpa.annotations.file_status).package_version_status = ACTIVE; option (xds.annotations.v3.file_status).work_in_progress = true; // [#protodoc-title: OAuth2 Credential] // [#not-implemented-hide:] -// [#extension: envoy.injected_credentials.oauth2] +// [#extension: envoy.http.injected_credentials.oauth2] // OAuth2 extension can be used to retrieve an OAuth2 access token from an authorization server and inject it into the // proxied requests. diff --git a/api/src/main/proto/envoy/extensions/load_balancing_policies/least_request/v3/least_request.proto b/api/src/main/proto/envoy/extensions/load_balancing_policies/least_request/v3/least_request.proto index ebef61852..095f60752 100644 --- a/api/src/main/proto/envoy/extensions/load_balancing_policies/least_request/v3/least_request.proto +++ b/api/src/main/proto/envoy/extensions/load_balancing_policies/least_request/v3/least_request.proto @@ -7,6 +7,7 @@ import "envoy/extensions/load_balancing_policies/common/v3/common.proto"; import "google/protobuf/wrappers.proto"; +import "envoy/annotations/deprecation.proto"; import "udpa/annotations/status.proto"; import "validate/validate.proto"; @@ -22,10 +23,34 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // This configuration allows the built-in LEAST_REQUEST LB policy to be configured via the LB policy // extension point. See the :ref:`load balancing architecture overview // ` for more information. -// [#next-free-field: 6] +// [#next-free-field: 7] message LeastRequest { + // Available methods for selecting the host set from which to return the host with the + // fewest active requests. + enum SelectionMethod { + // Return host with fewest requests from a set of ``choice_count`` randomly selected hosts. + // Best selection method for most scenarios. + N_CHOICES = 0; + + // Return host with fewest requests from all hosts. + // Useful in some niche use cases involving low request rates and one of: + // (example 1) low request limits on workloads, or (example 2) few hosts. + // + // Example 1: Consider a workload type that can only accept one connection at a time. + // If such workloads are deployed across many hosts, only a small percentage of those + // workloads have zero connections at any given time, and the rate of new connections is low, + // the ``FULL_SCAN`` method is more likely to select a suitable host than ``N_CHOICES``. + // + // Example 2: Consider a workload type that is only deployed on 2 hosts. With default settings, + // the ``N_CHOICES`` method will return the host with more active requests 25% of the time. + // If the request rate is sufficiently low, the behavior of always selecting the host with least + // requests as of the last metrics refresh may be preferable. + FULL_SCAN = 1; + } + // The number of random healthy hosts from which the host with the fewest active requests will // be chosen. Defaults to 2 so that we perform two-choice selection if the field is not set. + // Only applies to the ``N_CHOICES`` selection method. google.protobuf.UInt32Value choice_count = 1 [(validate.rules).uint32 = {gte: 2}]; // The following formula is used to calculate the dynamic weights when hosts have different load @@ -61,8 +86,12 @@ message LeastRequest { common.v3.LocalityLbConfig locality_lb_config = 4; // [#not-implemented-hide:] - // Configuration for performing full scan on the list of hosts. - // If this configuration is set, when selecting the host a full scan on the list hosts will be - // used to select the one with least requests instead of using random choices. - google.protobuf.BoolValue enable_full_scan = 5; + // Unused. Replaced by the `selection_method` enum for better extensibility. + google.protobuf.BoolValue enable_full_scan = 5 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; + + // Method for selecting the host set from which to return the host with the fewest active requests. + // + // Defaults to ``N_CHOICES``. + SelectionMethod selection_method = 6 [(validate.rules).enum = {defined_only: true}]; } diff --git a/api/src/main/proto/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.proto b/api/src/main/proto/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.proto index b6583cc3a..f154be55a 100644 --- a/api/src/main/proto/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.proto +++ b/api/src/main/proto/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.proto @@ -46,7 +46,8 @@ message RingHash { // provided host) the better the request distribution will reflect the desired weights. Defaults // to 1024 entries, and limited to 8M entries. See also // :ref:`maximum_ring_size`. - google.protobuf.UInt64Value minimum_ring_size = 2 [(validate.rules).uint64 = {lte: 8388608}]; + google.protobuf.UInt64Value minimum_ring_size = 2 + [(validate.rules).uint64 = {lte: 8388608 gte: 1}]; // Maximum hash ring size. Defaults to 8M entries, and limited to 8M entries, but can be lowered // to further constrain resource use. See also diff --git a/api/src/main/proto/envoy/extensions/outlier_detection_monitors/common/v3/error_types.proto b/api/src/main/proto/envoy/extensions/outlier_detection_monitors/common/v3/error_types.proto new file mode 100644 index 000000000..7ea14dde2 --- /dev/null +++ b/api/src/main/proto/envoy/extensions/outlier_detection_monitors/common/v3/error_types.proto @@ -0,0 +1,44 @@ +syntax = "proto3"; + +package envoy.extensions.outlier_detection_monitors.common.v3; + +import "envoy/type/v3/range.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.outlier_detection_monitors.common.v3"; +option java_outer_classname = "ErrorTypesProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/outlier_detection_monitors/common/v3;commonv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Outlier detection error buckets] +// Error bucket for HTTP codes. +// [#not-implemented-hide:] +message HttpErrors { + type.v3.Int32Range range = 1; +} + +// Error bucket for locally originated errors. +// [#not-implemented-hide:] +message LocalOriginErrors { +} + +// Error bucket for database errors. +// Sub-parameters may be added later, like malformed response, error on write, etc. +// [#not-implemented-hide:] +message DatabaseErrors { +} + +// Union of possible error buckets. +// [#not-implemented-hide:] +message ErrorBuckets { + // List of buckets "catching" HTTP codes. + repeated HttpErrors http_errors = 1; + + // List of buckets "catching" locally originated errors. + repeated LocalOriginErrors local_origin_errors = 2; + + // List of buckets "catching" database errors. + repeated DatabaseErrors database_errors = 3; +} diff --git a/api/src/main/proto/envoy/extensions/outlier_detection_monitors/consecutive_errors/v3/consecutive_errors.proto b/api/src/main/proto/envoy/extensions/outlier_detection_monitors/consecutive_errors/v3/consecutive_errors.proto new file mode 100644 index 000000000..8c74f6b57 --- /dev/null +++ b/api/src/main/proto/envoy/extensions/outlier_detection_monitors/consecutive_errors/v3/consecutive_errors.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; + +package envoy.extensions.outlier_detection_monitors.consecutive_errors.v3; + +import "envoy/extensions/outlier_detection_monitors/common/v3/error_types.proto"; + +import "google/protobuf/wrappers.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.outlier_detection_monitors.consecutive_errors.v3"; +option java_outer_classname = "ConsecutiveErrorsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/outlier_detection_monitors/consecutive_errors/v3;consecutive_errorsv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// Monitor which counts consecutive errors. +// If number of consecutive errors exceeds the threshold, monitor will report that the host +// is unhealthy. +// [#not-implemented-hide:] +message ConsecutiveErrors { + // Monitor name. + string name = 1; + + // The number of consecutive errors before ejection occurs. + google.protobuf.UInt32Value threshold = 2 [(validate.rules).uint32 = {lte: 100}]; + + // The % chance that a host is actually ejected. Defaults to 100. + google.protobuf.UInt32Value enforcing = 3 [(validate.rules).uint32 = {lte: 100}]; + + // Error buckets. + common.v3.ErrorBuckets error_buckets = 4; +} diff --git a/api/src/main/proto/envoy/extensions/resource_monitors/downstream_connections/v3/downstream_connections.proto b/api/src/main/proto/envoy/extensions/resource_monitors/downstream_connections/v3/downstream_connections.proto index 782acda56..5028fdf38 100644 --- a/api/src/main/proto/envoy/extensions/resource_monitors/downstream_connections/v3/downstream_connections.proto +++ b/api/src/main/proto/envoy/extensions/resource_monitors/downstream_connections/v3/downstream_connections.proto @@ -2,8 +2,6 @@ syntax = "proto3"; package envoy.extensions.resource_monitors.downstream_connections.v3; -import "xds/annotations/v3/status.proto"; - import "udpa/annotations/status.proto"; import "validate/validate.proto"; @@ -12,7 +10,6 @@ option java_outer_classname = "DownstreamConnectionsProto"; option java_multiple_files = true; option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/resource_monitors/downstream_connections/v3;downstream_connectionsv3"; option (udpa.annotations.file_status).package_version_status = ACTIVE; -option (xds.annotations.v3.file_status).work_in_progress = true; // [#protodoc-title: Downstream connections] // [#extension: envoy.resource_monitors.downstream_connections] diff --git a/api/src/main/proto/envoy/extensions/string_matcher/lua/v3/lua.proto b/api/src/main/proto/envoy/extensions/string_matcher/lua/v3/lua.proto new file mode 100644 index 000000000..04c5b36f4 --- /dev/null +++ b/api/src/main/proto/envoy/extensions/string_matcher/lua/v3/lua.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; + +package envoy.extensions.string_matcher.lua.v3; + +import "envoy/config/core/v3/base.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.string_matcher.lua.v3"; +option java_outer_classname = "LuaProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/string_matcher/lua/v3;luav3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Lua StringMatcher] +// A Lua StringMatcher allows executing a Lua script to determine if a string is a match. The configured source +// code must define a function named `envoy_match`. If the function returns true, the string is considered a match. +// Any other result, including an execution error, is considered a non-match. +// +// Example: +// +// .. code-block:: yaml +// +// source_code: +// inline_string: | +// function envoy_match(str) +// -- Do something. +// return true +// end +// +// [#extension: envoy.string_matcher.lua] + +message Lua { + // The Lua code that Envoy will execute + config.core.v3.DataSource source_code = 1 [(validate.rules).message = {required: true}]; +} diff --git a/api/src/main/proto/envoy/extensions/tracers/opentelemetry/samplers/v3/dynatrace_sampler.proto b/api/src/main/proto/envoy/extensions/tracers/opentelemetry/samplers/v3/dynatrace_sampler.proto new file mode 100644 index 000000000..31bc82c14 --- /dev/null +++ b/api/src/main/proto/envoy/extensions/tracers/opentelemetry/samplers/v3/dynatrace_sampler.proto @@ -0,0 +1,54 @@ +syntax = "proto3"; + +package envoy.extensions.tracers.opentelemetry.samplers.v3; + +import "envoy/config/core/v3/http_service.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.tracers.opentelemetry.samplers.v3"; +option java_outer_classname = "DynatraceSamplerProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/tracers/opentelemetry/samplers/v3;samplersv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Dynatrace Sampler config] + +// Configuration for the Dynatrace Sampler extension. +// [#extension: envoy.tracers.opentelemetry.samplers.dynatrace] +message DynatraceSamplerConfig { + // The Dynatrace tenant. + // + // The value can be obtained from the Envoy deployment page in Dynatrace. + string tenant = 1; + + // The id of the Dynatrace cluster id. + // + // The value can be obtained from the Envoy deployment page in Dynatrace. + int32 cluster_id = 2; + + // The HTTP service to fetch the sampler configuration from the Dynatrace API (root spans per minute). For example: + // + // .. code-block:: yaml + // + // http_service: + // http_uri: + // cluster: dynatrace + // uri: .dev.dynatracelabs.com/api/v2/samplingConfiguration + // timeout: 10s + // request_headers_to_add: + // - header: + // key : "authorization" + // value: "Api-Token dt..." + // + config.core.v3.HttpService http_service = 3; + + // Default number of root spans per minute, used when the value can't be obtained from the Dynatrace API. + // + // A default value of ``1000`` is used when: + // + // - ``root_spans_per_minute`` is unset + // - ``root_spans_per_minute`` is set to 0 + // + uint32 root_spans_per_minute = 4; +} diff --git a/api/src/main/proto/envoy/extensions/wasm/v3/wasm.proto b/api/src/main/proto/envoy/extensions/wasm/v3/wasm.proto index 54ef437cb..58b7b57c4 100644 --- a/api/src/main/proto/envoy/extensions/wasm/v3/wasm.proto +++ b/api/src/main/proto/envoy/extensions/wasm/v3/wasm.proto @@ -50,7 +50,7 @@ message VmConfig { string vm_id = 1; // The Wasm runtime type, defaults to the first available Wasm engine used at Envoy build-time. - // The priority to search for the available engine is: v8 -> wasmtime -> wamr -> wavm. + // The priority to search for the available engine is: v8 -> wasmtime -> wamr. // Available Wasm runtime types are registered as extensions. The following runtimes are included // in Envoy code base: // @@ -68,11 +68,6 @@ message VmConfig { // **envoy.wasm.runtime.wamr**: `WAMR `_-based WebAssembly runtime. // This runtime is not enabled in the official build. // - // .. _extension_envoy.wasm.runtime.wavm: - // - // **envoy.wasm.runtime.wavm**: `WAVM `_-based WebAssembly runtime. - // This runtime is not enabled in the official build. - // // .. _extension_envoy.wasm.runtime.wasmtime: // // **envoy.wasm.runtime.wasmtime**: `Wasmtime `_-based WebAssembly runtime. diff --git a/api/src/main/proto/envoy/service/auth/v3/attribute_context.proto b/api/src/main/proto/envoy/service/auth/v3/attribute_context.proto index 152672685..ef76499d1 100644 --- a/api/src/main/proto/envoy/service/auth/v3/attribute_context.proto +++ b/api/src/main/proto/envoy/service/auth/v3/attribute_context.proto @@ -7,6 +7,7 @@ import "envoy/config/core/v3/base.proto"; import "google/protobuf/timestamp.proto"; +import "udpa/annotations/migrate.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; @@ -99,7 +100,7 @@ message AttributeContext { // This message defines attributes for an HTTP request. // HTTP/1.x, HTTP/2, gRPC are all considered as HTTP requests. - // [#next-free-field: 13] + // [#next-free-field: 14] message HttpRequest { option (udpa.annotations.versioning).previous_message_type = "envoy.service.auth.v2.AttributeContext.HttpRequest"; @@ -116,7 +117,31 @@ message AttributeContext { // The HTTP request headers. If multiple headers share the same key, they // must be merged according to the HTTP spec. All header keys must be // lower-cased, because HTTP header keys are case-insensitive. - map headers = 3; + // Header value is encoded as UTF-8 string. Non-UTF-8 characters will be replaced by "!". + // This field will not be set if + // :ref:`encode_raw_headers ` + // is set to true. + map headers = 3 + [(udpa.annotations.field_migrate).oneof_promotion = "headers_type"]; + + // A list of the raw HTTP request headers. This is used instead of + // :ref:`headers ` when + // :ref:`encode_raw_headers ` + // is set to true. + // + // Note that this is not actually a map type. ``header_map`` contains a single repeated field + // ``headers``. + // + // Here, only the ``key`` and ``raw_value`` fields will be populated for each HeaderValue, and + // that is only when + // :ref:`encode_raw_headers ` + // is set to true. + // + // Also, unlike the + // :ref:`headers ` + // field, headers with the same key are not combined into a single comma separated header. + config.core.v3.HeaderMap header_map = 13 + [(udpa.annotations.field_migrate).oneof_promotion = "headers_type"]; // The request target, as it appears in the first line of the HTTP request. This includes // the URL path and query-string. No decoding is performed. @@ -187,7 +212,11 @@ message AttributeContext { config.core.v3.Metadata route_metadata_context = 13; // TLS session details of the underlying connection. - // This is not populated by default and will be populated if ext_authz filter's - // :ref:`include_tls_session ` is set to true. + // This is not populated by default and will be populated only if the ext_authz filter has + // been specifically configured to include this information. + // For HTTP ext_authz, that requires :ref:`include_tls_session ` + // to be set to true. + // For network ext_authz, that requires :ref:`include_tls_session ` + // to be set to true. TLSSession tls_session = 12; } diff --git a/api/src/main/proto/envoy/service/ext_proc/v3/external_processor.proto b/api/src/main/proto/envoy/service/ext_proc/v3/external_processor.proto index 50fba503f..5d12ecfae 100644 --- a/api/src/main/proto/envoy/service/ext_proc/v3/external_processor.proto +++ b/api/src/main/proto/envoy/service/ext_proc/v3/external_processor.proto @@ -9,6 +9,7 @@ import "envoy/type/v3/http_status.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/struct.proto"; +import "envoy/annotations/deprecation.proto"; import "udpa/annotations/status.proto"; import "validate/validate.proto"; @@ -56,20 +57,11 @@ service ExternalProcessor { // This represents the different types of messages that Envoy can send // to an external processing server. -// [#next-free-field: 8] +// [#next-free-field: 11] message ProcessingRequest { - // Specify whether the filter that sent this request is running in synchronous - // or asynchronous mode. The choice of synchronous or asynchronous mode - // can be set in the filter configuration, and defaults to false. - // - // * A value of ``false`` indicates that the server must respond - // to this message by either sending back a matching ProcessingResponse message, - // or by closing the stream. - // * A value of ``true`` indicates that the server must not respond to this - // message, although it may still close the stream to indicate that no more messages - // are needed. - // - bool async_mode = 1; + reserved 1; + + reserved "async_mode"; // Each request message will include one of the following sub-messages. Which // ones are set for a particular HTTP request/response depend on the @@ -78,46 +70,62 @@ message ProcessingRequest { option (validate.required) = true; // Information about the HTTP request headers, as well as peer info and additional - // properties. Unless ``async_mode`` is ``true``, the server must send back a + // properties. Unless ``observability_mode`` is ``true``, the server must send back a // HeaderResponse message, an ImmediateResponse message, or close the stream. HttpHeaders request_headers = 2; // Information about the HTTP response headers, as well as peer info and additional - // properties. Unless ``async_mode`` is ``true``, the server must send back a + // properties. Unless ``observability_mode`` is ``true``, the server must send back a // HeaderResponse message or close the stream. HttpHeaders response_headers = 3; - // A chunk of the HTTP request body. Unless ``async_mode`` is true, the server must send back + // A chunk of the HTTP request body. Unless ``observability_mode`` is true, the server must send back // a BodyResponse message, an ImmediateResponse message, or close the stream. HttpBody request_body = 4; - // A chunk of the HTTP request body. Unless ``async_mode`` is ``true``, the server must send back + // A chunk of the HTTP response body. Unless ``observability_mode`` is ``true``, the server must send back // a BodyResponse message or close the stream. HttpBody response_body = 5; - // The HTTP trailers for the request path. Unless ``async_mode`` is ``true``, the server + // The HTTP trailers for the request path. Unless ``observability_mode`` is ``true``, the server // must send back a TrailerResponse message or close the stream. // - // This message is only sent if the trailers processing mode is set to ``SEND``. - // If there are no trailers on the original downstream request, then this message - // will only be sent (with empty trailers waiting to be populated) if the - // processing mode is set before the request headers are sent, such as - // in the filter configuration. + // This message is only sent if the trailers processing mode is set to ``SEND`` and + // the original downstream request has trailers. HttpTrailers request_trailers = 6; - // The HTTP trailers for the response path. Unless ``async_mode`` is ``true``, the server + // The HTTP trailers for the response path. Unless ``observability_mode`` is ``true``, the server // must send back a TrailerResponse message or close the stream. // - // This message is only sent if the trailers processing mode is set to ``SEND``. - // If there are no trailers on the original downstream request, then this message - // will only be sent (with empty trailers waiting to be populated) if the - // processing mode is set before the request headers are sent, such as - // in the filter configuration. + // This message is only sent if the trailers processing mode is set to ``SEND`` and + // the original upstream response has trailers. HttpTrailers response_trailers = 7; } + + // Dynamic metadata associated with the request. + config.core.v3.Metadata metadata_context = 8; + + // The values of properties selected by the ``request_attributes`` + // or ``response_attributes`` list in the configuration. Each entry + // in the list is populated from the standard + // :ref:`attributes ` supported across Envoy. + map attributes = 9; + + // Specify whether the filter that sent this request is running in :ref:`observability_mode + // ` + // and defaults to false. + // + // * A value of ``false`` indicates that the server must respond + // to this message by either sending back a matching ProcessingResponse message, + // or by closing the stream. + // * A value of ``true`` indicates that the server should not respond to this message, as any + // responses will be ignored. However, it may still close the stream to indicate that no more messages + // are needed. + // + bool observability_mode = 10; } -// For every ProcessingRequest received by the server with the ``async_mode`` field +// For every ProcessingRequest received by the server with the ``observability_mode`` field // set to false, the server must send back exactly one ProcessingResponse message. // [#next-free-field: 11] message ProcessingResponse { @@ -158,9 +166,9 @@ message ProcessingResponse { ImmediateResponse immediate_response = 7; } - // [#not-implemented-hide:] - // Optional metadata that will be emitted as dynamic metadata to be consumed by the next - // filter. This metadata will be placed in the namespace ``envoy.filters.http.ext_proc``. + // Optional metadata that will be emitted as dynamic metadata to be consumed by + // following filters. This metadata will be placed in the namespace(s) specified by the top-level + // field name(s) of the struct. google.protobuf.Struct dynamic_metadata = 8; // Override how parts of the HTTP request and response are processed @@ -207,12 +215,11 @@ message HttpHeaders { config.core.v3.HeaderMap headers = 1; // [#not-implemented-hide:] - // The values of properties selected by the ``request_attributes`` - // or ``response_attributes`` list in the configuration. Each entry - // in the list is populated - // from the standard :ref:`attributes ` - // supported across Envoy. - map attributes = 2; + // This field is deprecated and not implemented. Attributes will be sent in + // the top-level :ref:`attributes attributes = 2 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; // If true, then there is no message body associated with this // request or response. @@ -311,7 +318,8 @@ message CommonResponse { // Clear the route cache for the current client request. This is necessary // if the remote server modified headers that are used to calculate the route. - // This field is ignored in the response direction. + // This field is ignored in the response direction. This field is also ignored + // if the Envoy ext_proc filter is in the upstream filter chain. bool clear_route_cache = 5; } diff --git a/api/src/main/proto/envoy/service/status/v3/csds.proto b/api/src/main/proto/envoy/service/status/v3/csds.proto index b764f1cc3..1c51f2bac 100644 --- a/api/src/main/proto/envoy/service/status/v3/csds.proto +++ b/api/src/main/proto/envoy/service/status/v3/csds.proto @@ -185,6 +185,11 @@ message ClientConfig { // Represents generic xDS config and the exact config structure depends on // the type URL (like Cluster if it is CDS) repeated GenericXdsConfig generic_xds_configs = 3; + + // For xDS clients, the scope in which the data is used. + // For example, gRPC indicates the data plane target or that the data is + // associated with gRPC server(s). + string client_scope = 4; } message ClientStatusResponse { diff --git a/api/src/main/proto/envoy/type/http/v3/cookie.proto b/api/src/main/proto/envoy/type/http/v3/cookie.proto index 4fe0c2f69..0ceda999d 100644 --- a/api/src/main/proto/envoy/type/http/v3/cookie.proto +++ b/api/src/main/proto/envoy/type/http/v3/cookie.proto @@ -22,7 +22,7 @@ message Cookie { string name = 1 [(validate.rules).string = {min_len: 1}]; // Duration of cookie. This will be used to set the expiry time of a new cookie when it is - // generated. Set this to 0 to use a session cookie. + // generated. Set this to 0s to use a session cookie and disable cookie expiration. google.protobuf.Duration ttl = 2 [(validate.rules).duration = {gte {}}]; // Path of cookie. This will be used to set the path of a new cookie when it is generated. diff --git a/api/src/main/proto/envoy/type/matcher/v3/string.proto b/api/src/main/proto/envoy/type/matcher/v3/string.proto index 2df1bd37a..10033749a 100644 --- a/api/src/main/proto/envoy/type/matcher/v3/string.proto +++ b/api/src/main/proto/envoy/type/matcher/v3/string.proto @@ -4,6 +4,8 @@ package envoy.type.matcher.v3; import "envoy/type/matcher/v3/regex.proto"; +import "xds/core/v3/extension.proto"; + import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; import "validate/validate.proto"; @@ -17,7 +19,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: String matcher] // Specifies the way to match a string. -// [#next-free-field: 8] +// [#next-free-field: 9] message StringMatcher { option (udpa.annotations.versioning).previous_message_type = "envoy.type.matcher.StringMatcher"; @@ -61,6 +63,10 @@ message StringMatcher { // // * ``abc`` matches the value ``xyz.abc.def`` string contains = 7 [(validate.rules).string = {min_len: 1}]; + + // Use an extension as the matcher type. + // [#extension-category: envoy.string_matcher] + xds.core.v3.TypedExtensionConfig custom = 8; } // If true, indicates the exact/prefix/suffix/contains matching should be case insensitive. This diff --git a/api/src/main/proto/io/prometheus/client/metrics.proto b/api/src/main/proto/io/prometheus/client/metrics.proto index c3c8cc133..3e9168e66 100644 --- a/api/src/main/proto/io/prometheus/client/metrics.proto +++ b/api/src/main/proto/io/prometheus/client/metrics.proto @@ -107,6 +107,9 @@ message Histogram { // histograms. repeated sint64 positive_delta = 13; // Count delta of each bucket compared to previous one (or to zero for 1st bucket). repeated double positive_count = 14; // Absolute count of each bucket. + + // Only used for native histograms. These exemplars MUST have a timestamp. + repeated Exemplar exemplars = 16; } // A Bucket of a conventional histogram, each of which is treated as @@ -150,4 +153,5 @@ message MetricFamily { optional string help = 2; optional MetricType type = 3; repeated Metric metric = 4; + optional string unit = 5; } diff --git a/api/src/main/proto/opentelemetry/proto/logs/v1/logs.proto b/api/src/main/proto/opentelemetry/proto/logs/v1/logs.proto index 0b4b64972..f9b97dd74 100644 --- a/api/src/main/proto/opentelemetry/proto/logs/v1/logs.proto +++ b/api/src/main/proto/opentelemetry/proto/logs/v1/logs.proto @@ -55,6 +55,9 @@ message ResourceLogs { // A list of ScopeLogs that originate from a resource. repeated ScopeLogs scope_logs = 2; + // The Schema URL, if known. This is the identifier of the Schema that the resource data + // is recorded in. To learn more about Schema URL see + // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url // This schema_url applies to the data in the "resource" field. It does not apply // to the data in the "scope_logs" field which have their own schema_url field. string schema_url = 3; @@ -70,6 +73,9 @@ message ScopeLogs { // A list of log records. repeated LogRecord log_records = 2; + // The Schema URL, if known. This is the identifier of the Schema that the log data + // is recorded in. To learn more about Schema URL see + // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url // This schema_url applies to all logs in the "logs" field. string schema_url = 3; } @@ -104,9 +110,11 @@ enum SeverityNumber { SEVERITY_NUMBER_FATAL4 = 24; } -// LogRecordFlags is defined as a protobuf 'uint32' type and is to be used as -// bit-fields. Each non-zero value defined in this enum is a bit-mask. -// To extract the bit-field, for example, use an expression like: +// LogRecordFlags represents constants used to interpret the +// LogRecord.flags field, which is protobuf 'fixed32' type and is to +// be used as bit-fields. Each non-zero value defined in this enum is +// a bit-mask. To extract the bit-field, for example, use an +// expression like: // // (logRecord.flags & LOG_RECORD_FLAGS_TRACE_FLAGS_MASK) // diff --git a/api/src/main/proto/opentelemetry/proto/metrics/v1/metrics.proto b/api/src/main/proto/opentelemetry/proto/metrics/v1/metrics.proto index da986dda1..3394aee93 100644 --- a/api/src/main/proto/opentelemetry/proto/metrics/v1/metrics.proto +++ b/api/src/main/proto/opentelemetry/proto/metrics/v1/metrics.proto @@ -55,6 +55,9 @@ message ResourceMetrics { // A list of metrics that originate from a resource. repeated ScopeMetrics scope_metrics = 2; + // The Schema URL, if known. This is the identifier of the Schema that the resource data + // is recorded in. To learn more about Schema URL see + // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url // This schema_url applies to the data in the "resource" field. It does not apply // to the data in the "scope_metrics" field which have their own schema_url field. string schema_url = 3; @@ -70,6 +73,9 @@ message ScopeMetrics { // A list of metrics that originate from an instrumentation library. repeated Metric metrics = 2; + // The Schema URL, if known. This is the identifier of the Schema that the metric data + // is recorded in. To learn more about Schema URL see + // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url // This schema_url applies to all metrics in the "metrics" field. string schema_url = 3; } @@ -162,7 +168,7 @@ message ScopeMetrics { message Metric { reserved 4, 6, 8; - // name of the metric, including its DNS name prefix. It must be unique. + // name of the metric. string name = 1; // description of the metric, which can be used in documentation. diff --git a/api/src/main/proto/opentelemetry/proto/trace/v1/trace.proto b/api/src/main/proto/opentelemetry/proto/trace/v1/trace.proto index b2869edc4..a1fdfa3ac 100644 --- a/api/src/main/proto/opentelemetry/proto/trace/v1/trace.proto +++ b/api/src/main/proto/opentelemetry/proto/trace/v1/trace.proto @@ -55,6 +55,9 @@ message ResourceSpans { // A list of ScopeSpans that originate from a resource. repeated ScopeSpans scope_spans = 2; + // The Schema URL, if known. This is the identifier of the Schema that the resource data + // is recorded in. To learn more about Schema URL see + // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url // This schema_url applies to the data in the "resource" field. It does not apply // to the data in the "scope_spans" field which have their own schema_url field. string schema_url = 3; @@ -70,6 +73,9 @@ message ScopeSpans { // A list of Spans that originate from an instrumentation scope. repeated Span spans = 2; + // The Schema URL, if known. This is the identifier of the Schema that the span data + // is recorded in. To learn more about Schema URL see + // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url // This schema_url applies to all spans and span events in the "spans" field. string schema_url = 3; } @@ -103,6 +109,22 @@ message Span { // field must be empty. The ID is an 8-byte array. bytes parent_span_id = 4; + // Flags, a bit field. 8 least significant bits are the trace + // flags as defined in W3C Trace Context specification. Readers + // MUST not assume that 24 most significant bits will be zero. + // To read the 8-bit W3C trace flag, use `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`. + // + // When creating span messages, if the message is logically forwarded from another source + // with an equivalent flags fields (i.e., usually another OTLP span message), the field SHOULD + // be copied as-is. If creating from a source that does not have an equivalent flags field + // (such as a runtime representation of an OpenTelemetry span), the high 24 bits MUST + // be set to zero. + // + // [Optional]. + // + // See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. + fixed32 flags = 16; + // A description of the span's operation. // // For example, the name can be a qualified method name or a file name @@ -236,6 +258,16 @@ message Span { // dropped_attributes_count is the number of dropped attributes. If the value is 0, // then no attributes were dropped. uint32 dropped_attributes_count = 5; + + // Flags, a bit field. 8 least significant bits are the trace + // flags as defined in W3C Trace Context specification. Readers + // MUST not assume that 24 most significant bits will be zero. + // When creating new spans, the most-significant 24-bits MUST be + // zero. To read the 8-bit W3C trace flag (use flags & + // SPAN_FLAGS_TRACE_FLAGS_MASK). [Optional]. + // + // See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. + fixed32 flags = 6; } // links is a collection of Links, which are references from this span to a span @@ -274,3 +306,28 @@ message Status { // The status code. StatusCode code = 3; } + +// SpanFlags represents constants used to interpret the +// Span.flags field, which is protobuf 'fixed32' type and is to +// be used as bit-fields. Each non-zero value defined in this enum is +// a bit-mask. To extract the bit-field, for example, use an +// expression like: +// +// (span.flags & SPAN_FLAGS_TRACE_FLAGS_MASK) +// +// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. +// +// Note that Span flags were introduced in version 1.1 of the +// OpenTelemetry protocol. Older Span producers do not set this +// field, consequently consumers should not rely on the absence of a +// particular flag bit to indicate the presence of a particular feature. +enum SpanFlags { + // The zero value for the enum. Should not be used for comparisons. + // Instead use bitwise "and" with the appropriate mask as shown above. + SPAN_FLAGS_DO_NOT_USE = 0; + + // Bits 0-7 are used for trace flags. + SPAN_FLAGS_TRACE_FLAGS_MASK = 0x000000FF; + + // Bits 8-31 are reserved for future use. +} diff --git a/api/src/main/proto/udpa/annotations/migrate.proto b/api/src/main/proto/udpa/annotations/migrate.proto index 5289cb8a7..5f5f389b7 100644 --- a/api/src/main/proto/udpa/annotations/migrate.proto +++ b/api/src/main/proto/udpa/annotations/migrate.proto @@ -8,7 +8,7 @@ package udpa.annotations; import "google/protobuf/descriptor.proto"; -option go_package = "github.com/cncf/xds/go/annotations"; +option go_package = "github.com/cncf/xds/go/udpa/annotations"; // Magic number in this file derived from top 28bit of SHA256 digest of // "udpa.annotation.migrate". diff --git a/api/src/main/proto/udpa/annotations/security.proto b/api/src/main/proto/udpa/annotations/security.proto index 52801d30d..0ef919716 100644 --- a/api/src/main/proto/udpa/annotations/security.proto +++ b/api/src/main/proto/udpa/annotations/security.proto @@ -10,7 +10,7 @@ import "udpa/annotations/status.proto"; import "google/protobuf/descriptor.proto"; -option go_package = "github.com/cncf/xds/go/annotations"; +option go_package = "github.com/cncf/xds/go/udpa/annotations"; // All annotations in this file are experimental and subject to change. Their // only consumer today is the Envoy APIs and SecuritAnnotationValidator protoc diff --git a/api/src/main/proto/udpa/annotations/sensitive.proto b/api/src/main/proto/udpa/annotations/sensitive.proto index ab822fb48..c7d8af608 100644 --- a/api/src/main/proto/udpa/annotations/sensitive.proto +++ b/api/src/main/proto/udpa/annotations/sensitive.proto @@ -8,7 +8,7 @@ package udpa.annotations; import "google/protobuf/descriptor.proto"; -option go_package = "github.com/cncf/xds/go/annotations"; +option go_package = "github.com/cncf/xds/go/udpa/annotations"; extend google.protobuf.FieldOptions { // Magic number is the 28 most significant bits in the sha256sum of "udpa.annotations.sensitive". diff --git a/api/src/main/proto/udpa/annotations/status.proto b/api/src/main/proto/udpa/annotations/status.proto index 76cfd4dcf..5a90bde29 100644 --- a/api/src/main/proto/udpa/annotations/status.proto +++ b/api/src/main/proto/udpa/annotations/status.proto @@ -8,7 +8,7 @@ package udpa.annotations; import "google/protobuf/descriptor.proto"; -option go_package = "github.com/cncf/xds/go/annotations"; +option go_package = "github.com/cncf/xds/go/udpa/annotations"; // Magic number in this file derived from top 28bit of SHA256 digest of // "udpa.annotation.status". diff --git a/api/src/main/proto/udpa/annotations/versioning.proto b/api/src/main/proto/udpa/annotations/versioning.proto index dcb7c85fd..06df78d81 100644 --- a/api/src/main/proto/udpa/annotations/versioning.proto +++ b/api/src/main/proto/udpa/annotations/versioning.proto @@ -8,7 +8,7 @@ package udpa.annotations; import "google/protobuf/descriptor.proto"; -option go_package = "github.com/cncf/xds/go/annotations"; +option go_package = "github.com/cncf/xds/go/udpa/annotations"; extend google.protobuf.MessageOptions { // Magic number derived from 0x78 ('x') 0x44 ('D') 0x53 ('S') diff --git a/api/src/main/proto/validate/validate.proto b/api/src/main/proto/validate/validate.proto index 705d382aa..5aa965393 100644 --- a/api/src/main/proto/validate/validate.proto +++ b/api/src/main/proto/validate/validate.proto @@ -534,7 +534,7 @@ message StringRules { // at a maximum optional uint64 max_bytes = 5; - // Pattern specifes that this field must match against the specified + // Pattern specifies that this field must match against the specified // regular expression (RE2 syntax). The included expression should elide // any delimiters. optional string pattern = 6; @@ -646,7 +646,7 @@ message BytesRules { // at a maximum optional uint64 max_len = 3; - // Pattern specifes that this field must match against the specified + // Pattern specifies that this field must match against the specified // regular expression (RE2 syntax). The included expression should elide // any delimiters. optional string pattern = 4; @@ -732,11 +732,11 @@ message RepeatedRules { optional uint64 max_items = 2; // Unique specifies that all elements in this field must be unique. This - // contraint is only applicable to scalar and enum types (messages are not + // constraint is only applicable to scalar and enum types (messages are not // supported). optional bool unique = 3; - // Items specifies the contraints to be applied to each item in the field. + // Items specifies the constraints to be applied to each item in the field. // Repeated message fields will still execute validation against each item // unless skip is specified here. optional FieldRules items = 4; diff --git a/api/src/main/proto/xds/type/matcher/v3/string.proto b/api/src/main/proto/xds/type/matcher/v3/string.proto index fdc598e17..e58cb413e 100644 --- a/api/src/main/proto/xds/type/matcher/v3/string.proto +++ b/api/src/main/proto/xds/type/matcher/v3/string.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package xds.type.matcher.v3; +import "xds/core/v3/extension.proto"; import "xds/type/matcher/v3/regex.proto"; import "validate/validate.proto"; @@ -14,7 +15,7 @@ option go_package = "github.com/cncf/xds/go/xds/type/matcher/v3"; // [#protodoc-title: String matcher] // Specifies the way to match a string. -// [#next-free-field: 8] +// [#next-free-field: 9] message StringMatcher { oneof match_pattern { option (validate.required) = true; @@ -52,6 +53,10 @@ message StringMatcher { // // * *abc* matches the value *xyz.abc.def* string contains = 7 [(validate.rules).string = {min_len: 1}]; + + // Use an extension as the matcher type. + // [#extension-category: envoy.string_matcher] + xds.core.v3.TypedExtensionConfig custom = 8; } // If true, indicates the exact/prefix/suffix matching should be case insensitive. This has no diff --git a/api/src/main/proto/xds/type/v3/cel.proto b/api/src/main/proto/xds/type/v3/cel.proto index 71f6cbaf3..df4f81d90 100644 --- a/api/src/main/proto/xds/type/v3/cel.proto +++ b/api/src/main/proto/xds/type/v3/cel.proto @@ -4,6 +4,8 @@ package xds.type.v3; import "google/api/expr/v1alpha1/checked.proto"; import "google/api/expr/v1alpha1/syntax.proto"; +import "cel/expr/checked.proto"; +import "cel/expr/syntax.proto"; import "google/protobuf/wrappers.proto"; import "xds/annotations/v3/status.proto"; @@ -23,14 +25,28 @@ option (xds.annotations.v3.file_status).work_in_progress = true; // `_ (CEL) program. message CelExpression { oneof expr_specifier { - option (validate.required) = true; - // Parsed expression in abstract syntax tree (AST) form. - google.api.expr.v1alpha1.ParsedExpr parsed_expr = 1; + // + // Deprecated -- use ``cel_expr_parsed`` field instead. + // If ``cel_expr_parsed`` or ``cel_expr_checked`` is set, this field is not used. + google.api.expr.v1alpha1.ParsedExpr parsed_expr = 1 [deprecated = true]; // Parsed expression in abstract syntax tree (AST) form that has been successfully type checked. - google.api.expr.v1alpha1.CheckedExpr checked_expr = 2; + // + // Deprecated -- use ``cel_expr_checked`` field instead. + // If ``cel_expr_parsed`` or ``cel_expr_checked`` is set, this field is not used. + google.api.expr.v1alpha1.CheckedExpr checked_expr = 2 [deprecated = true]; } + + // Parsed expression in abstract syntax tree (AST) form. + // + // If ``cel_expr_checked`` is set, this field is not used. + cel.expr.ParsedExpr cel_expr_parsed = 3; + + // Parsed expression in abstract syntax tree (AST) form that has been successfully type checked. + // + // If set, takes precedence over ``cel_expr_parsed``. + cel.expr.CheckedExpr cel_expr_checked = 4; } // Extracts a string by evaluating a `Common Expression Language diff --git a/server/src/test/java/io/envoyproxy/controlplane/server/EnvoyContainer.java b/server/src/test/java/io/envoyproxy/controlplane/server/EnvoyContainer.java index 7c3a74994..5aa4db5e4 100644 --- a/server/src/test/java/io/envoyproxy/controlplane/server/EnvoyContainer.java +++ b/server/src/test/java/io/envoyproxy/controlplane/server/EnvoyContainer.java @@ -24,7 +24,7 @@ class EnvoyContainer extends GenericContainer { EnvoyContainer(String config, Supplier controlPlanePortSupplier) { // this version is changed automatically by /tools/update-sha.sh:57 // if you change it make sure to reflect changes there - super("envoyproxy/envoy:v1.29.2"); + super("envoyproxy/envoy:v1.30.1"); this.config = config; this.controlPlanePortSupplier = controlPlanePortSupplier; } diff --git a/tools/API_SHAS b/tools/API_SHAS index 87611e452..be5244fd3 100644 --- a/tools/API_SHAS +++ b/tools/API_SHAS @@ -1,12 +1,13 @@ # Update the versions here and run update-api.sh # envoy (source: SHA from https://github.com/envoyproxy/envoy) -ENVOY_SHA="2092d65bd4d476be8235ea541e5d25c096b513e6" +ENVOY_SHA="816188b86a0a52095b116b107f576324082c7c02" -# dependencies (source: https://github.com/envoyproxy/envoy/blob/2092d65bd4d476be8235ea541e5d25c096b513e6/api/bazel/repository_locations.bzl) +# dependencies (source: https://github.com/envoyproxy/envoy/blob/816188b86a0a52095b116b107f576324082c7c02/api/bazel/repository_locations.bzl) GOOGLEAPIS_SHA="114a745b2841a044e98cdbb19358ed29fcf4a5f1" # 2023-01-10 -PGV_VERSION="1.0.2" # 2023-06-26 -PROMETHEUS_SHA="0.5.0" # 2023-10-03 +PGV_VERSION="1.0.4" # 2024-01-17 +PROMETHEUS_SHA="0.6.1" # 2024-04-03 OPENCENSUS_VERSION="0.4.1" # 2022-09-23 -OPENTELEMETRY_VERSION="1.0.0" # 2023-07-03 -XDS_SHA="3a472e524827f72d1ad621c4983dd5af54c46776" # 2023-11-16 +OPENTELEMETRY_VERSION="1.1.0" # 2024-01-11 +CEL_VERSION="0.15.0" # 2024-03-27 +XDS_SHA="0c46c01016dc5c9aeddf6c745a230c32bf62841d" # 2024-03-29 diff --git a/tools/envoy_release b/tools/envoy_release index 11d6ae8ef..46aa51be0 100644 --- a/tools/envoy_release +++ b/tools/envoy_release @@ -1 +1 @@ -v1.29.2 +v1.30.1