[#xx] node: Validate RPC limiter configuration
Some checks failed
DCO action / DCO (pull_request) Failing after 37s
Vulncheck / Vulncheck (pull_request) Successful in 1m12s
Build / Build Components (pull_request) Successful in 1m43s
Pre-commit hooks / Pre-commit (pull_request) Successful in 1m42s
Tests and linters / Run gofumpt (pull_request) Successful in 2m42s
Tests and linters / Tests with -race (pull_request) Successful in 3m1s
Tests and linters / Lint (pull_request) Successful in 3m11s
Tests and linters / Staticcheck (pull_request) Successful in 3m9s
Tests and linters / Tests (pull_request) Successful in 3m25s
Tests and linters / gopls check (pull_request) Successful in 3m36s

Validate that configured limits correspond to the methods registered earlier.

Signed-off-by: Aleksey Savchuk <a.savchuk@yadro.com>
This commit is contained in:
Aleksey Savchuk 2025-02-28 15:14:15 +03:00
parent e32e9c5005
commit 9e81952048
Signed by: a-savchuk
GPG key ID: 70C0A7FF6F9C4639

View file

@ -240,6 +240,10 @@ func initRPCLimiter(c *cfg) error {
limits = append(limits, limiting.KeyLimit{Keys: l.Methods, Limit: l.MaxOps})
}
if err := validateRPCLimits(c, limits); err != nil {
return fmt.Errorf("validate RPC limits: %w", err)
}
limiter, err := limiting.NewSemaphoreLimiter(limits)
if err != nil {
return fmt.Errorf("create RPC limiter: %w", err)
@ -248,3 +252,35 @@ func initRPCLimiter(c *cfg) error {
c.cfgGRPC.limiter.Store(limiter)
return nil
}
func validateRPCLimits(c *cfg, limits []limiting.KeyLimit) error {
availableMethods := getAvailableMethods(c.cfgGRPC.servers)
for _, limit := range limits {
for _, method := range limit.Keys {
if _, ok := availableMethods[method]; !ok {
return fmt.Errorf("set limit on unknown method %q", method)
}
}
}
return nil
}
func getAvailableMethods(servers []grpcServer) map[string]struct{} {
res := make(map[string]struct{})
for _, server := range servers {
for _, method := range getMethodsForServer(server.Server) {
res[method] = struct{}{}
}
}
return res
}
func getMethodsForServer(server *grpc.Server) []string {
var res []string
for service, info := range server.GetServiceInfo() {
for _, method := range info.Methods {
res = append(res, fmt.Sprintf("/%s/%s", service, method.Name))
}
}
return res
}