mirror of
https://github.com/status-im/consul.git
synced 2025-01-11 06:16:08 +00:00
d4c435856b
Adds automation for generating the map of `gRPC Method Name → Rate Limit Type` used by the middleware introduced in #15550, and will ensure we don't forget to add new endpoints. Engineers must annotate their RPCs in the proto file like so: ``` rpc Foo(FooRequest) returns (FooResponse) { option (consul.internal.ratelimit.spec) = { operation_type: READ, }; } ``` When they run `make proto` a protoc plugin `protoc-gen-consul-rate-limit` will be installed that writes rate-limit specs as a JSON array to a file called `.ratelimit.tmp` (one per protobuf package/directory). After running Buf, `make proto` will execute a post-process script that will ingest all of the `.ratelimit.tmp` files and generate a Go file containing the mappings in the `agent/grpc-middleware` package. In the enterprise repository, it will write an additional file with the enterprise-only endpoints. If an engineer forgets to add the annotation to a new RPC, the plugin will return an error like so: ``` RPC Foo is missing rate-limit specification, fix it with: import "proto-public/annotations/ratelimit/ratelimit.proto"; service Bar { rpc Foo(...) returns (...) { option (hashicorp.consul.internal.ratelimit.spec) = { operation_type: OPERATION_READ | OPERATION_WRITE | OPERATION_EXEMPT, }; } } ``` In the future, this annotation can be extended to support rate-limit category (e.g. KV vs Catalog) and to determine the retry policy.
49 lines
1.1 KiB
Go
49 lines
1.1 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// update allows golden files to be updated based on the current output.
|
|
var update = flag.Bool("update", false, "update golden files")
|
|
|
|
func TestE2E(t *testing.T) {
|
|
// Generate new output
|
|
*flagPath = "./e2e/source.pb.go"
|
|
require.NoError(t, run(*flagPath))
|
|
|
|
raw, err := os.ReadFile("./e2e/source.rpcglue.pb.go")
|
|
require.NoError(t, err)
|
|
|
|
got := string(raw)
|
|
|
|
golden(t, got, "./e2e/source.rpcglue.pb.go")
|
|
}
|
|
|
|
// golden reads the expected value from the file at path and returns the
|
|
// value.
|
|
//
|
|
// If the `-update` flag is used with `go test`, the golden file will be
|
|
// updated to the value of actual.
|
|
func golden(t *testing.T, actual, path string) string {
|
|
t.Helper()
|
|
|
|
path += ".golden"
|
|
if *update {
|
|
if dir := filepath.Dir(path); dir != "." {
|
|
require.NoError(t, os.MkdirAll(dir, 0755))
|
|
}
|
|
err := os.WriteFile(path, []byte(actual), 0644)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
expected, err := os.ReadFile(path)
|
|
require.NoError(t, err)
|
|
return string(expected)
|
|
}
|