diff --git a/go.mod b/go.mod index 2d43afa..a4798b2 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/atc0005/check-process go 1.20 require ( - github.com/atc0005/go-nagios v0.16.1 + github.com/atc0005/go-nagios v0.17.1 github.com/rs/zerolog v1.33.0 ) diff --git a/go.sum b/go.sum index bd5f65f..67f3b1d 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/atc0005/go-nagios v0.16.1 h1:ef0AWjY9sqWq6dhfJuXtASe7dCkVDonoZhtYvNYWBlo= -github.com/atc0005/go-nagios v0.16.1/go.mod h1:NSm1HeneeyBe27BYzhC7FMx4gg3x8PddeZIMX9YZj5M= +github.com/atc0005/go-nagios v0.17.1 h1:VdI70UPm7WuAZWePBuuJETdX0maFX3evylSzDoTtkxc= +github.com/atc0005/go-nagios v0.17.1/go.mod h1:n2RHhsrgI8xiapqkJ240dKLwMXWbWvkOPLE92x0IGaM= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -15,7 +15,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/vendor/github.com/atc0005/go-nagios/.golangci.yml b/vendor/github.com/atc0005/go-nagios/.golangci.yml index 28e1d93..d9835ff 100644 --- a/vendor/github.com/atc0005/go-nagios/.golangci.yml +++ b/vendor/github.com/atc0005/go-nagios/.golangci.yml @@ -27,7 +27,6 @@ linters: - goimports - gosec - govet - - maligned - misspell - prealloc - revive diff --git a/vendor/github.com/atc0005/go-nagios/CHANGELOG.md b/vendor/github.com/atc0005/go-nagios/CHANGELOG.md index 1419ee5..51ac9d1 100644 --- a/vendor/github.com/atc0005/go-nagios/CHANGELOG.md +++ b/vendor/github.com/atc0005/go-nagios/CHANGELOG.md @@ -26,6 +26,52 @@ The following types of changes will be recorded in this file: - placeholder +## [v0.17.1] - 2024-11-08 + +### Changed + +- (GH-296) Unescape encoded Ascii85 payload before decoding + +## [v0.17.0] - 2024-11-06 + +### Added + +- (GH-288) Add support for embedded/encoded payloads +- (GH-289) Add support for (internal) debug logging output + +### Changed + +- (GH-291) Clarify handling of empty payload input +- (GH-292) Enable LongServiceOutput header/label for payloads + +### Fixed + +- (GH-268) Fix `Plugin.SetOutputTarget` method +- (GH-273) Fix test case validity check +- (GH-290) Minor refactoring of Range and Thresholds support + +## [v0.16.2] - 2024-10-10 + +### Changed + +#### Dependency Updates + +- (GH-240) Update Dependabot PR prefixes +- (GH-241) Update Dependabot PR prefixes (redux) +- (GH-242) Go Dependency: Bump github.com/stretchr/testify from 1.8.4 to 1.9.0 + +#### Other + +- (GH-245) Add check_cert plugin perfdata success test case +- (GH-254) Update README reference links + +### Fixed + +- (GH-247) Remove inactive maligned linter +- (GH-248) Fix errcheck linting errors +- (GH-252) Fix `TestEmptyServiceOutputProducesNoOutput` test +- (GH-257) Fix `predeclared` linter warnings + ## [v0.16.1] - 2024-01-25 ### Added @@ -521,7 +567,10 @@ Initial package state - Nagios state map -[Unreleased]: https://github.com/atc0005/go-nagios/compare/v0.16.1...HEAD +[Unreleased]: https://github.com/atc0005/go-nagios/compare/v0.17.1...HEAD +[v0.17.1]: https://github.com/atc0005/go-nagios/releases/tag/v0.17.1 +[v0.17.0]: https://github.com/atc0005/go-nagios/releases/tag/v0.17.0 +[v0.16.2]: https://github.com/atc0005/go-nagios/releases/tag/v0.16.2 [v0.16.1]: https://github.com/atc0005/go-nagios/releases/tag/v0.16.1 [v0.16.0]: https://github.com/atc0005/go-nagios/releases/tag/v0.16.0 [v0.15.0]: https://github.com/atc0005/go-nagios/releases/tag/v0.15.0 diff --git a/vendor/github.com/atc0005/go-nagios/README.md b/vendor/github.com/atc0005/go-nagios/README.md index 76d9277..1cef2a6 100644 --- a/vendor/github.com/atc0005/go-nagios/README.md +++ b/vendor/github.com/atc0005/go-nagios/README.md @@ -12,8 +12,8 @@ Shared Golang package for Nagios plugins ## Table of contents -- [Status](#status) - [Overview](#overview) +- [Status](#status) - [Features](#features) - [Changelog](#changelog) - [Examples](#examples) @@ -21,19 +21,19 @@ Shared Golang package for Nagios plugins - [Used by](#used-by) - [References](#references) -## Status - -Alpha quality. +## Overview -This codebase is subject to change without notice and may break client code -that depends on it. You are encouraged to [vendor](#references) this package -if you find it useful until such time that the API is considered stable. +This package provides support and functionality common to monitoring plugins. +While Nagios (Core and XI) are primary monitoring platform targets, the intent +is to support (where feasible) all monitoring platforms compatible with Nagios +plugins. -## Overview +## Status -This package contains common types and package-level variables used when -developing Nagios plugins. The intent is to reduce code duplication between -various plugins and help reduce typos associated with literal strings. +While attempts are made to provide stability, this codebase is subject to +change without notice and may break client code that depends on it. You are +encouraged to [vendor](#references) this package if you find it useful until +such time that the API is considered stable. ## Features @@ -41,8 +41,9 @@ various plugins and help reduce typos associated with literal strings. - state labels (e.g., `StateOKLabel`) - state exit codes (e.g., `StateOKExitCode`) - Nagios `CheckOutputEOL` constant - - provides a consistent newline format for both Nagios Core and Nagios XI - (and presumably other similar monitoring systems) + - provides a common newline format shown to produce consistent results for + both Nagios Core and Nagios XI (and presumably other similar monitoring + systems) - Nagios `ServiceState` type - simple label and exit code "wrapper" - useful in client code as a way to map internal check results to a Nagios @@ -58,21 +59,32 @@ various plugins and help reduce typos associated with literal strings. the service or host state to be an issue - Panics from client code are captured and reported - panics are surfaced as `CRITICAL` state - - service output and error details are overridden to panic prominent + - service output and error details are overridden to make panics prominent - Optional support for emitting performance data generated by plugins - if not overridden by client code *and* if using the provided `nagios.NewPlugin()` constructor, a default `time` performance data metric is emitted to indicate total plugin runtime - Support for collecting multiple errors from client code -- Support for explicitly omitting Errors section in `LongServiceOutput` +- Support for explicitly omitting Errors section - this section is automatically omitted if no errors were recorded (by client code or panic handling code) -- Support for explicitly omitting Thresholds section in `LongServiceOutput` +- Support for explicitly omitting Thresholds section - this section is automatically omitted if no thresholds were specified by client code - Automatically omit `LongServiceOutput` section if not specified by client code - Support for overriding text used for section headers/labels +- Support for adding/embedding an encoded payload (Ascii85) in plugin output +- Support for decoding (Ascii85) encoded input (payload) +- Support for extracting an (Ascii85) encoded payload from captured plugin + output +- Support for extracting and decoding an (Ascii85) encoded payload (into the + original non-encoded form) from captured plugin output +- Optional debug logging for plugin activity + - debug log output is sent to `stderr` by default but can be redirected to a + custom target + - toggles are provided to enable debug logging for all plugin activity or + for select types ## Changelog @@ -155,14 +167,13 @@ using either this library or the original project. - Nagios - - - + - - - - - - - - - - - + - [max plugin output length](https://github.com/NagiosEnterprises/nagioscore/blob/a30a89e0a493da49416e32ed770e294b1fe800f5/include/nagios.h#L274-L280) + - [character restrictions applicable to LongServiceOutput macro](https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/4/en/configmain.html#illegal_macro_output_chars) - Icinga - - diff --git a/vendor/github.com/atc0005/go-nagios/logging.go b/vendor/github.com/atc0005/go-nagios/logging.go new file mode 100644 index 0000000..71ba924 --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/logging.go @@ -0,0 +1,291 @@ +// Copyright 2024 Adam Chalkley +// +// https://github.com/atc0005/go-nagios +// +// Licensed under the MIT License. See LICENSE file in the project root for +// full license information. + +package nagios + +import ( + "io" + "log" + "os" + "strings" +) + +// Logger related values set as constants so that their values are exposed to +// internal tests. +const ( + logMsgPrefix string = "[" + MyPackageName + "] " + logFlags int = log.Ldate | log.Ltime + + // using log.Lshortfile reports the helper function use instead of the + // caller's location. + // + // logFlags int = log.Ldate | log.Ltime | log.Lshortfile +) + +// debugLoggingOptions controls all debug logging behavior for this library. +type debugLoggingOptions struct { + // actions indicates whether actions taken by this library are logged. + // This covers enabling/disabling settings or other general plugin + // activity. + actions bool + + // pluginOutputSize indicates whether all output to the configured plugin + // output sink should be measured and written to the log output sink. + pluginOutputSize bool +} + +// defaultPluginDebugLoggingOutputTarget returns the default debug logging +// output target used when a user-specified value is not provided. +func defaultPluginDebugLoggingOutputTarget() io.Writer { + return os.Stderr +} + +// defaultPluginAbortMessageOutputTarget returns the default abort message +// output target. +func defaultPluginAbortMessageOutputTarget() io.Writer { + return os.Stderr +} + +// defaultPluginDebugLoggerTarget returns the default debug logger target used +// when a user-specified value is not provided for the debug output target. +func defaultPluginDebugLoggerTarget() io.Writer { + // The intended default behavior is to throw away debug log messages if a + // debug log message output target has not been specified. + return io.Discard +} + +// allDebugLoggingOptionsEnabled is a helper function that provides a +// debugLoggingOptions value with all settings enabled. +func allDebugLoggingOptionsEnabled() debugLoggingOptions { + return debugLoggingOptions{ + actions: true, + pluginOutputSize: true, + // Expand this for any new fields added in the future. + } +} + +// allDebugLoggingOptionsDisabled is a helper function that provides a +// debugLoggingOptions value with all settings disabled. +func allDebugLoggingOptionsDisabled() debugLoggingOptions { + return debugLoggingOptions{ + actions: false, + pluginOutputSize: false, + // Expand this for any new fields added in the future. + } +} + +// enableAll enables all debug logging options. The user is able to optionally +// disable select portions of the debug logging output that they do not wish +// to see. +func (dlo *debugLoggingOptions) enableAll() { + *dlo = allDebugLoggingOptionsEnabled() +} + +// disableAll disables all debug logging options. +func (dlo *debugLoggingOptions) disableAll() { + *dlo = allDebugLoggingOptionsDisabled() +} + +// enableActions enables logging plugin actions. +func (dlo *debugLoggingOptions) enableActions() { + dlo.actions = true +} + +// disableActions disables logging plugin actions. +func (dlo *debugLoggingOptions) disableActions() { + dlo.actions = false +} + +// enablePluginOutputSize enables logging plugin output size. +func (dlo *debugLoggingOptions) enablePluginOutputSize() { + dlo.pluginOutputSize = true +} + +// disablePluginOutputSize disables logging plugin output size. +func (dlo *debugLoggingOptions) disablePluginOutputSize() { + dlo.pluginOutputSize = false +} + +// DebugLoggingEnableAll changes the default state of all debug logging +// options for this library from disabled to enabled. +// +// Once enabled, debug logging output is emitted to os.Stderr. This can be +// overridden by explicitly setting a custom debug output target. +func (p *Plugin) DebugLoggingEnableAll() { + // Enable all (granular) debug log options. + p.debugLogging.enableAll() + + // Ensure we have a valid output target, but do not overwrite any custom + // target already set. + if p.logOutputSink == nil { + p.setFallbackDebugLogTarget() + } + + // Connect logger to configured debug log target. + p.setupLogger() +} + +// DebugLoggingDisableAll changes the default state of all debug logging +// options for this library from any custom state back to the default state of +// disabled. +// +// Any custom debug log output target remains as it was before calling this +// function. +func (p *Plugin) DebugLoggingDisableAll() { + p.debugLogging.disableAll() +} + +// DebugLoggingDisableActions disables debug logging of general "actions" or +// plugin activity. This is the most verbose debug logging output generated by +// this library. +func (p *Plugin) DebugLoggingDisableActions() { + p.debugLogging.disableActions() +} + +// DebugLoggingEnableActions enables debug logging of general "actions" or +// plugin activity. This is the most verbose debug logging output generated by +// this library. +// +// Once enabled, debug logging output is emitted to os.Stderr. This can be +// overridden by explicitly setting a custom debug output target. +func (p *Plugin) DebugLoggingEnableActions() { + p.debugLogging.enableActions() + + // Ensure we have a valid output target, but do not overwrite any custom + // target already set. + if p.logOutputSink == nil { + p.setFallbackDebugLogTarget() + } + + // Connect logger to configured debug log target. + p.setupLogger() +} + +// DebugLoggingDisablePluginOutputSize disables debug logging of plugin output +// size calculations. +func (p *Plugin) DebugLoggingDisablePluginOutputSize() { + p.debugLogging.disablePluginOutputSize() +} + +// DebugLoggingEnablePluginOutputSize enables debug logging of plugin output +// size calculations. This debug logging output produces minimal output. +// +// Once enabled, debug logging output is emitted to os.Stderr. This can be +// overridden by explicitly setting a custom debug output target. +func (p *Plugin) DebugLoggingEnablePluginOutputSize() { + p.debugLogging.enablePluginOutputSize() + + // Ensure we have a valid output target, but do not overwrite any custom + // target already set. + if p.logOutputSink == nil { + p.setFallbackDebugLogTarget() + } + + // Connect logger to configured debug log target. + p.setupLogger() +} + +// SetDebugLoggingOutputTarget overrides the current debug logging target with +// the given output target. If the given output target is not valid the +// current target will be used instead. If there isn't a debug logging target +// already set then the default debug logging output target of os.Stderr will +// be used. This behavior is chosen for consistency with the current behavior +// of the Plugin.SetOutputTarget function. +// +// NOTE: While an error message is logged when calling this function with an +// invalid target, calling this function does not change the default debug +// logging state from disabled to enabled. That step must be performed +// separately by either enabling all debug logging options OR enabling select +// debug logging options. +func (p *Plugin) SetDebugLoggingOutputTarget(w io.Writer) { + if w == nil { + if p.logOutputSink == nil { + p.setFallbackDebugLogTarget() + } + + // Connect logger to configured debug log target. + p.setupLogger() + + // We log using an "unfiltered" logger call to ensure this has the + // best chance of being seen. + p.log("invalid output target provided; using default debug log target instead") + + return + } + + p.logOutputSink = w + + // Connect logger to configured debug log target. + p.setupLogger() + + // Use a filtered logger call to allow this message to be emitted or + // excluded based on user-specified debug logging settings. + p.logAction("custom debug logging target set as requested") +} + +// DebugLoggingOutputTarget returns the user-specified debug output target or +// the default value if one was not specified. +func (p *Plugin) DebugLoggingOutputTarget() io.Writer { + if p.logOutputSink == nil { + return defaultPluginDebugLoggingOutputTarget() + } + + return p.logOutputSink +} + +func (p *Plugin) setFallbackDebugLogTarget() { + p.logOutputSink = defaultPluginDebugLoggingOutputTarget() +} + +// setupLogger should be called after the debug log output sink is explicitly +// configured. If called before configuring the debug log output sink the +// plugin's default debug logger target will be used instead. +func (p *Plugin) setupLogger() { + var loggerTarget io.Writer + switch { + case p.logOutputSink == nil: + loggerTarget = defaultPluginDebugLoggerTarget() + default: + loggerTarget = p.logOutputSink + } + + p.logger = log.New(loggerTarget, logMsgPrefix, logFlags) +} + +// log uses the plugin's logger to write the given message to the configured +// output sink. +func (p *Plugin) log(msg string) { + if p.logger == nil { + return + } + + if !strings.HasSuffix(msg, CheckOutputEOL) { + msg += CheckOutputEOL + } + + p.logger.Print(msg) +} + +// logAction is used to log actions taken by this library such as +// enabling/disabling settings or other general plugin activity. +func (p *Plugin) logAction(msg string) { + if !p.debugLogging.actions { + return + } + + p.log(msg) +} + +// logPluginOutputSize is used to log activity related to measuring all output +// to the configured plugin output sink. +func (p *Plugin) logPluginOutputSize(msg string) { + if !p.debugLogging.pluginOutputSize { + return + } + + p.log(msg) +} diff --git a/vendor/github.com/atc0005/go-nagios/nagios.go b/vendor/github.com/atc0005/go-nagios/nagios.go index dce167c..fe4d6fa 100644 --- a/vendor/github.com/atc0005/go-nagios/nagios.go +++ b/vendor/github.com/atc0005/go-nagios/nagios.go @@ -8,15 +8,23 @@ package nagios import ( + "bytes" "errors" "fmt" "io" + "log" "os" "runtime/debug" "strings" "time" ) +// General package information. +const ( + MyPackageName string = "go-nagios" + MyPackagePurpose string = "Provide support and functionality common to monitoring plugins." +) + // Nagios plugin/service check states. These constants replicate the values // from utils.sh which is normally found at one of these two locations, // depending on which Linux distribution you're using: @@ -58,9 +66,10 @@ const CheckOutputEOL string = " \n" // Default header text for various sections of the output if not overridden. const ( - defaultThresholdsLabel string = "THRESHOLDS" - defaultErrorsLabel string = "ERRORS" - defaultDetailedInfoLabel string = "DETAILED INFO" + defaultThresholdsLabel string = "THRESHOLDS" + defaultErrorsLabel string = "ERRORS" + defaultDetailedInfoLabel string = "DETAILED INFO" + defaultEncodedPayloadLabel string = "ENCODED PAYLOAD" ) // Default performance data metrics emitted if not specified by client code. @@ -69,6 +78,39 @@ const ( defaultTimeMetricUnitOfMeasurement string = "ms" ) +// Default payload values if not specified by client code. +const ( + defaultPayloadDelimiterLeft string = DefaultASCII85EncodingDelimiterLeft + defaultPayloadDelimiterRight string = DefaultASCII85EncodingDelimiterRight +) + +const ( + // DefaultASCII85EncodingDelimiterLeft is the left delimiter often used + // with ascii85-encoded data. + DefaultASCII85EncodingDelimiterLeft string = "<~" + + // DefaultASCII85EncodingDelimiterRight is the right delimiter often used + // with ascii85-encoded data. + DefaultASCII85EncodingDelimiterRight string = "~>" + + // DefaultASCII85EncodingPatternRegex is the default regex pattern used to + // match and extract an Ascii85 encoded payload as used in the btoa tool + // and Adobe's PostScript and PDF document formats. + // + // In Ascii85-encoded blocks, whitespace and line-break characters may be + // present anywhere, including in the middle of a 5-character block, but + // they must be silently ignored. + // + // - https://pkg.go.dev/encoding/ascii85 + // - https://en.wikipedia.org/wiki/Ascii85 + // + // NOTE: Not using delimiters when saving an encoded payload makes the + // extraction process *VERY* unreliable as this regex pattern (by itself) + // matches far more than likely intended. + // + DefaultASCII85EncodingPatternRegex string = `[\x21-\x75\s]+` +) + // Sentinel error collection. Exported for potential use by client code to // detect & handle specific error scenarios. var ( @@ -112,6 +154,21 @@ var ( // ErrInvalidPerformanceDataCritField = errors.New("invalid field Crit in parsed performance data") // ErrInvalidPerformanceDataMinField = errors.New("invalid field Min in parsed performance data") // ErrInvalidPerformanceDataMaxField = errors.New("invalid field Max in parsed performance data") + + // ErrMissingValue indicates that an expected value was missing. + ErrMissingValue = errors.New("missing expected value") + + // ErrEncodedPayloadNotFound indicates that an encoded payload was not + // found during an extraction attempt. + ErrEncodedPayloadNotFound = errors.New("encoded payload not found") + + // ErrEncodedPayloadInvalid indicates that an encoded payload was found + // during extraction but was found to be invalid. + ErrEncodedPayloadInvalid = errors.New("encoded payload invalid") + + // ErrEncodedPayloadInvalid indicates that a regular expression used to + // identify an encoded payload was found to be invalid. + ErrEncodedPayloadRegexInvalid = errors.New("encoded payload regex invalid") ) // ServiceState represents the status label and exit code for a service check. @@ -137,6 +194,29 @@ type Plugin struct { // outputSink is the user-specified or fallback target for plugin output. outputSink io.Writer + // logOutputSink is the user-specified or fallback target for debug level + // plugin output. + logOutputSink io.Writer + + // logger is an embedded logger used to emit debug log messages (if + // enabled). + logger *log.Logger + + // encodedPayloadBuffer holds a user-specified payload *before* encoding + // is performed. If provided, this payload is later encoded and included + // in the generated plugin output. + encodedPayloadBuffer bytes.Buffer + + // encodedPayloadDelimiterLeft is the user-specified custom encoded + // payload delimiter. If not set the default payload left delimiter is + // used. + encodedPayloadDelimiterLeft *string + + // encodedPayloadDelimiterRight is the user-specified custom encoded + // payload delimiter. If not set the default payload right delimiter is + // used. + encodedPayloadDelimiterRight *string + // start tracks when the associated plugin begins executing. This value is // used to generate a default `time` performance data metric (which can be // overridden by client code). @@ -193,6 +273,10 @@ type Plugin struct { // standard text prior to emitting LongServiceOutput. detailedInfoLabel string + // encodedPayloadLabel is an optional custom label used in place of the + // standard text prior to emitting an encoded payload. + encodedPayloadLabel string + // hideThresholdsSection indicates whether client code has opted to hide // the thresholds section, regardless of whether client code previously // specified values for display. @@ -209,6 +293,9 @@ type Plugin struct { // instead. shouldSkipOSExit bool + // debugLogging is the collection of debug logging options for the plugin. + debugLogging debugLoggingOptions + // BrandingCallback is a function that is called before application // termination to emit branding details at the end of the notification. // See also ExitCallBackFunc. @@ -273,7 +360,9 @@ func (p *Plugin) ReturnCheckResults() { // Check for unhandled panic in client code. If present, override // Plugin and make clear that the client code/plugin crashed. + p.logAction("Checking for unhandled panic") if err := recover(); err != nil { + p.logAction("Handling panic") p.AddError(fmt.Errorf("%w: %s", ErrPanicDetected, err)) @@ -304,33 +393,49 @@ func (p *Plugin) ReturnCheckResults() { } + p.logAction("No unhandled panic found") + + p.logAction("Processing ServiceOutput section") p.handleServiceOutputSection(&output) + p.logAction("Processing Errors section") p.handleErrorsSection(&output) + p.logAction("Processing Thresholds section") p.handleThresholdsSection(&output) + p.logAction("Processing LongServiceOutput section") p.handleLongServiceOutput(&output) + p.logAction("Processing Encoded Payload section") + p.handleEncodedPayload(&output) + // If set, call user-provided branding function before emitting // performance data and exiting application. - if p.BrandingCallback != nil { - fmt.Fprintf(&output, "%s%s%s", CheckOutputEOL, p.BrandingCallback(), CheckOutputEOL) + switch { + case p.BrandingCallback != nil: + p.logAction("Adding Branding Callback") + written, err := fmt.Fprintf(&output, "%s%s%s", CheckOutputEOL, p.BrandingCallback(), CheckOutputEOL) + if err != nil { + panic("Failed to write BrandingCallback content to buffer") + } + p.logPluginOutputSize(fmt.Sprintf("%d bytes plugin BrandingCalling content written to buffer", written)) + + default: + p.logAction("Branding Callback not requested, skipping") } + p.logAction("Processing Performance Data section") p.handlePerformanceData(&output) // Emit all collected plugin output using user-specified or fallback // output target. + p.logAction("Processing final plugin output") p.emitOutput(output.String()) - // TODO: Should we offer an option to redirect the log message to stderr - // to another error output sink? - // - // TODO: Perhaps just don't emit anything at all? switch { case p.shouldSkipOSExit: - fmt.Fprintln(os.Stderr, "Skipping os.Exit call as requested.") + p.logAction("Skipping os.Exit call as requested.") default: os.Exit(p.ExitStatusCode) } @@ -374,6 +479,11 @@ func (p *Plugin) AddPerfData(skipValidate bool, perfData ...PerformanceData) err // for ensuring that a given error is not already recorded in the collection. func (p *Plugin) AddError(errs ...error) { p.Errors = append(p.Errors, errs...) + + p.logAction(fmt.Sprintf( + "%d errors added to collection", + len(errs), + )) } // AddUniqueError appends provided errors to the collection if they are not @@ -387,25 +497,74 @@ func (p *Plugin) AddUniqueError(errs ...error) { existingErrStrings[i] = p.Errors[i].Error() } + var totalUniqueErrors int + for _, err := range errs { if inList(err.Error(), existingErrStrings, true) { continue } p.Errors = append(p.Errors, err) + totalUniqueErrors++ } + + p.logAction(fmt.Sprintf( + "%d unique errors added to collection", + totalUniqueErrors, + )) +} + +// OutputTarget returns the user-specified plugin output target or +// the default value if one was not specified. +func (p *Plugin) OutputTarget() io.Writer { + if p.outputSink == nil { + p.logAction("Plugin output target not explicitly set, returning default plugin output target") + + return defaultPluginOutputTarget() + } + + p.logAction("Returning current plugin output target") + + return p.outputSink } // SetOutputTarget assigns a target for Nagios plugin output. By default -// output is emitted to os.Stdout. +// output is emitted to os.Stdout. If given an invalid output target the +// default output target will be used instead. func (p *Plugin) SetOutputTarget(w io.Writer) { // Guard against potential nil argument. if w == nil { - p.outputSink = os.Stdout + // We log using an "filtered" logger call to retain previous behavior + // of not emitting a "problem has occurred" message. + p.logAction("Specified output target is invalid, falling back to default") + + p.outputSink = defaultPluginOutputTarget() + + return } + p.logAction("Setting output target to specified value") + p.outputSink = w } +// SetEncodedPayloadDelimiterLeft uses the given value to override the default +// left delimiter used when encoding a provided payload. Specify an empty +// string if no left delimiter should be used. +// +// This value is ignored if no payload is provided. +func (p *Plugin) SetEncodedPayloadDelimiterLeft(delimiter string) { + p.encodedPayloadDelimiterLeft = &delimiter +} + +// SetEncodedPayloadDelimiterRight uses the given value to override the +// default right delimiter used when encoding a provided payload. Specify an +// empty string if no right delimiter should be used. +// +// This value is ignored if no payload is provided. +func (p *Plugin) SetEncodedPayloadDelimiterRight(delimiter string) { + p.encodedPayloadDelimiterRight = &delimiter +} + // SkipOSExit indicates that the os.Exit(x) step used to signal to Nagios what // state plugin execution has completed in (e.g., OK, WARNING, ...) should be // skipped. If skipped, a message is logged to os.Stderr in place of the @@ -414,20 +573,143 @@ func (p *Plugin) SetOutputTarget(w io.Writer) { // Disabling the call to os.Exit is needed by tests to prevent panics in Go // 1.16 and newer. func (p *Plugin) SkipOSExit() { + p.logAction("Setting plugin to skip os.Exit call as requested") p.shouldSkipOSExit = true } +// SetPayloadBytes uses the given input in bytes to overwrite any existing +// content in the payload buffer. It returns the length of input and a +// potential error. If given empty input the payload buffer is reset without +// adding any content. +// +// The contents of this buffer will be included in the plugin's output as an +// encoded payload suitable for later retrieval/decoding. +func (p *Plugin) SetPayloadBytes(input []byte) (int, error) { + p.logAction(fmt.Sprintf( + "Overwriting payload buffer with %d bytes input", + len(input), + )) + + p.encodedPayloadBuffer.Reset() + + if len(input) == 0 { + return 0, nil + } + + return p.encodedPayloadBuffer.Write(input) +} + +// SetPayloadString uses the given input string to overwrite any existing +// content in the payload buffer. It returns the length of input and a +// potential error. If given empty input the payload buffer is reset without +// adding any content. +// +// The contents of this buffer will be included in the plugin's output as an +// encoded payload suitable for later retrieval/decoding. +func (p *Plugin) SetPayloadString(input string) (int, error) { + p.logAction(fmt.Sprintf( + "Overwriting payload buffer with %d bytes input", + len(input), + )) + + p.encodedPayloadBuffer.Reset() + + if len(input) == 0 { + return 0, nil + } + + return p.encodedPayloadBuffer.WriteString(input) +} + +// AddPayloadBytes appends the given input in bytes to the payload buffer. It +// returns the length of input and a potential error. Empty input is silently +// ignored. +// +// The contents of this buffer will be included in the plugin's output as an +// encoded payload suitable for later retrieval/decoding. +func (p *Plugin) AddPayloadBytes(input []byte) (int, error) { + if len(input) == 0 { + return 0, nil + } + + p.logAction(fmt.Sprintf( + "Appending %d bytes input to payload buffer", + len(input), + )) + + return p.encodedPayloadBuffer.Write(input) +} + +// AddPayloadString appends the given input string to the payload buffer. It +// returns the length of input and a potential error. Empty input is silently +// ignored. +// +// The contents of this buffer will be included in the plugin's output as an +// encoded payload suitable for later retrieval/decoding. +func (p *Plugin) AddPayloadString(input string) (int, error) { + if len(input) == 0 { + return 0, nil + } + + p.logAction(fmt.Sprintf( + "Appending %d bytes input to payload buffer", + len(input), + )) + + return p.encodedPayloadBuffer.WriteString(input) +} + +// UnencodedPayload returns the payload buffer contents in string format as-is +// without encoding applied. If the payload buffer is empty an empty string is +// returned. +func (p *Plugin) UnencodedPayload() string { + p.logAction(fmt.Sprintf( + "Returning %d bytes from payload buffer", + p.encodedPayloadBuffer.Len(), + )) + + return p.encodedPayloadBuffer.String() +} + +// defaultPluginOutputTarget returns the fallback/default plugin output target +// used when a user-specified value is not provided. +func defaultPluginOutputTarget() io.Writer { + return os.Stdout +} + // emitOutput writes final plugin output to the previously set output target. // No further modifications to plugin output are performed. func (p Plugin) emitOutput(pluginOutput string) { + p.logPluginOutputSize(fmt.Sprintf("%d bytes total plugin output to write", len(pluginOutput))) - // Emit all collected output using user-specified output target. Fall back - // to standard output if not set. + // Emit all collected output using user-specified output target or + // fallback to the default if not set. if p.outputSink == nil { - p.outputSink = os.Stdout + p.logAction("Custom plugin output target not set") + p.logAction("Falling back to default plugin output target") + p.outputSink = defaultPluginOutputTarget() } - fmt.Fprint(p.outputSink, pluginOutput) + p.logAction("Writing plugin output") + + // Attempt to write to output sink. If this fails, send error to the + // default abort message output target. If that fails (however unlikely), + // we have bigger problems and should abort. + pluginOutputWritten, sinkWriteErr := fmt.Fprint(p.outputSink, pluginOutput) + if sinkWriteErr != nil { + p.logAction("Failed to write plugin output") + + _, stdErrWriteErr := fmt.Fprintf( + defaultPluginAbortMessageOutputTarget(), + "Failed to write output to given output sink: %s", + sinkWriteErr.Error(), + ) + if stdErrWriteErr != nil { + panic("Failed to write initial output sink failure error message to stderr") + } + } + + p.logPluginOutputSize(fmt.Sprintf("%d bytes total plugin output written", pluginOutputWritten)) } // tryAddDefaultTimeMetric inserts a default `time` performance data metric @@ -437,6 +719,8 @@ func (p *Plugin) tryAddDefaultTimeMetric() { // We already have an existing time metric, skip replacing it. if _, hasTimeMetric := p.perfData[defaultTimeMetricLabel]; hasTimeMetric { + p.logAction("Existing time metric present, skipping replacement") + return } @@ -444,6 +728,8 @@ func (p *Plugin) tryAddDefaultTimeMetric() { // not have an internal plugin start time that we can use to generate a // default time metric. if p.start.IsZero() { + p.logAction("Plugin not created using constructor, so no default time metric to use") + return } @@ -452,6 +738,8 @@ func (p *Plugin) tryAddDefaultTimeMetric() { } p.perfData[defaultTimeMetricLabel] = defaultTimeMetric(p.start) + + p.logAction("Added default time metric to collection") } // defaultTimeMetric is a helper function that wraps the logic used to provide diff --git a/vendor/github.com/atc0005/go-nagios/payload.go b/vendor/github.com/atc0005/go-nagios/payload.go new file mode 100644 index 0000000..f11cd84 --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/payload.go @@ -0,0 +1,241 @@ +// Copyright 2024 Adam Chalkley +// +// https://github.com/atc0005/go-nagios +// +// Licensed under the MIT License. See LICENSE file in the project root for +// full license information. +// +// Code in this file inspired by or generated with the help of ChatGPT, OpenAI. + +package nagios + +import ( + "bytes" + "encoding/ascii85" + "fmt" + "regexp" +) + +// getEncodedPayloadDelimiterLeft retrieves the custom left delimiter used +// when enclosing an encoded payload if set, otherwise returns the default +// value. +func (p Plugin) getEncodedPayloadDelimiterLeft() string { + switch { + case p.encodedPayloadDelimiterLeft != nil: + return *p.encodedPayloadDelimiterLeft + default: + return defaultPayloadDelimiterLeft + } +} + +// getEncodedPayloadDelimiterRight retrieves the custom right delimiter used +// when enclosing an encoded payload if set, otherwise returns the default +// value. +func (p Plugin) getEncodedPayloadDelimiterRight() string { + switch { + case p.encodedPayloadDelimiterRight != nil: + return *p.encodedPayloadDelimiterRight + default: + return defaultPayloadDelimiterRight + } +} + +// EncodeASCII85Payload encodes the given input as Ascii85. If no input is +// provided, an empty string is returned. +// +// If specified, the given left and right delimiters are used to enclose the +// encoded payload. If not specified, no delimiters are used. +func EncodeASCII85Payload(data []byte, leftDelimiter string, rightDelimiter string) string { + if len(data) == 0 { + return "" + } + + encoded := make([]byte, ascii85.MaxEncodedLen(len(data))) + ascii85.Encode(encoded, data) + + // Add optional delimiters. + return leftDelimiter + string(encoded) + rightDelimiter +} + +// unescapeASCII85 unescapes an Ascii85 input payload by removing escape +// patterns added to the payload as it passes through a monitoring system +// (e.g., for inclusion in a JSON API response). +func unescapeASCII85(encodedInput []byte) ([]byte, error) { + if len(encodedInput) == 0 { + return nil, fmt.Errorf( + "failed to unescape empty payload: %w", + ErrMissingValue, + ) + } + + // Based on initial testing this is sufficient to unescape an Ascii85 + // payload that passes through the Nagios XI API. + encodedInput = bytes.ReplaceAll(encodedInput, []byte(`\\`), []byte(`\`)) + + return encodedInput, nil +} + +// decodeASCII85 decodes given Ascii85 encoded input or an error if one occurs +// during decoding. +// +// The caller is expected to remove any delimiters from the input before +// calling this function. +// +// This function is also not intended for extraction of an Ascii85 encoded +// payload from surrounding text. +func decodeASCII85(encodedInput []byte) ([]byte, error) { + if len(encodedInput) == 0 { + return nil, fmt.Errorf( + "failed to decode empty payload: %w", + ErrMissingValue, + ) + } + + unescapedInput, unescapeErr := unescapeASCII85(encodedInput) + if unescapeErr != nil { + return nil, unescapeErr + } + + decoded := make([]byte, len(unescapedInput)) + n, _, decodeErr := ascii85.Decode(decoded, unescapedInput, true) + if decodeErr != nil { + return nil, decodeErr + } + + decodedBytes := decoded[:n] + + // Remove any trailing null (\x00) bytes that may have been added as + // padding during the encoding process. + // + // https://blog.manugarri.com/note-to-self-fixing-encoding-in-golang-ascii85/ + decodedBytes = bytes.Trim(decodedBytes, "\x00") + + return decodedBytes, nil +} + +// DecodeASCII85Payload decodes given Ascii85 encoded input or an error if one +// occurs during decoding. If provided, the left and right delimiters are +// trimmed from the given input before decoding is performed. +// +// This function is not intended to extract an Ascii85 encoded payload from +// surrounding text. +func DecodeASCII85Payload(encodedInput []byte, leftDelimiter string, rightDelimiter string) ([]byte, error) { + if len(encodedInput) == 0 { + return nil, fmt.Errorf( + "failed to decode empty payload: %w", + ErrMissingValue, + ) + } + + if leftDelimiter != "" { + encodedInput = bytes.TrimPrefix(encodedInput, []byte(leftDelimiter)) + } + + if rightDelimiter != "" { + encodedInput = bytes.TrimSuffix(encodedInput, []byte(rightDelimiter)) + } + + decodedPayload, err := decodeASCII85(encodedInput) + if err != nil { + // return nil, err + return nil, fmt.Errorf( + "failed to decode %d bytes input payload: %w", + len(encodedInput), + err, + ) + } + + return decodedPayload, nil +} + +// ExtractEncodedASCII85Payload extracts an Ascii85 encoded payload from given +// text input using specified delimiters. +// +// If not provided, a default regular expression for the Ascii85 encoding +// format is used to perform matching/extraction. +// +// If specified, delimiters are removed during the extraction process. +// +// NOTE: While technically optional, the use of delimiters for matching an +// encoded payload is *highly* recommended; reliability of payload matching is +// *greatly* reduced without using delimiters. +// +// The extracted payload is Ascii85 encoded and will need to be decoded before +// the original content is accessible. +func ExtractEncodedASCII85Payload(text string, customRegex string, leftDelimiter string, rightDelimiter string) (string, error) { + if len(text) == 0 { + return "", fmt.Errorf( + "failed to extract encoded payload from empty input: %w", + ErrMissingValue, + ) + } + + // Regular expression to match Ascii85 block without delimiters. + ascii85EncodingPattern := DefaultASCII85EncodingPatternRegex + + defaultMatchPattern := leftDelimiter + ascii85EncodingPattern + rightDelimiter + + chosenRegex := defaultMatchPattern + if customRegex != "" { + chosenRegex = leftDelimiter + customRegex + rightDelimiter + } + + // Assert that combined expression is valid. + re, err := regexp.Compile(chosenRegex) + if err != nil { + return "", fmt.Errorf( + "failed to use regex %q to match encoded payload "+ + "in given text: %w", + chosenRegex, + ErrEncodedPayloadRegexInvalid, + ) + } + + matches := re.FindStringSubmatch(text) + if len(matches) == 0 { + return "", fmt.Errorf("no encoded Ascii85 data found: %w", ErrEncodedPayloadNotFound) + } + + // Dynamically remove the delimiters based on input delimiter length. + leftDelimiterLength := len(leftDelimiter) + rightDelimiterLength := len(rightDelimiter) + + return matches[0][leftDelimiterLength : len(matches[0])-rightDelimiterLength], nil +} + +// ExtractAndDecodeASCII85Payload extracts and decodes a Ascii85 encoded +// payload from given input text. +// +// If not provided, a default regular expression for the Ascii85 encoding +// format is used to perform matching/extraction. +// +// If specified, delimiters are removed during the extraction process. +// +// NOTE: While technically optional, the use of delimiters for matching an +// encoded payload is *highly* recommended; without delimiters, reliability of +// payload matching is *greatly* reduced (LOTS of false positives). +// +// The extracted content is the original unencoded payload before Ascii85 +// encoding was performed. Depending on the type of the original data, the +// retrieved payload may require additional processing (e.g., JSON vs +// plaintext). +func ExtractAndDecodeASCII85Payload(text string, customRegex string, leftDelimiter string, rightDelimiter string) (string, error) { + if len(text) == 0 { + return "", fmt.Errorf( + "failed to extract and decode payload from empty input: %w", + ErrMissingValue, + ) + } + + encodedPayload, err := ExtractEncodedASCII85Payload(text, customRegex, leftDelimiter, rightDelimiter) + if err != nil { + return "", err + } + + decodedPayload, err := decodeASCII85([]byte(encodedPayload)) + if err != nil { + return "", err + } + + return string(decodedPayload), nil +} diff --git a/vendor/github.com/atc0005/go-nagios/perfdata.go b/vendor/github.com/atc0005/go-nagios/perfdata.go index 2e6a851..2630123 100644 --- a/vendor/github.com/atc0005/go-nagios/perfdata.go +++ b/vendor/github.com/atc0005/go-nagios/perfdata.go @@ -322,22 +322,22 @@ func parsePerfData(perfdataString string) (PerformanceData, error) { rawWarn, rawCrit, rawMin, rawMax := extractRawWarnCritMinMaxRawFieldVals(perfdataFields) - warn, err := parsePerfDataWarnField(rawWarn) + warnVal, err := parsePerfDataWarnField(rawWarn) if err != nil { return PerformanceData{}, fmt.Errorf("failed to parse warn field: %w", err) } - crit, err := parsePerfDataCritField(rawCrit) + critVal, err := parsePerfDataCritField(rawCrit) if err != nil { return PerformanceData{}, fmt.Errorf("failed to parse crit field: %w", err) } - min, err := parsePerfDataMinField(rawMin) + minVal, err := parsePerfDataMinField(rawMin) if err != nil { return PerformanceData{}, fmt.Errorf("failed to parse min field: %w", err) } - max, err := parsePerfDataMaxField(rawMax) + maxVal, err := parsePerfDataMaxField(rawMax) if err != nil { return PerformanceData{}, fmt.Errorf("failed to parse max field: %w", err) } @@ -346,10 +346,10 @@ func parsePerfData(perfdataString string) (PerformanceData, error) { Label: label, Value: value, UnitOfMeasurement: uom, - Warn: warn, - Crit: crit, - Min: min, - Max: max, + Warn: warnVal, + Crit: critVal, + Min: minVal, + Max: maxVal, } return perfdata, nil @@ -494,27 +494,27 @@ func extractValueAndUoM(input string) (string, string, error) { // fields) into Warn, Crit, Min and Max values. If values are not present for // those fields an empty string is returned in its place. func extractRawWarnCritMinMaxRawFieldVals(perfdataFields []string) (string, string, string, string) { - var warn string + var warnVal string if len(perfdataFields) >= 2 { - warn = perfdataFields[1] + warnVal = perfdataFields[1] } - var crit string + var critVal string if len(perfdataFields) >= 3 { - crit = perfdataFields[2] + critVal = perfdataFields[2] } - var min string + var minVal string if len(perfdataFields) >= 4 { - min = perfdataFields[3] + minVal = perfdataFields[3] } - var max string + var maxVal string if len(perfdataFields) >= 5 { - max = perfdataFields[4] + maxVal = perfdataFields[4] } - return warn, crit, min, max + return warnVal, critVal, minVal, maxVal } // parsePerfDataWarnField evaluates the given input string as a Performance diff --git a/vendor/github.com/atc0005/go-nagios/range.go b/vendor/github.com/atc0005/go-nagios/range.go index 76d5879..432edc4 100644 --- a/vendor/github.com/atc0005/go-nagios/range.go +++ b/vendor/github.com/atc0005/go-nagios/range.go @@ -5,6 +5,9 @@ // // Licensed under the MIT License. See LICENSE file in the project root for // full license information. +// +// Portions of the code in this file inspired by or generated with the help of +// ChatGPT and Google Gemini. package nagios @@ -47,94 +50,111 @@ func (r Range) CheckRange(value string) bool { // // [Nagios Plugin Dev Guidelines: Threshold and Ranges]: https://nagios-plugins.org/doc/guidelines.html#THRESHOLDFORMAT func (r Range) checkOutsideRange(valueAsAFloat float64) bool { - switch { - case !r.EndInfinity && !r.StartInfinity: - if r.Start <= valueAsAFloat && valueAsAFloat <= r.End { - return false - } - return true - - case !r.StartInfinity && r.EndInfinity: - if valueAsAFloat >= r.Start { - return false - } - return true - - case r.StartInfinity && !r.EndInfinity: - if valueAsAFloat <= r.End { - return false - } - return true - - default: - return false + // This alternative implementation was provided by Google Gemini (model + // 'Gemini 1.5 Flash'). + // + // Explanation of the logic: + // + // Infinite Bounds: + // + // If the start is infinite, the value is outside the range only if it's + // greater than the end. If the end is infinite, the value is outside the + // range only if it's less than the start. + // + // Finite Bounds: + // + // The value is outside the range if it's either less than the start or + // greater than the end. + + // Handle infinite bounds first + if r.StartInfinity { + return valueAsAFloat > r.End + } else if r.EndInfinity { + return valueAsAFloat < r.Start } + + // Handle finite bounds + return valueAsAFloat < r.Start || valueAsAFloat > r.End } +// checkOutsideRange is provided by ChatGPT (model 'GPT-4o') as a +// simplification of the original checkOutsideRange function. +// func (r Range) checkOutsideRange(value float64) bool { +// // Explanation of the Simplification: +// // +// // Each case is now focused only on the conditions that make the value +// // outside the range. The final default case covers the fully infinite +// // range, simplifying the logic to just return false since no bounds +// // restrict the range. +// +// switch { +// case !r.StartInfinity && value < r.Start: +// return true +// case !r.EndInfinity && value > r.End: +// return true +// case r.StartInfinity && r.EndInfinity: +// return false +// default: +// return false +// } +// } + // ParseRangeString static method to construct a Range object from the string // representation based on the [Nagios Plugin Dev Guidelines: Threshold and // Ranges] definition. // // [Nagios Plugin Dev Guidelines: Threshold and Ranges]: https://nagios-plugins.org/doc/guidelines.html#THRESHOLDFORMAT func ParseRangeString(input string) *Range { - r := Range{} + // Initialize range with default values + r := Range{ + Start: 0, + End: 0, + StartInfinity: false, + EndInfinity: false, + AlertOn: "OUTSIDE", + } + // Define regular expressions digitOrInfinity := regexp.MustCompile(`[\d~]`) optionalInvertAndRange := regexp.MustCompile(`^@?([-+]?[\d.]+(?:e[-+]?[\d.]+)?|~)?(:([-+]?[\d.]+(?:e[-+]?[\d.]+)?)?)?$`) firstHalfOfRange := regexp.MustCompile(`^([-+]?[\d.]+(?:e[-+]?[\d.]+)?)?:`) endOfRange := regexp.MustCompile(`^[-+]?[\d.]+(?:e[-+]?[\d.]+)?$`) - r.Start = 0 - r.StartInfinity = false - r.End = 0 - r.EndInfinity = false - r.AlertOn = "OUTSIDE" - - valid := true - - // If regex does not match ... + // Validate input format if !(digitOrInfinity.MatchString(input) && optionalInvertAndRange.MatchString(input)) { return nil } - // Invert the range. - // - // i.e. @10:20 means ≥ 10 and ≤ 20 (inside the range of {10 .. 20} - // inclusive) - if strings.HasPrefix(input, "@") { + switch { + // Parse alert inversion (starts with @) + case strings.HasPrefix(input, "@"): r.AlertOn = "INSIDE" input = input[1:] - } - // ~ represents infinity - if strings.HasPrefix(input, "~") { + // Parse start infinity (~ symbol at start) + case strings.HasPrefix(input, "~"): r.StartInfinity = true input = input[1:] } - // 10: - rangeComponents := firstHalfOfRange.FindAllStringSubmatch(input, -1) - if rangeComponents != nil { - if rangeComponents[0][1] != "" { - r.Start, _ = strconv.ParseFloat(rangeComponents[0][1], 64) + // Parse start of range (e.g., "10:") + if rangeComponents := firstHalfOfRange.FindStringSubmatch(input); rangeComponents != nil { + if rangeComponents[1] != "" { + r.Start, _ = strconv.ParseFloat(rangeComponents[1], 64) r.StartInfinity = false } - r.EndInfinity = true - input = strings.TrimPrefix(input, rangeComponents[0][0]) - valid = true + input = strings.TrimPrefix(input, rangeComponents[0]) } - // x:10 or 10 - endOfRangeComponents := endOfRange.FindAllStringSubmatch(input, -1) - if endOfRangeComponents != nil { - - r.End, _ = strconv.ParseFloat(endOfRangeComponents[0][0], 64) + // Parse end of range (e.g., "10" or "x:10") + if endOfRangeComponents := endOfRange.FindStringSubmatch(input); endOfRangeComponents != nil { + r.End, _ = strconv.ParseFloat(endOfRangeComponents[0], 64) r.EndInfinity = false - valid = true } - if valid && (r.StartInfinity || r.EndInfinity || r.Start <= r.End) { + // Ensure valid range boundaries + if r.StartInfinity || r.EndInfinity || r.Start <= r.End { return &r } @@ -146,36 +166,39 @@ func ParseRangeString(input string) *Range { // ExitStatusCode of the plugin as appropriate. func (p *Plugin) EvaluateThreshold(perfData ...PerformanceData) error { for i := range perfData { - - if perfData[i].Crit != "" { - - CriticalThresholdObject := ParseRangeString(perfData[i].Crit) - if CriticalThresholdObject == nil { - err := fmt.Errorf("failed to parse critical range string %s: %w ", perfData[i].Crit, ErrInvalidRangeThreshold) - p.ExitStatusCode = StateUNKNOWNExitCode - return err - } - - if CriticalThresholdObject.CheckRange(perfData[i].Value) { - p.ExitStatusCode = StateCRITICALExitCode - return nil - } + // Evaluate critical threshold + if inCritical, err := evaluateThreshold(perfData[i].Crit, perfData[i].Value); err != nil { + p.ExitStatusCode = StateUNKNOWNExitCode + return err + } else if inCritical { + p.ExitStatusCode = StateCRITICALExitCode + return nil } - if perfData[i].Warn != "" { - warningThresholdObject := ParseRangeString(perfData[i].Warn) - if warningThresholdObject == nil { - err := fmt.Errorf("failed to parse warning range string %s: %w ", perfData[i].Warn, ErrInvalidRangeThreshold) - p.ExitStatusCode = StateUNKNOWNExitCode - return err - } - - if warningThresholdObject.CheckRange(perfData[i].Value) { - p.ExitStatusCode = StateWARNINGExitCode - return nil - } + // Evaluate warning threshold + if inWarning, err := evaluateThreshold(perfData[i].Warn, perfData[i].Value); err != nil { + p.ExitStatusCode = StateUNKNOWNExitCode + return err + } else if inWarning { + p.ExitStatusCode = StateWARNINGExitCode + return nil } } return nil } + +// evaluateThreshold is a helper function used to handle both parsing and +// range-checking, taking rangeStr (the threshold string), value, and +// exitCode. If the parsing fails, it returns an error to simplify error +// handling within the caller. +func evaluateThreshold(rangeStr, value string) (bool, error) { + if rangeStr == "" { + return false, nil // Skip empty thresholds + } + thresholdObj := ParseRangeString(rangeStr) + if thresholdObj == nil { + return false, fmt.Errorf("failed to parse range string %s: %w", rangeStr, ErrInvalidRangeThreshold) + } + return thresholdObj.CheckRange(value), nil +} diff --git a/vendor/github.com/atc0005/go-nagios/sections.go b/vendor/github.com/atc0005/go-nagios/sections.go index f8b023f..40ce482 100644 --- a/vendor/github.com/atc0005/go-nagios/sections.go +++ b/vendor/github.com/atc0005/go-nagios/sections.go @@ -33,81 +33,127 @@ func (p Plugin) handleServiceOutputSection(w io.Writer) { // formatting changes to this content, simply emit it as-is. This helps // avoid potential issues with literal characters being interpreted as // formatting verbs. - fmt.Fprint(w, p.ServiceOutput) + written, err := fmt.Fprint(w, p.ServiceOutput) + if err != nil { + // Very unlikely to occur, but we should still account for it. + panic("Failed to write ServiceOutput to given output sink") + } + + p.logPluginOutputSize(fmt.Sprintf("%d bytes plugin ServiceOutput content written to buffer", written)) } // handleErrorsSection is a wrapper around the logic used to handle/process // the Errors section header and listing. func (p Plugin) handleErrorsSection(w io.Writer) { + if p.isErrorsHidden() { + p.logAction("Skipping processing of errors section; option to hide errors enabled") + + return + } // If one or more errors were recorded and client code has not opted to // hide the section ... - if !p.isErrorsHidden() { - fmt.Fprintf(w, - "%s%s**%s**%s%s", - CheckOutputEOL, - CheckOutputEOL, - p.getErrorsLabelText(), - CheckOutputEOL, - CheckOutputEOL, - ) + var totalWritten int - if p.LastError != nil { - fmt.Fprintf(w, "* %v%s", p.LastError, CheckOutputEOL) + writeErrorToOutputSink := func(err error) { + written, writeErr := fmt.Fprintf(w, "* %v%s", err, CheckOutputEOL) + if writeErr != nil { + panic("Failed to write LastError field content to given output sink") } - // Process any non-nil errors in the collection. - for _, err := range p.Errors { - if err != nil { - fmt.Fprintf(w, "* %v%s", err, CheckOutputEOL) - } - } + totalWritten += written + } + written, writeErr := fmt.Fprintf(w, + "%s%s**%s**%s%s", + CheckOutputEOL, + CheckOutputEOL, + p.getErrorsLabelText(), + CheckOutputEOL, + CheckOutputEOL, + ) + if writeErr != nil { + panic("Failed to write errors section label to given output sink") } + totalWritten += written + if p.LastError != nil { + writeErrorToOutputSink(p.LastError) + } + + // Process any non-nil errors in the collection. + for _, err := range p.Errors { + if err != nil { + writeErrorToOutputSink(err) + } + } + + p.logPluginOutputSize(fmt.Sprintf("%d bytes total plugin errors content written to buffer", totalWritten)) } // handleThresholdsSection is a wrapper around the logic used to // handle/process the Thresholds section header and listing. func (p Plugin) handleThresholdsSection(w io.Writer) { + switch { + case p.LongServiceOutput == "": + p.logAction("Skipping emission of thresholds section; LongServiceOutput is empty") + + return + + case p.isThresholdsSectionHidden(): + p.logAction("Skipping emission of thresholds section; option to hide errors enabled") + + return + } + + // If one or more threshold values were recorded and client code has + // not opted to hide the section ... + + var totalWritten int + + written, err := fmt.Fprintf(w, "%s**%s**%s%s", + CheckOutputEOL, + p.getThresholdsLabelText(), + CheckOutputEOL, + CheckOutputEOL, + ) + if err != nil { + panic("Failed to write thresholds section label to given output sink") + } + + totalWritten += written - // We skip emitting the thresholds section if there isn't any - // LongServiceOutput to process. - if p.LongServiceOutput != "" { - - // If one or more threshold values were recorded and client code has - // not opted to hide the section ... - if !p.isThresholdsSectionHidden() { - - fmt.Fprintf(w, - "%s**%s**%s%s", - CheckOutputEOL, - p.getThresholdsLabelText(), - CheckOutputEOL, - CheckOutputEOL, - ) - - if p.CriticalThreshold != "" { - fmt.Fprintf(w, - "* %s: %v%s", - StateCRITICALLabel, - p.CriticalThreshold, - CheckOutputEOL, - ) - } - - if p.WarningThreshold != "" { - fmt.Fprintf(w, - "* %s: %v%s", - StateWARNINGLabel, - p.WarningThreshold, - CheckOutputEOL, - ) - } + if p.CriticalThreshold != "" { + written, err := fmt.Fprintf(w, "* %s: %v%s", + StateCRITICALLabel, + p.CriticalThreshold, + CheckOutputEOL, + ) + if err != nil { + panic("Failed to write thresholds section label to given output sink") } + + totalWritten += written } + if p.WarningThreshold != "" { + warningThresholdText := fmt.Sprintf( + "* %s: %v%s", + StateWARNINGLabel, + p.WarningThreshold, + CheckOutputEOL, + ) + + written, err := fmt.Fprint(w, warningThresholdText) + if err != nil { + panic("Failed to write thresholds section label to given output sink") + } + + totalWritten += written + } + + p.logPluginOutputSize(fmt.Sprintf("%d bytes plugin thresholds section content written to buffer", totalWritten)) } // handleLongServiceOutput is a wrapper around the logic used to @@ -116,39 +162,132 @@ func (p Plugin) handleLongServiceOutput(w io.Writer) { // Early exit if there is no content to emit. if p.LongServiceOutput == "" { + p.logAction("Skipping processing of LongServiceOutput; LongServiceOutput is empty") + return } + var totalWritten int + // Hide section header/label if threshold and error values were not - // specified by client code or if client code opted to explicitly hide - // those sections; there is no need to use a header to separate the - // LongServiceOutput from those sections if they are not displayed. + // specified by client code, if client code opted to explicitly hide + // threshold or error sections or if no encoded payload content was + // provided; there is no need to use a header to separate the + // LongServiceOutput from those sections if they are not displayed (or + // provided in the case of an encoded payload). // // If we hide the section header, we still provide some padding to // prevent the LongServiceOutput from running up against the // ServiceOutput content. switch { - case !p.isThresholdsSectionHidden() || !p.isErrorsHidden(): - fmt.Fprintf(w, + case !p.isThresholdsSectionHidden() || !p.isErrorsHidden() || !p.isPayloadSectionHidden(): + written, err := fmt.Fprintf(w, "%s**%s**%s", CheckOutputEOL, p.getDetailedInfoLabelText(), CheckOutputEOL, ) + if err != nil { + panic("Failed to write LongServiceOutput section label to given output sink") + } + + totalWritten += written + default: - fmt.Fprint(w, CheckOutputEOL) + written, err := fmt.Fprint(w, CheckOutputEOL) + if err != nil { + panic("Failed to write LongServiceOutput section label spacer to given output sink") + } + + totalWritten += written } // Note: fmt.Println() (and fmt.Fprintln()) has the same issue as `\n`: // Nagios seems to interpret them literally instead of emitting an actual // newline. We work around that by using fmt.Fprintf() for output that is // intended for display within the Nagios web UI. - fmt.Fprintf(w, + written, err := fmt.Fprintf(w, "%s%v%s", CheckOutputEOL, p.LongServiceOutput, CheckOutputEOL, ) + if err != nil { + panic("Failed to write LongServiceOutput field content to given output sink") + } + + totalWritten += written + + p.logPluginOutputSize(fmt.Sprintf("%d bytes plugin LongServiceOutput content written to buffer", totalWritten)) +} + +// handleEncodedPayload is a wrapper around the logic used to handle/process +// any user-provided content to be encoded and included in the plugin output. +func (p Plugin) handleEncodedPayload(w io.Writer) { + // Early exit if there is no content to process. + if p.encodedPayloadBuffer.Len() == 0 { + p.logAction("Skipping processing of encoded payload buffer; buffer is empty") + + return + } + + leftDelimiter := p.getEncodedPayloadDelimiterLeft() + rightDelimiter := p.getEncodedPayloadDelimiterRight() + + // Encode the contents of the buffer to Ascii85 with delimiters. + encodedWithDelimiters := EncodeASCII85Payload( + p.encodedPayloadBuffer.Bytes(), + leftDelimiter, + rightDelimiter, + ) + + var totalWritten int + + // Hide section header/label if no payload was specified. + // + // If we hide the section header, we still provide some padding to prevent + // this output from running up against the LongServiceOutput content. + switch { + case p.encodedPayloadBuffer.Len() > 0: + written, err := fmt.Fprintf(w, + "%s**%s**%s", + CheckOutputEOL, + p.getEncodedPayloadLabelText(), + CheckOutputEOL, + ) + if err != nil { + panic("Failed to write EncodedPayload section label to given output sink") + } + + totalWritten += written + + // Note: fmt.Println() (and fmt.Fprintln()) has the same issue as + // `\n`: Nagios seems to interpret them literally instead of emitting + // an actual newline. We work around that by using fmt.Fprintf() for + // output that is intended for display within the Nagios web UI. + written, err = fmt.Fprintf(w, + "%s%v%s", + CheckOutputEOL, + encodedWithDelimiters, + CheckOutputEOL, + ) + + if err != nil { + panic("Failed to write EncodedPayload content to given output sink") + } + + totalWritten += written + + default: + written, err := fmt.Fprint(w, CheckOutputEOL) + if err != nil { + panic("Failed to write EncodedPayload section spacer to given output sink") + } + + totalWritten += written + } + + p.logPluginOutputSize(fmt.Sprintf("%d bytes plugin EncodedPayload content written to buffer", totalWritten)) } // handlePerformanceData is a wrapper around the logic used to @@ -158,6 +297,8 @@ func (p *Plugin) handlePerformanceData(w io.Writer) { // We require that a one-line summary is set by client code before // emitting performance data metrics. if strings.TrimSpace(p.ServiceOutput) == "" { + p.logAction("Skipping processing of performance data; ServiceOutput is empty") + return } @@ -167,25 +308,45 @@ func (p *Plugin) handlePerformanceData(w io.Writer) { // If no metrics have been collected by this point we have nothing further // to do. if len(p.perfData) == 0 { + p.logAction("Skipping processing of performance data; perfdata collection is empty") + return } + var totalWritten int + // Performance data metrics are appended to plugin output. These // metrics are provided as a single line, leading with a pipe // character, a space and one or more metrics each separated from // another by a single space. - fmt.Fprint(w, " |") + written, err := fmt.Fprint(w, " |") + if err != nil { + panic("Failed to write performance data content to given output sink") + } + + totalWritten += written // Sort performance data values prior to emitting them so that the // output is consistent across plugin execution. perfData := p.getSortedPerfData() for _, pd := range perfData { - fmt.Fprint(w, pd.String()) + written, err = fmt.Fprint(w, pd.String()) + if err != nil { + panic("Failed to write performance data content to given output sink") + } + totalWritten += written } // Add final trailing newline to satisfy Nagios plugin output format. - fmt.Fprint(w, CheckOutputEOL) + written, err = fmt.Fprint(w, CheckOutputEOL) + if err != nil { + panic("Failed to write performance data content to given output sink") + } + + totalWritten += written + + p.logPluginOutputSize(fmt.Sprintf("%d bytes plugin performance data content written to buffer", totalWritten)) } @@ -207,6 +368,12 @@ func (p Plugin) isErrorsHidden() bool { return false } +// isPayloadSectionHidden indicates whether the Payload section should be +// omitted from output. +func (p Plugin) isPayloadSectionHidden() bool { + return p.encodedPayloadBuffer.Len() == 0 +} + // getThresholdsLabelText retrieves the custom thresholds label text if set, // otherwise returns the default value. func (p Plugin) getThresholdsLabelText() string { @@ -240,6 +407,17 @@ func (p Plugin) getDetailedInfoLabelText() string { } } +// getEncodedPayloadLabelText retrieves the custom encoded payload label text +// if set, otherwise returns the default value. +func (p Plugin) getEncodedPayloadLabelText() string { + switch { + case p.encodedPayloadLabel != "": + return p.encodedPayloadLabel + default: + return defaultEncodedPayloadLabel + } +} + // SetThresholdsLabel overrides the default thresholds label text. func (p *Plugin) SetThresholdsLabel(newLabel string) { p.thresholdsLabel = newLabel @@ -255,6 +433,11 @@ func (p *Plugin) SetDetailedInfoLabel(newLabel string) { p.detailedInfoLabel = newLabel } +// SetEncodedPayloadLabel overrides the default encoded payload label text. +func (p *Plugin) SetEncodedPayloadLabel(newLabel string) { + p.encodedPayloadLabel = newLabel +} + // HideThresholdsSection indicates that client code has opted to hide the // thresholds section, regardless of whether values were previously provided // for display. diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/large_payload_encoded_with_custom_delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/large_payload_encoded_with_custom_delimiters.txt new file mode 100644 index 0000000..4c8a6d0 --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/large_payload_encoded_with_custom_delimiters.txt @@ -0,0 +1 @@ +CUSTOM_ENCODING_DELIMITER_LEFT9Q+r_D'3P3F*2=BA8c:&EZfF;F-F(Jj'ATW'8+EV12CiseACgggfDJdmF!,@=DCco@Bk)7-D'3n.E+rm$/g*Q#DIm<#D..O.BlbD5@:OG$+CoV//0JMG+Eh16Bm"J>De*R#+DG7oF_kc5+CT@E+B*E(E+NotBle?,+E27@ASuU(/g*ksARf:h@<3Q&FWbO0F`M2;+ED.6DI[g1+DkP.F($2%BkMi.+DkP3Bl/!6+EMI;Ch[BnFEM,.DBNY(+Du+8+CT;#FY4e8ARlp+Ci!Ns@rHC,ATAo6BQ%cuF`S[B@2EcZAE+Dtb1F_)\0DBNn:EccD;FDl1P$497FF(8c(AS5RqFCB55F(K22DJsD8Ch[?iEc3(@F`_YHD'3G%F_>DsFi++Dbt:ASiPu+EV=8@qfIrDKIKR;g!/#ASu$mF)tn8D..6lF*1o%@3B-&FD/X6,BlbmL;g!/#ASu$mF)tn8F(Jl)CiAF6/0JM:ATT&,ATDX!DKL#<+Dbb)F_kJ/G%G`:Bju4$F_r`R76+EMI;Ch[BnFEM,.DBNk.Bl>,/F`VYC/0K"JFFC?;&BkM,D/Ws'+Dtb#+Co1pD(Zr0ARlp)BlkJ+D.Rf3A8,OqF_r7>Earf9+Ad)eATMF#FFD..'p@3B`)F*),*F_l2;+D#A#BkCpoA1f!"F_kl&+CT@7@u4Ecc5?+EhI@@:^u4@rH7+AT;j$Fl7@;R-)Df-\=@:s:rFD5eK+Am8qF)c>6+EhIBATDg"+D#S3F!,X?FCA`'@,DK]H)Ch[rC+BBl5OGoBju4$F_r70DKKG4BlJ-9D'3eEc,;:+CSb&Cgh7&AS#s+Ch7*uF`T/X:i]uUF(K62+EV13E,Tb>G%#E*F`S[:GUstY@qBIfEbTT7F_)\:Des6(@qg%-A8,p(A9DT/AmoglBju4++D#[J+A$GnBOu'lEb09*FDJsD8G%GK(F=n\4BOPsnCi"68+DG@/CgggrF!,F?EccD;FDl1N+EDUHEcl4A@<,k#+CT@C+E2@4FD5l7+Co1pD(Zr-ASc0oDKKH2EHPh8Bk/?*BOPpmFE1e4Ch7N9+DG@/B6%F(Bk1WpASu4!/d_q^Ec5Z0+CQC$DKKG4F(8ctATDL+EHPhD+Co2!DJ=05Bl+u/BkMR)@3BW&A1SjFEbTT:BlS9,+CT;#FY4e2@:`q[DIIT/E,Tf?ATD?)@rH6qBl.F!FEMFCF`MA./0JMH+Cf>-F(Jj'ATW'8+Dtn7Bcq82Ch7[0Bk8DuF=n\2F_kl&D'3n2A0?&,Ch[u6@:LF'ASc(&+E27>FC?;%Df'?0A8a(C6uQsS@j#c6BlbD5BkMR)@3BW&A0>c(F(lb,Df'?0A8`T%Ch7dfF_kJ/F(o_=@;TRt/0JA2@s)X0@;[32AS`K2F`MG8F"SS6F`VM5DIdI&F(HJ(Df031ALnsGASc1*F!,X;C`m\;ATVX/D'3q7DI[BkF`):P+D#G)D'3n.E+rm$+DG7oF_kc5+DbV!FEMXU+DG^9An?""ASuU4D'3D2F>t@;]UiFu7BleB1EHPh8AS,Og@qg%-E\&>FASc(%+DbV!FEMXIAmoglBju4++E_^B@4WO0FE$Ci=>:ASu4!+E_cK@<,k#/g*o3Ci!Ns+CT)#EHP],+CTD*F_)\0DBNA.@s&o8F`V&,E+sDF+DG@/FE2):FD5`;AKZ/-Ch[u6Bl8$(Eb'<0/g*u2DeX)3F`\aDF_kl&+ELt(BlnH2F"AGFAnGaeBlnK<+DkP0EbTS;F(Jl5+Cno"Bju4++Dbt:ASj%B;g!/#ASu$mF)tn8Ch7N-An>dmF"AGN@;KLrF^\fh+DG@/DfT?%+EM+)/0K+YCiFN=@-F(Jj'ATW'8+EV12CiseACgggfDJdmF!,@=DCco@Bk)7-D'3n.E+rm$/g*Q#DIm<#D..O.BlbD5@:OG$+CoV//0JMG+Eh16Bm"J>De*R#+DG7oF_kc5+CT@E+B*E(E+NotBle?,+E27@ASuU(/g*ksARf:h@<3Q&FWbO0F`M2;+ED.6DI[g1+DkP.F($2%BkMi.+DkP3Bl/!6+EMI;Ch[BnFEM,.DBNY(+Du+8+CT;#FY4e8ARlp+Ci!Ns@rHC,ATAo6BQ%cuF`S[B@2EcZAE+Dtb1F_)\0DBNn:EccD;FDl1P$497FF(8c(AS5RqFCB55F(K22DJsD8Ch[?iEc3(@F`_YHD'3G%F_>DsFi++Dbt:ASiPu+EV=8@qfIrDKIKR;g!/#ASu$mF)tn8D..6lF*1o%@3B-&FD/X6,BlbmL;g!/#ASu$mF)tn8F(Jl)CiAF6/0JM:ATT&,ATDX!DKL#<+Dbb)F_kJ/G%G`:Bju4$F_r`R76+EMI;Ch[BnFEM,.DBNk.Bl>,/F`VYC/0K"JFFC?;&BkM,D/Ws'+Dtb#+Co1pD(Zr0ARlp)BlkJ+D.Rf3A8,OqF_r7>Earf9+Ad)eATMF#FFD..'p@3B`)F*),*F_l2;+D#A#BkCpoA1f!"F_kl&+CT@7@u4Ecc5?+EhI@@:^u4@rH7+AT;j$Fl7@;R-)Df-\=@:s:rFD5eK+Am8qF)c>6+EhIBATDg"+D#S3F!,X?FCA`'@,DK]H)Ch[rC+BBl5OGoBju4$F_r70DKKG4BlJ-9D'3eEc,;:+CSb&Cgh7&AS#s+Ch7*uF`T/X:i]uUF(K62+EV13E,Tb>G%#E*F`S[:GUstY@qBIfEbTT7F_)\:Des6(@qg%-A8,p(A9DT/AmoglBju4++D#[J+A$GnBOu'lEb09*FDJsD8G%GK(F=n\4BOPsnCi"68+DG@/CgggrF!,F?EccD;FDl1N+EDUHEcl4A@<,k#+CT@C+E2@4FD5l7+Co1pD(Zr-ASc0oDKKH2EHPh8Bk/?*BOPpmFE1e4Ch7N9+DG@/B6%F(Bk1WpASu4!/d_q^Ec5Z0+CQC$DKKG4F(8ctATDL+EHPhD+Co2!DJ=05Bl+u/BkMR)@3BW&A1SjFEbTT:BlS9,+CT;#FY4e2@:`q[DIIT/E,Tf?ATD?)@rH6qBl.F!FEMFCF`MA./0JMH+Cf>-F(Jj'ATW'8+Dtn7Bcq82Ch7[0Bk8DuF=n\2F_kl&D'3n2A0?&,Ch[u6@:LF'ASc(&+E27>FC?;%Df'?0A8a(C6uQsS@j#c6BlbD5BkMR)@3BW&A0>c(F(lb,Df'?0A8`T%Ch7dfF_kJ/F(o_=@;TRt/0JA2@s)X0@;[32AS`K2F`MG8F"SS6F`VM5DIdI&F(HJ(Df031ALnsGASc1*F!,X;C`m\;ATVX/D'3q7DI[BkF`):P+D#G)D'3n.E+rm$+DG7oF_kc5+DbV!FEMXU+DG^9An?""ASuU4D'3D2F>t@;]UiFu7BleB1EHPh8AS,Og@qg%-E\&>FASc(%+DbV!FEMXIAmoglBju4++E_^B@4WO0FE$Ci=>:ASu4!+E_cK@<,k#/g*o3Ci!Ns+CT)#EHP],+CTD*F_)\0DBNA.@s&o8F`V&,E+sDF+DG@/FE2):FD5`;AKZ/-Ch[u6Bl8$(Eb'<0/g*u2DeX)3F`\aDF_kl&+ELt(BlnH2F"AGFAnGaeBlnK<+DkP0EbTS;F(Jl5+Cno"Bju4++Dbt:ASj%B;g!/#ASu$mF)tn8Ch7N-An>dmF"AGN@;KLrF^\fh+DG@/DfT?%+EM+)/0K+YCiFN=@ \ No newline at end of file diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/large_payload_encoded_without_delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/large_payload_encoded_without_delimiters.txt new file mode 100644 index 0000000..49b0508 --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/large_payload_encoded_without_delimiters.txt @@ -0,0 +1 @@ +9Q+r_D'3P3F*2=BA8c:&EZfF;F-F(Jj'ATW'8+EV12CiseACgggfDJdmF!,@=DCco@Bk)7-D'3n.E+rm$/g*Q#DIm<#D..O.BlbD5@:OG$+CoV//0JMG+Eh16Bm"J>De*R#+DG7oF_kc5+CT@E+B*E(E+NotBle?,+E27@ASuU(/g*ksARf:h@<3Q&FWbO0F`M2;+ED.6DI[g1+DkP.F($2%BkMi.+DkP3Bl/!6+EMI;Ch[BnFEM,.DBNY(+Du+8+CT;#FY4e8ARlp+Ci!Ns@rHC,ATAo6BQ%cuF`S[B@2EcZAE+Dtb1F_)\0DBNn:EccD;FDl1P$497FF(8c(AS5RqFCB55F(K22DJsD8Ch[?iEc3(@F`_YHD'3G%F_>DsFi++Dbt:ASiPu+EV=8@qfIrDKIKR;g!/#ASu$mF)tn8D..6lF*1o%@3B-&FD/X6,BlbmL;g!/#ASu$mF)tn8F(Jl)CiAF6/0JM:ATT&,ATDX!DKL#<+Dbb)F_kJ/G%G`:Bju4$F_r`R76+EMI;Ch[BnFEM,.DBNk.Bl>,/F`VYC/0K"JFFC?;&BkM,D/Ws'+Dtb#+Co1pD(Zr0ARlp)BlkJ+D.Rf3A8,OqF_r7>Earf9+Ad)eATMF#FFD..'p@3B`)F*),*F_l2;+D#A#BkCpoA1f!"F_kl&+CT@7@u4Ecc5?+EhI@@:^u4@rH7+AT;j$Fl7@;R-)Df-\=@:s:rFD5eK+Am8qF)c>6+EhIBATDg"+D#S3F!,X?FCA`'@,DK]H)Ch[rC+BBl5OGoBju4$F_r70DKKG4BlJ-9D'3eEc,;:+CSb&Cgh7&AS#s+Ch7*uF`T/X:i]uUF(K62+EV13E,Tb>G%#E*F`S[:GUstY@qBIfEbTT7F_)\:Des6(@qg%-A8,p(A9DT/AmoglBju4++D#[J+A$GnBOu'lEb09*FDJsD8G%GK(F=n\4BOPsnCi"68+DG@/CgggrF!,F?EccD;FDl1N+EDUHEcl4A@<,k#+CT@C+E2@4FD5l7+Co1pD(Zr-ASc0oDKKH2EHPh8Bk/?*BOPpmFE1e4Ch7N9+DG@/B6%F(Bk1WpASu4!/d_q^Ec5Z0+CQC$DKKG4F(8ctATDL+EHPhD+Co2!DJ=05Bl+u/BkMR)@3BW&A1SjFEbTT:BlS9,+CT;#FY4e2@:`q[DIIT/E,Tf?ATD?)@rH6qBl.F!FEMFCF`MA./0JMH+Cf>-F(Jj'ATW'8+Dtn7Bcq82Ch7[0Bk8DuF=n\2F_kl&D'3n2A0?&,Ch[u6@:LF'ASc(&+E27>FC?;%Df'?0A8a(C6uQsS@j#c6BlbD5BkMR)@3BW&A0>c(F(lb,Df'?0A8`T%Ch7dfF_kJ/F(o_=@;TRt/0JA2@s)X0@;[32AS`K2F`MG8F"SS6F`VM5DIdI&F(HJ(Df031ALnsGASc1*F!,X;C`m\;ATVX/D'3q7DI[BkF`):P+D#G)D'3n.E+rm$+DG7oF_kc5+DbV!FEMXU+DG^9An?""ASuU4D'3D2F>t@;]UiFu7BleB1EHPh8AS,Og@qg%-E\&>FASc(%+DbV!FEMXIAmoglBju4++E_^B@4WO0FE$Ci=>:ASu4!+E_cK@<,k#/g*o3Ci!Ns+CT)#EHP],+CTD*F_)\0DBNA.@s&o8F`V&,E+sDF+DG@/FE2):FD5`;AKZ/-Ch[u6Bl8$(Eb'<0/g*u2DeX)3F`\aDF_kl&+ELt(BlnH2F"AGFAnGaeBlnK<+DkP0EbTS;F(Jl5+Cno"Bju4++Dbt:ASj%B;g!/#ASu$mF)tn8Ch7N-An>dmF"AGN@;KLrF^\fh+DG@/DfT?%+EM+)/0K+YCiFN=@-F(Jj'ATW'8+EV12CiseACgggfDJdmF!,@=DCco@Bk)7-D'3n.E+rm$/g*Q#DIm<#D..O.BlbD5@:OG$+CoV//0JMG+Eh16Bm"J>De*R#+DG7oF_kc5+CT@E+B*E(E+NotBle?,+E27@ASuU(/g*ksARf:h@<3Q&FWbO0F`M2;+ED.6DI[g1+DkP.F($2%BkMi.+DkP3Bl/!6+EMI;Ch[BnFEM,.DBNY(+Du+8+CT;#FY4e8ARlp+Ci!Ns@rHC,ATAo6BQ%cuF`S[B@2EcZAE+Dtb1F_)\0DBNn:EccD;FDl1P$497FF(8c(AS5RqFCB55F(K22DJsD8Ch[?iEc3(@F`_YHD'3G%F_>DsFi++Dbt:ASiPu+EV=8@qfIrDKIKR;g!/#ASu$mF)tn8D..6lF*1o%@3B-&FD/X6,BlbmL;g!/#ASu$mF)tn8F(Jl)CiAF6/0JM:ATT&,ATDX!DKL#<+Dbb)F_kJ/G%G`:Bju4$F_r`R76+EMI;Ch[BnFEM,.DBNk.Bl>,/F`VYC/0K"JFFC?;&BkM,D/Ws'+Dtb#+Co1pD(Zr0ARlp)BlkJ+D.Rf3A8,OqF_r7>Earf9+Ad)eATMF#FFD..'p@3B`)F*),*F_l2;+D#A#BkCpoA1f!"F_kl&+CT@7@u4Ecc5?+EhI@@:^u4@rH7+AT;j$Fl7@;R-)Df-\=@:s:rFD5eK+Am8qF)c>6+EhIBATDg"+D#S3F!,X?FCA`'@,DK]H)Ch[rC+BBl5OGoBju4$F_r70DKKG4BlJ-9D'3eEc,;:+CSb&Cgh7&AS#s+Ch7*uF`T/X:i]uUF(K62+EV13E,Tb>G%#E*F`S[:GUstY@qBIfEbTT7F_)\:Des6(@qg%-A8,p(A9DT/AmoglBju4++D#[J+A$GnBOu'lEb09*FDJsD8G%GK(F=n\4BOPsnCi"68+DG@/CgggrF!,F?EccD;FDl1N+EDUHEcl4A@<,k#+CT@C+E2@4FD5l7+Co1pD(Zr-ASc0oDKKH2EHPh8Bk/?*BOPpmFE1e4Ch7N9+DG@/B6%F(Bk1WpASu4!/d_q^Ec5Z0+CQC$DKKG4F(8ctATDL+EHPhD+Co2!DJ=05Bl+u/BkMR)@3BW&A1SjFEbTT:BlS9,+CT;#FY4e2@:`q[DIIT/E,Tf?ATD?)@rH6qBl.F!FEMFCF`MA./0JMH+Cf>-F(Jj'ATW'8+Dtn7Bcq82Ch7[0Bk8DuF=n\2F_kl&D'3n2A0?&,Ch[u6@:LF'ASc(&+E27>FC?;%Df'?0A8a(C6uQsS@j#c6BlbD5BkMR)@3BW&A0>c(F(lb,Df'?0A8`T%Ch7dfF_kJ/F(o_=@;TRt/0JA2@s)X0@;[32AS`K2F`MG8F"SS6F`VM5DIdI&F(HJ(Df031ALnsGASc1*F!,X;C`m\;ATVX/D'3q7DI[BkF`):P+D#G)D'3n.E+rm$+DG7oF_kc5+DbV!FEMXU+DG^9An?""ASuU4D'3D2F>t@;]UiFu7BleB1EHPh8AS,Og@qg%-E\&>FASc(%+DbV!FEMXIAmoglBju4++E_^B@4WO0FE$Ci=>:ASu4!+E_cK@<,k#/g*o3Ci!Ns+CT)#EHP],+CTD*F_)\0DBNA.@s&o8F`V&,E+sDF+DG@/FE2):FD5`;AKZ/-Ch[u6Bl8$(Eb'<0/g*u2DeX)3F`\aDF_kl&+ELt(BlnH2F"AGFAnGaeBlnK<+DkP0EbTS;F(Jl5+Cno"Bju4++Dbt:ASj%B;g!/#ASu$mF)tn8Ch7N-An>dmF"AGN@;KLrF^\fh+DG@/DfT?%+EM+)/0K+YCiFN=@-F(Jj'ATW'8+EV12CiseACgggfDJdmF!,@=DCco@Bk)7-D'3n.E+rm$/g*Q#DIm<#D..O.BlbD5@:OG$+CoV//0JMG+Eh16Bm"J>De*R#+DG7oF_kc5+CT@E+B*E(E+NotBle?,+E27@ASuU(/g*ksARf:h@<3Q&FWbO0F`M2;+ED.6DI[g1+DkP.F($2%BkMi.+DkP3Bl/!6+EMI;Ch[BnFEM,.DBNY(+Du+8+CT;#FY4e8ARlp+Ci!Ns@rHC,ATAo6BQ%cuF`S[B@2EcZAE+Dtb1F_)\0DBNn:EccD;FDl1P$497FF(8c(AS5RqFCB55F(K22DJsD8Ch[?iEc3(@F`_YHD'3G%F_>DsFi++Dbt:ASiPu+EV=8@qfIrDKIKR;g!/#ASu$mF)tn8D..6lF*1o%@3B-&FD/X6,BlbmL;g!/#ASu$mF)tn8F(Jl)CiAF6/0JM:ATT&,ATDX!DKL#<+Dbb)F_kJ/G%G`:Bju4$F_r`R76+EMI;Ch[BnFEM,.DBNk.Bl>,/F`VYC/0K"JFFC?;&BkM,D/Ws'+Dtb#+Co1pD(Zr0ARlp)BlkJ+D.Rf3A8,OqF_r7>Earf9+Ad)eATMF#FFD..'p@3B`)F*),*F_l2;+D#A#BkCpoA1f!"F_kl&+CT@7@u4Ecc5?+EhI@@:^u4@rH7+AT;j$Fl7@;R-)Df-\=@:s:rFD5eK+Am8qF)c>6+EhIBATDg"+D#S3F!,X?FCA`'@,DK]H)Ch[rC+BBl5OGoBju4$F_r70DKKG4BlJ-9D'3eEc,;:+CSb&Cgh7&AS#s+Ch7*uF`T/X:i]uUF(K62+EV13E,Tb>G%#E*F`S[:GUstY@qBIfEbTT7F_)\:Des6(@qg%-A8,p(A9DT/AmoglBju4++D#[J+A$GnBOu'lEb09*FDJsD8G%GK(F=n\4BOPsnCi"68+DG@/CgggrF!,F?EccD;FDl1N+EDUHEcl4A@<,k#+CT@C+E2@4FD5l7+Co1pD(Zr-ASc0oDKKH2EHPh8Bk/?*BOPpmFE1e4Ch7N9+DG@/B6%F(Bk1WpASu4!/d_q^Ec5Z0+CQC$DKKG4F(8ctATDL+EHPhD+Co2!DJ=05Bl+u/BkMR)@3BW&A1SjFEbTT:BlS9,+CT;#FY4e2@:`q[DIIT/E,Tf?ATD?)@rH6qBl.F!FEMFCF`MA./0JMH+Cf>-F(Jj'ATW'8+Dtn7Bcq82Ch7[0Bk8DuF=n\2F_kl&D'3n2A0?&,Ch[u6@:LF'ASc(&+E27>FC?;%Df'?0A8a(C6uQsS@j#c6BlbD5BkMR)@3BW&A0>c(F(lb,Df'?0A8`T%Ch7dfF_kJ/F(o_=@;TRt/0JA2@s)X0@;[32AS`K2F`MG8F"SS6F`VM5DIdI&F(HJ(Df031ALnsGASc1*F!,X;C`m\;ATVX/D'3q7DI[BkF`):P+D#G)D'3n.E+rm$+DG7oF_kc5+DbV!FEMXU+DG^9An?""ASuU4D'3D2F>t@;]UiFu7BleB1EHPh8AS,Og@qg%-E\&>FASc(%+DbV!FEMXIAmoglBju4++E_^B@4WO0FE$Ci=>:ASu4!+E_cK@<,k#/g*o3Ci!Ns+CT)#EHP],+CTD*F_)\0DBNA.@s&o8F`V&,E+sDF+DG@/FE2):FD5`;AKZ/-Ch[u6Bl8$(Eb'<0/g*u2DeX)3F`\aDF_kl&+ELt(BlnH2F"AGFAnGaeBlnK<+DkP0EbTS;F(Jl5+Cno"Bju4++Dbt:ASj%B;g!/#ASu$mF)tn8Ch7N-An>dmF"AGN@;KLrF^\fh+DG@/DfT?%+EM+)/0K+YCiFN=@ + | 'time'=874ms;;;; diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-custom-section-header-and-large-encoded-payload-with-no-delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-custom-section-header-and-large-encoded-payload-with-no-delimiters.txt new file mode 100644 index 0000000..cea2f8f --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-custom-section-header-and-large-encoded-payload-with-no-delimiters.txt @@ -0,0 +1,26 @@ +OK: Datastore HUSVM-DC1-vol6 space usage (0 VMs) is 0.01% of 18.0TB with 18.0TB remaining [WARNING: 90% , CRITICAL: 95%] +**THRESHOLDS** + +* CRITICAL: 95% datastore usage +* WARNING: 90% datastore usage + +**DETAILED INFO** + +Datastore Space Summary: + +* Name: HUSVM-DC1-vol6 +* Space Used: 2.3GB (0.01%) +* Space Remaining: 18.0TB (99.99%) +* VMs: 0 + + +--- + +* vSphere environment: https://vc1.example.com:443/sdk +* Plugin User Agent: check-vmware/v0.30.6-0-g25fdcdc + + +**PAYLOAD FOR LATER API USE** + +9Q+r_D'3P3F*2=BA8c:&EZfF;F-F(Jj'ATW'8+EV12CiseACgggfDJdmF!,@=DCco@Bk)7-D'3n.E+rm$/g*Q#DIm<#D..O.BlbD5@:OG$+CoV//0JMG+Eh16Bm"J>De*R#+DG7oF_kc5+CT@E+B*E(E+NotBle?,+E27@ASuU(/g*ksARf:h@<3Q&FWbO0F`M2;+ED.6DI[g1+DkP.F($2%BkMi.+DkP3Bl/!6+EMI;Ch[BnFEM,.DBNY(+Du+8+CT;#FY4e8ARlp+Ci!Ns@rHC,ATAo6BQ%cuF`S[B@2EcZAE+Dtb1F_)\0DBNn:EccD;FDl1P$497FF(8c(AS5RqFCB55F(K22DJsD8Ch[?iEc3(@F`_YHD'3G%F_>DsFi++Dbt:ASiPu+EV=8@qfIrDKIKR;g!/#ASu$mF)tn8D..6lF*1o%@3B-&FD/X6,BlbmL;g!/#ASu$mF)tn8F(Jl)CiAF6/0JM:ATT&,ATDX!DKL#<+Dbb)F_kJ/G%G`:Bju4$F_r`R76+EMI;Ch[BnFEM,.DBNk.Bl>,/F`VYC/0K"JFFC?;&BkM,D/Ws'+Dtb#+Co1pD(Zr0ARlp)BlkJ+D.Rf3A8,OqF_r7>Earf9+Ad)eATMF#FFD..'p@3B`)F*),*F_l2;+D#A#BkCpoA1f!"F_kl&+CT@7@u4Ecc5?+EhI@@:^u4@rH7+AT;j$Fl7@;R-)Df-\=@:s:rFD5eK+Am8qF)c>6+EhIBATDg"+D#S3F!,X?FCA`'@,DK]H)Ch[rC+BBl5OGoBju4$F_r70DKKG4BlJ-9D'3eEc,;:+CSb&Cgh7&AS#s+Ch7*uF`T/X:i]uUF(K62+EV13E,Tb>G%#E*F`S[:GUstY@qBIfEbTT7F_)\:Des6(@qg%-A8,p(A9DT/AmoglBju4++D#[J+A$GnBOu'lEb09*FDJsD8G%GK(F=n\4BOPsnCi"68+DG@/CgggrF!,F?EccD;FDl1N+EDUHEcl4A@<,k#+CT@C+E2@4FD5l7+Co1pD(Zr-ASc0oDKKH2EHPh8Bk/?*BOPpmFE1e4Ch7N9+DG@/B6%F(Bk1WpASu4!/d_q^Ec5Z0+CQC$DKKG4F(8ctATDL+EHPhD+Co2!DJ=05Bl+u/BkMR)@3BW&A1SjFEbTT:BlS9,+CT;#FY4e2@:`q[DIIT/E,Tf?ATD?)@rH6qBl.F!FEMFCF`MA./0JMH+Cf>-F(Jj'ATW'8+Dtn7Bcq82Ch7[0Bk8DuF=n\2F_kl&D'3n2A0?&,Ch[u6@:LF'ASc(&+E27>FC?;%Df'?0A8a(C6uQsS@j#c6BlbD5BkMR)@3BW&A0>c(F(lb,Df'?0A8`T%Ch7dfF_kJ/F(o_=@;TRt/0JA2@s)X0@;[32AS`K2F`MG8F"SS6F`VM5DIdI&F(HJ(Df031ALnsGASc1*F!,X;C`m\;ATVX/D'3q7DI[BkF`):P+D#G)D'3n.E+rm$+DG7oF_kc5+DbV!FEMXU+DG^9An?""ASuU4D'3D2F>t@;]UiFu7BleB1EHPh8AS,Og@qg%-E\&>FASc(%+DbV!FEMXIAmoglBju4++E_^B@4WO0FE$Ci=>:ASu4!+E_cK@<,k#/g*o3Ci!Ns+CT)#EHP],+CTD*F_)\0DBNA.@s&o8F`V&,E+sDF+DG@/FE2):FD5`;AKZ/-Ch[u6Bl8$(Eb'<0/g*u2DeX)3F`\aDF_kl&+ELt(BlnH2F"AGFAnGaeBlnK<+DkP0EbTS;F(Jl5+Cno"Bju4++Dbt:ASj%B;g!/#ASu$mF)tn8Ch7N-An>dmF"AGN@;KLrF^\fh+DG@/DfT?%+EM+)/0K+YCiFN=@ + | 'time'=874ms;;;; diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-custom-section-header-and-small-encoded-json-payload-with-no-delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-custom-section-header-and-small-encoded-json-payload-with-no-delimiters.txt new file mode 100644 index 0000000..e7754d6 --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-custom-section-header-and-small-encoded-json-payload-with-no-delimiters.txt @@ -0,0 +1,26 @@ +OK: Datastore HUSVM-DC1-vol6 space usage (0 VMs) is 0.01% of 18.0TB with 18.0TB remaining [WARNING: 90% , CRITICAL: 95%] +**THRESHOLDS** + +* CRITICAL: 95% datastore usage +* WARNING: 90% datastore usage + +**DETAILED INFO** + +Datastore Space Summary: + +* Name: HUSVM-DC1-vol6 +* Space Used: 2.3GB (0.01%) +* Space Remaining: 18.0TB (99.99%) +* VMs: 0 + + +--- + +* vSphere environment: https://vc1.example.com:443/sdk +* Plugin User Agent: check-vmware/v0.30.6-0-g25fdcdc + + +**PAYLOAD FOR LATER API USE** + +HQkagAKj/i2_6.EDKKH1ATMs7,!&pP@W-1#F!<.ZB45XgF!<.X,"$BrF*(i,+B*ArGTpFA + | 'time'=874ms;;;; diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-custom-section-header-and-small-encoded-plaintext-payload-with-custom-delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-custom-section-header-and-small-encoded-plaintext-payload-with-custom-delimiters.txt new file mode 100644 index 0000000..630581d --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-custom-section-header-and-small-encoded-plaintext-payload-with-custom-delimiters.txt @@ -0,0 +1,26 @@ +OK: Datastore HUSVM-DC1-vol6 space usage (0 VMs) is 0.01% of 18.0TB with 18.0TB remaining [WARNING: 90% , CRITICAL: 95%] +**THRESHOLDS** + +* CRITICAL: 95% datastore usage +* WARNING: 90% datastore usage + +**DETAILED INFO** + +Datastore Space Summary: + +* Name: HUSVM-DC1-vol6 +* Space Used: 2.3GB (0.01%) +* Space Remaining: 18.0TB (99.99%) +* VMs: 0 + + +--- + +* vSphere environment: https://vc1.example.com:443/sdk +* Plugin User Agent: check-vmware/v0.30.6-0-g25fdcdc + + +**PAYLOAD FOR LATER API USE** + +CUSTOM_ENCODING_DELIMITER_LEFT87cURD_*#4DfTZ)+TMKBCUSTOM_ENCODING_DELIMITER_RIGHT + | 'time'=874ms;;;; diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-custom-section-header-and-small-encoded-plaintext-payload-with-default-delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-custom-section-header-and-small-encoded-plaintext-payload-with-default-delimiters.txt new file mode 100644 index 0000000..b7e9386 --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-custom-section-header-and-small-encoded-plaintext-payload-with-default-delimiters.txt @@ -0,0 +1,26 @@ +OK: Datastore HUSVM-DC1-vol6 space usage (0 VMs) is 0.01% of 18.0TB with 18.0TB remaining [WARNING: 90% , CRITICAL: 95%] +**THRESHOLDS** + +* CRITICAL: 95% datastore usage +* WARNING: 90% datastore usage + +**DETAILED INFO** + +Datastore Space Summary: + +* Name: HUSVM-DC1-vol6 +* Space Used: 2.3GB (0.01%) +* Space Remaining: 18.0TB (99.99%) +* VMs: 0 + + +--- + +* vSphere environment: https://vc1.example.com:443/sdk +* Plugin User Agent: check-vmware/v0.30.6-0-g25fdcdc + + +**PAYLOAD FOR LATER API USE** + +<~87cURD_*#4DfTZ)+TMKB~> + | 'time'=874ms;;;; diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-custom-section-header-and-small-encoded-plaintext-payload-with-no-delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-custom-section-header-and-small-encoded-plaintext-payload-with-no-delimiters.txt new file mode 100644 index 0000000..987051b --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-custom-section-header-and-small-encoded-plaintext-payload-with-no-delimiters.txt @@ -0,0 +1,26 @@ +OK: Datastore HUSVM-DC1-vol6 space usage (0 VMs) is 0.01% of 18.0TB with 18.0TB remaining [WARNING: 90% , CRITICAL: 95%] +**THRESHOLDS** + +* CRITICAL: 95% datastore usage +* WARNING: 90% datastore usage + +**DETAILED INFO** + +Datastore Space Summary: + +* Name: HUSVM-DC1-vol6 +* Space Used: 2.3GB (0.01%) +* Space Remaining: 18.0TB (99.99%) +* VMs: 0 + + +--- + +* vSphere environment: https://vc1.example.com:443/sdk +* Plugin User Agent: check-vmware/v0.30.6-0-g25fdcdc + + +**PAYLOAD FOR LATER API USE** + +87cURD_*#4DfTZ)+TMKB + | 'time'=874ms;;;; diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-large-encoded-payload-with-custom-delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-large-encoded-payload-with-custom-delimiters.txt new file mode 100644 index 0000000..8cbf179 --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-large-encoded-payload-with-custom-delimiters.txt @@ -0,0 +1,26 @@ +OK: Datastore HUSVM-DC1-vol6 space usage (0 VMs) is 0.01% of 18.0TB with 18.0TB remaining [WARNING: 90% , CRITICAL: 95%] +**THRESHOLDS** + +* CRITICAL: 95% datastore usage +* WARNING: 90% datastore usage + +**DETAILED INFO** + +Datastore Space Summary: + +* Name: HUSVM-DC1-vol6 +* Space Used: 2.3GB (0.01%) +* Space Remaining: 18.0TB (99.99%) +* VMs: 0 + + +--- + +* vSphere environment: https://vc1.example.com:443/sdk +* Plugin User Agent: check-vmware/v0.30.6-0-g25fdcdc + + +**ENCODED PAYLOAD** + +CUSTOM_ENCODING_DELIMITER_LEFT9Q+r_D'3P3F*2=BA8c:&EZfF;F-F(Jj'ATW'8+EV12CiseACgggfDJdmF!,@=DCco@Bk)7-D'3n.E+rm$/g*Q#DIm<#D..O.BlbD5@:OG$+CoV//0JMG+Eh16Bm"J>De*R#+DG7oF_kc5+CT@E+B*E(E+NotBle?,+E27@ASuU(/g*ksARf:h@<3Q&FWbO0F`M2;+ED.6DI[g1+DkP.F($2%BkMi.+DkP3Bl/!6+EMI;Ch[BnFEM,.DBNY(+Du+8+CT;#FY4e8ARlp+Ci!Ns@rHC,ATAo6BQ%cuF`S[B@2EcZAE+Dtb1F_)\0DBNn:EccD;FDl1P$497FF(8c(AS5RqFCB55F(K22DJsD8Ch[?iEc3(@F`_YHD'3G%F_>DsFi++Dbt:ASiPu+EV=8@qfIrDKIKR;g!/#ASu$mF)tn8D..6lF*1o%@3B-&FD/X6,BlbmL;g!/#ASu$mF)tn8F(Jl)CiAF6/0JM:ATT&,ATDX!DKL#<+Dbb)F_kJ/G%G`:Bju4$F_r`R76+EMI;Ch[BnFEM,.DBNk.Bl>,/F`VYC/0K"JFFC?;&BkM,D/Ws'+Dtb#+Co1pD(Zr0ARlp)BlkJ+D.Rf3A8,OqF_r7>Earf9+Ad)eATMF#FFD..'p@3B`)F*),*F_l2;+D#A#BkCpoA1f!"F_kl&+CT@7@u4Ecc5?+EhI@@:^u4@rH7+AT;j$Fl7@;R-)Df-\=@:s:rFD5eK+Am8qF)c>6+EhIBATDg"+D#S3F!,X?FCA`'@,DK]H)Ch[rC+BBl5OGoBju4$F_r70DKKG4BlJ-9D'3eEc,;:+CSb&Cgh7&AS#s+Ch7*uF`T/X:i]uUF(K62+EV13E,Tb>G%#E*F`S[:GUstY@qBIfEbTT7F_)\:Des6(@qg%-A8,p(A9DT/AmoglBju4++D#[J+A$GnBOu'lEb09*FDJsD8G%GK(F=n\4BOPsnCi"68+DG@/CgggrF!,F?EccD;FDl1N+EDUHEcl4A@<,k#+CT@C+E2@4FD5l7+Co1pD(Zr-ASc0oDKKH2EHPh8Bk/?*BOPpmFE1e4Ch7N9+DG@/B6%F(Bk1WpASu4!/d_q^Ec5Z0+CQC$DKKG4F(8ctATDL+EHPhD+Co2!DJ=05Bl+u/BkMR)@3BW&A1SjFEbTT:BlS9,+CT;#FY4e2@:`q[DIIT/E,Tf?ATD?)@rH6qBl.F!FEMFCF`MA./0JMH+Cf>-F(Jj'ATW'8+Dtn7Bcq82Ch7[0Bk8DuF=n\2F_kl&D'3n2A0?&,Ch[u6@:LF'ASc(&+E27>FC?;%Df'?0A8a(C6uQsS@j#c6BlbD5BkMR)@3BW&A0>c(F(lb,Df'?0A8`T%Ch7dfF_kJ/F(o_=@;TRt/0JA2@s)X0@;[32AS`K2F`MG8F"SS6F`VM5DIdI&F(HJ(Df031ALnsGASc1*F!,X;C`m\;ATVX/D'3q7DI[BkF`):P+D#G)D'3n.E+rm$+DG7oF_kc5+DbV!FEMXU+DG^9An?""ASuU4D'3D2F>t@;]UiFu7BleB1EHPh8AS,Og@qg%-E\&>FASc(%+DbV!FEMXIAmoglBju4++E_^B@4WO0FE$Ci=>:ASu4!+E_cK@<,k#/g*o3Ci!Ns+CT)#EHP],+CTD*F_)\0DBNA.@s&o8F`V&,E+sDF+DG@/FE2):FD5`;AKZ/-Ch[u6Bl8$(Eb'<0/g*u2DeX)3F`\aDF_kl&+ELt(BlnH2F"AGFAnGaeBlnK<+DkP0EbTS;F(Jl5+Cno"Bju4++Dbt:ASj%B;g!/#ASu$mF)tn8Ch7N-An>dmF"AGN@;KLrF^\fh+DG@/DfT?%+EM+)/0K+YCiFN=@-F(Jj'ATW'8+EV12CiseACgggfDJdmF!,@=DCco@Bk)7-D'3n.E+rm$/g*Q#DIm<#D..O.BlbD5@:OG$+CoV//0JMG+Eh16Bm"J>De*R#+DG7oF_kc5+CT@E+B*E(E+NotBle?,+E27@ASuU(/g*ksARf:h@<3Q&FWbO0F`M2;+ED.6DI[g1+DkP.F($2%BkMi.+DkP3Bl/!6+EMI;Ch[BnFEM,.DBNY(+Du+8+CT;#FY4e8ARlp+Ci!Ns@rHC,ATAo6BQ%cuF`S[B@2EcZAE+Dtb1F_)\0DBNn:EccD;FDl1P$497FF(8c(AS5RqFCB55F(K22DJsD8Ch[?iEc3(@F`_YHD'3G%F_>DsFi++Dbt:ASiPu+EV=8@qfIrDKIKR;g!/#ASu$mF)tn8D..6lF*1o%@3B-&FD/X6,BlbmL;g!/#ASu$mF)tn8F(Jl)CiAF6/0JM:ATT&,ATDX!DKL#<+Dbb)F_kJ/G%G`:Bju4$F_r`R76+EMI;Ch[BnFEM,.DBNk.Bl>,/F`VYC/0K"JFFC?;&BkM,D/Ws'+Dtb#+Co1pD(Zr0ARlp)BlkJ+D.Rf3A8,OqF_r7>Earf9+Ad)eATMF#FFD..'p@3B`)F*),*F_l2;+D#A#BkCpoA1f!"F_kl&+CT@7@u4Ecc5?+EhI@@:^u4@rH7+AT;j$Fl7@;R-)Df-\=@:s:rFD5eK+Am8qF)c>6+EhIBATDg"+D#S3F!,X?FCA`'@,DK]H)Ch[rC+BBl5OGoBju4$F_r70DKKG4BlJ-9D'3eEc,;:+CSb&Cgh7&AS#s+Ch7*uF`T/X:i]uUF(K62+EV13E,Tb>G%#E*F`S[:GUstY@qBIfEbTT7F_)\:Des6(@qg%-A8,p(A9DT/AmoglBju4++D#[J+A$GnBOu'lEb09*FDJsD8G%GK(F=n\4BOPsnCi"68+DG@/CgggrF!,F?EccD;FDl1N+EDUHEcl4A@<,k#+CT@C+E2@4FD5l7+Co1pD(Zr-ASc0oDKKH2EHPh8Bk/?*BOPpmFE1e4Ch7N9+DG@/B6%F(Bk1WpASu4!/d_q^Ec5Z0+CQC$DKKG4F(8ctATDL+EHPhD+Co2!DJ=05Bl+u/BkMR)@3BW&A1SjFEbTT:BlS9,+CT;#FY4e2@:`q[DIIT/E,Tf?ATD?)@rH6qBl.F!FEMFCF`MA./0JMH+Cf>-F(Jj'ATW'8+Dtn7Bcq82Ch7[0Bk8DuF=n\2F_kl&D'3n2A0?&,Ch[u6@:LF'ASc(&+E27>FC?;%Df'?0A8a(C6uQsS@j#c6BlbD5BkMR)@3BW&A0>c(F(lb,Df'?0A8`T%Ch7dfF_kJ/F(o_=@;TRt/0JA2@s)X0@;[32AS`K2F`MG8F"SS6F`VM5DIdI&F(HJ(Df031ALnsGASc1*F!,X;C`m\;ATVX/D'3q7DI[BkF`):P+D#G)D'3n.E+rm$+DG7oF_kc5+DbV!FEMXU+DG^9An?""ASuU4D'3D2F>t@;]UiFu7BleB1EHPh8AS,Og@qg%-E\&>FASc(%+DbV!FEMXIAmoglBju4++E_^B@4WO0FE$Ci=>:ASu4!+E_cK@<,k#/g*o3Ci!Ns+CT)#EHP],+CTD*F_)\0DBNA.@s&o8F`V&,E+sDF+DG@/FE2):FD5`;AKZ/-Ch[u6Bl8$(Eb'<0/g*u2DeX)3F`\aDF_kl&+ELt(BlnH2F"AGFAnGaeBlnK<+DkP0EbTS;F(Jl5+Cno"Bju4++Dbt:ASj%B;g!/#ASu$mF)tn8Ch7N-An>dmF"AGN@;KLrF^\fh+DG@/DfT?%+EM+)/0K+YCiFN=@ + | 'time'=874ms;;;; diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-large-encoded-payload-with-no-delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-large-encoded-payload-with-no-delimiters.txt new file mode 100644 index 0000000..497040b --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-large-encoded-payload-with-no-delimiters.txt @@ -0,0 +1,26 @@ +OK: Datastore HUSVM-DC1-vol6 space usage (0 VMs) is 0.01% of 18.0TB with 18.0TB remaining [WARNING: 90% , CRITICAL: 95%] +**THRESHOLDS** + +* CRITICAL: 95% datastore usage +* WARNING: 90% datastore usage + +**DETAILED INFO** + +Datastore Space Summary: + +* Name: HUSVM-DC1-vol6 +* Space Used: 2.3GB (0.01%) +* Space Remaining: 18.0TB (99.99%) +* VMs: 0 + + +--- + +* vSphere environment: https://vc1.example.com:443/sdk +* Plugin User Agent: check-vmware/v0.30.6-0-g25fdcdc + + +**ENCODED PAYLOAD** + +9Q+r_D'3P3F*2=BA8c:&EZfF;F-F(Jj'ATW'8+EV12CiseACgggfDJdmF!,@=DCco@Bk)7-D'3n.E+rm$/g*Q#DIm<#D..O.BlbD5@:OG$+CoV//0JMG+Eh16Bm"J>De*R#+DG7oF_kc5+CT@E+B*E(E+NotBle?,+E27@ASuU(/g*ksARf:h@<3Q&FWbO0F`M2;+ED.6DI[g1+DkP.F($2%BkMi.+DkP3Bl/!6+EMI;Ch[BnFEM,.DBNY(+Du+8+CT;#FY4e8ARlp+Ci!Ns@rHC,ATAo6BQ%cuF`S[B@2EcZAE+Dtb1F_)\0DBNn:EccD;FDl1P$497FF(8c(AS5RqFCB55F(K22DJsD8Ch[?iEc3(@F`_YHD'3G%F_>DsFi++Dbt:ASiPu+EV=8@qfIrDKIKR;g!/#ASu$mF)tn8D..6lF*1o%@3B-&FD/X6,BlbmL;g!/#ASu$mF)tn8F(Jl)CiAF6/0JM:ATT&,ATDX!DKL#<+Dbb)F_kJ/G%G`:Bju4$F_r`R76+EMI;Ch[BnFEM,.DBNk.Bl>,/F`VYC/0K"JFFC?;&BkM,D/Ws'+Dtb#+Co1pD(Zr0ARlp)BlkJ+D.Rf3A8,OqF_r7>Earf9+Ad)eATMF#FFD..'p@3B`)F*),*F_l2;+D#A#BkCpoA1f!"F_kl&+CT@7@u4Ecc5?+EhI@@:^u4@rH7+AT;j$Fl7@;R-)Df-\=@:s:rFD5eK+Am8qF)c>6+EhIBATDg"+D#S3F!,X?FCA`'@,DK]H)Ch[rC+BBl5OGoBju4$F_r70DKKG4BlJ-9D'3eEc,;:+CSb&Cgh7&AS#s+Ch7*uF`T/X:i]uUF(K62+EV13E,Tb>G%#E*F`S[:GUstY@qBIfEbTT7F_)\:Des6(@qg%-A8,p(A9DT/AmoglBju4++D#[J+A$GnBOu'lEb09*FDJsD8G%GK(F=n\4BOPsnCi"68+DG@/CgggrF!,F?EccD;FDl1N+EDUHEcl4A@<,k#+CT@C+E2@4FD5l7+Co1pD(Zr-ASc0oDKKH2EHPh8Bk/?*BOPpmFE1e4Ch7N9+DG@/B6%F(Bk1WpASu4!/d_q^Ec5Z0+CQC$DKKG4F(8ctATDL+EHPhD+Co2!DJ=05Bl+u/BkMR)@3BW&A1SjFEbTT:BlS9,+CT;#FY4e2@:`q[DIIT/E,Tf?ATD?)@rH6qBl.F!FEMFCF`MA./0JMH+Cf>-F(Jj'ATW'8+Dtn7Bcq82Ch7[0Bk8DuF=n\2F_kl&D'3n2A0?&,Ch[u6@:LF'ASc(&+E27>FC?;%Df'?0A8a(C6uQsS@j#c6BlbD5BkMR)@3BW&A0>c(F(lb,Df'?0A8`T%Ch7dfF_kJ/F(o_=@;TRt/0JA2@s)X0@;[32AS`K2F`MG8F"SS6F`VM5DIdI&F(HJ(Df031ALnsGASc1*F!,X;C`m\;ATVX/D'3q7DI[BkF`):P+D#G)D'3n.E+rm$+DG7oF_kc5+DbV!FEMXU+DG^9An?""ASuU4D'3D2F>t@;]UiFu7BleB1EHPh8AS,Og@qg%-E\&>FASc(%+DbV!FEMXIAmoglBju4++E_^B@4WO0FE$Ci=>:ASu4!+E_cK@<,k#/g*o3Ci!Ns+CT)#EHP],+CTD*F_)\0DBNA.@s&o8F`V&,E+sDF+DG@/FE2):FD5`;AKZ/-Ch[u6Bl8$(Eb'<0/g*u2DeX)3F`\aDF_kl&+ELt(BlnH2F"AGFAnGaeBlnK<+DkP0EbTS;F(Jl5+Cno"Bju4++Dbt:ASj%B;g!/#ASu$mF)tn8Ch7N-An>dmF"AGN@;KLrF^\fh+DG@/DfT?%+EM+)/0K+YCiFN=@ + | 'time'=874ms;;;; diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-small-encoded-json-payload-with-no-delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-small-encoded-json-payload-with-no-delimiters.txt new file mode 100644 index 0000000..c619fac --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-small-encoded-json-payload-with-no-delimiters.txt @@ -0,0 +1,26 @@ +OK: Datastore HUSVM-DC1-vol6 space usage (0 VMs) is 0.01% of 18.0TB with 18.0TB remaining [WARNING: 90% , CRITICAL: 95%] +**THRESHOLDS** + +* CRITICAL: 95% datastore usage +* WARNING: 90% datastore usage + +**DETAILED INFO** + +Datastore Space Summary: + +* Name: HUSVM-DC1-vol6 +* Space Used: 2.3GB (0.01%) +* Space Remaining: 18.0TB (99.99%) +* VMs: 0 + + +--- + +* vSphere environment: https://vc1.example.com:443/sdk +* Plugin User Agent: check-vmware/v0.30.6-0-g25fdcdc + + +**ENCODED PAYLOAD** + +HQkagAKj/i2_6.EDKKH1ATMs7,!&pP@W-1#F!<.ZB45XgF!<.X,"$BrF*(i,+B*ArGTpFA + | 'time'=874ms;;;; diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-small-encoded-plaintext-payload-with-custom-delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-small-encoded-plaintext-payload-with-custom-delimiters.txt new file mode 100644 index 0000000..8ea881d --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-small-encoded-plaintext-payload-with-custom-delimiters.txt @@ -0,0 +1,26 @@ +OK: Datastore HUSVM-DC1-vol6 space usage (0 VMs) is 0.01% of 18.0TB with 18.0TB remaining [WARNING: 90% , CRITICAL: 95%] +**THRESHOLDS** + +* CRITICAL: 95% datastore usage +* WARNING: 90% datastore usage + +**DETAILED INFO** + +Datastore Space Summary: + +* Name: HUSVM-DC1-vol6 +* Space Used: 2.3GB (0.01%) +* Space Remaining: 18.0TB (99.99%) +* VMs: 0 + + +--- + +* vSphere environment: https://vc1.example.com:443/sdk +* Plugin User Agent: check-vmware/v0.30.6-0-g25fdcdc + + +**ENCODED PAYLOAD** + +CUSTOM_ENCODING_DELIMITER_LEFT87cURD_*#4DfTZ)+TMKBCUSTOM_ENCODING_DELIMITER_RIGHT + | 'time'=874ms;;;; diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-small-encoded-plaintext-payload-with-default-delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-small-encoded-plaintext-payload-with-default-delimiters.txt new file mode 100644 index 0000000..fef8f42 --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-small-encoded-plaintext-payload-with-default-delimiters.txt @@ -0,0 +1,26 @@ +OK: Datastore HUSVM-DC1-vol6 space usage (0 VMs) is 0.01% of 18.0TB with 18.0TB remaining [WARNING: 90% , CRITICAL: 95%] +**THRESHOLDS** + +* CRITICAL: 95% datastore usage +* WARNING: 90% datastore usage + +**DETAILED INFO** + +Datastore Space Summary: + +* Name: HUSVM-DC1-vol6 +* Space Used: 2.3GB (0.01%) +* Space Remaining: 18.0TB (99.99%) +* VMs: 0 + + +--- + +* vSphere environment: https://vc1.example.com:443/sdk +* Plugin User Agent: check-vmware/v0.30.6-0-g25fdcdc + + +**ENCODED PAYLOAD** + +<~87cURD_*#4DfTZ)+TMKB~> + | 'time'=874ms;;;; diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-small-encoded-plaintext-payload-with-no-delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-small-encoded-plaintext-payload-with-no-delimiters.txt new file mode 100644 index 0000000..8447bca --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/plugin-output-gh251-default-section-header-and-small-encoded-plaintext-payload-with-no-delimiters.txt @@ -0,0 +1,26 @@ +OK: Datastore HUSVM-DC1-vol6 space usage (0 VMs) is 0.01% of 18.0TB with 18.0TB remaining [WARNING: 90% , CRITICAL: 95%] +**THRESHOLDS** + +* CRITICAL: 95% datastore usage +* WARNING: 90% datastore usage + +**DETAILED INFO** + +Datastore Space Summary: + +* Name: HUSVM-DC1-vol6 +* Space Used: 2.3GB (0.01%) +* Space Remaining: 18.0TB (99.99%) +* VMs: 0 + + +--- + +* vSphere environment: https://vc1.example.com:443/sdk +* Plugin User Agent: check-vmware/v0.30.6-0-g25fdcdc + + +**ENCODED PAYLOAD** + +87cURD_*#4DfTZ)+TMKB + | 'time'=874ms;;;; diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/small_json_payload_encoded_with_custom_delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/small_json_payload_encoded_with_custom_delimiters.txt new file mode 100644 index 0000000..859a1f0 --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/small_json_payload_encoded_with_custom_delimiters.txt @@ -0,0 +1 @@ +CUSTOM_ENCODING_DELIMITER_LEFTHQkagAKj/i2_6.EDKKH1ATMs7,!&pP@W-1#F!<.ZB45XgF!<.X,"$BrF*(i,+B*ArGTpFACUSTOM_ENCODING_DELIMITER_RIGHT \ No newline at end of file diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/small_json_payload_encoded_with_default_delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/small_json_payload_encoded_with_default_delimiters.txt new file mode 100644 index 0000000..3e0e50d --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/small_json_payload_encoded_with_default_delimiters.txt @@ -0,0 +1 @@ +<~HQkagAKj/i2_6.EDKKH1ATMs7,!&pP@W-1#F!<.ZB45XgF!<.X,"$BrF*(i,+B*ArGTpFA~> \ No newline at end of file diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/small_json_payload_encoded_without_delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/small_json_payload_encoded_without_delimiters.txt new file mode 100644 index 0000000..1b53fb7 --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/small_json_payload_encoded_without_delimiters.txt @@ -0,0 +1 @@ +HQkagAKj/i2_6.EDKKH1ATMs7,!&pP@W-1#F!<.ZB45XgF!<.X,"$BrF*(i,+B*ArGTpFA \ No newline at end of file diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/small_json_payload_unencoded.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/small_json_payload_unencoded.txt new file mode 100644 index 0000000..3a76778 --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/small_json_payload_unencoded.txt @@ -0,0 +1 @@ +{"Age":17,"Interests":["books","games", "Crystal Stix"]} \ No newline at end of file diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/small_plaintext_payload_encoded_with_custom_delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/small_plaintext_payload_encoded_with_custom_delimiters.txt new file mode 100644 index 0000000..94b61ad --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/small_plaintext_payload_encoded_with_custom_delimiters.txt @@ -0,0 +1 @@ +CUSTOM_ENCODING_DELIMITER_LEFT87cURD_*#4DfTZ)+TMKBCUSTOM_ENCODING_DELIMITER_RIGHT \ No newline at end of file diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/small_plaintext_payload_encoded_with_default_delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/small_plaintext_payload_encoded_with_default_delimiters.txt new file mode 100644 index 0000000..7dc110f --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/small_plaintext_payload_encoded_with_default_delimiters.txt @@ -0,0 +1 @@ +<~87cURD_*#4DfTZ)+TMKB~> \ No newline at end of file diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/small_plaintext_payload_encoded_without_delimiters.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/small_plaintext_payload_encoded_without_delimiters.txt new file mode 100644 index 0000000..0d7f36f --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/small_plaintext_payload_encoded_without_delimiters.txt @@ -0,0 +1 @@ +87cURD_*#4DfTZ)+TMKB \ No newline at end of file diff --git a/vendor/github.com/atc0005/go-nagios/testdata/payload/small_plaintext_payload_unencoded.txt b/vendor/github.com/atc0005/go-nagios/testdata/payload/small_plaintext_payload_unencoded.txt new file mode 100644 index 0000000..b45ef6f --- /dev/null +++ b/vendor/github.com/atc0005/go-nagios/testdata/payload/small_plaintext_payload_unencoded.txt @@ -0,0 +1 @@ +Hello, World! \ No newline at end of file diff --git a/vendor/github.com/atc0005/go-nagios/textutils.go b/vendor/github.com/atc0005/go-nagios/textutils.go index 572d1c7..a866df9 100644 --- a/vendor/github.com/atc0005/go-nagios/textutils.go +++ b/vendor/github.com/atc0005/go-nagios/textutils.go @@ -27,3 +27,32 @@ func inList(needle string, haystack []string, ignoreCase bool) bool { return false } + +// removeEntry is a helper function to allow removing an entry or "line" from +// input which matches a given substring. The specified delimiter is used to +// perform the initial line splitting for entry removal and then to rejoin the +// elements into the original input string (minus the intended entry to +// remove). +func removeEntry(input string, substr string, delimiter string) string { + if len(input) == 0 || len(substr) == 0 || len(delimiter) == 0 { + return input + } + + // https://stackoverflow.com/a/57213476/903870 + removeAtIndex := func(s []string, index int) []string { + // ret := make([]string, 0) + ret := make([]string, 0, len(s)-1) + ret = append(ret, s[:index]...) + return append(ret, s[index+1:]...) + } + + lines := strings.Split(input, delimiter) + var idxToRemove int + for idx, line := range lines { + if strings.Contains(line, substr) { + idxToRemove = idx + } + } + + return strings.Join(removeAtIndex(lines, idxToRemove), delimiter) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 4d71aca..bf66297 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,4 +1,4 @@ -# github.com/atc0005/go-nagios v0.16.1 +# github.com/atc0005/go-nagios v0.17.1 ## explicit; go 1.19 github.com/atc0005/go-nagios # github.com/mattn/go-colorable v0.1.13