Skip to content

Commit

Permalink
agent: Allow custom HTTP headers and method for checks (#3106)
Browse files Browse the repository at this point in the history
This patch adds support for custom headers and
method for HTTP checks.

Fixes #2474
Fixes #2657
Fixes #3106
  • Loading branch information
magiconair committed Jun 4, 2017
1 parent 240413f commit fcb8621
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 14 deletions.
24 changes: 13 additions & 11 deletions api/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,19 @@ type AgentCheckRegistration struct {

// AgentServiceCheck is used to define a node or service level check
type AgentServiceCheck struct {
Script string `json:",omitempty"`
DockerContainerID string `json:",omitempty"`
Shell string `json:",omitempty"` // Only supported for Docker.
Interval string `json:",omitempty"`
Timeout string `json:",omitempty"`
TTL string `json:",omitempty"`
HTTP string `json:",omitempty"`
TCP string `json:",omitempty"`
Status string `json:",omitempty"`
Notes string `json:",omitempty"`
TLSSkipVerify bool `json:",omitempty"`
Script string `json:",omitempty"`
DockerContainerID string `json:",omitempty"`
Shell string `json:",omitempty"` // Only supported for Docker.
Interval string `json:",omitempty"`
Timeout string `json:",omitempty"`
TTL string `json:",omitempty"`
HTTP string `json:",omitempty"`
Header map[string][]string `json:",omitempty"`
Method string `json:",omitempty"`
TCP string `json:",omitempty"`
Status string `json:",omitempty"`
Notes string `json:",omitempty"`
TLSSkipVerify bool `json:",omitempty"`

// In Consul 0.7 and later, checks that are associated with a service
// may also contain this optional DeregisterCriticalServiceAfter field,
Expand Down
2 changes: 2 additions & 0 deletions command/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -1575,6 +1575,8 @@ func (a *Agent) AddCheck(check *structs.HealthCheck, chkType *CheckType, persist
Notify: &a.state,
CheckID: check.CheckID,
HTTP: chkType.HTTP,
Header: chkType.Header,
Method: chkType.Method,
Interval: chkType.Interval,
Timeout: chkType.Timeout,
Logger: a.logger,
Expand Down
20 changes: 17 additions & 3 deletions command/agent/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ type CheckType struct {

Script string
HTTP string
Header map[string][]string
Method string
TCP string
Interval time.Duration
DockerContainerID string
Expand Down Expand Up @@ -347,6 +349,8 @@ type CheckHTTP struct {
Notify CheckNotifier
CheckID types.CheckID
HTTP string
Header map[string][]string
Method string
Interval time.Duration
Timeout time.Duration
Logger *log.Logger
Expand Down Expand Up @@ -429,15 +433,25 @@ func (c *CheckHTTP) run() {

// check is invoked periodically to perform the HTTP check
func (c *CheckHTTP) check() {
req, err := http.NewRequest("GET", c.HTTP, nil)
method := c.Method
if method == "" {
method = "GET"
}

req, err := http.NewRequest(method, c.HTTP, nil)
if err != nil {
c.Logger.Printf("[WARN] agent: http request failed '%s': %s", c.HTTP, err)
c.Notify.UpdateCheck(c.CheckID, api.HealthCritical, err.Error())
return
}

req.Header.Set("User-Agent", UserAgent)
req.Header.Set("Accept", "text/plain, text/*, */*")
req.Header = http.Header(c.Header)
if req.Header.Get("User-Agent") == "" {
req.Header.Set("User-Agent", UserAgent)
}
if req.Header.Get("Accept") == "" {
req.Header.Set("Accept", "text/plain, text/*, */*")
}

resp, err := c.httpClient.Do(req)
if err != nil {
Expand Down
14 changes: 14 additions & 0 deletions command/agent/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -1437,6 +1437,20 @@ func FixupCheckType(raw interface{}) error {
case "service_id":
rawMap["serviceid"] = v
delete(rawMap, k)
case "header":
vm, ok := v.(map[string]interface{})
if ok {
m := map[string][]string{}
for k, vv := range vm {
vs, ok := vv.([]interface{})
if ok {
for _, s := range vs {
m[k] = append(m[k], s.(string))
}
}
}
rawMap["header"] = m
}
case "docker_container_id":
rawMap["DockerContainerID"] = v
delete(rawMap, k)
Expand Down
22 changes: 22 additions & 0 deletions command/agent/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1429,6 +1429,17 @@ func TestDecodeConfig_Checks(t *testing.T) {
"timeout": "100ms",
"service_id": "insecure-sslservice",
"tls_skip_verify": true
},
{
"id": "chk7",
"name": "service:insecure-sslservice",
"HTTP": "https://insecure-sslservice/status",
"Header": {"a":["b"], "c":["d", "e"]},
"Method": "PUT",
"interval": "10s",
"timeout": "100ms",
"service_id": "insecure-sslservice",
"tls_skip_verify": true
}
]
}`
Expand Down Expand Up @@ -1485,6 +1496,17 @@ func TestDecodeConfig_Checks(t *testing.T) {
Timeout: 100 * time.Millisecond,
TLSSkipVerify: true,
},
&CheckDefinition{
ID: "chk7",
Name: "service:insecure-sslservice",
ServiceID: "insecure-sslservice",
HTTP: "https://insecure-sslservice/status",
Header: map[string][]string{"a": []string{"b"}, "c": []string{"d", "e"}},
Method: "PUT",
Interval: 10 * time.Second,
Timeout: 100 * time.Millisecond,
TLSSkipVerify: true,
},
},
}
verify.Values(t, "", got, want)
Expand Down
2 changes: 2 additions & 0 deletions command/agent/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ type CheckDefinition struct {
//
Script string
HTTP string
Header map[string][]string
Method string
TCP string
Interval time.Duration
DockerContainerID string
Expand Down

1 comment on commit fcb8621

@pierrecdn
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me you also fix #1184 with this commit.

Please sign in to comment.