feat: add the check_output_matches plugin ()

This PR adds the `check_output_matches` plugin, which can be used to count regexp or substring matches from either text files or command outputs and determine the final status based on the amount of matches that were found.

Reviewed-on: 
Co-authored-by: Emmanuel BENOÎT <tseeker@nocternity.net>
Co-committed-by: Emmanuel BENOÎT <tseeker@nocternity.net>
This commit is contained in:
Emmanuel BENOîT 2024-07-20 22:57:10 +02:00 committed by Emmanuel BENOîT
parent 9fac656cdf
commit c46c9d76d9
22 changed files with 1063 additions and 55 deletions
cmd/sslcert

View file

@ -17,6 +17,7 @@ import (
"nocternity.net/gomonop/pkg/perfdata"
"nocternity.net/gomonop/pkg/plugin"
"nocternity.net/gomonop/pkg/results"
"nocternity.net/gomonop/pkg/status"
)
//--------------------------------------------------------------------------------------------------------
@ -224,20 +225,20 @@ func (program *checkProgram) Results() *results.Results {
// if the arguments made sense.
func (program *checkProgram) CheckArguments() bool {
if program.hostname == "" {
program.plugin.SetState(results.StatusUnknown, "no hostname specified")
program.plugin.SetState(status.StatusUnknown, "no hostname specified")
return false
}
if program.port < 1 || program.port > 65535 {
program.plugin.SetState(results.StatusUnknown, "invalid or missing port number")
program.plugin.SetState(status.StatusUnknown, "invalid or missing port number")
return false
}
if program.warn != -1 && program.crit != -1 && program.warn <= program.crit {
program.plugin.SetState(results.StatusUnknown, "nonsensical thresholds")
program.plugin.SetState(status.StatusUnknown, "nonsensical thresholds")
return false
}
if _, ok := certGetters[program.startTLS]; !ok {
errstr := "unsupported StartTLS protocol " + program.startTLS
program.plugin.SetState(results.StatusUnknown, errstr)
program.plugin.SetState(status.StatusUnknown, errstr)
return false
}
program.hostname = strings.ToLower(program.hostname)
@ -262,13 +263,13 @@ func (program *checkProgram) getCertificate() error {
// matches the requested host name.
func (program *checkProgram) checkSANlessCertificate() bool {
if !program.ignoreCnOnly || len(program.extraNames) != 0 {
program.plugin.SetState(results.StatusWarning,
program.plugin.SetState(status.StatusWarning,
"certificate doesn't have SAN domain names")
return false
}
dn := strings.ToLower(program.certificate.Subject.String())
if !strings.HasPrefix(dn, fmt.Sprintf("cn=%s,", program.hostname)) {
program.plugin.SetState(results.StatusCritical, "incorrect certificate CN")
program.plugin.SetState(status.StatusCritical, "incorrect certificate CN")
return false
}
return true
@ -298,7 +299,7 @@ func (program *checkProgram) checkNames() bool {
certificateIsOk = program.checkHostName(name) && certificateIsOk
}
if !certificateIsOk {
program.plugin.SetState(results.StatusCritical, "names missing from SAN domain names")
program.plugin.SetState(status.StatusCritical, "names missing from SAN domain names")
}
return certificateIsOk
}
@ -306,26 +307,26 @@ func (program *checkProgram) checkNames() bool {
// Check a certificate's time to expiry against the warning and critical
// thresholds, returning a status code and description based on these
// values.
func (program *checkProgram) checkCertificateExpiry(tlDays int) (results.Status, string) {
func (program *checkProgram) checkCertificateExpiry(tlDays int) (status.Status, string) {
if tlDays <= 0 {
return results.StatusCritical, "certificate expired"
return status.StatusCritical, "certificate expired"
}
var limitStr string
var state results.Status
var state status.Status
switch {
case program.crit > 0 && tlDays <= program.crit:
limitStr = fmt.Sprintf(" (<= %d)", program.crit)
state = results.StatusCritical
state = status.StatusCritical
case program.warn > 0 && tlDays <= program.warn:
limitStr = fmt.Sprintf(" (<= %d)", program.warn)
state = results.StatusWarning
state = status.StatusWarning
default:
limitStr = ""
state = results.StatusOK
state = status.StatusOK
}
statusString := fmt.Sprintf("certificate will expire in %d days%s",
@ -351,7 +352,7 @@ func (program *checkProgram) setPerfData(tlDays int) {
func (program *checkProgram) RunCheck() {
err := program.getCertificate()
if err != nil {
program.plugin.SetState(results.StatusUnknown, err.Error())
program.plugin.SetState(status.StatusUnknown, err.Error())
} else if program.checkNames() {
timeLeft := time.Until(program.certificate.NotAfter)
tlDays := int((timeLeft + 86399*time.Second) / (24 * time.Hour))