Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add account name tag to monitoring endpoints #6310

Merged
merged 5 commits into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions server/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ type Account struct {
stats
gwReplyMapping
Name string
LogicalName string
Nkey string
Issuer string
claimJWT string
Expand Down Expand Up @@ -257,10 +256,9 @@ type importMap struct {
// NewAccount creates a new unlimited account with the given name.
func NewAccount(name string) *Account {
a := &Account{
Name: name,
LogicalName: name,
limits: limits{-1, -1, -1, -1, false},
eventIds: nuid.New(),
Name: name,
limits: limits{-1, -1, -1, -1, false},
eventIds: nuid.New(),
}
return a
}
Expand Down Expand Up @@ -462,6 +460,20 @@ func (a *Account) GetName() string {
return name
}

// getNameTag will return the name tag or the account name if not set.
func (a *Account) getNameTag() string {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the context of monitoring and operator mode, this PR makes the assumption that if an explicit JWT name (not the subject) is not set, the name tag will default to the JWT which equates to the account name.

This may seem redundant, but the purpose is that its a consistent way to report on a standard value regardless if the name is set.

if a == nil {
return _EMPTY_
}
a.mu.RLock()
nameTag := a.nameTag
bruth marked this conversation as resolved.
Show resolved Hide resolved
if nameTag == _EMPTY_ {
nameTag = a.Name
}
a.mu.RUnlock()
return nameTag
}

// NumConnections returns active number of clients for this account for
// all known servers.
func (a *Account) NumConnections() int {
Expand Down Expand Up @@ -3818,8 +3830,6 @@ func (s *Server) updateAccountClaimsWithRefresh(a *Account, ac *jwt.AccountClaim
func (s *Server) buildInternalAccount(ac *jwt.AccountClaims) *Account {
acc := NewAccount(ac.Subject)
acc.Issuer = ac.Issuer
// Override subject with logical name.
acc.LogicalName = ac.Name
// Set this here since we are placing in s.tmpAccounts below and may be
// referenced by an route RS+, etc.
s.setAccountSublist(acc)
Expand Down
15 changes: 10 additions & 5 deletions server/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -2337,9 +2337,14 @@ func (s *Server) sendAccConnsUpdate(a *Account, subj ...string) {
func (a *Account) statz() *AccountStat {
localConns := a.numLocalConnections()
leafConns := a.numLocalLeafNodes()
// Do not use getNameTag() to avoid a deadlock with `registerWithAccount`.
nameTag := a.nameTag
if nameTag == _EMPTY_ {
nameTag = a.Name
}
return &AccountStat{
Account: a.Name,
Name: a.LogicalName,
Name: nameTag,
Conns: localConns,
LeafNodes: leafConns,
TotalConns: localConns + leafConns,
Expand Down Expand Up @@ -2410,7 +2415,7 @@ func (s *Server) accountConnectEvent(c *client) {
Jwt: c.opts.JWT,
IssuerKey: issuerForClient(c),
Tags: c.tags,
NameTag: c.nameTag,
NameTag: c.acc.getNameTag(),
Kind: c.kindString(),
ClientType: c.clientTypeString(),
MQTTClient: c.getMQTTClientID(),
Expand Down Expand Up @@ -2462,7 +2467,7 @@ func (s *Server) accountDisconnectEvent(c *client, now time.Time, reason string)
Jwt: c.opts.JWT,
IssuerKey: issuerForClient(c),
Tags: c.tags,
NameTag: c.nameTag,
NameTag: c.acc.getNameTag(),
Kind: c.kindString(),
ClientType: c.clientTypeString(),
MQTTClient: c.getMQTTClientID(),
Expand Down Expand Up @@ -2516,7 +2521,7 @@ func (s *Server) sendAuthErrorEvent(c *client) {
Jwt: c.opts.JWT,
IssuerKey: issuerForClient(c),
Tags: c.tags,
NameTag: c.nameTag,
NameTag: c.acc.getNameTag(),
Kind: c.kindString(),
ClientType: c.clientTypeString(),
MQTTClient: c.getMQTTClientID(),
Expand Down Expand Up @@ -2574,7 +2579,7 @@ func (s *Server) sendAccountAuthErrorEvent(c *client, acc *Account, reason strin
Jwt: c.opts.JWT,
IssuerKey: issuerForClient(c),
Tags: c.tags,
NameTag: c.nameTag,
NameTag: c.acc.getNameTag(),
Kind: c.kindString(),
ClientType: c.clientTypeString(),
MQTTClient: c.getMQTTClientID(),
Expand Down
2 changes: 1 addition & 1 deletion server/jwt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4598,7 +4598,7 @@ func TestJWTUserRevocation(t *testing.T) {
t.Fatalf("Expected connection to have failed")
}
m := <-ncChan
require_Len(t, strings.Count(string(m.Data), apub), 2)
require_Len(t, strings.Count(string(m.Data), apub), 3)
require_True(t, strings.Contains(string(m.Data), `"jwt":"eyJ0`))
// try again with old credentials. Expected to fail
if nc1, err := nats.Connect(srv.ClientURL(), nats.UserCredentials(aCreds1)); err == nil {
Expand Down
73 changes: 37 additions & 36 deletions server/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,14 +415,13 @@ func (s *Server) Connz(opts *ConnzOptions) (*Connz, error) {
// Fill in user if auth requested.
if auth {
ci.AuthorizedUser = client.getRawAuthUser()
// Add in account iff not the global account.
if client.acc != nil && (client.acc.Name != globalAccountName) {
ci.Account = client.acc.Name
if name := client.acc.GetName(); name != globalAccountName {
ci.Account = name
}
ci.JWT = client.opts.JWT
ci.IssuerKey = issuerForClient(client)
ci.Tags = client.tags
ci.NameTag = client.nameTag
ci.NameTag = client.acc.getNameTag()
bruth marked this conversation as resolved.
Show resolved Hide resolved
}
client.mu.Unlock()
pconns[i] = ci
Expand Down Expand Up @@ -465,9 +464,11 @@ func (s *Server) Connz(opts *ConnzOptions) (*Connz, error) {
// Fill in user if auth requested.
if auth {
cc.AuthorizedUser = cc.user
// Add in account iff not the global account.
if cc.acc != _EMPTY_ && (cc.acc != globalAccountName) {
bruth marked this conversation as resolved.
Show resolved Hide resolved
cc.Account = cc.acc
if acc, err := s.LookupAccount(cc.acc); err == nil {
cc.NameTag = acc.getNameTag()
}
}
}
pconns[i] = &cc.ConnInfo
Expand Down Expand Up @@ -925,21 +926,21 @@ type SubszOptions struct {

// SubDetail is for verbose information for subscriptions.
type SubDetail struct {
Account string `json:"account,omitempty"`
Subject string `json:"subject"`
Queue string `json:"qgroup,omitempty"`
Sid string `json:"sid"`
Msgs int64 `json:"msgs"`
Max int64 `json:"max,omitempty"`
Cid uint64 `json:"cid"`
Account string `json:"account,omitempty"`
AccountTag string `json:"account_tag,omitempty"`
Subject string `json:"subject"`
Queue string `json:"qgroup,omitempty"`
Sid string `json:"sid"`
Msgs int64 `json:"msgs"`
Max int64 `json:"max,omitempty"`
Cid uint64 `json:"cid"`
}

// Subscription client should be locked and guaranteed to be present.
func newSubDetail(sub *subscription) SubDetail {
sd := newClientSubDetail(sub)
if sub.client.acc != nil {
sd.Account = sub.client.acc.Name
}
sd.Account = sub.client.acc.GetName()
bruth marked this conversation as resolved.
Show resolved Hide resolved
sd.AccountTag = sub.client.acc.getNameTag()
return sd
}

Expand Down Expand Up @@ -2713,27 +2714,27 @@ func (s *Server) accountInfo(accName string) (*AccountInfo, error) {
mappings[src] = dests
}
return &AccountInfo{
accName,
a.updated.UTC(),
isSys,
a.expired.Load(),
!a.incomplete,
a.js != nil,
a.numLocalLeafNodes(),
a.numLocalConnections(),
a.sl.Count(),
mappings,
exports,
imports,
a.claimJWT,
a.Issuer,
a.nameTag,
a.tags,
claim,
vrIssues,
collectRevocations(a.usersRevoked),
a.sl.Stats(),
responses,
AccountName: accName,
LastUpdate: a.updated.UTC(),
IsSystem: isSys,
Expired: a.expired.Load(),
Complete: !a.incomplete,
JetStream: a.js != nil,
LeafCnt: a.numLocalLeafNodes(),
ClientCnt: a.numLocalConnections(),
SubCnt: a.sl.Count(),
Mappings: mappings,
Exports: exports,
Imports: imports,
Jwt: a.claimJWT,
IssuerKey: a.Issuer,
NameTag: a.getNameTag(),
Tags: a.tags,
Claim: claim,
Vr: vrIssues,
RevokedUser: collectRevocations(a.usersRevoked),
Sublist: a.sl.Stats(),
Responses: responses,
}, nil
}

Expand Down
Loading
Loading