mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-15 18:50:41 -07:00
Merge pull request #767 from nats-io/global_account
Support for global/reserved accounts
This commit is contained in:
@@ -108,8 +108,9 @@ func TestAccountFromOptions(t *testing.T) {
|
||||
}
|
||||
s := New(&opts)
|
||||
|
||||
if la := len(s.accounts); la != 2 {
|
||||
t.Fatalf("Expected to have a server with two accounts, got %v", la)
|
||||
ta := s.numReservedAccounts() + 2
|
||||
if la := len(s.accounts); la != ta {
|
||||
t.Fatalf("Expected to have a server with %d total accounts, got %v", ta, la)
|
||||
}
|
||||
// Check that sl is filled in.
|
||||
fooAcc := s.LookupAccount("foo")
|
||||
@@ -1003,6 +1004,27 @@ func TestAccountMapsUsers(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccountGlobalDefault(t *testing.T) {
|
||||
opts := defaultServerOptions
|
||||
s := New(&opts)
|
||||
|
||||
if acc := s.LookupAccount(globalAccountName); acc == nil {
|
||||
t.Fatalf("Expected a global default account on a new server, got none.")
|
||||
}
|
||||
// Make sure we can not create one with same name..
|
||||
if _, err := s.RegisterAccount(globalAccountName); err == nil {
|
||||
t.Fatalf("Expected error trying to create a new reserved account")
|
||||
}
|
||||
|
||||
// Make sure we can not define one in a config file either.
|
||||
confFileName := createConfFile(t, []byte(`accounts { $G {} }`))
|
||||
defer os.Remove(confFileName)
|
||||
|
||||
if _, err := ProcessConfigFile(confFileName); err == nil {
|
||||
t.Fatalf("Expected an error parsing config file with reserved account")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNewRouteReply(b *testing.B) {
|
||||
opts := defaultServerOptions
|
||||
s := New(&opts)
|
||||
|
||||
@@ -41,6 +41,10 @@ type ClientAuthentication interface {
|
||||
RegisterUser(*User)
|
||||
}
|
||||
|
||||
// For backwards compatibility, users who are not explicitly defined into an
|
||||
// account will be grouped in the default global account.
|
||||
const globalAccountName = "$G"
|
||||
|
||||
// Accounts
|
||||
type Account struct {
|
||||
Name string
|
||||
|
||||
@@ -56,6 +56,9 @@ var (
|
||||
// ErrBadAccount represents a malformed or incorrect account.
|
||||
ErrBadAccount = errors.New("Bad Account")
|
||||
|
||||
// ErrReservedAccount represents a reserved account that can not be created.
|
||||
ErrReservedAccount = errors.New("Reserved Account")
|
||||
|
||||
// ErrMissingAccount is returned when an account does not exist.
|
||||
ErrMissingAccount = errors.New("Account Missing")
|
||||
|
||||
|
||||
@@ -627,6 +627,11 @@ type importService struct {
|
||||
to string
|
||||
}
|
||||
|
||||
// Checks if an account name is reserved.
|
||||
func isReservedAccount(name string) bool {
|
||||
return name == globalAccountName
|
||||
}
|
||||
|
||||
// parseAccounts will parse the different accounts syntax.
|
||||
func parseAccounts(v interface{}, opts *Options) error {
|
||||
var (
|
||||
@@ -643,6 +648,10 @@ func parseAccounts(v interface{}, opts *Options) error {
|
||||
m := make(map[string]struct{}, len(v.([]interface{})))
|
||||
for _, name := range v.([]interface{}) {
|
||||
ns := name.(string)
|
||||
// Check for reserved names.
|
||||
if isReservedAccount(ns) {
|
||||
return fmt.Errorf("%q is a Reserved Account", ns)
|
||||
}
|
||||
if _, ok := m[ns]; ok {
|
||||
return fmt.Errorf("Duplicate Account Entry: %s", ns)
|
||||
}
|
||||
@@ -661,6 +670,9 @@ func parseAccounts(v interface{}, opts *Options) error {
|
||||
if !ok {
|
||||
return fmt.Errorf("Expected map entries for accounts")
|
||||
}
|
||||
if isReservedAccount(aname) {
|
||||
return fmt.Errorf("%q is a Reserved Account", aname)
|
||||
}
|
||||
acc := &Account{Name: aname}
|
||||
opts.Accounts = append(opts.Accounts, acc)
|
||||
|
||||
|
||||
@@ -196,6 +196,9 @@ func New(opts *Options) *Server {
|
||||
// For tracking accounts
|
||||
s.accounts = make(map[string]*Account)
|
||||
|
||||
// Create global account.
|
||||
s.registerAccount(&Account{Name: globalAccountName, sl: s.gsl})
|
||||
|
||||
// For tracking clients
|
||||
s.clients = make(map[uint64]*client)
|
||||
|
||||
@@ -302,6 +305,12 @@ func (s *Server) newAccountsAllowed() bool {
|
||||
return s.opts.AllowNewAccounts
|
||||
}
|
||||
|
||||
// numReservedAccounts will return the number of reserved accounts configured in the server.
|
||||
// Currently this is 1 for the global default service.
|
||||
func (s *Server) numReservedAccounts() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
// LookupOrRegisterAccount will return the given account if known or create a new entry.
|
||||
func (s *Server) LookupOrRegisterAccount(name string) (account *Account, isNew bool) {
|
||||
s.mu.Lock()
|
||||
@@ -1166,7 +1175,6 @@ func (s *Server) NumSubscriptions() uint32 {
|
||||
subs += acc.sl.Count()
|
||||
}
|
||||
}
|
||||
subs += s.gsl.Count()
|
||||
s.mu.Unlock()
|
||||
return subs
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user