Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,5 @@ extensions/filters/http/oauth2 @rgs1 @derekargueta @snowp
/*/extensions/filters/common/local_ratelimit @mattklein123 @rgs1
# HTTP Kill Request
/*/extensions/filters/http/kill_request @qqustc @htuch
# Rate limit expression descriptor
/*/extensions/rate_limit_descriptors/expr @kyessenov @lizan
3 changes: 3 additions & 0 deletions REPO_LAYOUT.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ code/extensions, and allows us specify extension owners in [CODEOWNERS](CODEOWNE
`Envoy::Extensions::Upstreams` namespace.
* [watchdog](/source/extensions/watchdog): Watchdog extensions use the
`Envoy::Extensions::Watchdog` namespace.
* [descriptors](/source/extensions/rate_limit_descriptors): Rate limit
descriptor extensions use the `Envoy::Extensions::RateLimitDescriptors`
namespace.
* Each extension is contained wholly in its own namespace. E.g.,
`Envoy::Extensions::NetworkFilters::Echo`.
* Common code that is used by multiple extensions should be in a `common/` directory as close to
Expand Down
1 change: 1 addition & 0 deletions api/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ proto_library(
"//envoy/extensions/internal_redirect/previous_routes/v3:pkg",
"//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg",
"//envoy/extensions/network/socket_interface/v3:pkg",
"//envoy/extensions/rate_limit_descriptors/expr/v3:pkg",
"//envoy/extensions/retry/host/omit_host_metadata/v3:pkg",
"//envoy/extensions/retry/priority/previous_priorities/v3:pkg",
"//envoy/extensions/stat_sinks/wasm/v3:pkg",
Expand Down
5 changes: 4 additions & 1 deletion api/envoy/config/route/v3/route_components.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1544,7 +1544,7 @@ message VirtualCluster {
message RateLimit {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.RateLimit";

// [#next-free-field: 9]
// [#next-free-field: 10]
message Action {
option (udpa.annotations.versioning).previous_message_type =
"envoy.api.v2.route.RateLimit.Action";
Expand Down Expand Up @@ -1742,6 +1742,9 @@ message RateLimit {

// Rate limit on metadata.
MetaData metadata = 8;

// Rate limit descriptor extension. See the rate limit descriptor extensions documentation.
core.v3.TypedExtensionConfig extension = 9;
}
}

Expand Down
5 changes: 4 additions & 1 deletion api/envoy/config/route/v4alpha/route_components.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions api/envoy/extensions/rate_limit_descriptors/expr/v3/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# 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",
"@com_google_googleapis//google/api/expr/v1alpha1:syntax_proto",
],
)
41 changes: 41 additions & 0 deletions api/envoy/extensions/rate_limit_descriptors/expr/v3/expr.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
syntax = "proto3";

package envoy.extensions.rate_limit_descriptors.expr.v3;

import "google/api/expr/v1alpha1/syntax.proto";

import "udpa/annotations/status.proto";
import "validate/validate.proto";

option java_package = "io.envoyproxy.envoy.extensions.rate_limit_descriptors.expr.v3";
option java_outer_classname = "ExprProto";
option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: Rate limit descriptor expression]
// [#extension: envoy.rate_limit_descriptors.expr]

// The following descriptor entry is appended with a value computed
// from a symbolic Common Expression Language expression.
// See :ref:`attributes <arch_overview_attributes>` for the set of
// available attributes.
//
// .. code-block:: cpp
//
// ("<descriptor_key>", "<expression_value>")
message Descriptor {
// The key to use in the descriptor entry.
string descriptor_key = 1 [(validate.rules).string = {min_len: 1}];

// If set to true, Envoy skips the descriptor if the expression evaluates to an error.
// By default, the rate limit is not applied when an expression produces an error.
bool skip_if_error = 2;

oneof expr_specifier {
// Expression in a text form, e.g. "connection.requested_server_name".
string text = 3 [(validate.rules).string = {min_len: 1}];

// Parsed expression in AST form.
google.api.expr.v1alpha1.Expr parsed = 4;
}
}
1 change: 1 addition & 0 deletions api/versioning/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ proto_library(
"//envoy/extensions/internal_redirect/previous_routes/v3:pkg",
"//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg",
"//envoy/extensions/network/socket_interface/v3:pkg",
"//envoy/extensions/rate_limit_descriptors/expr/v3:pkg",
"//envoy/extensions/retry/host/omit_host_metadata/v3:pkg",
"//envoy/extensions/retry/priority/previous_priorities/v3:pkg",
"//envoy/extensions/stat_sinks/wasm/v3:pkg",
Expand Down
4 changes: 4 additions & 0 deletions bazel/repository_locations.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,7 @@ REPOSITORY_LOCATIONS_SPEC = dict(
extensions = [
"envoy.access_loggers.wasm",
"envoy.bootstrap.wasm",
"envoy.rate_limit_descriptors.expr",
"envoy.filters.http.rbac",
"envoy.filters.http.wasm",
"envoy.filters.network.rbac",
Expand All @@ -734,6 +735,7 @@ REPOSITORY_LOCATIONS_SPEC = dict(
extensions = [
"envoy.access_loggers.wasm",
"envoy.bootstrap.wasm",
"envoy.rate_limit_descriptors.expr",
"envoy.filters.http.rbac",
"envoy.filters.http.wasm",
"envoy.filters.network.rbac",
Expand Down Expand Up @@ -912,6 +914,7 @@ REPOSITORY_LOCATIONS_SPEC = dict(
extensions = [
"envoy.access_loggers.wasm",
"envoy.bootstrap.wasm",
"envoy.rate_limit_descriptors.expr",
"envoy.filters.http.wasm",
"envoy.filters.network.wasm",
"envoy.stat_sinks.wasm",
Expand All @@ -931,6 +934,7 @@ REPOSITORY_LOCATIONS_SPEC = dict(
extensions = [
"envoy.access_loggers.wasm",
"envoy.bootstrap.wasm",
"envoy.rate_limit_descriptors.expr",
"envoy.filters.http.wasm",
"envoy.filters.network.wasm",
"envoy.stat_sinks.wasm",
Expand Down
1 change: 1 addition & 0 deletions docs/root/api-v3/config/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ Extensions
upstream/upstream
wasm/wasm
watchdog/watchdog
descriptors/descriptors
8 changes: 8 additions & 0 deletions docs/root/api-v3/config/descriptors/descriptors.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Rate limit descriptors
======================

.. toctree::
:glob:
:maxdepth: 2

../../extensions/rate_limit_descriptors/expr/v3/*
17 changes: 17 additions & 0 deletions docs/root/configuration/http/http_filters/rate_limit_filter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,23 @@ the rate limit override of 42 requests per hour will be appended to the rate lim
requests_per_unit: 42
unit: HOUR

Descriptor extensions
---------------------

Rate limit descriptors are extensible with custom descriptors. For example, :ref:`computed descriptors
<envoy_v3_api_msg_extensions.rate_limit_descriptors.expr.v3.Descriptor>` extension allows using any of the
:ref:`request attributes <arch_overview_request_attributes>` as a descriptor value:

.. code-block:: yaml

actions:
- extension:
name: custom
typed_config:
"@type": type.googleapis.com/envoy.extensions.rate_limit_descriptors.expr.v3.Descriptor
descriptor_key: my_descriptor_name
text: request.method

Statistics
----------

Expand Down
2 changes: 2 additions & 0 deletions docs/root/version_history/current.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ New Features
* ratelimit: added support for use of various :ref:`metadata <envoy_v3_api_field_config.route.v3.RateLimit.Action.metadata>` as a ratelimit action.
* ratelimit: added :ref:`disable_x_envoy_ratelimited_header <envoy_v3_api_msg_extensions.filters.http.ratelimit.v3.RateLimit>` option to disable `X-Envoy-RateLimited` header.
* ratelimit: added :ref:`body <envoy_v3_api_field_service.ratelimit.v3.RateLimitResponse.raw_body>` field to support custom response bodies for non-OK responses from the external ratelimit service.
* ratelimit: added :ref:`descriptor extensions <envoy_v3_api_field_config.route.v3.RateLimit.Action.extension>`.
* ratelimit: added :ref:`computed descriptors <envoy_v3_api_msg_extensions.rate_limit_descriptors.expr.v3.Descriptor>`.
* ratelimit: added :ref:`dynamic_metadata <envoy_v3_api_field_service.ratelimit.v3.RateLimitResponse.dynamic_metadata>` field to support setting dynamic metadata from the ratelimit service.
* router: added support for regex rewrites during HTTP redirects using :ref:`regex_rewrite <envoy_v3_api_field_config.route.v3.RedirectAction.regex_rewrite>`.
* sds: improved support for atomic :ref:`key rotations <xds_certificate_rotation>` and added configurable rotation triggers for
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions include/envoy/ratelimit/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ envoy_cc_library(
name = "ratelimit_interface",
hdrs = ["ratelimit.h"],
deps = [
"//include/envoy/config:typed_config_interface",
"//include/envoy/http:header_map_interface",
"//include/envoy/protobuf:message_validator_interface",
"//include/envoy/stream_info:stream_info_interface",
"@envoy_api//envoy/type/v3:pkg_cc_proto",
],
)
49 changes: 49 additions & 0 deletions include/envoy/ratelimit/ratelimit.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
#include <string>
#include <vector>

#include "envoy/config/typed_config.h"
#include "envoy/http/header_map.h"
#include "envoy/protobuf/message_validator.h"
#include "envoy/stream_info/stream_info.h"
#include "envoy/type/v3/ratelimit_unit.pb.h"

#include "absl/types/optional.h"
Expand Down Expand Up @@ -34,5 +38,50 @@ struct Descriptor {
absl::optional<RateLimitOverride> limit_ = absl::nullopt;
};

/**
* Base interface for generic rate limit descriptor producer.
*/
class DescriptorProducer {
public:
virtual ~DescriptorProducer() = default;

/**
* Potentially append a descriptor entry to the end of descriptor.
* @param descriptor supplies the descriptor to optionally fill.
* @param local_service_cluster supplies the name of the local service cluster.
* @param headers supplies the header for the request.
* @param info stream info associated with the request
* @return true if the producer populated the descriptor.
*/
virtual bool populateDescriptor(Descriptor& descriptor, const std::string& local_service_cluster,
const Http::RequestHeaderMap& headers,
const StreamInfo::StreamInfo& info) const PURE;
};

