Allow optional reporting of authorized user under connz

This commit is contained in:
Derek Collison
2016-05-15 10:07:37 -07:00
parent 46a9e6f0bc
commit 82f04baa12
4 changed files with 77 additions and 20 deletions

View File

@@ -8,7 +8,7 @@ import (
const (
// VERSION is the current version for the server.
VERSION = "0.8.1"
VERSION = "0.8.2"
// DEFAULT_PORT is the deault port for client connections.
DEFAULT_PORT = 4222

View File

@@ -36,25 +36,26 @@ type Connz struct {
// ConnInfo has detailed information on a per connection basis.
type ConnInfo struct {
Cid uint64 `json:"cid"`
IP string `json:"ip"`
Port int `json:"port"`
Start time.Time `json:"start"`
LastActivity time.Time `json:"last_activity"`
Uptime string `json:"uptime"`
Idle string `json:"idle"`
Pending int `json:"pending_bytes"`
InMsgs int64 `json:"in_msgs"`
OutMsgs int64 `json:"out_msgs"`
InBytes int64 `json:"in_bytes"`
OutBytes int64 `json:"out_bytes"`
NumSubs uint32 `json:"subscriptions"`
Name string `json:"name,omitempty"`
Lang string `json:"lang,omitempty"`
Version string `json:"version,omitempty"`
TLSVersion string `json:"tls_version,omitempty"`
TLSCipher string `json:"tls_cipher_suite,omitempty"`
Subs []string `json:"subscriptions_list,omitempty"`
Cid uint64 `json:"cid"`
IP string `json:"ip"`
Port int `json:"port"`
Start time.Time `json:"start"`
LastActivity time.Time `json:"last_activity"`
Uptime string `json:"uptime"`
Idle string `json:"idle"`
Pending int `json:"pending_bytes"`
InMsgs int64 `json:"in_msgs"`
OutMsgs int64 `json:"out_msgs"`
InBytes int64 `json:"in_bytes"`
OutBytes int64 `json:"out_bytes"`
NumSubs uint32 `json:"subscriptions"`
Name string `json:"name,omitempty"`
Lang string `json:"lang,omitempty"`
Version string `json:"version,omitempty"`
TLSVersion string `json:"tls_version,omitempty"`
TLSCipher string `json:"tls_cipher_suite,omitempty"`
AuthorizedUser string `json:"authorized_user,omitempty"`
Subs []string `json:"subscriptions_list,omitempty"`
}
// DefaultConnListSize is the default size of the connection list.
@@ -76,6 +77,7 @@ func (s *Server) HandleConnz(w http.ResponseWriter, r *http.Request) {
c := &Connz{}
c.Now = time.Now()
auth, _ := strconv.Atoi(r.URL.Query().Get("auth"))
subs, _ := strconv.Atoi(r.URL.Query().Get("subs"))
c.Offset, _ = strconv.Atoi(r.URL.Query().Get("offset"))
c.Limit, _ = strconv.Atoi(r.URL.Query().Get("limit"))
@@ -216,6 +218,7 @@ func (s *Server) HandleConnz(w http.ResponseWriter, r *http.Request) {
ci.IP = addr.IP.String()
}
// Fill in subscription data if requested.
if subs == 1 {
sublist := make([]*subscription, 0, len(client.subs))
for _, sub := range client.subs {
@@ -224,6 +227,11 @@ func (s *Server) HandleConnz(w http.ResponseWriter, r *http.Request) {
ci.Subs = castToSliceString(sublist)
}
// Fill in user if auth requested.
if auth == 1 {
ci.AuthorizedUser = client.opts.Username
}
client.mu.Unlock()
i++
}

View File

@@ -1,6 +1,7 @@
# Copyright 2016 Apcera Inc. All rights reserved.
listen: 127.0.0.1:4233
http: 127.0.0.1:8233
authorization {
users = [

View File

@@ -377,6 +377,54 @@ func TestConnzWithSubs(t *testing.T) {
}
}
func TestConnzWithAuth(t *testing.T) {
srv, opts := RunServerWithConfig("./configs/multi_user.conf")
defer srv.Shutdown()
endpoint := fmt.Sprintf("%s:%d", opts.Host, opts.Port)
curl := fmt.Sprintf("nats://%s:%s@%s/", opts.Users[0].Username, opts.Users[0].Password, endpoint)
nc, err := nats.Connect(curl)
if err != nil {
t.Fatalf("Got an error on Connect: %+v\n", err)
}
defer nc.Close()
ch := make(chan struct{})
nc.Subscribe("foo", func(m *nats.Msg) { ch <- struct{}{} })
nc.Publish("foo", []byte("Hello"))
// Wait for message
<-ch
url := fmt.Sprintf("http://localhost:%d/", opts.HTTPPort)
resp, err := http.Get(url + "connz?auth=1")
if err != nil {
t.Fatalf("Expected no error: Got %v\n", err)
}
if resp.StatusCode != 200 {
t.Fatalf("Expected a 200 response, got %d\n", resp.StatusCode)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatalf("Got an error reading the body: %v\n", err)
}
c := server.Connz{}
if err := json.Unmarshal(body, &c); err != nil {
t.Fatalf("Got an error unmarshalling the body: %v\n", err)
}
// Test that we have authorized_user and its Alice.
ci := c.Conns[0]
if ci.AuthorizedUser != opts.Users[0].Username {
t.Fatalf("Expected authorized_user to be %q, got %q\n",
opts.Users[0].Username, ci.AuthorizedUser)
}
}
func TestConnzWithOffsetAndLimit(t *testing.T) {
s := runMonitorServer()
defer s.Shutdown()