diff --git a/BUILD b/BUILD index 51248b22..4a8bfc14 100644 --- a/BUILD +++ b/BUILD @@ -131,6 +131,7 @@ proto_library( "//envoy/extensions/compression/brotli/decompressor/v3:pkg", "//envoy/extensions/compression/gzip/compressor/v3:pkg", "//envoy/extensions/compression/gzip/decompressor/v3:pkg", + "//envoy/extensions/config/validators/minimum_clusters/v3:pkg", "//envoy/extensions/filters/common/dependency/v3:pkg", "//envoy/extensions/filters/common/fault/v3:pkg", "//envoy/extensions/filters/common/matcher/action/v3:pkg", diff --git a/envoy/config/core/v3/config_source.proto b/envoy/config/core/v3/config_source.proto index cce94027..a49a05de 100644 --- a/envoy/config/core/v3/config_source.proto +++ b/envoy/config/core/v3/config_source.proto @@ -3,8 +3,10 @@ syntax = "proto3"; package envoy.config.core.v3; import "envoy/config/core/v3/base.proto"; +import "envoy/config/core/v3/extension.proto"; import "envoy/config/core/v3/grpc_service.proto"; +import "google/protobuf/any.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/wrappers.proto"; @@ -40,7 +42,7 @@ enum ApiVersion { // API configuration source. This identifies the API type and cluster that Envoy // will use to fetch an xDS API. -// [#next-free-field: 9] +// [#next-free-field: 10] message ApiConfigSource { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.core.ApiConfigSource"; @@ -108,6 +110,16 @@ message ApiConfigSource { // Skip the node identifier in subsequent discovery requests for streaming gRPC config types. bool set_node_on_first_message_only = 7; + + // A list of config validators that will be executed when a new update is + // received from the ApiConfigSource. Note that each validator handles a + // specific xDS service type, and only the validators corresponding to the + // type url (in `:ref: DiscoveryResponse` or `:ref: DeltaDiscoveryResponse`) + // will be invoked. + // If the validator returns false or throws an exception, the config will be rejected by + // the client, and a NACK will be sent. + // [#extension-category: envoy.config.validators] + repeated TypedExtensionConfig config_validators = 9; } // Aggregated Discovery Service (ADS) options. This is currently empty, but when @@ -240,3 +252,32 @@ message ConfigSource { // turn expect to be delivered. ApiVersion resource_api_version = 6 [(validate.rules).enum = {defined_only: true}]; } + +// Configuration source specifier for a late-bound extension configuration. The +// parent resource is warmed until all the initial extension configurations are +// received, unless the flag to apply the default configuration is set. +// Subsequent extension updates are atomic on a per-worker basis. Once an +// extension configuration is applied to a request or a connection, it remains +// constant for the duration of processing. If the initial delivery of the +// extension configuration fails, due to a timeout for example, the optional +// default configuration is applied. Without a default configuration, the +// extension is disabled, until an extension configuration is received. The +// behavior of a disabled extension depends on the context. For example, a +// filter chain with a disabled extension filter rejects all incoming streams. +message ExtensionConfigSource { + ConfigSource config_source = 1 [(validate.rules).any = {required: true}]; + + // Optional default configuration to use as the initial configuration if + // there is a failure to receive the initial extension configuration or if + // `apply_default_config_without_warming` flag is set. + google.protobuf.Any default_config = 2; + + // Use the default config as the initial configuration without warming and + // waiting for the first discovery response. Requires the default configuration + // to be supplied. + bool apply_default_config_without_warming = 3; + + // A set of permitted extension type URLs. Extension configuration updates are rejected + // if they do not match any type URL in the set. + repeated string type_urls = 4 [(validate.rules).repeated = {min_items: 1}]; +} diff --git a/envoy/config/core/v3/extension.proto b/envoy/config/core/v3/extension.proto index 12a37cd8..80afce69 100644 --- a/envoy/config/core/v3/extension.proto +++ b/envoy/config/core/v3/extension.proto @@ -2,8 +2,6 @@ syntax = "proto3"; package envoy.config.core.v3; -import "envoy/config/core/v3/config_source.proto"; - import "google/protobuf/any.proto"; import "udpa/annotations/status.proto"; @@ -32,32 +30,3 @@ message TypedExtensionConfig { // ` for further details. google.protobuf.Any typed_config = 2 [(validate.rules).any = {required: true}]; } - -// Configuration source specifier for a late-bound extension configuration. The -// parent resource is warmed until all the initial extension configurations are -// received, unless the flag to apply the default configuration is set. -// Subsequent extension updates are atomic on a per-worker basis. Once an -// extension configuration is applied to a request or a connection, it remains -// constant for the duration of processing. If the initial delivery of the -// extension configuration fails, due to a timeout for example, the optional -// default configuration is applied. Without a default configuration, the -// extension is disabled, until an extension configuration is received. The -// behavior of a disabled extension depends on the context. For example, a -// filter chain with a disabled extension filter rejects all incoming streams. -message ExtensionConfigSource { - ConfigSource config_source = 1 [(validate.rules).any = {required: true}]; - - // Optional default configuration to use as the initial configuration if - // there is a failure to receive the initial extension configuration or if - // `apply_default_config_without_warming` flag is set. - google.protobuf.Any default_config = 2; - - // Use the default config as the initial configuration without warming and - // waiting for the first discovery response. Requires the default configuration - // to be supplied. - bool apply_default_config_without_warming = 3; - - // A set of permitted extension type URLs. Extension configuration updates are rejected - // if they do not match any type URL in the set. - repeated string type_urls = 4 [(validate.rules).repeated = {min_items: 1}]; -} diff --git a/envoy/config/listener/v3/listener_components.proto b/envoy/config/listener/v3/listener_components.proto index 5d86b797..1116031c 100644 --- a/envoy/config/listener/v3/listener_components.proto +++ b/envoy/config/listener/v3/listener_components.proto @@ -4,7 +4,7 @@ package envoy.config.listener.v3; import "envoy/config/core/v3/address.proto"; import "envoy/config/core/v3/base.proto"; -import "envoy/config/core/v3/extension.proto"; +import "envoy/config/core/v3/config_source.proto"; import "envoy/type/v3/range.proto"; import "google/protobuf/any.proto"; diff --git a/envoy/extensions/config/validators/minimum_clusters/v3/BUILD b/envoy/extensions/config/validators/minimum_clusters/v3/BUILD new file mode 100644 index 00000000..ee92fb65 --- /dev/null +++ b/envoy/extensions/config/validators/minimum_clusters/v3/BUILD @@ -0,0 +1,9 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = ["@com_github_cncf_udpa//udpa/annotations:pkg"], +) diff --git a/envoy/extensions/config/validators/minimum_clusters/v3/minimum_clusters.proto b/envoy/extensions/config/validators/minimum_clusters/v3/minimum_clusters.proto new file mode 100644 index 00000000..2a24d7a0 --- /dev/null +++ b/envoy/extensions/config/validators/minimum_clusters/v3/minimum_clusters.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +package envoy.extensions.config.validators.minimum_clusters.v3; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.config.validators.minimum_clusters.v3"; +option java_outer_classname = "MinimumClustersProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/config/validators/minimum_clusters/v3;minimum_clustersv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Minimum Clusters] +// [#extension: envoy.config.validators.minimum_clusters] + +// Validates a CDS config, and ensures that the number of clusters is above the +// set threshold. +message MinimumClustersValidator { + // The minimal clusters threshold. Any CDS config update leading to less than + // this number will be rejected. + // Default value is 0. + uint32 min_clusters_num = 1; +} diff --git a/versioning/BUILD b/versioning/BUILD index ec1462ad..8da30302 100644 --- a/versioning/BUILD +++ b/versioning/BUILD @@ -68,6 +68,7 @@ proto_library( "//envoy/extensions/compression/brotli/decompressor/v3:pkg", "//envoy/extensions/compression/gzip/compressor/v3:pkg", "//envoy/extensions/compression/gzip/decompressor/v3:pkg", + "//envoy/extensions/config/validators/minimum_clusters/v3:pkg", "//envoy/extensions/filters/common/dependency/v3:pkg", "//envoy/extensions/filters/common/fault/v3:pkg", "//envoy/extensions/filters/common/matcher/action/v3:pkg",