Merge pull request #3068 from hashicorp/f-add-deployments-search-api
Add deployments to search api
This commit is contained in:
commit
49542712f9
|
@ -241,6 +241,37 @@ func TestHTTP_Search_Nodes(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHTTP_Search_Deployments(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
t.Parallel()
|
||||||
|
httpTest(t, nil, func(s *TestAgent) {
|
||||||
|
state := s.Agent.server.State()
|
||||||
|
deployment := mock.Deployment()
|
||||||
|
assert.Nil(state.UpsertDeployment(999, deployment), "UpsertDeployment")
|
||||||
|
|
||||||
|
prefix := deployment.ID[:len(deployment.ID)-2]
|
||||||
|
data := structs.SearchRequest{Prefix: prefix, Context: structs.Deployments}
|
||||||
|
req, err := http.NewRequest("POST", "/v1/search", encodeReq(data))
|
||||||
|
assert.Nil(err)
|
||||||
|
|
||||||
|
respW := httptest.NewRecorder()
|
||||||
|
|
||||||
|
resp, err := s.Server.SearchRequest(respW, req)
|
||||||
|
assert.Nil(err)
|
||||||
|
|
||||||
|
res := resp.(structs.SearchResponse)
|
||||||
|
|
||||||
|
assert.Equal(1, len(res.Matches))
|
||||||
|
|
||||||
|
n := res.Matches[structs.Deployments]
|
||||||
|
assert.Equal(1, len(n))
|
||||||
|
assert.Contains(n, deployment.ID)
|
||||||
|
|
||||||
|
assert.Equal("999", respW.HeaderMap.Get("X-Nomad-Index"))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestHTTP_Search_NoJob(t *testing.T) {
|
func TestHTTP_Search_NoJob(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,8 @@ const (
|
||||||
var (
|
var (
|
||||||
// allContexts are the available contexts which are searched to find matches
|
// allContexts are the available contexts which are searched to find matches
|
||||||
// for a given prefix
|
// for a given prefix
|
||||||
allContexts = []structs.Context{structs.Allocs, structs.Jobs, structs.Nodes, structs.Evals}
|
allContexts = []structs.Context{structs.Allocs, structs.Jobs, structs.Nodes,
|
||||||
|
structs.Evals, structs.Deployments}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Search endpoint is used to look up matches for a given prefix and context
|
// Search endpoint is used to look up matches for a given prefix and context
|
||||||
|
@ -47,6 +48,8 @@ func (s *Search) getMatches(iter memdb.ResultIterator, prefix string) ([]string,
|
||||||
id = raw.(*structs.Allocation).ID
|
id = raw.(*structs.Allocation).ID
|
||||||
case *structs.Node:
|
case *structs.Node:
|
||||||
id = raw.(*structs.Node).ID
|
id = raw.(*structs.Node).ID
|
||||||
|
case *structs.Deployment:
|
||||||
|
id = raw.(*structs.Deployment).ID
|
||||||
default:
|
default:
|
||||||
s.srv.logger.Printf("[ERR] nomad.resources: unexpected type for resources context: %T", t)
|
s.srv.logger.Printf("[ERR] nomad.resources: unexpected type for resources context: %T", t)
|
||||||
continue
|
continue
|
||||||
|
@ -74,6 +77,8 @@ func getResourceIter(context structs.Context, prefix string, ws memdb.WatchSet,
|
||||||
return state.AllocsByIDPrefix(ws, prefix)
|
return state.AllocsByIDPrefix(ws, prefix)
|
||||||
case structs.Nodes:
|
case structs.Nodes:
|
||||||
return state.NodesByIDPrefix(ws, prefix)
|
return state.NodesByIDPrefix(ws, prefix)
|
||||||
|
case structs.Deployments:
|
||||||
|
return state.DeploymentsByIDPrefix(ws, prefix)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("context must be one of %v; got %q", allContexts, context)
|
return nil, fmt.Errorf("context must be one of %v; got %q", allContexts, context)
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,6 +199,39 @@ func TestSearch_PrefixSearch_Node(t *testing.T) {
|
||||||
assert.Equal(uint64(100), resp.Index)
|
assert.Equal(uint64(100), resp.Index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSearch_PrefixSearch_Deployment(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
t.Parallel()
|
||||||
|
s := testServer(t, func(c *Config) {
|
||||||
|
c.NumSchedulers = 0
|
||||||
|
})
|
||||||
|
|
||||||
|
defer s.Shutdown()
|
||||||
|
codec := rpcClient(t, s)
|
||||||
|
testutil.WaitForLeader(t, s.RPC)
|
||||||
|
|
||||||
|
deployment := mock.Deployment()
|
||||||
|
s.fsm.State().UpsertDeployment(2000, deployment)
|
||||||
|
|
||||||
|
prefix := deployment.ID[:len(deployment.ID)-2]
|
||||||
|
|
||||||
|
req := &structs.SearchRequest{
|
||||||
|
Prefix: prefix,
|
||||||
|
Context: structs.Deployments,
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp structs.SearchResponse
|
||||||
|
if err := msgpackrpc.CallWithCodec(codec, "Search.PrefixSearch", req, &resp); err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(1, len(resp.Matches[structs.Deployments]))
|
||||||
|
assert.Equal(deployment.ID, resp.Matches[structs.Deployments][0])
|
||||||
|
assert.Equal(resp.Truncations[structs.Deployments], false)
|
||||||
|
|
||||||
|
assert.Equal(uint64(2000), resp.Index)
|
||||||
|
}
|
||||||
|
|
||||||
func TestSearch_PrefixSearch_AllContext(t *testing.T) {
|
func TestSearch_PrefixSearch_AllContext(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
|
@ -23,7 +23,7 @@ import (
|
||||||
"github.com/gorhill/cronexpr"
|
"github.com/gorhill/cronexpr"
|
||||||
"github.com/hashicorp/consul/api"
|
"github.com/hashicorp/consul/api"
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
"github.com/hashicorp/go-version"
|
version "github.com/hashicorp/go-version"
|
||||||
"github.com/hashicorp/nomad/helper"
|
"github.com/hashicorp/nomad/helper"
|
||||||
"github.com/hashicorp/nomad/helper/args"
|
"github.com/hashicorp/nomad/helper/args"
|
||||||
"github.com/mitchellh/copystructure"
|
"github.com/mitchellh/copystructure"
|
||||||
|
@ -89,15 +89,17 @@ const (
|
||||||
GetterModeDir = "dir"
|
GetterModeDir = "dir"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Context defines the scope in which a search for Nomad object operates
|
// Context defines the scope in which a search for Nomad object operates, and
|
||||||
|
// is also used to query the matching index value for this context
|
||||||
type Context string
|
type Context string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Allocs Context = "allocs"
|
Allocs Context = "allocs"
|
||||||
Evals Context = "evals"
|
Deployments Context = "deployment"
|
||||||
Jobs Context = "jobs"
|
Evals Context = "evals"
|
||||||
Nodes Context = "nodes"
|
Jobs Context = "jobs"
|
||||||
All Context = ""
|
Nodes Context = "nodes"
|
||||||
|
All Context = ""
|
||||||
)
|
)
|
||||||
|
|
||||||
// RPCInfo is used to describe common information about query
|
// RPCInfo is used to describe common information about query
|
||||||
|
|
Loading…
Reference in New Issue