Merge pull request #2755 from nats-io/acc_config_limits

Added in ability to have account limits configured in server config.
This commit is contained in:
Derek Collison
2021-12-21 19:50:38 -08:00
committed by GitHub
5 changed files with 85 additions and 3 deletions

View File

@@ -1,4 +1,4 @@
// Copyright 2012-2019 The NATS Authors
// Copyright 2012-2021 The NATS Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

View File

@@ -278,6 +278,8 @@ func (a *Account) shallowCopy() *Account {
}
// JetStream
na.jsLimits = a.jsLimits
// Server config account limits.
na.limits = a.limits
return na
}

View File

@@ -3377,3 +3377,44 @@ func TestImportSubscriptionPartialOverlapWithTransform(t *testing.T) {
})
}
}
func TestAccountLimitsServerConfig(t *testing.T) {
cf := createConfFile(t, []byte(`
max_connections: 10
accounts {
MAXC {
users = [{user: derek, password: foo}]
limits {
max_connections: 5
max_subs: 10
max_payload: 32k
max_leafnodes: 1
}
}
}
`))
defer removeFile(t, cf)
s, _ := RunServerWithConfig(cf)
defer s.Shutdown()
acc, err := s.lookupAccount("MAXC")
require_NoError(t, err)
if mc := acc.MaxActiveConnections(); mc != 5 {
t.Fatalf("Did not set MaxActiveConnections properly, expected 5, got %d", mc)
}
if mlc := acc.MaxActiveLeafNodes(); mlc != 1 {
t.Fatalf("Did not set MaxActiveLeafNodes properly, expected 1, got %d", mlc)
}
// Do quick test on connections, but if they are registered above should be good.
for i := 0; i < 5; i++ {
_, err := nats.Connect(s.ClientURL(), nats.UserInfo("derek", "foo"))
require_NoError(t, err)
}
// Should fail.
_, err = nats.Connect(s.ClientURL(), nats.UserInfo("derek", "foo"))
require_Error(t, err)
}

View File

@@ -2315,6 +2315,39 @@ func parseAccountMappings(v interface{}, acc *Account, errors *[]error, warnings
return nil
}
// parseAccountLimits is called to parse account limits in a server config.
func parseAccountLimits(mv interface{}, acc *Account, errors *[]error, warnings *[]error) error {
var lt token
defer convertPanicToErrorList(&lt, errors)
tk, v := unwrapValue(mv, &lt)
am, ok := v.(map[string]interface{})
if !ok {
return &configErr{tk, fmt.Sprintf("Expected account limits to be a map/struct, got %+v", v)}
}
for k, v := range am {
tk, mv = unwrapValue(v, &lt)
switch strings.ToLower(k) {
case "max_connections", "max_conn":
acc.mconns = int32(mv.(int64))
case "max_subscriptions", "max_subs":
acc.msubs = int32(mv.(int64))
case "max_payload", "max_pay":
acc.mpay = int32(mv.(int64))
case "max_leafnodes", "max_leafs":
acc.mleafs = int32(mv.(int64))
default:
if !tk.IsUsedVariable() {
err := &configErr{tk, fmt.Sprintf("Unknown field %q parsing account limits", k)}
*errors = append(*errors, err)
}
}
}
return nil
}
// parseAccounts will parse the different accounts syntax.
func parseAccounts(v interface{}, opts *Options, errors *[]error, warnings *[]error) error {
var (
@@ -2435,6 +2468,12 @@ func parseAccounts(v interface{}, opts *Options, errors *[]error, warnings *[]er
*errors = append(*errors, err)
continue
}
case "limits":
err := parseAccountLimits(tk, acc, errors, warnings)
if err != nil {
*errors = append(*errors, err)
continue
}
default:
if !tk.IsUsedVariable() {
err := &unknownConfigFieldErr{
@@ -2574,7 +2613,7 @@ func parseAccounts(v interface{}, opts *Options, errors *[]error, warnings *[]er
*errors = append(*errors, &configErr{tk, msg})
continue
}
if service.to == "" {
if service.to == _EMPTY_ {
service.to = service.sub
}
if err := service.acc.AddServiceImport(ta, service.to, service.sub); err != nil {

View File

@@ -1,4 +1,4 @@
// Copyright 2012-2020 The NATS Authors
// Copyright 2012-2021 The NATS Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at