Skip to content

Commit

Permalink
Add table-style rate-limiting capability (#15)
Browse files Browse the repository at this point in the history
* add tableActions to proto
* add descriptor rules stuff to proto, change 'table' to 'set'
* Merge branch 'master' of https://github.com/solo-io/solo-apis into table-rate-limiting
* make generate-code
* run ci/check-code-gen.sh
  • Loading branch information
arianaw66 authored Nov 3, 2020
1 parent 5f4c88f commit bbe4f60
Show file tree
Hide file tree
Showing 4 changed files with 612 additions and 96 deletions.
104 changes: 100 additions & 4 deletions api/rate-limiter/v1alpha1/ratelimit.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ message RateLimitConfigSpec {
// Actions specify how the client (Envoy) will compose the descriptors that
// will be sent to the server to make a rate limiting decision.
repeated RateLimitActions rate_limits = 2;

// The set descriptors that will be applied to the server.
repeated SetDescriptor set_descriptors = 3;
}

// Each `RateLimitConfig` is an instance of one specific configuration type.
Expand Down Expand Up @@ -63,7 +66,7 @@ message RateLimitConfigStatus {
// Each configuration contains a top level descriptor list and potentially multiple nested lists beneath that.
// The format is:
//
// ```yaml
// ```
// descriptors:
// - key: <rule key: required>
// value: <rule value: optional>
Expand All @@ -80,7 +83,7 @@ message RateLimitConfigStatus {
// Otherwise, nested descriptors allow more complex matching and rate limiting scenarios.
message Descriptor {

// The key of the descriptor. Ths field is required.
// The key of the descriptor. This field is required.
string key = 1;

// Optional value for the descriptor. If omitted, the server will create a rate limit for
Expand Down Expand Up @@ -115,9 +118,80 @@ message Descriptor {
bool always_apply = 6;
}

// Each action in the list maps part of the request (or its context) to a descriptor. The tuple of descriptors
// A setDescriptor is a list of key/value pairs that the rate limit server uses to select
// the correct rate limit to use when limiting with the set style. Descriptors are case-sensitive.
//
// Each configuration contains a simpleDescriptor list and a rateLimit.
// The format is:
//
// ```
// set_descriptors:
// - simple_descriptors: (optional block)
// - key: <rule key: required>
// value: <rule value: optional>
// - ... (repetition of above)
// rate_limit:
// requests_per_unit: <see below: required>
// unit: <see below: required>
// always_apply: <bool value: optional>
// - ... (repetition of above)
// ```
//
// Each SetDescriptor defines a new Rate Limit "rule". When a request comes in, rate limit
// actions are applied to the request to generate descriptor tuples that are sent to the rate limit
// server. If any rule is triggered then the entire request returns HTTP 429 Too Many Requests.
//
// The `rate_limit` block sets up an actual rate limit rule.
message SetDescriptor {

// Simple descriptor key/value pairs.
repeated SimpleDescriptor simple_descriptors = 1;

// Rate limit rule for the descriptor.
RateLimit rate_limit = 2;

// Typically, rule priority is signalled by rule ordering, as the first rule match for
// the descriptor tuple generated by the rate limit actions is used.
//
// In some cases this is too restrictive; A boolean override can be specified. Any rule with `alwaysApply` set to `true` will
// always be considered for rate limiting, regardless of the rule's place in the ordered list of rules.
// The first rule to match will still be considered. (This can be a rule that also has `alwaysApply` set to `true`.)
//
// If any of these rules trigger rate limiting then the entire request will return a 429.
// Rules that are not considered for rate limiting are ignored in the
// rate limit server, and their request count is not incremented in the rate limit server cache.
//
// Defaults to false.
bool always_apply = 3;
}

// A simpleDescriptor is a list of key/value pairs that the rate limit server uses to select
// the correct rate limit to use when limiting with the set style. Descriptors are case-sensitive.
//
// The format is:
//
// ```
// simple_descriptors:
// - key: <rule key: required>
// value: <rule value: optional>
// - ... (repetition of above)
// ```
//
// Each simpleDescriptor in a simpleDescriptor list must have a key. It can also optionally have a value to enable
// a more specific match.
message SimpleDescriptor {

// The key of the descriptor. This field is required.
string key = 1;

// Optional value for the descriptor. If omitted, the server will create a rate limit for
// each value that is provided for this descriptor in rate limit requests.
string value = 2;
}

// Each action and setAction in the lists maps part of the request (or its context) to a descriptor. The tuple or set of descriptors
// generated by the provided actions is sent to the rate limit server and matched against rate limit rules.
// Order matters on the provided actions, e.g. the following actions:
// Order matters on provided actions but not on setActions, e.g. the following actions:
// - actions:
// - requestHeaders:
// descriptorKey: account_id
Expand All @@ -142,8 +216,30 @@ message Descriptor {
// rateLimit:
// requestsPerUnit: 20
// unit: MINUTE
//
// Similarly, the following setActions:
// - setActions:
// - requestHeaders:
// descriptorKey: account_id
// headerName: x-account-id
// - requestHeaders:
// descriptorKey: plan
// headerName: x-plan
// define an unordered descriptor set like so: {('account_id', '<x-account-id value>'), ('plan', '<x-plan value>')}
//
// This set would match the following setDescriptor:
//
// setDescriptors:
// - simpleDescriptors:
// - key: plan
// value: BASIC
// - key: account_id
// rateLimit:
// requestsPerUnit: 20
// unit: MINUTE
message RateLimitActions {
repeated Action actions = 1;
repeated Action set_actions = 2;
}

// A `RateLimit` specifies the actual rate limit that will be used when there is a match.
Expand Down
Loading

0 comments on commit bbe4f60

Please sign in to comment.