using DescriptorProducerPtr = std::unique_ptr<DescriptorProducer>;

/**
* Implemented by each custom rate limit descriptor extension and registered via
* Registry::registerFactory() or the convenience class RegisterFactory.
*/
class DescriptorProducerFactory : public Config::TypedFactory {
public:
~DescriptorProducerFactory() override = default;

/**
* Creates a particular DescriptorProducer implementation.
*
* @param config supplies the configuration for the descriptor extension.
* @param validator configuration validation visitor.
* @return DescriptorProducerPtr the rate limit descriptor producer which will be used to populate
* rate limit descriptors.
*/
virtual DescriptorProducerPtr
createDescriptorProducerFromProto(const Protobuf::Message& config,
ProtobufMessage::ValidationVisitor& validator) PURE;

std::string category() const override { return "envoy.rate_limit_descriptors"; }
};

} // namespace RateLimit
} // namespace Envoy
1 change: 0 additions & 1 deletion include/envoy/router/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ envoy_cc_library(
hdrs = ["router_ratelimit.h"],
deps = [
"//include/envoy/http:filter_interface",
"//include/envoy/http:header_map_interface",
"//include/envoy/ratelimit:ratelimit_interface",
"@envoy_api//envoy/config/core/v3:pkg_cc_proto",
],
Expand Down
Loading