5ee7cc5e6d
* Rename common.go->healthcheck.go Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Push handling of no resources to the health checks This allows us to better run on empty mounts. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Exit when no issuers are found This makes health checks less useful. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add additional test criteria, refactor tests This will allow us to setup more tests. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add more OK statuses when checks are good Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add test cases for all bad results The test for too-many-certs was elided for now due to being too hard to setup in CI. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add test for missing mount Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add expected failure test on empty mount Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add test for only having an issuer in the mount Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * More consistently perform permission checks Also return them to the caller when they're relevant. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add test without token Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Run health check tests in parallel Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Update command/healthcheck/healthcheck.go Co-authored-by: Steven Clark <steven.clark@hashicorp.com> * Update command/healthcheck/healthcheck.go Co-authored-by: Steven Clark <steven.clark@hashicorp.com> Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> Co-authored-by: Steven Clark <steven.clark@hashicorp.com>
111 lines
2.7 KiB
Go
111 lines
2.7 KiB
Go
package healthcheck
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/go-secure-stdlib/parseutil"
|
|
)
|
|
|
|
type AllowIfModifiedSince struct {
|
|
Enabled bool
|
|
UnsupportedVersion bool
|
|
|
|
TuneData map[string]interface{}
|
|
}
|
|
|
|
func NewAllowIfModifiedSinceCheck() Check {
|
|
return &AllowIfModifiedSince{}
|
|
}
|
|
|
|
func (h *AllowIfModifiedSince) Name() string {
|
|
return "allow_if_modified_since"
|
|
}
|
|
|
|
func (h *AllowIfModifiedSince) IsEnabled() bool {
|
|
return h.Enabled
|
|
}
|
|
|
|
func (h *AllowIfModifiedSince) DefaultConfig() map[string]interface{} {
|
|
return map[string]interface{}{}
|
|
}
|
|
|
|
func (h *AllowIfModifiedSince) LoadConfig(config map[string]interface{}) error {
|
|
var err error
|
|
|
|
h.Enabled, err = parseutil.ParseBool(config["enabled"])
|
|
if err != nil {
|
|
return fmt.Errorf("error parsing %v.enabled: %w", h.Name(), err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (h *AllowIfModifiedSince) FetchResources(e *Executor) error {
|
|
exit, _, data, err := fetchMountTune(e, func() {
|
|
h.UnsupportedVersion = true
|
|
})
|
|
if exit {
|
|
return err
|
|
}
|
|
|
|
h.TuneData = data
|
|
|
|
return nil
|
|
}
|
|
|
|
func (h *AllowIfModifiedSince) Evaluate(e *Executor) (results []*Result, err error) {
|
|
if h.UnsupportedVersion {
|
|
ret := Result{
|
|
Status: ResultInvalidVersion,
|
|
Endpoint: "/sys/mounts/{{mount}}/tune",
|
|
Message: "This health check requires Vault 1.9+ but an earlier version of Vault Server was contacted, preventing this health check from running.",
|
|
}
|
|
return []*Result{&ret}, nil
|
|
}
|
|
|
|
req, err := stringList(h.TuneData["passthrough_request_headers"])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to parse value from server for passthrough_request_headers: %w", err)
|
|
}
|
|
|
|
resp, err := stringList(h.TuneData["allowed_response_headers"])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to parse value from server for allowed_response_headers: %w", err)
|
|
}
|
|
|
|
var foundIMS bool = false
|
|
for _, param := range req {
|
|
if strings.EqualFold(param, "If-Modified-Since") {
|
|
foundIMS = true
|
|
break
|
|
}
|
|
}
|
|
|
|
var foundLM bool = false
|
|
for _, param := range resp {
|
|
if strings.EqualFold(param, "Last-Modified") {
|
|
foundLM = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !foundIMS || !foundLM {
|
|
ret := Result{
|
|
Status: ResultInformational,
|
|
Endpoint: "/sys/mounts/{{mount}}/tune",
|
|
Message: "Mount hasn't enabled If-Modified-Since Request or Last-Modified Response headers; consider enabling these headers to allow clients to fetch CAs and CRLs only when they've changed, reducing total bandwidth.",
|
|
}
|
|
results = append(results, &ret)
|
|
} else {
|
|
ret := Result{
|
|
Status: ResultOK,
|
|
Endpoint: "/sys/mounts/{{mount}}/tune",
|
|
Message: "Mount allows the If-Modified-Since request header and Last-Modified response header.",
|
|
}
|
|
results = append(results, &ret)
|
|
}
|
|
|
|
return
|
|
}
|