mirror of https://github.com/status-im/consul.git
api: enable query options on agent endpoints
This PR adds support for setting QueryOptions on a few agent API endpoints. Nomad needs to be able to set the Namespace field on these endpoints to: - query for services / checks in a namespace - deregister services / checks in a namespace - update TTL status on checks in a namespace
This commit is contained in:
parent
11f60c46a3
commit
cd1cd4febd
|
@ -0,0 +1,4 @@
|
||||||
|
```release-note:improvement
|
||||||
|
api: Enable setting query options on agent endpoints.
|
||||||
|
```
|
||||||
|
|
39
api/agent.go
39
api/agent.go
|
@ -509,7 +509,14 @@ func (a *Agent) Checks() (map[string]*AgentCheck, error) {
|
||||||
// ChecksWithFilter returns a subset of the locally registered checks that match
|
// ChecksWithFilter returns a subset of the locally registered checks that match
|
||||||
// the given filter expression
|
// the given filter expression
|
||||||
func (a *Agent) ChecksWithFilter(filter string) (map[string]*AgentCheck, error) {
|
func (a *Agent) ChecksWithFilter(filter string) (map[string]*AgentCheck, error) {
|
||||||
|
return a.ChecksWithFilterOpts(filter, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChecksWithFilterOpts returns a subset of the locally registered checks that match
|
||||||
|
// the given filter expression and QueryOptions.
|
||||||
|
func (a *Agent) ChecksWithFilterOpts(filter string, q *QueryOptions) (map[string]*AgentCheck, error) {
|
||||||
r := a.c.newRequest("GET", "/v1/agent/checks")
|
r := a.c.newRequest("GET", "/v1/agent/checks")
|
||||||
|
r.setQueryOptions(q)
|
||||||
r.filterQuery(filter)
|
r.filterQuery(filter)
|
||||||
_, resp, err := requireOK(a.c.doRequest(r))
|
_, resp, err := requireOK(a.c.doRequest(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -532,7 +539,14 @@ func (a *Agent) Services() (map[string]*AgentService, error) {
|
||||||
// ServicesWithFilter returns a subset of the locally registered services that match
|
// ServicesWithFilter returns a subset of the locally registered services that match
|
||||||
// the given filter expression
|
// the given filter expression
|
||||||
func (a *Agent) ServicesWithFilter(filter string) (map[string]*AgentService, error) {
|
func (a *Agent) ServicesWithFilter(filter string) (map[string]*AgentService, error) {
|
||||||
|
return a.ServicesWithFilterOpts(filter, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServicesWithFilterOpts returns a subset of the locally registered services that match
|
||||||
|
// the given filter expression and QueryOptions.
|
||||||
|
func (a *Agent) ServicesWithFilterOpts(filter string, q *QueryOptions) (map[string]*AgentService, error) {
|
||||||
r := a.c.newRequest("GET", "/v1/agent/services")
|
r := a.c.newRequest("GET", "/v1/agent/services")
|
||||||
|
r.setQueryOptions(q)
|
||||||
r.filterQuery(filter)
|
r.filterQuery(filter)
|
||||||
_, resp, err := requireOK(a.c.doRequest(r))
|
_, resp, err := requireOK(a.c.doRequest(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -727,6 +741,19 @@ func (a *Agent) ServiceDeregister(serviceID string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServiceDeregisterOpts is used to deregister a service with
|
||||||
|
// the local agent with QueryOptions.
|
||||||
|
func (a *Agent) ServiceDeregisterOpts(serviceID string, q *QueryOptions) error {
|
||||||
|
r := a.c.newRequest("PUT", "/v1/agent/service/deregister/"+serviceID)
|
||||||
|
r.setQueryOptions(q)
|
||||||
|
_, resp, err := requireOK(a.c.doRequest(r))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
resp.Body.Close()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// PassTTL is used to set a TTL check to the passing state.
|
// PassTTL is used to set a TTL check to the passing state.
|
||||||
//
|
//
|
||||||
// DEPRECATION NOTICE: This interface is deprecated in favor of UpdateTTL().
|
// DEPRECATION NOTICE: This interface is deprecated in favor of UpdateTTL().
|
||||||
|
@ -801,6 +828,10 @@ type checkUpdate struct {
|
||||||
// strings for compatibility (though a newer version of Consul will still be
|
// strings for compatibility (though a newer version of Consul will still be
|
||||||
// required to use this API).
|
// required to use this API).
|
||||||
func (a *Agent) UpdateTTL(checkID, output, status string) error {
|
func (a *Agent) UpdateTTL(checkID, output, status string) error {
|
||||||
|
return a.UpdateTTLOpts(checkID, output, status, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Agent) UpdateTTLOpts(checkID, output, status string, q *QueryOptions) error {
|
||||||
switch status {
|
switch status {
|
||||||
case "pass", HealthPassing:
|
case "pass", HealthPassing:
|
||||||
status = HealthPassing
|
status = HealthPassing
|
||||||
|
@ -814,6 +845,7 @@ func (a *Agent) UpdateTTL(checkID, output, status string) error {
|
||||||
|
|
||||||
endpoint := fmt.Sprintf("/v1/agent/check/update/%s", checkID)
|
endpoint := fmt.Sprintf("/v1/agent/check/update/%s", checkID)
|
||||||
r := a.c.newRequest("PUT", endpoint)
|
r := a.c.newRequest("PUT", endpoint)
|
||||||
|
r.setQueryOptions(q)
|
||||||
r.obj = &checkUpdate{
|
r.obj = &checkUpdate{
|
||||||
Status: status,
|
Status: status,
|
||||||
Output: output,
|
Output: output,
|
||||||
|
@ -843,7 +875,14 @@ func (a *Agent) CheckRegister(check *AgentCheckRegistration) error {
|
||||||
// CheckDeregister is used to deregister a check with
|
// CheckDeregister is used to deregister a check with
|
||||||
// the local agent
|
// the local agent
|
||||||
func (a *Agent) CheckDeregister(checkID string) error {
|
func (a *Agent) CheckDeregister(checkID string) error {
|
||||||
|
return a.CheckDeregisterOpts(checkID, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckDeregisterOpts is used to deregister a check with
|
||||||
|
// the local agent using query options
|
||||||
|
func (a *Agent) CheckDeregisterOpts(checkID string, q *QueryOptions) error {
|
||||||
r := a.c.newRequest("PUT", "/v1/agent/check/deregister/"+checkID)
|
r := a.c.newRequest("PUT", "/v1/agent/check/deregister/"+checkID)
|
||||||
|
r.setQueryOptions(q)
|
||||||
_, resp, err := requireOK(a.c.doRequest(r))
|
_, resp, err := requireOK(a.c.doRequest(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -333,7 +333,7 @@ func TestAPI_AgentServices(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAPI_AgentServicesWithFilter(t *testing.T) {
|
func TestAPI_AgentServicesWithFilterOpts(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c, s := makeClient(t)
|
c, s := makeClient(t)
|
||||||
defer s.Stop()
|
defer s.Stop()
|
||||||
|
@ -362,7 +362,8 @@ func TestAPI_AgentServicesWithFilter(t *testing.T) {
|
||||||
}
|
}
|
||||||
require.NoError(t, agent.ServiceRegister(reg))
|
require.NoError(t, agent.ServiceRegister(reg))
|
||||||
|
|
||||||
services, err := agent.ServicesWithFilter("foo in Tags")
|
opts := &QueryOptions{Namespace: defaultNamespace}
|
||||||
|
services, err := agent.ServicesWithFilterOpts("foo in Tags", opts)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, services, 1)
|
require.Len(t, services, 1)
|
||||||
_, ok := services["foo2"]
|
_, ok := services["foo2"]
|
||||||
|
@ -852,6 +853,63 @@ func TestAPI_AgentSetTTLStatus(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAPI_AgentUpdateTTLOpts(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
c, s := makeClient(t)
|
||||||
|
defer s.Stop()
|
||||||
|
|
||||||
|
agent := c.Agent()
|
||||||
|
s.WaitForSerfCheck(t)
|
||||||
|
|
||||||
|
reg := &AgentServiceRegistration{
|
||||||
|
Name: "foo",
|
||||||
|
Check: &AgentServiceCheck{
|
||||||
|
TTL: "15s",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := agent.ServiceRegister(reg); err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
verify := func(status, output string) {
|
||||||
|
checks, err := agent.Checks()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
chk, ok := checks["service:foo"]
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("missing check: %v", checks)
|
||||||
|
}
|
||||||
|
if chk.Status != status {
|
||||||
|
t.Fatalf("Bad: %#v", chk)
|
||||||
|
}
|
||||||
|
if chk.Output != output {
|
||||||
|
t.Fatalf("Bad: %#v", chk)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := &QueryOptions{Namespace: defaultNamespace}
|
||||||
|
|
||||||
|
if err := agent.UpdateTTLOpts("service:foo", "foo", HealthWarning, opts); err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
verify(HealthWarning, "foo")
|
||||||
|
|
||||||
|
if err := agent.UpdateTTLOpts("service:foo", "bar", HealthPassing, opts); err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
verify(HealthPassing, "bar")
|
||||||
|
|
||||||
|
if err := agent.UpdateTTL("service:foo", "baz", HealthCritical); err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
verify(HealthCritical, "baz")
|
||||||
|
|
||||||
|
if err := agent.ServiceDeregister("foo"); err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAPI_AgentChecks(t *testing.T) {
|
func TestAPI_AgentChecks(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c, s := makeClient(t)
|
c, s := makeClient(t)
|
||||||
|
@ -887,7 +945,7 @@ func TestAPI_AgentChecks(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAPI_AgentChecksWithFilter(t *testing.T) {
|
func TestAPI_AgentChecksWithFilterOpts(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c, s := makeClient(t)
|
c, s := makeClient(t)
|
||||||
defer s.Stop()
|
defer s.Stop()
|
||||||
|
@ -905,7 +963,8 @@ func TestAPI_AgentChecksWithFilter(t *testing.T) {
|
||||||
reg.TTL = "15s"
|
reg.TTL = "15s"
|
||||||
require.NoError(t, agent.CheckRegister(reg))
|
require.NoError(t, agent.CheckRegister(reg))
|
||||||
|
|
||||||
checks, err := agent.ChecksWithFilter("Name == foo")
|
opts := &QueryOptions{Namespace: defaultNamespace}
|
||||||
|
checks, err := agent.ChecksWithFilterOpts("Name == foo", opts)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, checks, 1)
|
require.Len(t, checks, 1)
|
||||||
_, ok := checks["foo"]
|
_, ok := checks["foo"]
|
||||||
|
|
Loading…
Reference in New Issue