From 2cdd62208d5fddd79c767c8ac39a611b0044fdd0 Mon Sep 17 00:00:00 2001 From: gkze Date: Fri, 22 Dec 2023 00:17:23 -0800 Subject: [PATCH 1/2] Expose method and expected status code on http checks --- src/health/health_checks.go | 10 ++++++---- src/health/probe.go | 37 +++++++++++++++++++++++-------------- src/health/probe_test.go | 4 ++-- src/loader/merger_test.go | 10 +++++----- src/loader/mutators.go | 8 ++++---- src/loader/mutators_test.go | 16 ++++++++-------- 6 files changed, 48 insertions(+), 37 deletions(-) diff --git a/src/health/health_checks.go b/src/health/health_checks.go index 65cd2e0..ca267a8 100644 --- a/src/health/health_checks.go +++ b/src/health/health_checks.go @@ -39,7 +39,7 @@ func New(name string, probe Probe, onCheckEnd func(bool, bool, string)) (*Prober } return p, err } - if probe.HttpGet != nil { + if probe.Http != nil { err := p.addProber(p.getHttpChecker) if err != nil { return nil, err @@ -102,13 +102,15 @@ func (p *Prober) addProber(factory func() (health.ICheckable, error)) error { } func (p *Prober) getHttpChecker() (health.ICheckable, error) { - url, err := p.probe.HttpGet.getUrl() + url, err := p.probe.Http.getUrl() if err != nil { return nil, err } checker, err := checkers.NewHTTP(&checkers.HTTPConfig{ - URL: url, - Timeout: time.Duration(p.probe.TimeoutSeconds) * time.Second, + URL: url, + Timeout: time.Duration(p.probe.TimeoutSeconds) * time.Second, + Method: p.probe.Http.Method, + StatusCode: p.probe.Http.StatusCode, }) if err != nil { return nil, err diff --git a/src/health/probe.go b/src/health/probe.go index 896dc40..e10411a 100644 --- a/src/health/probe.go +++ b/src/health/probe.go @@ -2,13 +2,14 @@ package health import ( "fmt" + "net/http" "net/url" "strings" ) type Probe struct { Exec *ExecProbe `yaml:"exec,omitempty"` - HttpGet *HttpProbe `yaml:"http_get,omitempty"` + Http *HttpProbe `yaml:"http,omitempty"` InitialDelay int `yaml:"initial_delay_seconds,omitempty"` PeriodSeconds int `yaml:"period_seconds,omitempty"` TimeoutSeconds int `yaml:"timeout_seconds,omitempty"` @@ -22,10 +23,12 @@ type ExecProbe struct { } type HttpProbe struct { - Host string `yaml:"host,omitempty"` - Path string `yaml:"path,omitempty"` - Scheme string `yaml:"scheme,omitempty"` - Port int `yaml:"port,omitempty"` + Host string `yaml:"host,omitempty"` + Path string `yaml:"path,omitempty"` + Scheme string `yaml:"scheme,omitempty"` + Port int `yaml:"port,omitempty"` + Method string `yaml:"method,omitempty"` + StatusCode int `yaml:"status_code,omitempty"` } func (h HttpProbe) getUrl() (*url.URL, error) { @@ -60,20 +63,26 @@ func (p *Probe) validateAndSetDefaults() { } func (p *Probe) validateAndSetHttpDefaults() { - if p.HttpGet == nil { + if p.Http == nil { return } - if len(strings.TrimSpace(p.HttpGet.Host)) == 0 { - p.HttpGet.Host = "127.0.0.1" + if len(strings.TrimSpace(p.Http.Host)) == 0 { + p.Http.Host = "127.0.0.1" } - if len(strings.TrimSpace(p.HttpGet.Scheme)) == 0 { - p.HttpGet.Scheme = "http" + if len(strings.TrimSpace(p.Http.Scheme)) == 0 { + p.Http.Scheme = "http" } - if len(strings.TrimSpace(p.HttpGet.Path)) == 0 { - p.HttpGet.Path = "/" + if len(strings.TrimSpace(p.Http.Path)) == 0 { + p.Http.Path = "/" } - if p.HttpGet.Port < 1 || p.HttpGet.Port > 65535 { + if p.Http.Port < 1 || p.Http.Port > 65535 { // if undefined or wrong value - will be treated as undefined - p.HttpGet.Port = 0 + p.Http.Port = 0 + } + if len(strings.TrimSpace(p.Http.Method)) == 0 { + p.Http.Method = http.MethodGet + } + if p.Http.StatusCode == 0 { + p.Http.StatusCode = http.StatusOK } } diff --git a/src/health/probe_test.go b/src/health/probe_test.go index 35e02e1..7b101c3 100644 --- a/src/health/probe_test.go +++ b/src/health/probe_test.go @@ -9,7 +9,7 @@ import ( func TestProbe_validateAndSetDefaults(t *testing.T) { type fields struct { Exec *ExecProbe - HttpGet *HttpProbe + Http *HttpProbe InitialDelay int PeriodSeconds int TimeoutSeconds int @@ -71,7 +71,7 @@ func TestProbe_validateAndSetDefaults(t *testing.T) { t.Run(tt.name, func(t *testing.T) { p := &Probe{ Exec: tt.fields.Exec, - HttpGet: tt.fields.HttpGet, + Http: tt.fields.Http, InitialDelay: tt.fields.InitialDelay, PeriodSeconds: tt.fields.PeriodSeconds, TimeoutSeconds: tt.fields.TimeoutSeconds, diff --git a/src/loader/merger_test.go b/src/loader/merger_test.go index 60df0ff..6e1e2b9 100644 --- a/src/loader/merger_test.go +++ b/src/loader/merger_test.go @@ -33,7 +33,7 @@ func getBaseProcess() *types.ProcessConfig { }, LivenessProbe: nil, ReadinessProbe: &health.Probe{ - HttpGet: &health.HttpProbe{ + Http: &health.HttpProbe{ Host: "127.0.0.1", Path: "/is", Scheme: "http", @@ -83,7 +83,7 @@ func getOverrideProcess() *types.ProcessConfig { }, }, LivenessProbe: &health.Probe{ - HttpGet: &health.HttpProbe{ + Http: &health.HttpProbe{ Host: "google.com", Path: "/isAlive", Scheme: "https", @@ -96,7 +96,7 @@ func getOverrideProcess() *types.ProcessConfig { FailureThreshold: 5, }, ReadinessProbe: &health.Probe{ - HttpGet: &health.HttpProbe{ + Http: &health.HttpProbe{ Host: "google.com", Path: "/isAlive", Scheme: "https", @@ -150,7 +150,7 @@ func getMergedProcess() *types.ProcessConfig { }, }, LivenessProbe: &health.Probe{ - HttpGet: &health.HttpProbe{ + Http: &health.HttpProbe{ Host: "google.com", Path: "/isAlive", Scheme: "https", @@ -163,7 +163,7 @@ func getMergedProcess() *types.ProcessConfig { FailureThreshold: 5, }, ReadinessProbe: &health.Probe{ - HttpGet: &health.HttpProbe{ + Http: &health.HttpProbe{ Host: "google.com", Path: "/isAlive", Scheme: "https", diff --git a/src/loader/mutators.go b/src/loader/mutators.go index 5af106c..8afc9fa 100644 --- a/src/loader/mutators.go +++ b/src/loader/mutators.go @@ -139,9 +139,9 @@ func renderProbe(probe *health.Probe, tpl *templater.Templater, vars types.Vars) if probe.Exec != nil { probe.Exec.Command = tpl.RenderWithExtraVars(probe.Exec.Command, vars) - } else if probe.HttpGet != nil { - probe.HttpGet.Path = tpl.RenderWithExtraVars(probe.HttpGet.Path, vars) - probe.HttpGet.Host = tpl.RenderWithExtraVars(probe.HttpGet.Host, vars) - probe.HttpGet.Scheme = tpl.RenderWithExtraVars(probe.HttpGet.Scheme, vars) + } else if probe.Http != nil { + probe.Http.Path = tpl.RenderWithExtraVars(probe.Http.Path, vars) + probe.Http.Host = tpl.RenderWithExtraVars(probe.Http.Host, vars) + probe.Http.Scheme = tpl.RenderWithExtraVars(probe.Http.Scheme, vars) } } diff --git a/src/loader/mutators_test.go b/src/loader/mutators_test.go index 9fe72a6..0dad932 100644 --- a/src/loader/mutators_test.go +++ b/src/loader/mutators_test.go @@ -404,14 +404,14 @@ func Test_renderTemplates(t *testing.T) { Name: procNoWorkingDir, Command: "echo {{ .TEST }}", LivenessProbe: &health.Probe{ - HttpGet: &health.HttpProbe{ + Http: &health.HttpProbe{ Path: "/{{.PROJ_PATH}}/{{.PROC_PATH}}", Scheme: "{{.SCHEME}}", Host: "{{.HOST}}", }, }, ReadinessProbe: &health.Probe{ - HttpGet: &health.HttpProbe{ + Http: &health.HttpProbe{ Path: "/{{.PROJ_PATH}}/{{.PROC_PATH}}", Scheme: "{{.SCHEME}}", Host: "{{.HOST}}", @@ -466,12 +466,12 @@ func Test_renderTemplates(t *testing.T) { compareStrings(t, "echo proc test", p.LivenessProbe.Exec.Command, "liveness probe command") compareStrings(t, "echo ", p.Command, "process command") case "with http": - compareStrings(t, "/prj_path/proc_path", p.ReadinessProbe.HttpGet.Path, "readiness probe path") - compareStrings(t, "host", p.ReadinessProbe.HttpGet.Host, "readiness probe host") - compareStrings(t, "https", p.ReadinessProbe.HttpGet.Scheme, "readiness probe scheme") - compareStrings(t, "https", p.LivenessProbe.HttpGet.Scheme, "liveness probe scheme") - compareStrings(t, "host", p.LivenessProbe.HttpGet.Host, "liveness probe host") - compareStrings(t, "/prj_path/proc_path", p.LivenessProbe.HttpGet.Path, "liveness probe path") + compareStrings(t, "/prj_path/proc_path", p.ReadinessProbe.Http.Path, "readiness probe path") + compareStrings(t, "host", p.ReadinessProbe.Http.Host, "readiness probe host") + compareStrings(t, "https", p.ReadinessProbe.Http.Scheme, "readiness probe scheme") + compareStrings(t, "https", p.LivenessProbe.Http.Scheme, "liveness probe scheme") + compareStrings(t, "host", p.LivenessProbe.Http.Host, "liveness probe host") + compareStrings(t, "/prj_path/proc_path", p.LivenessProbe.Http.Path, "liveness probe path") compareStrings(t, "echo test", p.Command, "process command") } } From dec74e86df82fc45c8aa1a2c9c2b3929a9da37a0 Mon Sep 17 00:00:00 2001 From: gkze Date: Wed, 10 Jan 2024 00:06:35 -0800 Subject: [PATCH 2/2] Address (some) PR comments --- src/health/probe.go | 1 + src/health/probe_test.go | 49 ++++++++++++++++++++++++++++++++++++++++ src/loader/mutators.go | 1 + 3 files changed, 51 insertions(+) diff --git a/src/health/probe.go b/src/health/probe.go index e10411a..44895b0 100644 --- a/src/health/probe.go +++ b/src/health/probe.go @@ -9,6 +9,7 @@ import ( type Probe struct { Exec *ExecProbe `yaml:"exec,omitempty"` + HttpGet *HttpProbe `yaml:"http_get,omitempty"` Http *HttpProbe `yaml:"http,omitempty"` InitialDelay int `yaml:"initial_delay_seconds,omitempty"` PeriodSeconds int `yaml:"period_seconds,omitempty"` diff --git a/src/health/probe_test.go b/src/health/probe_test.go index 7b101c3..717a337 100644 --- a/src/health/probe_test.go +++ b/src/health/probe_test.go @@ -1,6 +1,7 @@ package health import ( + "net/http" "net/url" "reflect" "testing" @@ -98,6 +99,54 @@ func TestProbe_validateAndSetDefaults(t *testing.T) { } } +func TestHttpProbe_fields(t *testing.T) { + type fields struct { + Host string + Path string + Scheme string + Port int + Method string + StatusCode int + } + tests := []struct { + name string + fields fields + want fields + }{ + { + name: "Method and expected status code not set", + fields: fields{ + Host: "google.com", + Path: "/isAlive", + Scheme: "https", + Port: 0, + }, + want: fields{ + Host: "google.com", + Path: "/isAlive", + Scheme: "https", + Port: 0, + Method: http.MethodGet, + StatusCode: http.StatusOK, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + hp := HttpProbe(tt.fields) + p := Probe{Http: &hp} + p.validateAndSetHttpDefaults() + if p.Http.Method != http.MethodGet { + t.Error("HTTP method was not GET when not set in config file") + } + if p.Http.StatusCode != http.StatusOK { + t.Errorf("HTTP expected status code was not OK (200)") + } + }) + } +} + func TestHttpProbe_getUrl(t *testing.T) { type fields struct { Host string diff --git a/src/loader/mutators.go b/src/loader/mutators.go index 8afc9fa..d02071f 100644 --- a/src/loader/mutators.go +++ b/src/loader/mutators.go @@ -143,5 +143,6 @@ func renderProbe(probe *health.Probe, tpl *templater.Templater, vars types.Vars) probe.Http.Path = tpl.RenderWithExtraVars(probe.Http.Path, vars) probe.Http.Host = tpl.RenderWithExtraVars(probe.Http.Host, vars) probe.Http.Scheme = tpl.RenderWithExtraVars(probe.Http.Scheme, vars) + probe.Http.Method = tpl.RenderWithExtraVars(probe.Http.Method, vars) } }