mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 18:35:44 +03:00
http: add alloc service registration agent HTTP endpoint.
This commit is contained in:
@@ -86,6 +86,8 @@ func (s *HTTPServer) AllocSpecificRequest(resp http.ResponseWriter, req *http.Re
|
||||
switch tokens[1] {
|
||||
case "stop":
|
||||
return s.allocStop(allocID, resp, req)
|
||||
case "services":
|
||||
return s.allocServiceRegistrations(resp, req, allocID)
|
||||
}
|
||||
|
||||
return nil, CodedError(404, resourceNotFoundErr)
|
||||
@@ -167,6 +169,39 @@ func (s *HTTPServer) allocStop(allocID string, resp http.ResponseWriter, req *ht
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
// allocServiceRegistrations returns a list of all service registrations
|
||||
// assigned to the job identifier. It is callable via the
|
||||
// /v1/allocation/:alloc_id/services HTTP API and uses the
|
||||
// structs.AllocServiceRegistrationsRPCMethod RPC method.
|
||||
func (s *HTTPServer) allocServiceRegistrations(
|
||||
resp http.ResponseWriter, req *http.Request, allocID string) (interface{}, error) {
|
||||
|
||||
// The endpoint only supports GET requests.
|
||||
if req.Method != http.MethodGet {
|
||||
return nil, CodedError(http.StatusMethodNotAllowed, ErrInvalidMethod)
|
||||
}
|
||||
|
||||
// Set up the request args and parse this to ensure the query options are
|
||||
// set.
|
||||
args := structs.AllocServiceRegistrationsRequest{AllocID: allocID}
|
||||
if s.parse(resp, req, &args.Region, &args.QueryOptions) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Perform the RPC request.
|
||||
var reply structs.AllocServiceRegistrationsResponse
|
||||
if err := s.agent.RPC(structs.AllocServiceRegistrationsRPCMethod, &args, &reply); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
setMeta(resp, &reply.QueryMeta)
|
||||
|
||||
if reply.Services == nil {
|
||||
return nil, CodedError(http.StatusNotFound, allocNotFoundErr)
|
||||
}
|
||||
return reply.Services, nil
|
||||
}
|
||||
|
||||
func (s *HTTPServer) ClientAllocRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
reqSuffix := strings.TrimPrefix(req.URL.Path, "/v1/client/allocation/")
|
||||
|
||||
|
||||
@@ -433,6 +433,119 @@ func TestHTTP_AllocStop(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestHTTP_allocServiceRegistrations(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
testFn func(srv *TestAgent)
|
||||
name string
|
||||
}{
|
||||
{
|
||||
testFn: func(s *TestAgent) {
|
||||
|
||||
// Grab the state, so we can manipulate it and test against it.
|
||||
testState := s.Agent.server.State()
|
||||
|
||||
// Generate an alloc and upsert this.
|
||||
alloc := mock.Alloc()
|
||||
require.NoError(t, testState.UpsertAllocs(
|
||||
structs.MsgTypeTestSetup, 10, []*structs.Allocation{alloc}))
|
||||
|
||||
// Generate a service registration, assigned the allocID to the
|
||||
// mocked allocation ID, and upsert this.
|
||||
serviceReg := mock.ServiceRegistrations()[0]
|
||||
serviceReg.AllocID = alloc.ID
|
||||
require.NoError(t, testState.UpsertServiceRegistrations(
|
||||
structs.MsgTypeTestSetup, 20, []*structs.ServiceRegistration{serviceReg}))
|
||||
|
||||
// Build the HTTP request.
|
||||
path := fmt.Sprintf("/v1/allocation/%s/services", alloc.ID)
|
||||
req, err := http.NewRequest(http.MethodGet, path, nil)
|
||||
require.NoError(t, err)
|
||||
respW := httptest.NewRecorder()
|
||||
|
||||
// Send the HTTP request.
|
||||
obj, err := s.Server.AllocSpecificRequest(respW, req)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Check the response.
|
||||
require.Equal(t, "20", respW.Header().Get("X-Nomad-Index"))
|
||||
require.ElementsMatch(t, []*structs.ServiceRegistration{serviceReg},
|
||||
obj.([]*structs.ServiceRegistration))
|
||||
},
|
||||
name: "alloc has registrations",
|
||||
},
|
||||
{
|
||||
testFn: func(s *TestAgent) {
|
||||
|
||||
// Grab the state, so we can manipulate it and test against it.
|
||||
testState := s.Agent.server.State()
|
||||
|
||||
// Generate an alloc and upsert this.
|
||||
alloc := mock.Alloc()
|
||||
require.NoError(t, testState.UpsertAllocs(
|
||||
structs.MsgTypeTestSetup, 10, []*structs.Allocation{alloc}))
|
||||
|
||||
// Build the HTTP request.
|
||||
path := fmt.Sprintf("/v1/allocation/%s/services", alloc.ID)
|
||||
req, err := http.NewRequest(http.MethodGet, path, nil)
|
||||
require.NoError(t, err)
|
||||
respW := httptest.NewRecorder()
|
||||
|
||||
// Send the HTTP request.
|
||||
obj, err := s.Server.AllocSpecificRequest(respW, req)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Check the response.
|
||||
require.Equal(t, "1", respW.Header().Get("X-Nomad-Index"))
|
||||
require.ElementsMatch(t, []*structs.ServiceRegistration{},
|
||||
obj.([]*structs.ServiceRegistration))
|
||||
},
|
||||
name: "alloc without registrations",
|
||||
},
|
||||
{
|
||||
testFn: func(s *TestAgent) {
|
||||
|
||||
// Build the HTTP request.
|
||||
path := fmt.Sprintf("/v1/allocation/%s/services", uuid.Generate())
|
||||
req, err := http.NewRequest(http.MethodGet, path, nil)
|
||||
require.NoError(t, err)
|
||||
respW := httptest.NewRecorder()
|
||||
|
||||
// Send the HTTP request.
|
||||
obj, err := s.Server.AllocSpecificRequest(respW, req)
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "allocation not found")
|
||||
require.Nil(t, obj)
|
||||
},
|
||||
name: "alloc not found",
|
||||
},
|
||||
{
|
||||
testFn: func(s *TestAgent) {
|
||||
|
||||
// Build the HTTP request.
|
||||
path := fmt.Sprintf("/v1/allocation/%s/services", uuid.Generate())
|
||||
req, err := http.NewRequest(http.MethodHead, path, nil)
|
||||
require.NoError(t, err)
|
||||
respW := httptest.NewRecorder()
|
||||
|
||||
// Send the HTTP request.
|
||||
obj, err := s.Server.AllocSpecificRequest(respW, req)
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "Invalid method")
|
||||
require.Nil(t, obj)
|
||||
},
|
||||
name: "alloc not found",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
httpTest(t, nil, tc.testFn)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHTTP_AllocStats(t *testing.T) {
|
||||
t.Parallel()
|
||||
require := require.New(t)
|
||||
|
||||
Reference in New Issue
Block a user