add http2 ping health checks (#8431)

* add http2 ping checks

* fix test issue

* add h2ping check to config resources

* add new test and docs for h2ping

* fix grammatical inconsistency in H2PING documentation

* resolve rebase conflicts, add test for h2ping tls verification failure

* api documentation for h2ping

* update test config data with H2PING

* add H2PING to protocol buffers and update changelog

* fix typo in changelog entry
This commit is contained in:
Tara Tufano 2021-04-09 15:12:10 -04:00 committed by GitHub
parent 5755c97bc7
commit 9deb52e868
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 558 additions and 79 deletions

3
.changelog/8431.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:enhancement
health-checks: add H2 ping health checks.
```

View File

@ -204,6 +204,9 @@ type Agent struct {
// checkHTTPs maps the check ID to an associated HTTP check
checkHTTPs map[structs.CheckID]*checks.CheckHTTP
// checkH2PINGs maps the check ID to an associated HTTP2 PING check
checkH2PINGs map[structs.CheckID]*checks.CheckH2PING
// checkTCPs maps the check ID to an associated TCP check
checkTCPs map[structs.CheckID]*checks.CheckTCP
@ -349,6 +352,7 @@ func New(bd BaseDeps) (*Agent, error) {
checkMonitors: make(map[structs.CheckID]*checks.CheckMonitor),
checkTTLs: make(map[structs.CheckID]*checks.CheckTTL),
checkHTTPs: make(map[structs.CheckID]*checks.CheckHTTP),
checkH2PINGs: make(map[structs.CheckID]*checks.CheckH2PING),
checkTCPs: make(map[structs.CheckID]*checks.CheckTCP),
checkGRPCs: make(map[structs.CheckID]*checks.CheckGRPC),
checkDockers: make(map[structs.CheckID]*checks.CheckDocker),
@ -1367,6 +1371,9 @@ func (a *Agent) ShutdownAgent() error {
for _, chk := range a.checkAliases {
chk.Stop()
}
for _, chk := range a.checkH2PINGs {
chk.Stop()
}
// Stop gRPC
if a.grpcServer != nil {
@ -2685,6 +2692,36 @@ func (a *Agent) addCheck(check *structs.HealthCheck, chkType *structs.CheckType,
monitor.Start()
a.checkMonitors[cid] = monitor
case chkType.IsH2PING():
if existing, ok := a.checkH2PINGs[cid]; ok {
existing.Stop()
delete(a.checkH2PINGs, cid)
}
if chkType.Interval < checks.MinInterval {
a.logger.Warn("check has interval below minimum",
"check", cid.String(),
"minimum_interval", checks.MinInterval,
)
chkType.Interval = checks.MinInterval
}
tlsClientConfig := a.tlsConfigurator.OutgoingTLSConfigForCheck(chkType.TLSSkipVerify, chkType.TLSServerName)
tlsClientConfig.NextProtos = []string{http2.NextProtoTLS}
h2ping := &checks.CheckH2PING{
CheckID: cid,
ServiceID: sid,
H2PING: chkType.H2PING,
Interval: chkType.Interval,
Timeout: chkType.Timeout,
Logger: a.logger,
TLSClientConfig: tlsClientConfig,
StatusHandler: statusHandler,
}
h2ping.Start()
a.checkH2PINGs[cid] = h2ping
case chkType.IsAlias():
if existing, ok := a.checkAliases[cid]; ok {
existing.Stop()
@ -2890,6 +2927,11 @@ func (a *Agent) cancelCheckMonitors(checkID structs.CheckID) {
check.Stop()
delete(a.checkDockers, checkID)
}
if check, ok := a.checkH2PINGs[checkID]; ok {
check.Stop()
delete(a.checkH2PINGs, checkID)
}
}
// updateTTLCheck is used to update the status of a TTL check via the Agent API.

View File

@ -811,6 +811,31 @@ func TestAgent_CheckAliasRPC(t *testing.T) {
}
}
func TestAgent_AddServiceWithH2PINGCheck(t *testing.T) {
t.Parallel()
a := NewTestAgent(t, "")
defer a.Shutdown()
check := []*structs.CheckType{
{
CheckID: "test-h2ping-check",
Name: "test-h2ping-check",
H2PING: "localhost:12345",
TLSSkipVerify: true,
Interval: 10 * time.Second,
},
}
nodeService := &structs.NodeService{
ID: "test-h2ping-check-service",
Service: "test-h2ping-check-service",
}
err := a.addServiceFromSource(nodeService, check, false, "", ConfigSourceLocal)
if err != nil {
t.Fatalf("Error registering service: %v", err)
}
requireCheckExists(t, a, "test-h2ping-check")
}
func TestAgent_AddServiceNoExec(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")

View File

@ -1,8 +1,10 @@
package checks
import (
"context"
"crypto/tls"
"fmt"
http2 "golang.org/x/net/http2"
"io"
"io/ioutil"
"net"
@ -504,6 +506,86 @@ func (c *CheckHTTP) check() {
}
}
type CheckH2PING struct {
CheckID structs.CheckID
ServiceID structs.ServiceID
H2PING string
Interval time.Duration
Timeout time.Duration
Logger hclog.Logger
TLSClientConfig *tls.Config
StatusHandler *StatusHandler
stop bool
stopCh chan struct{}
stopLock sync.Mutex
}
func (c *CheckH2PING) check() {
t := &http2.Transport{
TLSClientConfig: c.TLSClientConfig,
}
target := c.H2PING
conn, err := tls.Dial("tcp", target, c.TLSClientConfig)
if err != nil {
message := fmt.Sprintf("Failed to dial to %s: %s", target, err)
c.StatusHandler.updateCheck(c.CheckID, api.HealthCritical, message)
return
}
defer conn.Close()
clientConn, err := t.NewClientConn(conn)
if err != nil {
message := fmt.Sprintf("Failed to create client connection %s", err)
c.StatusHandler.updateCheck(c.CheckID, api.HealthCritical, message)
return
}
ctx, cancel := context.WithTimeout(context.Background(), c.Timeout)
defer cancel()
err = clientConn.Ping(ctx)
if err == nil {
c.StatusHandler.updateCheck(c.CheckID, api.HealthPassing, "HTTP2 ping was successful")
} else {
message := fmt.Sprintf("HTTP2 ping failed: %s", err)
c.StatusHandler.updateCheck(c.CheckID, api.HealthCritical, message)
}
}
// Stop is used to stop an H2PING check.
func (c *CheckH2PING) Stop() {
c.stopLock.Lock()
defer c.stopLock.Unlock()
if !c.stop {
c.stop = true
close(c.stopCh)
}
}
func (c *CheckH2PING) run() {
// Get the randomized initial pause time
initialPauseTime := lib.RandomStagger(c.Interval)
next := time.After(initialPauseTime)
for {
select {
case <-next:
c.check()
next = time.After(c.Interval)
case <-c.stopCh:
return
}
}
}
func (c *CheckH2PING) Start() {
c.stopLock.Lock()
defer c.stopLock.Unlock()
if c.Timeout <= 0 {
c.Timeout = 10 * time.Second
}
c.stop = false
c.stopCh = make(chan struct{})
go c.run()
}
// CheckTCP is used to periodically make an TCP/UDP connection to
// determine the health of a given check.
// The check is passing if the connection succeeds

View File

@ -20,6 +20,7 @@ import (
"github.com/hashicorp/consul/sdk/testutil/retry"
"github.com/hashicorp/go-uuid"
"github.com/stretchr/testify/require"
http2 "golang.org/x/net/http2"
)
func uniqueID() string {
@ -964,6 +965,162 @@ func TestCheckTCPPassing(t *testing.T) {
tcpServer.Close()
}
func TestCheckH2PING(t *testing.T) {
t.Parallel()
tests := []struct {
desc string
passing bool
timeout time.Duration
connTimeout time.Duration
}{
{desc: "passing", passing: true, timeout: 1 * time.Second, connTimeout: 1 * time.Second},
{desc: "failing because of time out", passing: false, timeout: 1 * time.Nanosecond, connTimeout: 1 * time.Second},
{desc: "failing because of closed connection", passing: false, timeout: 1 * time.Nanosecond, connTimeout: 1 * time.Millisecond},
}
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return })
server := httptest.NewUnstartedServer(handler)
server.EnableHTTP2 = true
server.Config.ReadTimeout = tt.connTimeout
server.StartTLS()
defer server.Close()
serverAddress := server.Listener.Addr()
target := serverAddress.String()
notif := mock.NewNotify()
logger := testutil.Logger(t)
statusHandler := NewStatusHandler(notif, logger, 0, 0)
cid := structs.NewCheckID("foo", nil)
tlsCfg := &api.TLSConfig{
InsecureSkipVerify: true,
}
tlsClientCfg, err := api.SetupTLSConfig(tlsCfg)
if err != nil {
t.Fatalf("%v", err)
}
tlsClientCfg.NextProtos = []string{http2.NextProtoTLS}
check := &CheckH2PING{
CheckID: cid,
H2PING: target,
Interval: 5 * time.Second,
Timeout: tt.timeout,
Logger: logger,
TLSClientConfig: tlsClientCfg,
StatusHandler: statusHandler,
}
check.Start()
defer check.Stop()
if tt.passing {
retry.Run(t, func(r *retry.R) {
if got, want := notif.State(cid), api.HealthPassing; got != want {
r.Fatalf("got state %q want %q", got, want)
}
})
} else {
retry.Run(t, func(r *retry.R) {
if got, want := notif.State(cid), api.HealthCritical; got != want {
r.Fatalf("got state %q want %q", got, want)
}
})
}
})
}
}
func TestCheckH2PING_TLS_BadVerify(t *testing.T) {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return })
server := httptest.NewUnstartedServer(handler)
server.EnableHTTP2 = true
server.StartTLS()
defer server.Close()
serverAddress := server.Listener.Addr()
target := serverAddress.String()
notif := mock.NewNotify()
logger := testutil.Logger(t)
statusHandler := NewStatusHandler(notif, logger, 0, 0)
cid := structs.NewCheckID("foo", nil)
tlsCfg := &api.TLSConfig{}
tlsClientCfg, err := api.SetupTLSConfig(tlsCfg)
if err != nil {
t.Fatalf("%v", err)
}
tlsClientCfg.NextProtos = []string{http2.NextProtoTLS}
check := &CheckH2PING{
CheckID: cid,
H2PING: target,
Interval: 5 * time.Second,
Timeout: 2 * time.Second,
Logger: logger,
TLSClientConfig: tlsClientCfg,
StatusHandler: statusHandler,
}
check.Start()
defer check.Stop()
insecureSkipVerifyValue := check.TLSClientConfig.InsecureSkipVerify
if insecureSkipVerifyValue {
t.Fatalf("The default value for InsecureSkipVerify should be false but was %v", insecureSkipVerifyValue)
}
retry.Run(t, func(r *retry.R) {
if got, want := notif.State(cid), api.HealthCritical; got != want {
r.Fatalf("got state %q want %q", got, want)
}
expectedOutput := "certificate signed by unknown authority"
if !strings.Contains(notif.Output(cid), expectedOutput) {
r.Fatalf("should have included output %s: %v", expectedOutput, notif.OutputMap())
}
})
}
func TestCheckH2PINGInvalidListener(t *testing.T) {
t.Parallel()
notif := mock.NewNotify()
logger := testutil.Logger(t)
statusHandler := NewStatusHandler(notif, logger, 0, 0)
cid := structs.NewCheckID("foo", nil)
tlsCfg := &api.TLSConfig{
InsecureSkipVerify: true,
}
tlsClientCfg, err := api.SetupTLSConfig(tlsCfg)
if err != nil {
t.Fatalf("%v", err)
}
tlsClientCfg.NextProtos = []string{http2.NextProtoTLS}
check := &CheckH2PING{
CheckID: cid,
H2PING: "localhost:55555",
Interval: 5 * time.Second,
Timeout: 1 * time.Second,
Logger: logger,
TLSClientConfig: tlsClientCfg,
StatusHandler: statusHandler,
}
check.Start()
defer check.Stop()
retry.Run(t, func(r *retry.R) {
if got, want := notif.State(cid), api.HealthCritical; got != want {
r.Fatalf("got state %q want %q", got, want)
}
expectedOutput := "Failed to dial to"
if !strings.Contains(notif.Output(cid), expectedOutput) {
r.Fatalf("should have included output %s: %v", expectedOutput, notif.OutputMap())
}
})
}
func TestCheck_Docker(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")

View File

@ -1579,6 +1579,7 @@ func (b *builder) checkVal(v *CheckDefinition) *structs.CheckDefinition {
TTL: b.durationVal(fmt.Sprintf("check[%s].ttl", id), v.TTL),
SuccessBeforePassing: intVal(v.SuccessBeforePassing),
FailuresBeforeCritical: intVal(v.FailuresBeforeCritical),
H2PING: stringVal(v.H2PING),
DeregisterCriticalServiceAfter: b.durationVal(fmt.Sprintf("check[%s].deregister_critical_service_after", id), v.DeregisterCriticalServiceAfter),
OutputMaxSize: intValWithDefault(v.OutputMaxSize, checks.DefaultBufSize),
EnterpriseMeta: v.EnterpriseMeta.ToStructs(),

View File

@ -411,6 +411,7 @@ type CheckDefinition struct {
AliasService *string `mapstructure:"alias_service"`
Timeout *string `mapstructure:"timeout"`
TTL *string `mapstructure:"ttl"`
H2PING *string `mapstructure:"h2ping"`
SuccessBeforePassing *int `mapstructure:"success_before_passing"`
FailuresBeforeCritical *int `mapstructure:"failures_before_critical"`
DeregisterCriticalServiceAfter *string `mapstructure:"deregister_critical_service_after" alias:"deregistercriticalserviceafter"`

View File

@ -470,6 +470,7 @@ type RuntimeConfig struct {
// header = map[string][]string
// method = string
// tcp = string
// h2ping = string
// interval = string
// docker_container_id = string
// shell = string

View File

@ -5205,6 +5205,7 @@ func TestLoad_FullConfig(t *testing.T) {
Method: "aldrIQ4l",
Body: "wSjTy7dg",
TCP: "RJQND605",
H2PING: "9N1cSb5B",
Interval: 22164 * time.Second,
OutputMaxSize: checks.DefaultBufSize,
DockerContainerID: "ipgdFtjd",
@ -5232,6 +5233,7 @@ func TestLoad_FullConfig(t *testing.T) {
Body: "0jkKgGUC",
OutputMaxSize: checks.DefaultBufSize,
TCP: "4jG5casb",
H2PING: "HCHU7gEb",
Interval: 28767 * time.Second,
DockerContainerID: "THW6u7rL",
Shell: "C1Zt3Zwh",
@ -5258,6 +5260,7 @@ func TestLoad_FullConfig(t *testing.T) {
Body: "5PBQd2OT",
OutputMaxSize: checks.DefaultBufSize,
TCP: "JY6fTTcw",
H2PING: "rQ8eyCSF",
Interval: 18714 * time.Second,
DockerContainerID: "qF66POS9",
Shell: "sOnDy228",
@ -5464,6 +5467,7 @@ func TestLoad_FullConfig(t *testing.T) {
Body: "WeikigLh",
OutputMaxSize: checks.DefaultBufSize,
TCP: "ICbxkpSF",
H2PING: "7s7BbMyb",
Interval: 24392 * time.Second,
DockerContainerID: "ZKXr68Yb",
Shell: "CEfzx0Fo",
@ -5515,6 +5519,7 @@ func TestLoad_FullConfig(t *testing.T) {
Body: "7CRjCJyz",
OutputMaxSize: checks.DefaultBufSize,
TCP: "MN3oA9D2",
H2PING: "OV6Q2XEg",
Interval: 32718 * time.Second,
DockerContainerID: "cU15LMet",
Shell: "nEz9qz2l",
@ -5539,6 +5544,7 @@ func TestLoad_FullConfig(t *testing.T) {
Body: "4I8ucZgZ",
OutputMaxSize: checks.DefaultBufSize,
TCP: "2exjZIGE",
H2PING: "jTDuR1DC",
Interval: 5656 * time.Second,
DockerContainerID: "5tDBWpfA",
Shell: "rlTpLM8s",
@ -5657,6 +5663,7 @@ func TestLoad_FullConfig(t *testing.T) {
Body: "OwGjTFQi",
OutputMaxSize: checks.DefaultBufSize,
TCP: "bNnNfx2A",
H2PING: "qC1pidiW",
Interval: 22224 * time.Second,
DockerContainerID: "ipgdFtjd",
Shell: "omVZq7Sz",
@ -5681,6 +5688,7 @@ func TestLoad_FullConfig(t *testing.T) {
Body: "lUVLGYU7",
OutputMaxSize: checks.DefaultBufSize,
TCP: "FfvCwlqH",
H2PING: "spI3muI3",
Interval: 12356 * time.Second,
DockerContainerID: "HBndBU6R",
Shell: "hVI33JjA",
@ -5705,6 +5713,7 @@ func TestLoad_FullConfig(t *testing.T) {
Body: "wVVL2V6f",
OutputMaxSize: checks.DefaultBufSize,
TCP: "fjiLFqVd",
H2PING: "5NbNWhan",
Interval: 23926 * time.Second,
DockerContainerID: "dO5TtRHk",
Shell: "e6q2ttES",

View File

@ -93,6 +93,7 @@
"FailuresBeforeCritical": 0,
"GRPC": "",
"GRPCUseTLS": false,
"H2PING": "",
"HTTP": "",
"Header": {},
"ID": "",
@ -294,6 +295,7 @@
"FailuresBeforeCritical": 0,
"GRPC": "",
"GRPCUseTLS": false,
"H2PING": "",
"HTTP": "",
"Header": {},
"Interval": "0s",

View File

@ -109,6 +109,7 @@ check = {
method = "Dou0nGT5"
body = "5PBQd2OT"
tcp = "JY6fTTcw"
h2ping = "rQ8eyCSF"
interval = "18714s"
output_max_size = 4096
docker_container_id = "qF66POS9"
@ -136,6 +137,7 @@ checks = [
method = "aldrIQ4l"
body = "wSjTy7dg"
tcp = "RJQND605"
h2ping = "9N1cSb5B"
interval = "22164s"
output_max_size = 4096
docker_container_id = "ipgdFtjd"
@ -162,6 +164,7 @@ checks = [
method = "gLrztrNw"
body = "0jkKgGUC"
tcp = "4jG5casb"
h2ping = "HCHU7gEb"
interval = "28767s"
output_max_size = 4096
docker_container_id = "THW6u7rL"
@ -378,6 +381,7 @@ service = {
method = "9afLm3Mj"
body = "wVVL2V6f"
tcp = "fjiLFqVd"
h2ping = "5NbNWhan"
interval = "23926s"
docker_container_id = "dO5TtRHk"
shell = "e6q2ttES"
@ -402,6 +406,7 @@ service = {
method = "T66MFBfR"
body = "OwGjTFQi"
tcp = "bNnNfx2A"
h2ping = "qC1pidiW"
interval = "22224s"
output_max_size = 4096
docker_container_id = "ipgdFtjd"
@ -426,6 +431,7 @@ service = {
method = "ciYHWors"
body = "lUVLGYU7"
tcp = "FfvCwlqH"
h2ping = "spI3muI3"
interval = "12356s"
output_max_size = 4096
docker_container_id = "HBndBU6R"
@ -464,6 +470,7 @@ services = [
method = "X5DrovFc"
body = "WeikigLh"
tcp = "ICbxkpSF"
h2ping = "7s7BbMyb"
interval = "24392s"
output_max_size = 4096
docker_container_id = "ZKXr68Yb"
@ -505,6 +512,7 @@ services = [
method = "5wkAxCUE"
body = "7CRjCJyz"
tcp = "MN3oA9D2"
h2ping = "OV6Q2XEg"
interval = "32718s"
output_max_size = 4096
docker_container_id = "cU15LMet"
@ -529,6 +537,7 @@ services = [
method = "wzByP903"
body = "4I8ucZgZ"
tcp = "2exjZIGE"
h2ping = "jTDuR1DC"
interval = "5656s"
output_max_size = 4096
docker_container_id = "5tDBWpfA"
@ -675,4 +684,4 @@ watches = [{
datacenter = "fYrl3F5d"
key = "sl3Dffu7"
args = ["dltjDJ2a", "flEa7C2d"]
}]
}]

View File

@ -111,6 +111,7 @@
"body": "5PBQd2OT",
"output_max_size": 4096,
"tcp": "JY6fTTcw",
"h2ping": "rQ8eyCSF",
"interval": "18714s",
"docker_container_id": "qF66POS9",
"shell": "sOnDy228",
@ -137,6 +138,7 @@
"method": "aldrIQ4l",
"body": "wSjTy7dg",
"tcp": "RJQND605",
"h2ping": "9N1cSb5B",
"interval": "22164s",
"output_max_size": 4096,
"docker_container_id": "ipgdFtjd",
@ -163,6 +165,7 @@
"method": "gLrztrNw",
"body": "0jkKgGUC",
"tcp": "4jG5casb",
"h2ping": "HCHU7gEb",
"interval": "28767s",
"output_max_size": 4096,
"docker_container_id": "THW6u7rL",
@ -374,6 +377,7 @@
"method": "9afLm3Mj",
"body": "wVVL2V6f",
"tcp": "fjiLFqVd",
"h2ping": "5NbNWhan",
"interval": "23926s",
"output_max_size": 4096,
"docker_container_id": "dO5TtRHk",
@ -399,6 +403,7 @@
"method": "T66MFBfR",
"body": "OwGjTFQi",
"tcp": "bNnNfx2A",
"h2ping": "qC1pidiW",
"interval": "22224s",
"output_max_size": 4096,
"docker_container_id": "ipgdFtjd",
@ -423,6 +428,7 @@
"method": "ciYHWors",
"body": "lUVLGYU7",
"tcp": "FfvCwlqH",
"h2ping": "spI3muI3",
"interval": "12356s",
"output_max_size": 4096,
"docker_container_id": "HBndBU6R",
@ -461,6 +467,7 @@
"method": "X5DrovFc",
"body": "WeikigLh",
"tcp": "ICbxkpSF",
"h2ping": "7s7BbMyb",
"interval": "24392s",
"output_max_size": 4096,
"docker_container_id": "ZKXr68Yb",
@ -502,6 +509,7 @@
"method": "5wkAxCUE",
"body": "7CRjCJyz",
"tcp": "MN3oA9D2",
"h2ping": "OV6Q2XEg",
"interval": "32718s",
"output_max_size": 4096,
"docker_container_id": "cU15LMet",
@ -526,6 +534,7 @@
"method": "wzByP903",
"body": "4I8ucZgZ",
"tcp": "2exjZIGE",
"h2ping": "jTDuR1DC",
"interval": "5656s",
"output_max_size": 4096,
"docker_container_id": "5tDBWpfA",
@ -675,4 +684,4 @@
"args": ["dltjDJ2a", "flEa7C2d"]
}
]
}
}

View File

@ -24,6 +24,7 @@ type CheckDefinition struct {
//
ScriptArgs []string
HTTP string
H2PING string
Header map[string][]string
Method string
Body string
@ -177,6 +178,7 @@ func (c *CheckDefinition) CheckType() *CheckType {
AliasNode: c.AliasNode,
AliasService: c.AliasService,
HTTP: c.HTTP,
H2PING: c.H2PING,
GRPC: c.GRPC,
GRPCUseTLS: c.GRPCUseTLS,
Header: c.Header,

View File

@ -85,6 +85,7 @@ func TestCheckDefinitionToCheckType(t *testing.T) {
Token: "tok",
ScriptArgs: []string{"/bin/foo"},
HTTP: "someurl",
H2PING: "somehttp2url",
TCP: "host:port",
Interval: 1 * time.Second,
DockerContainerID: "abc123",
@ -102,6 +103,7 @@ func TestCheckDefinitionToCheckType(t *testing.T) {
ScriptArgs: []string{"/bin/foo"},
HTTP: "someurl",
H2PING: "somehttp2url",
TCP: "host:port",
Interval: 1 * time.Second,
DockerContainerID: "abc123",

View File

@ -12,10 +12,10 @@ import (
type CheckTypes []*CheckType
// CheckType is used to create either the CheckMonitor or the CheckTTL.
// The following types are supported: Script, HTTP, TCP, Docker, TTL, GRPC, Alias. Script,
// HTTP, Docker, TCP and GRPC all require Interval. Only one of the types may
// The following types are supported: Script, HTTP, TCP, Docker, TTL, GRPC, Alias, H2PING. Script,
// HTTP, Docker, TCP, GRPC, and H2PING all require Interval. Only one of the types may
// to be provided: TTL or Script/Interval or HTTP/Interval or TCP/Interval or
// Docker/Interval or GRPC/Interval or AliasService.
// Docker/Interval or GRPC/Interval or AliasService or H2PING/Interval.
// Since types like CheckHTTP and CheckGRPC derive from CheckType, there are
// helper conversion methods that do the reverse conversion. ie. checkHTTP.CheckType()
type CheckType struct {
@ -32,6 +32,7 @@ type CheckType struct {
ScriptArgs []string
HTTP string
H2PING string
Header map[string][]string
Method string
Body string
@ -161,13 +162,13 @@ func (t *CheckType) UnmarshalJSON(data []byte) (err error) {
// Validate returns an error message if the check is invalid
func (c *CheckType) Validate() error {
intervalCheck := c.IsScript() || c.HTTP != "" || c.TCP != "" || c.GRPC != ""
intervalCheck := c.IsScript() || c.HTTP != "" || c.TCP != "" || c.GRPC != "" || c.H2PING != ""
if c.Interval > 0 && c.TTL > 0 {
return fmt.Errorf("Interval and TTL cannot both be specified")
}
if intervalCheck && c.Interval <= 0 {
return fmt.Errorf("Interval must be > 0 for Script, HTTP, or TCP checks")
return fmt.Errorf("Interval must be > 0 for Script, HTTP, H2PING, or TCP checks")
}
if intervalCheck && c.IsAlias() {
return fmt.Errorf("Interval cannot be set for Alias checks")
@ -229,6 +230,11 @@ func (c *CheckType) IsGRPC() bool {
return c.GRPC != "" && c.Interval > 0
}
// IsH2PING checks if this is a H2PING type
func (c *CheckType) IsH2PING() bool {
return c.H2PING != "" && c.Interval > 0
}
func (c *CheckType) Type() string {
switch {
case c.IsGRPC():
@ -245,6 +251,8 @@ func (c *CheckType) Type() string {
return "docker"
case c.IsScript():
return "script"
case c.IsH2PING():
return "h2ping"
default:
return ""
}

View File

@ -1450,6 +1450,7 @@ type HealthCheckDefinition struct {
Method string `json:",omitempty"`
Body string `json:",omitempty"`
TCP string `json:",omitempty"`
H2PING string `json:",omitempty"`
Interval time.Duration `json:",omitempty"`
OutputMaxSize uint `json:",omitempty"`
Timeout time.Duration `json:",omitempty"`
@ -1596,6 +1597,7 @@ func (c *HealthCheck) CheckType() *CheckType {
Method: c.Definition.Method,
Body: c.Definition.Body,
TCP: c.Definition.TCP,
H2PING: c.Definition.H2PING,
Interval: c.Definition.Interval,
DockerContainerID: c.Definition.DockerContainerID,
Shell: c.Definition.Shell,

View File

@ -21,6 +21,7 @@ func CheckTypeToStructs(s CheckType) structs.CheckType {
t.AliasService = s.AliasService
t.DockerContainerID = s.DockerContainerID
t.Shell = s.Shell
t.H2PING = s.H2PING
t.GRPC = s.GRPC
t.GRPCUseTLS = s.GRPCUseTLS
t.TLSServerName = s.TLSServerName
@ -52,6 +53,7 @@ func NewCheckTypeFromStructs(t structs.CheckType) CheckType {
s.AliasService = t.AliasService
s.DockerContainerID = t.DockerContainerID
s.Shell = t.Shell
s.H2PING = t.H2PING
s.GRPC = t.GRPC
s.GRPCUseTLS = t.GRPCUseTLS
s.TLSServerName = t.TLSServerName
@ -116,6 +118,7 @@ func HealthCheckDefinitionToStructs(s HealthCheckDefinition) structs.HealthCheck
t.ScriptArgs = s.ScriptArgs
t.DockerContainerID = s.DockerContainerID
t.Shell = s.Shell
t.H2PING = s.H2PING
t.GRPC = s.GRPC
t.GRPCUseTLS = s.GRPCUseTLS
t.AliasNode = s.AliasNode
@ -139,6 +142,7 @@ func NewHealthCheckDefinitionFromStructs(t structs.HealthCheckDefinition) Health
s.ScriptArgs = t.ScriptArgs
s.DockerContainerID = t.DockerContainerID
s.Shell = t.Shell
s.H2PING = t.H2PING
s.GRPC = t.GRPC
s.GRPCUseTLS = t.GRPCUseTLS
s.AliasNode = t.AliasNode

View File

@ -148,6 +148,7 @@ type HealthCheckDefinition struct {
ScriptArgs []string `protobuf:"bytes,10,rep,name=ScriptArgs,proto3" json:"ScriptArgs,omitempty"`
DockerContainerID string `protobuf:"bytes,11,opt,name=DockerContainerID,proto3" json:"DockerContainerID,omitempty"`
Shell string `protobuf:"bytes,12,opt,name=Shell,proto3" json:"Shell,omitempty"`
H2PING string `protobuf:"bytes,20,opt,name=H2PING,proto3" json:"H2PING,omitempty"`
GRPC string `protobuf:"bytes,13,opt,name=GRPC,proto3" json:"GRPC,omitempty"`
GRPCUseTLS bool `protobuf:"varint,14,opt,name=GRPCUseTLS,proto3" json:"GRPCUseTLS,omitempty"`
AliasNode string `protobuf:"bytes,15,opt,name=AliasNode,proto3" json:"AliasNode,omitempty"`
@ -190,10 +191,10 @@ var xxx_messageInfo_HealthCheckDefinition proto.InternalMessageInfo
// CheckType is used to create either the CheckMonitor or the CheckTTL.
// The following types are supported: Script, HTTP, TCP, Docker, TTL, GRPC,
// Alias. Script,
// HTTP, Docker, TCP and GRPC all require Interval. Only one of the types may
// Alias. Script, H2PING,
// HTTP, Docker, TCP, H2PING and GRPC all require Interval. Only one of the types may
// to be provided: TTL or Script/Interval or HTTP/Interval or TCP/Interval or
// Docker/Interval or GRPC/Interval or AliasService.
// Docker/Interval or GRPC/Interval or H2PING/Interval or AliasService.
//
// mog annotation:
//
@ -217,6 +218,7 @@ type CheckType struct {
AliasService string `protobuf:"bytes,11,opt,name=AliasService,proto3" json:"AliasService,omitempty"`
DockerContainerID string `protobuf:"bytes,12,opt,name=DockerContainerID,proto3" json:"DockerContainerID,omitempty"`
Shell string `protobuf:"bytes,13,opt,name=Shell,proto3" json:"Shell,omitempty"`
H2PING string `protobuf:"bytes,28,opt,name=H2PING,proto3" json:"H2PING,omitempty"`
GRPC string `protobuf:"bytes,14,opt,name=GRPC,proto3" json:"GRPC,omitempty"`
GRPCUseTLS bool `protobuf:"varint,15,opt,name=GRPCUseTLS,proto3" json:"GRPCUseTLS,omitempty"`
TLSServerName string `protobuf:"bytes,27,opt,name=TLSServerName,proto3" json:"TLSServerName,omitempty"`
@ -283,71 +285,72 @@ func init() {
func init() { proto.RegisterFile("proto/pbservice/healthcheck.proto", fileDescriptor_8a6f7448747c9fbe) }
var fileDescriptor_8a6f7448747c9fbe = []byte{
// 1016 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xcf, 0x6f, 0xe3, 0x44,
0x14, 0x8e, 0x9b, 0x36, 0x8d, 0x27, 0x6d, 0xb7, 0x9d, 0xed, 0x96, 0xd9, 0x2e, 0x72, 0x43, 0xe0,
0x10, 0x44, 0x71, 0xa4, 0x22, 0x10, 0x20, 0x01, 0x6a, 0x92, 0xfd, 0x11, 0xd4, 0x2e, 0xc1, 0x31,
0x7b, 0xe0, 0xe6, 0x3a, 0x93, 0xc4, 0x8a, 0xe3, 0x89, 0xc6, 0xe3, 0xaa, 0xe1, 0xca, 0x3f, 0x80,
0xc4, 0x65, 0xff, 0xa4, 0x1e, 0x7b, 0xe4, 0x54, 0xa0, 0xfd, 0x27, 0x10, 0x27, 0x34, 0x6f, 0xec,
0xd4, 0xd9, 0x78, 0x49, 0x58, 0x2d, 0xa7, 0xcc, 0x7c, 0xef, 0xbd, 0x19, 0xcf, 0x7b, 0xdf, 0xf7,
0xb5, 0xe8, 0xbd, 0x31, 0x67, 0x82, 0xd5, 0xc6, 0x67, 0x21, 0xe5, 0xe7, 0x9e, 0x4b, 0x6b, 0x03,
0xea, 0xf8, 0x62, 0xe0, 0x0e, 0xa8, 0x3b, 0x34, 0x21, 0x86, 0xf5, 0x69, 0x70, 0xdf, 0xe8, 0x33,
0xd6, 0xf7, 0x69, 0x0d, 0x02, 0x67, 0x51, 0xaf, 0xd6, 0x8d, 0xb8, 0x23, 0x3c, 0x16, 0xa8, 0xd4,
0xfd, 0x47, 0xc9, 0x69, 0x2e, 0x1b, 0x8d, 0x58, 0x50, 0x53, 0x3f, 0x71, 0x70, 0xb7, 0xcf, 0xfa,
0x4c, 0x25, 0xc8, 0x95, 0x42, 0x2b, 0x3f, 0xaf, 0xa2, 0xd2, 0x33, 0xb8, 0xb3, 0x21, 0xef, 0xc4,
0x18, 0xad, 0x3e, 0x67, 0x5d, 0x4a, 0xb4, 0xb2, 0x56, 0xd5, 0x2d, 0x58, 0xe3, 0xa7, 0x68, 0x1d,
0x82, 0xad, 0x26, 0x59, 0x91, 0x70, 0xfd, 0xe3, 0xbf, 0xaf, 0x0f, 0x3e, 0xec, 0x7b, 0x62, 0x10,
0x9d, 0x99, 0x2e, 0x1b, 0xd5, 0x06, 0x4e, 0x38, 0xf0, 0x5c, 0xc6, 0xc7, 0x35, 0x97, 0x05, 0x61,
0xe4, 0xd7, 0xc4, 0x64, 0x4c, 0x43, 0x33, 0x2e, 0xb2, 0x92, 0x6a, 0x38, 0xdc, 0x19, 0x51, 0x92,
0x8f, 0x0f, 0x77, 0x46, 0x14, 0xef, 0xa1, 0x42, 0x47, 0x38, 0x22, 0x0a, 0xc9, 0x2a, 0xa0, 0xf1,
0x0e, 0xef, 0xa2, 0xb5, 0xe7, 0x4c, 0xd0, 0x90, 0xac, 0x01, 0xac, 0x36, 0x32, 0xfb, 0xbb, 0x48,
0x8c, 0x23, 0x41, 0x0a, 0x2a, 0x5b, 0xed, 0xf0, 0xbb, 0x48, 0xef, 0xa8, 0x26, 0xb5, 0x9a, 0x64,
0x1d, 0x42, 0x77, 0x00, 0x2e, 0xa3, 0x52, 0xbc, 0x81, 0xeb, 0x8b, 0x10, 0x4f, 0x43, 0xa9, 0x0c,
0xdb, 0xe9, 0x87, 0x44, 0x2f, 0xe7, 0x53, 0x19, 0x12, 0x92, 0xdf, 0x6e, 0x4f, 0xc6, 0x94, 0x6c,
0xa8, 0x6f, 0x97, 0x6b, 0xfc, 0x04, 0xa1, 0x26, 0xed, 0x79, 0x81, 0x27, 0x67, 0x40, 0x50, 0x59,
0xab, 0x96, 0x8e, 0xca, 0xe6, 0x74, 0x5e, 0x66, 0xaa, 0xb1, 0x77, 0x79, 0xf5, 0xd5, 0xcb, 0xeb,
0x83, 0x9c, 0x95, 0xaa, 0xc4, 0x5f, 0x20, 0xdd, 0x72, 0x7a, 0xa2, 0x15, 0x74, 0xe9, 0x05, 0x29,
0xc1, 0x31, 0x3b, 0x66, 0x3c, 0xbc, 0x69, 0xa0, 0x5e, 0x94, 0x75, 0x57, 0xd7, 0x07, 0x9a, 0x75,
0x97, 0x8d, 0x9b, 0x68, 0xeb, 0x71, 0x20, 0x28, 0x1f, 0x73, 0x2f, 0xa4, 0xa7, 0x54, 0x38, 0x64,
0x13, 0xea, 0xf7, 0x92, 0xfa, 0xd9, 0x68, 0x7c, 0xf9, 0x2b, 0x35, 0x95, 0xf7, 0x81, 0x04, 0x5d,
0xca, 0x5f, 0x38, 0x7e, 0x44, 0x65, 0xef, 0x61, 0x41, 0x34, 0xe8, 0x83, 0xda, 0x54, 0xfe, 0x2a,
0xa0, 0x07, 0x99, 0x2f, 0x92, 0xbd, 0x79, 0x66, 0xdb, 0xed, 0x84, 0x34, 0x72, 0x8d, 0x3f, 0x40,
0x9b, 0xf6, 0x49, 0x47, 0x76, 0x90, 0x72, 0xe8, 0xfa, 0x7d, 0x08, 0xce, 0x82, 0x49, 0xd6, 0xd0,
0x1b, 0xbf, 0xa0, 0xdc, 0xeb, 0x4d, 0x80, 0x60, 0x45, 0x6b, 0x16, 0xc4, 0xdf, 0xa2, 0x82, 0xfa,
0x3c, 0x92, 0x2f, 0xe7, 0xab, 0xa5, 0xa3, 0xc3, 0x45, 0x3d, 0x36, 0x55, 0xfa, 0xe3, 0x40, 0xf0,
0x49, 0xfc, 0xe4, 0xf8, 0x04, 0xc9, 0xa0, 0x53, 0x2a, 0x06, 0xac, 0x9b, 0xf0, 0x4d, 0xed, 0xe4,
0x1b, 0xea, 0xac, 0x3b, 0x21, 0x58, 0xbd, 0x41, 0xae, 0xf1, 0x36, 0xca, 0xdb, 0x8d, 0x76, 0xcc,
0x40, 0xb9, 0xc4, 0xdf, 0xa0, 0x62, 0x4b, 0xb6, 0xee, 0xdc, 0xf1, 0x81, 0x81, 0xa5, 0xa3, 0x87,
0xa6, 0x12, 0xa5, 0x99, 0x88, 0xd2, 0x6c, 0xc6, 0xa2, 0x54, 0x03, 0x7b, 0xf9, 0xfb, 0x81, 0x66,
0x4d, 0x8b, 0xe4, 0x83, 0x15, 0x65, 0x4f, 0x9d, 0x8b, 0x8e, 0xf7, 0x13, 0x25, 0x7a, 0x59, 0xab,
0x6e, 0x5a, 0xb3, 0x20, 0xfe, 0x0a, 0xad, 0xdb, 0xde, 0x88, 0xb2, 0x48, 0x00, 0x99, 0x97, 0xbc,
0x25, 0xa9, 0xc1, 0x43, 0x64, 0x34, 0x29, 0xa7, 0x7d, 0x2f, 0x14, 0x94, 0x37, 0xb8, 0x27, 0x3c,
0xd7, 0xf1, 0x63, 0x32, 0x1f, 0xf7, 0x04, 0xe5, 0x20, 0x81, 0x25, 0x4f, 0x5d, 0x70, 0x14, 0x36,
0x10, 0xea, 0xb8, 0xdc, 0x1b, 0x8b, 0x63, 0xde, 0x0f, 0x09, 0x02, 0xc6, 0xa4, 0x10, 0x7c, 0x88,
0x76, 0x9a, 0xcc, 0x1d, 0x52, 0xde, 0x60, 0x81, 0x70, 0xbc, 0x80, 0xf2, 0x56, 0x13, 0x48, 0xae,
0x5b, 0xf3, 0x01, 0x49, 0xbd, 0xce, 0x80, 0xfa, 0x7e, 0xac, 0x33, 0xb5, 0x91, 0xc3, 0x79, 0x6a,
0xb5, 0x1b, 0xc0, 0x6d, 0xdd, 0x82, 0xb5, 0xbc, 0x57, 0xfe, 0xfe, 0x10, 0x52, 0xfb, 0xa4, 0x43,
0xb6, 0x80, 0x37, 0x29, 0x44, 0x5a, 0xc2, 0xb1, 0xef, 0x39, 0x21, 0xd8, 0xd9, 0x3d, 0x65, 0x09,
0x53, 0x00, 0x57, 0xd0, 0x06, 0x6c, 0xe2, 0xa7, 0x90, 0x6d, 0x48, 0x98, 0xc1, 0xf0, 0xa7, 0x28,
0x6f, 0xdb, 0x27, 0x64, 0x67, 0xf9, 0x5e, 0xc9, 0xfc, 0xfd, 0xef, 0x13, 0x31, 0x01, 0xfd, 0x24,
0x89, 0x86, 0x74, 0x12, 0x6b, 0x43, 0x2e, 0xf1, 0x21, 0x5a, 0x3b, 0x07, 0x79, 0xad, 0xc4, 0x52,
0x9d, 0x61, 0x73, 0xa2, 0x42, 0x4b, 0x25, 0x7d, 0xb9, 0xf2, 0xb9, 0x56, 0xf9, 0x55, 0x47, 0x3a,
0x50, 0x1c, 0x6c, 0x27, 0xe5, 0xc7, 0xda, 0x5b, 0xf1, 0xe3, 0x95, 0x4c, 0x3f, 0xce, 0x67, 0xfb,
0xf1, 0x6a, 0xda, 0x8f, 0x67, 0x87, 0xbf, 0x36, 0x37, 0xfc, 0xc4, 0x19, 0x0a, 0x29, 0x67, 0xf8,
0x7a, 0xaa, 0xe6, 0x5d, 0x50, 0x73, 0xda, 0x31, 0xa7, 0x8f, 0x5c, 0x4a, 0xc1, 0xeb, 0x99, 0x0a,
0xde, 0x9f, 0x57, 0x70, 0x31, 0x5b, 0xc1, 0xfa, 0x9b, 0x28, 0x78, 0x86, 0x57, 0x68, 0x11, 0xaf,
0x4a, 0x19, 0xbc, 0xca, 0x54, 0xc4, 0xc6, 0x42, 0x45, 0x6c, 0x66, 0x29, 0x62, 0xeb, 0xb5, 0x8a,
0xb8, 0x37, 0xa7, 0x88, 0x39, 0x4b, 0x7e, 0xb4, 0x94, 0x25, 0x6f, 0x67, 0x59, 0x72, 0xca, 0xa1,
0x76, 0xde, 0xc0, 0xa1, 0x62, 0x69, 0xe1, 0xff, 0x26, 0x2d, 0x7c, 0x84, 0x76, 0x3b, 0x91, 0xeb,
0xd2, 0x30, 0xac, 0xd3, 0x1e, 0xe3, 0xb4, 0xed, 0x84, 0xa1, 0x17, 0xf4, 0xc9, 0x83, 0xb2, 0x56,
0x5d, 0xb3, 0x32, 0x63, 0xf8, 0x33, 0xb4, 0xf7, 0xc4, 0xf1, 0xfc, 0x88, 0xd3, 0x38, 0x90, 0xb8,
0x18, 0xd9, 0x83, 0xaa, 0xd7, 0x44, 0xe5, 0x9c, 0xdb, 0x9c, 0x5d, 0x4c, 0x80, 0xbf, 0xef, 0xa8,
0x39, 0x4f, 0x81, 0x69, 0x14, 0x86, 0x40, 0x52, 0x51, 0x98, 0xc4, 0x62, 0x03, 0xbe, 0xff, 0xf6,
0x0c, 0x78, 0xee, 0x4f, 0xca, 0x43, 0x78, 0xd7, 0x2c, 0xf8, 0x3f, 0xb8, 0x52, 0xfd, 0xf4, 0xf2,
0x4f, 0x23, 0x77, 0x79, 0x63, 0x68, 0x57, 0x37, 0x86, 0xf6, 0xc7, 0x8d, 0xa1, 0xfd, 0x72, 0x6b,
0xe4, 0x5e, 0xde, 0x1a, 0xb9, 0xab, 0x5b, 0x23, 0xf7, 0xdb, 0xad, 0x91, 0xfb, 0xf1, 0xa3, 0x7f,
0x33, 0xa5, 0x57, 0xfe, 0xf5, 0x3d, 0x2b, 0x00, 0xf0, 0xc9, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff,
0xf4, 0xca, 0x84, 0xe7, 0x14, 0x0b, 0x00, 0x00,
// 1031 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x4d, 0x73, 0xdb, 0x44,
0x18, 0xb6, 0xe2, 0x7c, 0x69, 0x9d, 0xa4, 0xc9, 0x36, 0x0d, 0xdb, 0xb4, 0xa3, 0x98, 0xc0, 0xc1,
0x0c, 0x41, 0x9e, 0x31, 0x03, 0x03, 0xcc, 0x00, 0x13, 0xdb, 0x6d, 0x62, 0x26, 0x09, 0x46, 0x16,
0x3d, 0x70, 0x53, 0xe4, 0xb5, 0xad, 0xb1, 0xac, 0xf5, 0xac, 0x56, 0x99, 0x98, 0x2b, 0x7f, 0xa0,
0xc7, 0xfe, 0x07, 0xfe, 0x48, 0x8e, 0x39, 0x72, 0x0a, 0x90, 0xfc, 0x0b, 0x4e, 0xcc, 0xbe, 0x2b,
0x39, 0x72, 0xad, 0x62, 0xd3, 0x69, 0x4f, 0x7e, 0x3f, 0x77, 0xb5, 0xef, 0xfb, 0x3c, 0x4f, 0x82,
0x3e, 0x1c, 0x72, 0x26, 0x58, 0x79, 0x78, 0x1e, 0x52, 0x7e, 0xe1, 0xb9, 0xb4, 0xdc, 0xa3, 0x8e,
0x2f, 0x7a, 0x6e, 0x8f, 0xba, 0x7d, 0x13, 0x72, 0x58, 0x1f, 0x27, 0x77, 0x8d, 0x2e, 0x63, 0x5d,
0x9f, 0x96, 0x21, 0x71, 0x1e, 0x75, 0xca, 0xed, 0x88, 0x3b, 0xc2, 0x63, 0x81, 0x2a, 0xdd, 0x7d,
0x92, 0x9c, 0xe6, 0xb2, 0xc1, 0x80, 0x05, 0x65, 0xf5, 0x13, 0x27, 0xb7, 0xbb, 0xac, 0xcb, 0x54,
0x81, 0xb4, 0x54, 0x74, 0xff, 0xb7, 0x45, 0x54, 0x38, 0x86, 0x3b, 0x6b, 0xf2, 0x4e, 0x8c, 0xd1,
0xe2, 0x19, 0x6b, 0x53, 0xa2, 0x15, 0xb5, 0x92, 0x6e, 0x81, 0x8d, 0x8f, 0xd0, 0x0a, 0x24, 0x1b,
0x75, 0xb2, 0x20, 0xc3, 0xd5, 0xcf, 0xfe, 0xb9, 0xd9, 0xfb, 0xa4, 0xeb, 0x89, 0x5e, 0x74, 0x6e,
0xba, 0x6c, 0x50, 0xee, 0x39, 0x61, 0xcf, 0x73, 0x19, 0x1f, 0x96, 0x5d, 0x16, 0x84, 0x91, 0x5f,
0x16, 0xa3, 0x21, 0x0d, 0xcd, 0xb8, 0xc9, 0x4a, 0xba, 0xe1, 0x70, 0x67, 0x40, 0x49, 0x3e, 0x3e,
0xdc, 0x19, 0x50, 0xbc, 0x83, 0x96, 0x5b, 0xc2, 0x11, 0x51, 0x48, 0x16, 0x21, 0x1a, 0x7b, 0x78,
0x1b, 0x2d, 0x9d, 0x31, 0x41, 0x43, 0xb2, 0x04, 0x61, 0xe5, 0xc8, 0xea, 0x1f, 0x23, 0x31, 0x8c,
0x04, 0x59, 0x56, 0xd5, 0xca, 0xc3, 0x4f, 0x91, 0xde, 0x52, 0x43, 0x6a, 0xd4, 0xc9, 0x0a, 0xa4,
0xee, 0x03, 0xb8, 0x88, 0x0a, 0xb1, 0x03, 0xd7, 0xaf, 0x42, 0x3e, 0x1d, 0x4a, 0x55, 0xd8, 0x4e,
0x37, 0x24, 0x7a, 0x31, 0x9f, 0xaa, 0x90, 0x21, 0xf9, 0xed, 0xf6, 0x68, 0x48, 0xc9, 0x9a, 0xfa,
0x76, 0x69, 0xe3, 0xe7, 0x08, 0xd5, 0x69, 0xc7, 0x0b, 0x3c, 0xb9, 0x03, 0x82, 0x8a, 0x5a, 0xa9,
0x50, 0x29, 0x9a, 0xe3, 0x7d, 0x99, 0xa9, 0xc1, 0xde, 0xd7, 0x55, 0x17, 0xaf, 0x6e, 0xf6, 0x72,
0x56, 0xaa, 0x13, 0x7f, 0x8d, 0x74, 0xcb, 0xe9, 0x88, 0x46, 0xd0, 0xa6, 0x97, 0xa4, 0x00, 0xc7,
0x6c, 0x99, 0xf1, 0xf2, 0xc6, 0x89, 0xea, 0xaa, 0xec, 0xbb, 0xbe, 0xd9, 0xd3, 0xac, 0xfb, 0x6a,
0x5c, 0x47, 0x1b, 0xcf, 0x02, 0x41, 0xf9, 0x90, 0x7b, 0x21, 0x3d, 0xa5, 0xc2, 0x21, 0xeb, 0xd0,
0xbf, 0x93, 0xf4, 0x4f, 0x66, 0xe3, 0xcb, 0x5f, 0xeb, 0xd9, 0xff, 0x08, 0x40, 0xd0, 0xa6, 0xfc,
0x85, 0xe3, 0x47, 0x54, 0xce, 0x1e, 0x0c, 0xa2, 0xc1, 0x1c, 0x94, 0xb3, 0xff, 0x72, 0x05, 0x3d,
0xca, 0x7c, 0x91, 0x9c, 0xcd, 0xb1, 0x6d, 0x37, 0x13, 0xd0, 0x48, 0x1b, 0x7f, 0x8c, 0xd6, 0xed,
0x93, 0x96, 0x9c, 0x20, 0xe5, 0x30, 0xf5, 0x87, 0x90, 0x9c, 0x0c, 0x26, 0x55, 0x7d, 0x6f, 0xf8,
0x82, 0x72, 0xaf, 0x33, 0x02, 0x80, 0xad, 0x5a, 0x93, 0x41, 0xfc, 0x03, 0x5a, 0x56, 0x9f, 0x47,
0xf2, 0xc5, 0x7c, 0xa9, 0x50, 0x39, 0x98, 0x35, 0x63, 0x53, 0x95, 0x3f, 0x0b, 0x04, 0x1f, 0xc5,
0x4f, 0x8e, 0x4f, 0x90, 0x08, 0x3a, 0xa5, 0xa2, 0xc7, 0xda, 0x09, 0xde, 0x94, 0x27, 0xdf, 0x50,
0x65, 0xed, 0x11, 0xc1, 0xea, 0x0d, 0xd2, 0xc6, 0x9b, 0x28, 0x6f, 0xd7, 0x9a, 0x31, 0x02, 0xa5,
0x89, 0xbf, 0x47, 0xab, 0x0d, 0x39, 0xba, 0x0b, 0xc7, 0x07, 0x04, 0x16, 0x2a, 0x8f, 0x4d, 0x45,
0x4a, 0x33, 0x21, 0xa5, 0x59, 0x8f, 0x49, 0xa9, 0x16, 0xf6, 0xea, 0xcf, 0x3d, 0xcd, 0x1a, 0x37,
0xc9, 0x07, 0x2b, 0xc8, 0x9e, 0x3a, 0x97, 0x2d, 0xef, 0x57, 0x4a, 0xf4, 0xa2, 0x56, 0x5a, 0xb7,
0x26, 0x83, 0xf8, 0x5b, 0xb4, 0x62, 0x7b, 0x03, 0xca, 0x22, 0x01, 0x60, 0x9e, 0xf3, 0x96, 0xa4,
0x07, 0xf7, 0x91, 0x51, 0xa7, 0x9c, 0x76, 0xbd, 0x50, 0x50, 0x5e, 0xe3, 0x9e, 0xf0, 0x5c, 0xc7,
0x8f, 0xc1, 0x7c, 0xd8, 0x11, 0x94, 0x03, 0x05, 0xe6, 0x3c, 0x75, 0xc6, 0x51, 0xd8, 0x40, 0xa8,
0xe5, 0x72, 0x6f, 0x28, 0x0e, 0x79, 0x37, 0x24, 0x08, 0x10, 0x93, 0x8a, 0xe0, 0x03, 0xb4, 0x55,
0x67, 0x6e, 0x9f, 0xf2, 0x1a, 0x0b, 0x84, 0xe3, 0x05, 0x94, 0x37, 0xea, 0x00, 0x72, 0xdd, 0x9a,
0x4e, 0x48, 0xe8, 0xb5, 0x7a, 0xd4, 0xf7, 0x63, 0x9e, 0x29, 0x47, 0x2e, 0xed, 0xb8, 0xd2, 0x6c,
0x9c, 0x1d, 0x91, 0x6d, 0xb5, 0x34, 0xe5, 0xc9, 0xa5, 0x1d, 0x59, 0xcd, 0x1a, 0x60, 0x5e, 0xb7,
0xc0, 0x96, 0xdf, 0x23, 0x7f, 0x7f, 0x0e, 0xa9, 0x7d, 0xd2, 0x22, 0x1b, 0x80, 0xa7, 0x54, 0x44,
0x4a, 0xc5, 0xa1, 0xef, 0x39, 0x21, 0xc8, 0xdc, 0x03, 0x25, 0x15, 0xe3, 0x00, 0xde, 0x47, 0x6b,
0xe0, 0xc4, 0x4f, 0x24, 0x9b, 0x50, 0x30, 0x11, 0xc3, 0x5f, 0xa0, 0xbc, 0x6d, 0x9f, 0x90, 0xad,
0xf9, 0x67, 0x28, 0xeb, 0x77, 0x7f, 0x4a, 0x48, 0x06, 0xb0, 0x94, 0xe0, 0xea, 0xd3, 0x51, 0xcc,
0x19, 0x69, 0xe2, 0x03, 0xb4, 0x74, 0x01, 0xb4, 0x5b, 0x88, 0x29, 0x3c, 0x81, 0xf2, 0x84, 0x9d,
0x96, 0x2a, 0xfa, 0x66, 0xe1, 0x2b, 0x6d, 0xff, 0x77, 0x1d, 0xe9, 0x00, 0x7d, 0x90, 0xa3, 0x94,
0x4e, 0x6b, 0xef, 0x44, 0xa7, 0x17, 0x32, 0x75, 0x3a, 0x9f, 0xad, 0xd3, 0x8b, 0x69, 0x9d, 0x9e,
0x04, 0xc5, 0xd2, 0x14, 0x28, 0x12, 0xc5, 0x58, 0x4e, 0x29, 0xc6, 0x77, 0x63, 0x96, 0x6f, 0x03,
0xcb, 0xd3, 0x4a, 0x3a, 0x7e, 0xe4, 0x5c, 0xcc, 0x5e, 0xc9, 0x64, 0xf6, 0xee, 0x34, 0xb3, 0x57,
0xb3, 0x99, 0xad, 0xbf, 0x0d, 0xb3, 0x27, 0x70, 0x85, 0x66, 0xe1, 0xaa, 0x90, 0x81, 0xab, 0x4c,
0xa6, 0xac, 0xcd, 0x64, 0xca, 0x7a, 0x36, 0x53, 0x9e, 0x66, 0x32, 0x65, 0xe3, 0x8d, 0x4c, 0x79,
0x30, 0xc5, 0x94, 0x29, 0x09, 0x7f, 0x32, 0x97, 0x84, 0x6f, 0x66, 0x49, 0x78, 0x4a, 0xd1, 0xb6,
0xde, 0x42, 0xd1, 0x62, 0xca, 0xe1, 0xff, 0x47, 0x39, 0x5c, 0x41, 0xdb, 0xad, 0xc8, 0x75, 0x69,
0x18, 0x56, 0x69, 0x87, 0x71, 0xda, 0x74, 0xc2, 0xd0, 0x0b, 0xba, 0xe4, 0x51, 0x51, 0x2b, 0x2d,
0x59, 0x99, 0x39, 0xfc, 0x25, 0xda, 0x79, 0xee, 0x78, 0x7e, 0xc4, 0x69, 0x9c, 0x48, 0x54, 0x8f,
0xec, 0x40, 0xd7, 0x1b, 0xb2, 0x72, 0xff, 0x4d, 0xce, 0x2e, 0x47, 0x80, 0xeb, 0x0f, 0xd4, 0xfe,
0xc7, 0x81, 0x71, 0x16, 0x96, 0x40, 0x52, 0x59, 0xd8, 0xc4, 0x6c, 0xc1, 0x7e, 0xf8, 0xee, 0x04,
0x7b, 0xea, 0x4f, 0xd0, 0x63, 0x78, 0xd7, 0x64, 0xf0, 0x3d, 0xa8, 0x55, 0xf5, 0xf4, 0xea, 0x6f,
0x23, 0x77, 0x75, 0x6b, 0x68, 0xd7, 0xb7, 0x86, 0xf6, 0xd7, 0xad, 0xa1, 0xbd, 0xbc, 0x33, 0x72,
0xaf, 0xee, 0x8c, 0xdc, 0xf5, 0x9d, 0x91, 0xfb, 0xe3, 0xce, 0xc8, 0xfd, 0xf2, 0xe9, 0x7f, 0x89,
0xd5, 0x6b, 0xff, 0x2a, 0x9f, 0x2f, 0x43, 0xe0, 0xf3, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x5b,
0x4c, 0x80, 0x35, 0x44, 0x0b, 0x00, 0x00,
}
func (m *HealthCheck) Marshal() (dAtA []byte, err error) {
@ -527,6 +530,15 @@ func (m *HealthCheckDefinition) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if len(m.H2PING) > 0 {
i -= len(m.H2PING)
copy(dAtA[i:], m.H2PING)
i = encodeVarintHealthcheck(dAtA, i, uint64(len(m.H2PING)))
i--
dAtA[i] = 0x1
i--
dAtA[i] = 0xa2
}
if len(m.TLSServerName) > 0 {
i -= len(m.TLSServerName)
copy(dAtA[i:], m.TLSServerName)
@ -718,6 +730,15 @@ func (m *CheckType) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if len(m.H2PING) > 0 {
i -= len(m.H2PING)
copy(dAtA[i:], m.H2PING)
i = encodeVarintHealthcheck(dAtA, i, uint64(len(m.H2PING)))
i--
dAtA[i] = 0x1
i--
dAtA[i] = 0xe2
}
if len(m.TLSServerName) > 0 {
i -= len(m.TLSServerName)
copy(dAtA[i:], m.TLSServerName)
@ -1118,6 +1139,10 @@ func (m *HealthCheckDefinition) Size() (n int) {
if l > 0 {
n += 2 + l + sovHealthcheck(uint64(l))
}
l = len(m.H2PING)
if l > 0 {
n += 2 + l + sovHealthcheck(uint64(l))
}
return n
}
@ -1229,6 +1254,10 @@ func (m *CheckType) Size() (n int) {
if l > 0 {
n += 2 + l + sovHealthcheck(uint64(l))
}
l = len(m.H2PING)
if l > 0 {
n += 2 + l + sovHealthcheck(uint64(l))
}
return n
}
@ -2496,6 +2525,38 @@ func (m *HealthCheckDefinition) Unmarshal(dAtA []byte) error {
}
m.TLSServerName = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 20:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field H2PING", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowHealthcheck
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthHealthcheck
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthHealthcheck
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.H2PING = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipHealthcheck(dAtA[iNdEx:])
@ -3451,6 +3512,38 @@ func (m *CheckType) Unmarshal(dAtA []byte) error {
}
m.TLSServerName = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 28:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field H2PING", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowHealthcheck
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthHealthcheck
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthHealthcheck
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.H2PING = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipHealthcheck(dAtA[iNdEx:])

View File

@ -76,6 +76,7 @@ message HealthCheckDefinition {
repeated string ScriptArgs = 10;
string DockerContainerID = 11;
string Shell = 12;
string H2PING = 20;
string GRPC = 13;
bool GRPCUseTLS = 14;
string AliasNode = 15;
@ -86,10 +87,10 @@ message HealthCheckDefinition {
// CheckType is used to create either the CheckMonitor or the CheckTTL.
// The following types are supported: Script, HTTP, TCP, Docker, TTL, GRPC,
// Alias. Script,
// HTTP, Docker, TCP and GRPC all require Interval. Only one of the types may
// Alias. Script, H2PING,
// HTTP, Docker, TCP, H2PING and GRPC all require Interval. Only one of the types may
// to be provided: TTL or Script/Interval or HTTP/Interval or TCP/Interval or
// Docker/Interval or GRPC/Interval or AliasService.
// Docker/Interval or GRPC/Interval or H2PING/Interval or AliasService.
//
// mog annotation:
//
@ -116,6 +117,7 @@ message CheckType {
string AliasService = 11;
string DockerContainerID = 12;
string Shell = 13;
string H2PING = 28;
string GRPC = 14;
bool GRPCUseTLS = 15;
string TLSServerName = 27;
@ -142,4 +144,4 @@ message CheckType {
// mog: func-to=int func-from=int32
int32 OutputMaxSize = 25;
}
}

View File

@ -162,6 +162,11 @@ The table below shows this endpoint's support for
If TLS is enabled, then by default, a valid TLS certificate is expected. Certificate
verification can be turned off by setting `TLSSkipVerify` to `true`.
- `H2PING` `(string "")` - Specifies an address that uses http2 with TLS to run a ping check on.
At the specified `Interval`, a connection is made to the address, and a ping is sent.
If the ping is successful, the check will be classified as `passing`, otherwise it will be marked as `critical`.
A valid SSL certificate is required by default, but verification can be removed with `TLSSkipVerify`.
- `HTTP` `(string: "")` - Specifies an `HTTP` check to perform a `GET` request
against the value of `HTTP` (expected to be a URL) every `Interval`. If the
response is any `2xx` code, the check is `passing`. If the response is `429 Too Many Requests`, the check is `warning`. Otherwise, the check is

View File

@ -120,6 +120,13 @@ There are several different kinds of checks:
`tls_skip_verify` field to `true` in the check definition.
To check on a specific service instead of the whole gRPC server, add the service identifier after the `gRPC` check's endpoint in the following format `/:service_identifier`.
- `H2ping + Interval` - These checks test an endpoint that uses http2 with TLS
by connecting to the endpoint and sending a ping frame. If the ping is successful
within a specified timeout, then the check is updated as passing.
The timeout defaults to 10 seconds, but is configurable using the `timeout` field. A valid
certificate is required, unless `tls_skip_verify` is set to `true`.
The check will be run on the interval specified by the `interval` field.
- `Alias` - These checks alias the health state of another registered
node or service. The state of the check will be updated asynchronously, but is
nearly instant. For aliased services on the same agent, the local state is monitored
@ -235,6 +242,19 @@ A gRPC check for the specific `my_service` service:
}
```
A h2ping check:
```javascript
{
"check": {
"id": "h2ping-check",
"name": "h2ping",
"h2ping": "localhost:22222",
"interval": "10s",
}
}
```
An alias check for a local service:
```javascript