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

Add 'body' field to service's 'check' stanza #10186

Merged
merged 8 commits into from
Apr 13, 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ IMPROVEMENTS:
* api: Removed unimplemented `CSIVolumes.PluginList` API. [[GH-10158](https://github.com/hashicorp/nomad/issues/10158)]
* cli: Update defaults for `nomad operator debug` flags `-interval` and `-server-id` to match common usage. [[GH-10121](https://github.com/hashicorp/nomad/issues/10121)]
* cli: Added `nomad ui -authenticate` flag to generate a one-time token for authenticating to the web UI when ACLs are enabled. [[GH-10097](https://github.com/hashicorp/nomad/issues/10097)]
* consul: Allow setting `body` field on service/check Consul health checks. [[GH-10186](https://github.com/hashicorp/nomad/issues/10186)]
* consul/connect: Enable setting `local_bind_address` field on connect upstreams [[GH-6248](https://github.com/hashicorp/nomad/issues/6248)]
* consul/connect: Automatically populate `CONSUL_HTTP_ADDR` for connect native tasks in host networking mode. [[GH-10239](https://github.com/hashicorp/nomad/issues/10239)]
* csi: Added support for jobs to request a unique volume ID per allocation. [[GH-10136](https://github.com/hashicorp/nomad/issues/10136)]
Expand Down
1 change: 1 addition & 0 deletions api/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ type ServiceCheck struct {
TaskName string `mapstructure:"task" hcl:"task,optional"`
SuccessBeforePassing int `mapstructure:"success_before_passing" hcl:"success_before_passing,optional"`
FailuresBeforeCritical int `mapstructure:"failures_before_critical" hcl:"failures_before_critical,optional"`
Body string `hcl:"body,optional"`
OnUpdate string `mapstructure:"on_update" hcl:"on_update,optional"`
}

Expand Down
1 change: 1 addition & 0 deletions command/agent/consul/service_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,7 @@ func createCheckReg(serviceID, checkID string, check *structs.ServiceCheck, host
chkReg.HTTP = checkURL.String()
chkReg.Method = check.Method
chkReg.Header = check.Header
chkReg.Body = check.Body

case structs.ServiceCheckTCP:
chkReg.TCP = net.JoinHostPort(host, strconv.Itoa(port))
Expand Down
2 changes: 2 additions & 0 deletions command/agent/job_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,7 @@ func ApiTaskToStructsTask(job *structs.Job, group *structs.TaskGroup,
TLSSkipVerify: check.TLSSkipVerify,
Header: check.Header,
Method: check.Method,
Body: check.Body,
GRPCService: check.GRPCService,
GRPCUseTLS: check.GRPCUseTLS,
SuccessBeforePassing: check.SuccessBeforePassing,
Expand Down Expand Up @@ -1316,6 +1317,7 @@ func ApiServicesToStructs(in []*api.Service) []*structs.Service {
TLSSkipVerify: check.TLSSkipVerify,
Header: check.Header,
Method: check.Method,
Body: check.Body,
GRPCService: check.GRPCService,
GRPCUseTLS: check.GRPCUseTLS,
TaskName: check.TaskName,
Expand Down
4 changes: 4 additions & 0 deletions command/agent/job_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1954,6 +1954,8 @@ func TestJobs_ApiJobToStructsJob(t *testing.T) {
Args: []string{"a", "b"},
Path: "/check",
Protocol: "http",
Method: "POST",
Body: "{\"check\":\"mem\"}",
PortLabel: "foo",
AddressMode: "driver",
GRPCService: "foo.Bar",
Expand Down Expand Up @@ -2330,6 +2332,8 @@ func TestJobs_ApiJobToStructsJob(t *testing.T) {
Args: []string{"a", "b"},
Path: "/check",
Protocol: "http",
Method: "POST",
Body: "{\"check\":\"mem\"}",
PortLabel: "foo",
AddressMode: "driver",
GRPCService: "foo.Bar",
Expand Down
49 changes: 49 additions & 0 deletions jobspec2/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -874,3 +874,52 @@ func TestParse_UndefinedVariables(t *testing.T) {
})
}
}

func TestParseServiceCheck(t *testing.T) {
hcl := ` job "group_service_check_script" {
group "group" {
service {
name = "foo-service"
port = "http"
check {
name = "check-name"
type = "http"
method = "POST"
body = "{\"check\":\"mem\"}"
}
}
}
}
`
parsedJob, err := ParseWithConfig(&ParseConfig{
Path: "input.hcl",
Body: []byte(hcl),
})
require.NoError(t, err)

expectedJob := &api.Job{
ID: stringToPtr("group_service_check_script"),
Name: stringToPtr("group_service_check_script"),
TaskGroups: []*api.TaskGroup{
{
Name: stringToPtr("group"),
Services: []*api.Service{
{
Name: "foo-service",
PortLabel: "http",
Checks: []api.ServiceCheck{
{
Name: "check-name",
Type: "http",
Method: "POST",
Body: "{\"check\":\"mem\"}",
},
},
},
},
},
},
}

require.Equal(t, expectedJob, parsedJob)
}
18 changes: 16 additions & 2 deletions nomad/structs/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2684,6 +2684,8 @@ func TestTaskGroupDiff(t *testing.T) {
Args: []string{"foo"},
Path: "foo",
Protocol: "http",
Method: "POST",
Body: "{\"key\": \"value\"}",
Expose: true,
Interval: 1 * time.Second,
Timeout: 1 * time.Second,
Expand Down Expand Up @@ -2895,6 +2897,12 @@ func TestTaskGroupDiff(t *testing.T) {
Old: "",
New: "",
},
{
Type: DiffTypeDeleted,
Name: "Body",
Old: "{\"key\": \"value\"}",
New: "",
},
{
Type: DiffTypeEdited,
Name: "Command",
Expand Down Expand Up @@ -2938,9 +2946,9 @@ func TestTaskGroupDiff(t *testing.T) {
New: "2000000000",
},
{
Type: DiffTypeNone,
Type: DiffTypeDeleted,
Name: "Method",
Old: "",
Old: "POST",
New: "",
},
{
Expand Down Expand Up @@ -6236,6 +6244,12 @@ func TestTaskDiff(t *testing.T) {
Old: "",
New: "",
},
{
Type: DiffTypeNone,
Name: "Body",
Old: "",
New: "",
},
{
Type: DiffTypeNone,
Name: "Command",
Expand Down
6 changes: 6 additions & 0 deletions nomad/structs/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ type ServiceCheck struct {
TaskName string // What task to execute this check in
SuccessBeforePassing int // Number of consecutive successes required before considered healthy
FailuresBeforeCritical int // Number of consecutive failures required before considered unhealthy
Body string // Body to use in HTTP check
tgross marked this conversation as resolved.
Show resolved Hide resolved
OnUpdate string
}

Expand Down Expand Up @@ -168,6 +169,10 @@ func (sc *ServiceCheck) Equals(o *ServiceCheck) bool {
return false
}

if sc.Body != o.Body {
return false
}

if sc.OnUpdate != o.OnUpdate {
return false
}
Expand Down Expand Up @@ -352,6 +357,7 @@ func (sc *ServiceCheck) Hash(serviceID string) string {
hashString(h, sc.Interval.String())
hashString(h, sc.Timeout.String())
hashString(h, sc.Method)
hashString(h, sc.Body)
hashString(h, sc.OnUpdate)

// use name "true" to maintain ID stability
Expand Down
1 change: 1 addition & 0 deletions vendor/github.com/hashicorp/nomad/api/services.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 25 additions & 23 deletions website/content/api-docs/json-jobs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -466,27 +466,27 @@ The `Task` object supports the following keys:

- `Name`: The name of the health check.

- `AddressMode`: Same as `AddressMode` on `Service`. Unlike services,
checks do not have an `auto` address mode as there's no way for
Nomad to know which is the best address to use for checks. Consul
needs access to the address for any HTTP or TCP checks. Added in
Nomad 0.7.1. Unlike `PortLabel`, this setting is _not_ inherited
from the `Service`.

- `PortLabel`: Specifies the label of the port on which the check will
be performed. Note this is the _label_ of the port and not the port
number unless `AddressMode: "driver"`. The port label must match one
defined in the Network stanza. If a port value was declared on the
`Service`, this will inherit from that value if not supplied. If
supplied, this value takes precedence over the `Service.PortLabel`
value. This is useful for services which operate on multiple ports.
`http` and `tcp` checks require a port while `script` checks do not.
Checks will use the host IP and ports by default. In Nomad 0.7.1 or
later numeric ports may be used if `AddressMode: "driver"` is set on
the check.

- `Header`: Headers for HTTP checks. Should be an object where the values are an
array of values. Headers will be written once for each value.
- `AddressMode`: Same as `AddressMode` on `Service`. Unlike services,
checks do not have an `auto` address mode as there's no way for
Nomad to know which is the best address to use for checks. Consul
needs access to the address for any HTTP or TCP checks. Added in
Nomad 0.7.1. Unlike `PortLabel`, this setting is _not_ inherited
from the `Service`.

- `PortLabel`: Specifies the label of the port on which the check will
be performed. Note this is the _label_ of the port and not the port
number unless `AddressMode: "driver"`. The port label must match one
defined in the Network stanza. If a port value was declared on the
`Service`, this will inherit from that value if not supplied. If
supplied, this value takes precedence over the `Service.PortLabel`
value. This is useful for services which operate on multiple ports.
`http` and `tcp` checks require a port while `script` checks do not.
Checks will use the host IP and ports by default. In Nomad 0.7.1 or
later numeric ports may be used if `AddressMode: "driver"` is set on
the check.

- `Header`: Headers for HTTP checks. Should be an object where the values
are an array of values. Headers will be written once for each value.

- `Interval`: This indicates the frequency of the health checks that
tgross marked this conversation as resolved.
Show resolved Hide resolved
Consul will perform.
Expand All @@ -496,6 +496,8 @@ The `Task` object supports the following keys:

- `Method`: The HTTP method to use for HTTP checks. Defaults to GET.

- `Body`: The HTTP body to use for HTTP checks. Defaults to an empty string.

- `Path`: The path of the HTTP endpoint which Consul will query to query
the health of a service if the type of the check is `http`. Nomad
will add the IP of the service and the port, users are only required
Expand All @@ -511,8 +513,8 @@ The `Task` object supports the following keys:
- `Args`: Additional arguments to the `command` for script based health
checks.

- `TLSSkipVerify`: If true, Consul will not attempt to verify the
certificate when performing HTTPS checks. Requires Consul >= 0.7.2.
- `TLSSkipVerify`: If true, Consul will not attempt to verify the
certificate when performing HTTPS checks. Requires Consul >= 0.7.2.

- `CheckRestart`: `CheckRestart` is an object which enables
restarting of tasks based upon Consul health checks.
Expand Down
2 changes: 2 additions & 0 deletions website/content/docs/job-specification/service.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ scripts.
- `method` `(string: "GET")` - Specifies the HTTP method to use for HTTP
checks.

- `body` `(string: "")` - Specifies the HTTP body to use for HTTP checks.

- `name` `(string: "service: <name> check")` - Specifies the name of the health
check. If the name is not specified Nomad generates one based on the service name.
If you have more than one check you must specify the name.
Expand Down