gomonop/cmd/matches/cmdline.go
Emmanuel BENOîT c46c9d76d9
All checks were successful
Run tests and linters / test (push) Successful in 50s
Run tests and linters / build (push) Successful in 48s
Run tests and linters / lint (push) Successful in 1m27s
feat: add the check_output_matches plugin (#5)
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: #5
Co-authored-by: Emmanuel BENOÎT <tseeker@nocternity.net>
Co-committed-by: Emmanuel BENOÎT <tseeker@nocternity.net>
2024-07-20 22:57:10 +02:00

95 lines
3 KiB
Go

package matches // import nocternity.net/gomonop/cmd/matches
import (
"context"
"regexp"
"strings"
"time"
"github.com/karrick/golf"
"nocternity.net/gomonop/pkg/perfdata"
)
// pluginFlags represent command line flags that have been parsed.
type pluginFlags struct {
isFile bool // Are we reading from a file?
dataSource string // The file or command to read from
timeout time.Duration // A timeout for the command, or 0 to disable
matches []matchConfig // Configuration for the matches to check
strict bool // Reject lines that don't match anything
}
// matchConfig is the configuration for a single match to check.
type matchConfig struct {
isRegexp bool // Are we checking against a regular expression?
matchString string // The string or regexp to match
compiledRe *regexp.Regexp // The compiled regexp
warn *perfdata.Range // Warning range
crit *perfdata.Range // Critical range
}
// parseArguments parses command line arguments for the plugin.
func (p *pluginFlags) parseArguments() {
golf.BoolVarP(&p.isFile, 'f', "is-file", false, "Are we reading from a file?")
golf.StringVarP(&p.dataSource, 's', "source", "", "The file or command to read from")
golf.DurationVarP(&p.timeout, 'T', "timeout", 0, "A timeout for the command, or 0 to disable")
golf.BoolVarP(&p.strict, 'S', "strict", false, "Reject lines that do not match anything")
isRegexp := golf.BoolP('R', "no-regexp", true, "Following match argument will be a basic string")
golf.BoolVarP(isRegexp, 'r', "regexp", false, "Following match argument will be a regexp")
var wRange *perfdata.Range
golf.StringFuncP('w', "warn", "", "Warning range, in Nagios-compatible format", func(s string) error {
locRange, err := perfdata.ParseRange(s)
if err == nil {
wRange = locRange
}
return err
})
golf.BoolFuncP('W', "no-warn", false, "Clear warning range", func(bool) error {
wRange = nil
return nil
})
var cRange *perfdata.Range
golf.StringFuncP('c', "critical", "", "Critical range, in Nagios-compatible format", func(s string) error {
locRange, err := perfdata.ParseRange(s)
if err == nil {
cRange = locRange
}
return err
})
golf.BoolFuncP('C', "no-critical", false, "Clear warning range", func(bool) error {
cRange = nil
return nil
})
golf.StringFuncP('m', "match", "", "Match string", func(s string) error {
p.matches = append(p.matches, matchConfig{
isRegexp: *isRegexp,
matchString: s,
warn: wRange,
crit: cRange,
})
return nil
})
golf.Parse()
}
// makeContext generates a context based on the timeout, if one is set.
func (p *pluginFlags) makeContext() (context.Context, context.CancelFunc) {
if p.timeout == 0 {
return context.Background(), func() {}
}
return context.WithTimeout(context.Background(), p.timeout)
}
// matches check if the specified string matches a configuration.
func (p *matchConfig) matches(s string) bool {
if p.isRegexp {
return p.compiledRe.MatchString(s)
}
return strings.Contains(s, p.matchString)
}