nomad: adding RPC endpoints for fetching Eval
This commit is contained in:
parent
9b921d9f92
commit
eff7170c77
|
@ -0,0 +1,49 @@
|
|||
package nomad
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/armon/go-metrics"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
)
|
||||
|
||||
// Eval endpoint is used for eval interactions
|
||||
type Eval struct {
|
||||
srv *Server
|
||||
}
|
||||
|
||||
// GetEval is used to request information about a specific evaluation
|
||||
func (e *Eval) GetEval(args *structs.EvalSpecificRequest,
|
||||
reply *structs.SingleEvalResponse) error {
|
||||
if done, err := e.srv.forward("Eval.GetEval", args, args, reply); done {
|
||||
return err
|
||||
}
|
||||
defer metrics.MeasureSince([]string{"nomad", "eval", "get_eval"}, time.Now())
|
||||
|
||||
// Look for the job
|
||||
snap, err := e.srv.fsm.State().Snapshot()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out, err := snap.GetEvalByID(args.EvalID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Setup the output
|
||||
if out != nil {
|
||||
reply.Eval = out
|
||||
reply.Index = out.ModifyIndex
|
||||
} else {
|
||||
// Use the last index that affected the nodes table
|
||||
index, err := snap.GetIndex("evals")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reply.Index = index
|
||||
}
|
||||
|
||||
// Set the query response
|
||||
e.srv.setQueryMeta(&reply.QueryMeta)
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package nomad
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/net-rpc-msgpackrpc"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
"github.com/hashicorp/nomad/testutil"
|
||||
)
|
||||
|
||||
func TestEvalEndpoint_GetEval(t *testing.T) {
|
||||
s1 := testServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
|
||||
// Create the register request
|
||||
eval1 := mockEval()
|
||||
s1.fsm.State().UpsertEval(1000, eval1)
|
||||
|
||||
// Lookup the eval
|
||||
get := &structs.EvalSpecificRequest{
|
||||
EvalID: eval1.ID,
|
||||
WriteRequest: structs.WriteRequest{Region: "region1"},
|
||||
}
|
||||
var resp structs.SingleEvalResponse
|
||||
if err := msgpackrpc.CallWithCodec(codec, "Eval.GetEval", get, &resp); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if resp.Index != 1000 {
|
||||
t.Fatalf("Bad index: %d %d", resp.Index, 1000)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(eval1, resp.Eval) {
|
||||
t.Fatalf("bad: %#v %#v", eval1, resp.Eval)
|
||||
}
|
||||
|
||||
// Lookup non-existing node
|
||||
get.EvalID = generateUUID()
|
||||
if err := msgpackrpc.CallWithCodec(codec, "Eval.GetEval", get, &resp); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if resp.Index != 1000 {
|
||||
t.Fatalf("Bad index: %d %d", resp.Index, 1000)
|
||||
}
|
||||
if resp.Eval != nil {
|
||||
t.Fatalf("unexpected eval")
|
||||
}
|
||||
}
|
|
@ -102,6 +102,7 @@ type endpoints struct {
|
|||
Status *Status
|
||||
Client *Client
|
||||
Job *Job
|
||||
Eval *Eval
|
||||
}
|
||||
|
||||
// NewServer is used to construct a new Nomad server from the
|
||||
|
@ -271,11 +272,13 @@ func (s *Server) setupRPC(tlsWrap tlsutil.DCWrapper) error {
|
|||
s.endpoints.Status = &Status{s}
|
||||
s.endpoints.Client = &Client{s}
|
||||
s.endpoints.Job = &Job{s}
|
||||
s.endpoints.Eval = &Eval{s}
|
||||
|
||||
// Register the handlers
|
||||
s.rpcServer.Register(s.endpoints.Status)
|
||||
s.rpcServer.Register(s.endpoints.Client)
|
||||
s.rpcServer.Register(s.endpoints.Job)
|
||||
s.rpcServer.Register(s.endpoints.Eval)
|
||||
|
||||
list, err := net.ListenTCP("tcp", s.config.RPCAddr)
|
||||
if err != nil {
|
||||
|
|
|
@ -173,6 +173,12 @@ type EvalDeleteRequest struct {
|
|||
WriteRequest
|
||||
}
|
||||
|
||||
// EvalSpecificRequest is used when we just need to specify a target evaluation
|
||||
type EvalSpecificRequest struct {
|
||||
EvalID string
|
||||
WriteRequest
|
||||
}
|
||||
|
||||
// GenericResponse is used to respond to a request where no
|
||||
// specific response information is needed.
|
||||
type GenericResponse struct {
|
||||
|
@ -191,6 +197,12 @@ type SingleJobResponse struct {
|
|||
QueryMeta
|
||||
}
|
||||
|
||||
// SingleEvalResponse is used to return a single evaluation
|
||||
type SingleEvalResponse struct {
|
||||
Eval *Evaluation
|
||||
QueryMeta
|
||||
}
|
||||
|
||||
const (
|
||||
NodeStatusInit = "initializing"
|
||||
NodeStatusReady = "ready"
|
||||
|
|
Loading…
Reference in New Issue