Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api: enable query options on agent endpoints #9903

Merged
merged 1 commit into from
Mar 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .changelog/9903.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
```release-note:improvement
api: Enable setting query options on agent endpoints.
```

39 changes: 39 additions & 0 deletions api/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,14 @@ func (a *Agent) Checks() (map[string]*AgentCheck, error) {
// ChecksWithFilter returns a subset of the locally registered checks that match
// the given filter expression
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.setQueryOptions(q)
r.filterQuery(filter)
_, resp, err := requireOK(a.c.doRequest(r))
if err != nil {
Expand All @@ -532,7 +539,14 @@ func (a *Agent) Services() (map[string]*AgentService, error) {
// ServicesWithFilter returns a subset of the locally registered services that match
// the given filter expression
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.setQueryOptions(q)
r.filterQuery(filter)
_, resp, err := requireOK(a.c.doRequest(r))
if err != nil {
Expand Down Expand Up @@ -727,6 +741,19 @@ func (a *Agent) ServiceDeregister(serviceID string) error {
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.
//
// DEPRECATION NOTICE: This interface is deprecated in favor of UpdateTTL().
Expand Down Expand Up @@ -801,6 +828,10 @@ type checkUpdate struct {
// strings for compatibility (though a newer version of Consul will still be
// required to use this API).
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 {
case "pass", HealthPassing:
status = HealthPassing
Expand All @@ -814,6 +845,7 @@ func (a *Agent) UpdateTTL(checkID, output, status string) error {

endpoint := fmt.Sprintf("/v1/agent/check/update/%s", checkID)
r := a.c.newRequest("PUT", endpoint)
r.setQueryOptions(q)
r.obj = &checkUpdate{
Status: status,
Output: output,
Expand Down Expand Up @@ -843,7 +875,14 @@ func (a *Agent) CheckRegister(check *AgentCheckRegistration) error {
// CheckDeregister is used to deregister a check with
// the local agent
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.setQueryOptions(q)
_, resp, err := requireOK(a.c.doRequest(r))
if err != nil {
return err
Expand Down
67 changes: 63 additions & 4 deletions api/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ func TestAPI_AgentServices(t *testing.T) {
}
}

func TestAPI_AgentServicesWithFilter(t *testing.T) {
func TestAPI_AgentServicesWithFilterOpts(t *testing.T) {
t.Parallel()
c, s := makeClient(t)
defer s.Stop()
Expand Down Expand Up @@ -362,7 +362,8 @@ func TestAPI_AgentServicesWithFilter(t *testing.T) {
}
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.Len(t, services, 1)
_, ok := services["foo2"]
Expand Down Expand Up @@ -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) {
t.Parallel()
c, s := makeClient(t)
Expand Down Expand Up @@ -887,7 +945,7 @@ func TestAPI_AgentChecks(t *testing.T) {
}
}

func TestAPI_AgentChecksWithFilter(t *testing.T) {
func TestAPI_AgentChecksWithFilterOpts(t *testing.T) {
t.Parallel()
c, s := makeClient(t)
defer s.Stop()
Expand All @@ -905,7 +963,8 @@ func TestAPI_AgentChecksWithFilter(t *testing.T) {
reg.TTL = "15s"
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.Len(t, checks, 1)
_, ok := checks["foo"]
Expand Down