diff --git a/docs/checks/commands/check_service_linux.md b/docs/checks/commands/check_service_linux.md index 91394ce1..4fe62f8e 100644 --- a/docs/checks/commands/check_service_linux.md +++ b/docs/checks/commands/check_service_linux.md @@ -67,10 +67,10 @@ Naemon Config ## Check Specific Arguments -| Argument | Description | -| -------- | ----------------------------------------------------------------------------------------------------- | -| exclude | List of services to exclude from the check (mainly used when service is set to \*) (case insensitive) | -| service | List of services to check (set to \* to check all services). (case insensitive) Default: \* | +| Argument | Description | +| -------- | ---------------------------------------------------------------------------------------------------------- | +| exclude | List of case-insensitive services to exclude from the check (mainly used when service is set to \*). Supports wildcards. | +| service | List of services to check (set to \* to check all services). (case insensitive) Default: \* | ## Attributes diff --git a/docs/checks/commands/check_service_windows.md b/docs/checks/commands/check_service_windows.md index 0ae2bb07..53518669 100755 --- a/docs/checks/commands/check_service_windows.md +++ b/docs/checks/commands/check_service_windows.md @@ -63,10 +63,10 @@ Naemon Config ## Check Specific Arguments -| Argument | Description | -| -------- | ----------------------------------------------------------------------------------------------------- | -| exclude | List of services to exclude from the check (mainly used when service is set to \*) (case insensitive) | -| service | List of services to check (set to \* to check all services). (case insensitive) Default: \* | +| Argument | Description | +| -------- | ---------------------------------------------------------------------------------------------------------- | +| exclude | List of case-insensitive services to exclude from the check (mainly used when service is set to \*). Supports wildcards. | +| service | List of services to check (set to \* to check all services). (case insensitive) Default: \* | ## Attributes diff --git a/pkg/snclient/check_service_common.go b/pkg/snclient/check_service_common.go index e1b9fd07..7dd94faf 100644 --- a/pkg/snclient/check_service_common.go +++ b/pkg/snclient/check_service_common.go @@ -5,6 +5,7 @@ package snclient import ( "context" "fmt" + "path" "slices" "strings" "time" @@ -163,10 +164,24 @@ func (l *CheckService) addServiceMetrics(service string, serviceState float64, c } } +// matchesServiceExclude reports whether a value matches a case-insensitive exclusion pattern, including wildcards. +func matchesServiceExclude(excludes []string, value string) bool { + value = strings.ToLower(value) + if slices.Contains(excludes, value) { + return true + } + + return slices.ContainsFunc(excludes, func(pattern string) bool { + match, err := path.Match(strings.ToLower(pattern), value) + + return err == nil && match + }) +} + func (l *CheckService) isRequired(check *CheckData, entry map[string]string, services, excludes []string) bool { name := strings.ToLower(entry["name"]) desc := strings.ToLower(entry["desc"]) - if slices.Contains(excludes, name) || slices.Contains(excludes, desc) { + if matchesServiceExclude(excludes, name) || matchesServiceExclude(excludes, desc) { log.Tracef("service %s excluded by exclude list", name) return false diff --git a/pkg/snclient/check_service_linux.go b/pkg/snclient/check_service_linux.go index c5a66125..7d448e40 100644 --- a/pkg/snclient/check_service_linux.go +++ b/pkg/snclient/check_service_linux.go @@ -66,7 +66,7 @@ There is a specific [check_service for windows](../check_service_windows) as wel description: "List of services to check (set to * to check all services). (case insensitive) Default: *", defaultCritical: stateCondition, }, - "exclude": {value: &l.excludes, description: "List of services to exclude from the check (mainly used when service is set to *) (case insensitive)"}, + "exclude": {value: &l.excludes, description: "List of case-insensitive services to exclude from the check (mainly used when service is set to *). Supports wildcards."}, }, defaultFilter: "active != inactive", defaultCritical: stateCondition + " && preset != 'disabled'", @@ -331,7 +331,7 @@ func (l *CheckService) parseAllServices(ctx context.Context, check *CheckData, o } service := serviceMatches[1] - if slices.Contains(l.excludes, strings.ToLower(service)) { + if matchesServiceExclude(l.excludes, service) { log.Tracef("service %s excluded by 'exclude' argument", service) continue diff --git a/pkg/snclient/check_service_test.go b/pkg/snclient/check_service_test.go new file mode 100644 index 00000000..c744d391 --- /dev/null +++ b/pkg/snclient/check_service_test.go @@ -0,0 +1,14 @@ +//go:build windows || linux + +package snclient + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCheckServiceExcludeWildcard(t *testing.T) { + assert.True(t, matchesServiceExclude([]string{"Wildcard*"}, "Wildcard")) + assert.True(t, matchesServiceExclude([]string{"Wildcard*"}, "WildcardTest")) +} diff --git a/pkg/snclient/check_service_windows.go b/pkg/snclient/check_service_windows.go index 8a711fa1..642a6d9f 100644 --- a/pkg/snclient/check_service_windows.go +++ b/pkg/snclient/check_service_windows.go @@ -65,7 +65,7 @@ There is a specific [check_service for linux](../check_service_linux) as well.`, defaultWarning: "state != 'running'", defaultCritical: "state != 'running'", }, - "exclude": {value: &l.excludes, description: "List of services to exclude from the check (mainly used when service is set to *) (case insensitive)"}, + "exclude": {value: &l.excludes, description: "List of case-insensitive services to exclude from the check (mainly used when service is set to *). Supports wildcards."}, }, defaultFilter: "none", defaultCritical: "state != 'running' && start_type = 'auto'", @@ -150,7 +150,7 @@ func (l *CheckService) Check(ctx context.Context, _ *Agent, check *CheckData, _ } for _, service := range serviceList { - if slices.Contains(l.excludes, strings.ToLower(strings.TrimSpace(service))) { + if matchesServiceExclude(l.excludes, strings.TrimSpace(service)) { log.Tracef("service %s excluded by 'exclude' argument", service) continue