genratelimit

package module
v0.0.0-...-d225e58 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 10, 2024 License: MIT Imports: 15 Imported by: 0

README

protoc-gen-ratelimit

This is a Rate Limit generator for Google Protocol Buffers compiler protoc. The plugin generates a Lua filter to bucket requests based on their paths, and a descriptor file for envoyproxy/ratelimit.

Installation

go get -u github.com/SafetyCulture/protoc-gen-ratelimit/cmd/protoc-gen-ratelimit

Usage

The plugin is invoked by passing the --ratelimit_out, and --ratelimit_opt options to the protoc compiler. The option has the following format:

--doc_opt=ratelimit/config.yaml

Annotations for rate limits can be applied at the service or method level. Here is an example of what that looks like:

service TasksService {
  option (s12.protobuf.ratelimit.api_limit) = {
    limits: {
      key: "public_api",
      value: {
        unit: "minute"
        requests_per_unit: 100
      }
    }
    limits: {
      key: "private_api",
      value: {
        unit: "minute"
        requests_per_unit: 400
      }
    }
  };

  // CreateTask is used to create a new task.
  rpc CreateTask(CreateTaskRequest) returns (CreateTaskResponse) {
    option (s12.protobuf.ratelimit.limit) = {
      limits: {
        key: "public_api",
        value: {
          unit: "minute"
          requests_per_unit: 10
        }
      }
      limits: {
        key: "private_api",
        value: {
          unit: "minute"
          requests_per_unit: 20
        }
      }
    };
  }

  // GetTask returns a task by id.
  rpc GetTask(GetTaskRequest) returns (GetTaskResponse) {}

  rpc AddComment(AddCommentRequest) returns (AddCommentResponse) {
    option (s12.protobuf.ratelimit.limit) = {
      bucket: "TaskComments" // Custom bucket, so AddComment and UpdateComment can share a ratelimit
    };
  }
  rpc UpdateComment(AddCommentRequest) returns (AddCommentResponse) {
    option (s12.protobuf.ratelimit.limit) = {
      bucket: "TaskComments" // Custom bucket, so AddComment and UpdateComment can share a ratelimit
    };
  }
}

Additional or default limits can be configured within the configuration file given to protoc-gen-ratelimit.

The format for key in both the configuration and proto file is a pipe separated string of values for the ratelimit descriptors. These map to the descriptors list supplied to the config base on their order. For example given a configuration of

descriptors:
  - api_class
  - user_id
  - bucket # Must be the final descriptor
default_limits:
  # Rate limit applied to the `TasksComments` bucket
  - key: "public_api||TasksComments"
    value:
      unit: minute
      requests_per_unit: 20

public_api||TasksComments maps to api_class=public_api,user_id:"",bucket:"TaskComments".

Example Configuration
descriptors:
  - api_class
  - user_id
  - bucket # Must be the final descriptor
default_limits:
  # All APIs have a limit of 800 RPM
  - key: ""
    value:
      unit: minute
      requests_per_unit: 800

  # Private APIs have no limits by default
  - key: "private_api"
    value:
      unlimited: true

  # This customer is running a migration, temporarily increase their limit
  - key: "|user_abc122"
    value:
      unlimited: true

  # Rate limit applied to the `TasksComments` bucket
  - key: "public_api||TasksComments"
    value:
      unit: minute
      requests_per_unit: 20

A complete example can be found in protos/.

Development

This repo uses buf to build Protocol Buffers.

To generate the image for fixtures run buf build -o fixtures/image.bin.

To generate the annotations Go package run buf generate.

Documentation

Index

Constants

View Source
const VERSION = "1.0.0"

VERSION is the version of protoc-gen-ratelimit being used.

Variables

SupportedFeatures describes a flag setting for supported features.

Functions

func GenerateLuaBucketer

func GenerateLuaBucketer(template *gendoc.Template) ([]byte, error)

GenerateLuaBucketer generates the Lua bucketer

func GenerateRateLimitsConfig

func GenerateRateLimitsConfig(template *gendoc.Template, cfg Config) ([]byte, error)

GenerateRateLimitsConfig generates a YAML file containing the rate limits

Types

type Config

type Config struct {
	Domain        string   `yaml:"domain"`
	Descriptors   []string `yaml:"descriptors"`
	DefaultLimits []Limit  `yaml:"default_limits"`
	Delimiter     string   `yaml:"delimiter"`
}

Config is the configuration of the plugin

type Limit

type Limit struct {
	Key   string
	Value *YamlRateLimit
}

Limit is the limit applied to specific descriptors

type Plugin

type Plugin struct{}

Plugin describes a protoc code generate plugin. It's an implementation of Plugin from github.com/pseudomuto/protokit

func (*Plugin) Generate

Generate compiles the documentation and generates the CodeGeneratorResponse to send back to protoc. It does this by rendering a template based on the options parsed from the CodeGeneratorRequest.

type PluginOptions

type PluginOptions struct {
	ConfigFile string
}

PluginOptions encapsulates options for the plugin. The type of renderer, template file, and the name of the output file are included.

func ParseOptions

func ParseOptions(req *plugin_go.CodeGeneratorRequest) (*PluginOptions, error)

ParseOptions parses plugin options from a CodeGeneratorRequest. It does this by splitting the `Parameter` field from the request object and parsing out the type of renderer to use and the name of the file to be generated.

The parameter (`--doc_opt`) must be of the format <TYPE|TEMPLATE_FILE>,<OUTPUT_FILE>[,default|source_relative]:<EXCLUDE_PATTERN>,<EXCLUDE_PATTERN>*. The file will be written to the directory specified with the `--doc_out` argument to protoc.

type YamlDescriptor

type YamlDescriptor struct {
	Key         string
	Value       string            `yaml:"value,omitempty"`
	RateLimit   *YamlRateLimit    `yaml:"rate_limit,omitempty"`
	Descriptors []*YamlDescriptor `yaml:"descriptors,omitempty"`
}

YamlDescriptor is the description of a rate limiting tuple

type YamlRateLimit

type YamlRateLimit struct {
	RequestsPerUnit uint32 `yaml:"requests_per_unit,omitempty"`
	Unit            string `yaml:"unit,omitempty"`
	Unlimited       bool   `yaml:"unlimited,omitempty"`
}

YamlRateLimit is the rate limit being applied to a descriptor

type YamlRoot

type YamlRoot struct {
	Domain      string
	Descriptors []*YamlDescriptor
}

YamlRoot is the root of the YAML document

Directories

Path Synopsis
cmd
protoc-gen-ratelimit
protoc-gen-ratelimit is used to generate supporting files for https://github.com/envoyproxy/ratelimit.
protoc-gen-ratelimit is used to generate supporting files for https://github.com/envoyproxy/ratelimit.
extensions
s12

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL