Fix panic when monitoring a local client node

Fixes a panic when accessing a.agent.Server() when agent is a client
instead. This pr removes a redundant ACL check since ACLs are validated
at the RPC layer. It also nil checks the agent server and uses Client()
when appropriate.
This commit is contained in:
Drew Bailey
2020-02-03 10:17:59 -05:00
parent e8136c0c66
commit 39a6c6374a
2 changed files with 46 additions and 12 deletions

View File

@@ -156,16 +156,6 @@ func (s *HTTPServer) AgentMembersRequest(resp http.ResponseWriter, req *http.Req
}
func (s *HTTPServer) AgentMonitor(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
var secret string
s.parseToken(req, &secret)
// Check agent read permissions
if aclObj, err := s.agent.Server().ResolveToken(secret); err != nil {
return nil, err
} else if aclObj != nil && !aclObj.AllowAgentRead() {
return nil, structs.ErrPermissionDenied
}
// Get the provided loglevel.
logLevel := req.URL.Query().Get("log_level")
if logLevel == "" {
@@ -229,8 +219,12 @@ func (s *HTTPServer) AgentMonitor(resp http.ResponseWriter, req *http.Request) (
handlerErr = CodedError(400, "No local Node and node_id not provided")
}
} else {
// No node id monitor server
handler, handlerErr = s.agent.Server().StreamingRpcHandler("Agent.Monitor")
// No node id monitor current server/client
if srv := s.agent.Server(); srv != nil {
handler, handlerErr = srv.StreamingRpcHandler("Agent.Monitor")
} else {
handler, handlerErr = s.agent.Client().StreamingRpcHandler("Agent.Monitor")
}
}
if handlerErr != nil {

View File

@@ -386,6 +386,46 @@ func TestHTTP_AgentMonitor(t *testing.T) {
require.Fail(t, err.Error())
})
}
// stream logs for a local client
{
req, err := http.NewRequest("GET", "/v1/agent/monitor?log_level=warn", nil)
require.Nil(t, err)
resp := newClosableRecorder()
defer resp.Close()
go func() {
// set server to nil to monitor as client
s.Agent.server = nil
_, err = s.Server.AgentMonitor(resp, req)
require.NoError(t, err)
}()
// send the same log until monitor sink is set up
maxLogAttempts := 10
tried := 0
out := ""
testutil.WaitForResult(func() (bool, error) {
if tried < maxLogAttempts {
s.Agent.logger.Warn("log that should be sent")
tried++
}
output, err := ioutil.ReadAll(resp.Body)
if err != nil {
return false, err
}
out += string(output)
want := `{"Data":"`
if strings.Contains(out, want) {
return true, nil
}
return false, fmt.Errorf("missing expected log, got: %v, want: %v", out, want)
}, func(err error) {
require.Fail(t, err.Error())
})
}
})
}