github.com/zoomfoo/nomad@v0.8.5-0.20180907175415-f28fd3a1a056/nomad/client_stats_endpoint.go (about) 1 package nomad 2 3 import ( 4 "errors" 5 "time" 6 7 metrics "github.com/armon/go-metrics" 8 "github.com/hashicorp/nomad/client/structs" 9 nstructs "github.com/hashicorp/nomad/nomad/structs" 10 ) 11 12 // ClientStats is used to forward RPC requests to the targed Nomad client's 13 // ClientStats endpoint. 14 type ClientStats struct { 15 srv *Server 16 } 17 18 func (s *ClientStats) Stats(args *nstructs.NodeSpecificRequest, reply *structs.ClientStatsResponse) error { 19 // We only allow stale reads since the only potentially stale information is 20 // the Node registration and the cost is fairly high for adding another hope 21 // in the forwarding chain. 22 args.QueryOptions.AllowStale = true 23 24 // Potentially forward to a different region. 25 if done, err := s.srv.forward("ClientStats.Stats", args, args, reply); done { 26 return err 27 } 28 defer metrics.MeasureSince([]string{"nomad", "client_stats", "stats"}, time.Now()) 29 30 // Check node read permissions 31 if aclObj, err := s.srv.ResolveToken(args.AuthToken); err != nil { 32 return err 33 } else if aclObj != nil && !aclObj.AllowNodeRead() { 34 return nstructs.ErrPermissionDenied 35 } 36 37 // Verify the arguments. 38 if args.NodeID == "" { 39 return errors.New("missing NodeID") 40 } 41 42 // Check if the node even exists and is compatible with NodeRpc 43 snap, err := s.srv.State().Snapshot() 44 if err != nil { 45 return err 46 } 47 48 // Make sure Node is new enough to support RPC 49 _, err = getNodeForRpc(snap, args.NodeID) 50 if err != nil { 51 return err 52 } 53 54 // Get the connection to the client 55 state, ok := s.srv.getNodeConn(args.NodeID) 56 if !ok { 57 58 // Determine the Server that has a connection to the node. 59 srv, err := s.srv.serverWithNodeConn(args.NodeID, s.srv.Region()) 60 if err != nil { 61 return err 62 } 63 64 if srv == nil { 65 return nstructs.ErrNoNodeConn 66 } 67 68 return s.srv.forwardServer(srv, "ClientStats.Stats", args, reply) 69 } 70 71 // Make the RPC 72 return NodeRpc(state.Session, "ClientStats.Stats", args, reply) 73 }