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