Merge pull request #767 from nats-io/global_account

Support for global/reserved accounts
This commit is contained in:
Derek Collison
2018-10-04 15:47:23 -07:00
committed by GitHub
5 changed files with 52 additions and 3 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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")

View File

@@ -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)

View File

@@ -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
}