From 22f19f59614e6f06a118b93139e10dc455111c35 Mon Sep 17 00:00:00 2001 From: lorenzg Date: Thu, 27 Aug 2026 16:45:00 +0200 Subject: [PATCH 1/3] add wildcard support for check_service excludes --- docs/checks/commands/check_service_linux.md | 2 +- docs/checks/commands/check_service_windows.md | 2 +- pkg/snclient/check_service_common.go | 17 ++++++++++++++++- pkg/snclient/check_service_linux.go | 4 ++-- pkg/snclient/check_service_linux_test.go | 5 +++++ pkg/snclient/check_service_windows.go | 4 ++-- pkg/snclient/check_service_windows_test.go | 5 +++++ 7 files changed, 32 insertions(+), 7 deletions(-) diff --git a/docs/checks/commands/check_service_linux.md b/docs/checks/commands/check_service_linux.md index 91394ce1..dd69be95 100644 --- a/docs/checks/commands/check_service_linux.md +++ b/docs/checks/commands/check_service_linux.md @@ -69,7 +69,7 @@ Naemon Config | Argument | Description | | -------- | ----------------------------------------------------------------------------------------------------- | -| exclude | List of services to exclude from the check (mainly used when service is set to \*) (case insensitive) | +| 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..04d2f815 100755 --- a/docs/checks/commands/check_service_windows.md +++ b/docs/checks/commands/check_service_windows.md @@ -65,7 +65,7 @@ Naemon Config | Argument | Description | | -------- | ----------------------------------------------------------------------------------------------------- | -| exclude | List of services to exclude from the check (mainly used when service is set to \*) (case insensitive) | +| 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_linux_test.go b/pkg/snclient/check_service_linux_test.go index 6ca7578d..496ae3b7 100644 --- a/pkg/snclient/check_service_linux_test.go +++ b/pkg/snclient/check_service_linux_test.go @@ -31,6 +31,11 @@ func TestCheckServiceLinux(t *testing.T) { assert.Containsf(t, string(res.BuildPluginOutput()), "UNKNOWN - could not find service: nonexistingservice", "output matches") } +func TestCheckServiceLinuxExcludeWildcard(t *testing.T) { + assert.True(t, matchesServiceExclude([]string{"Wildcard*"}, "Wildcard")) + assert.True(t, matchesServiceExclude([]string{"Wildcard*"}, "WildcardTest")) +} + func TestCheckServiceLinuxSystemCtlOutput_1(t *testing.T) { output := `● blah-service.service Loaded: loaded (/usr/lib/blub/blah-service.sh; enabled; preset: enabled) 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 diff --git a/pkg/snclient/check_service_windows_test.go b/pkg/snclient/check_service_windows_test.go index b5deec10..db8731da 100644 --- a/pkg/snclient/check_service_windows_test.go +++ b/pkg/snclient/check_service_windows_test.go @@ -31,3 +31,8 @@ func TestCheckService(t *testing.T) { assert.Equalf(t, CheckExitOK, res.State, "state OK") assert.Containsf(t, string(res.BuildPluginOutput()), "OK - All 1 service", "output matches") } + +func TestCheckServiceWindowsExcludeWildcard(t *testing.T) { + assert.True(t, matchesServiceExclude([]string{"Wildcard*"}, "Wildcard")) + assert.True(t, matchesServiceExclude([]string{"Wildcard*"}, "WildcardTest")) +} From fcc2ccec1732dd6f9279816b2548541723de5d20 Mon Sep 17 00:00:00 2001 From: Lorenz Gruenwald Date: Thu, 27 Aug 2026 16:59:26 +0200 Subject: [PATCH 2/3] fix docs --- docs/checks/commands/check_service_linux.md | 6 +++--- docs/checks/commands/check_service_windows.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/checks/commands/check_service_linux.md b/docs/checks/commands/check_service_linux.md index dd69be95..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 | -| -------- | ----------------------------------------------------------------------------------------------------- | +| 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: \* | +| 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 04d2f815..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 | -| -------- | ----------------------------------------------------------------------------------------------------- | +| 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: \* | +| service | List of services to check (set to \* to check all services). (case insensitive) Default: \* | ## Attributes From 702aa6690813371eff9d69d9141b117018b87268 Mon Sep 17 00:00:00 2001 From: lorenzg Date: Mon, 31 Aug 2026 15:02:57 +0200 Subject: [PATCH 3/3] cleanup tests --- pkg/snclient/check_service_linux_test.go | 5 ----- pkg/snclient/check_service_test.go | 14 ++++++++++++++ pkg/snclient/check_service_windows_test.go | 5 ----- 3 files changed, 14 insertions(+), 10 deletions(-) create mode 100644 pkg/snclient/check_service_test.go diff --git a/pkg/snclient/check_service_linux_test.go b/pkg/snclient/check_service_linux_test.go index 496ae3b7..6ca7578d 100644 --- a/pkg/snclient/check_service_linux_test.go +++ b/pkg/snclient/check_service_linux_test.go @@ -31,11 +31,6 @@ func TestCheckServiceLinux(t *testing.T) { assert.Containsf(t, string(res.BuildPluginOutput()), "UNKNOWN - could not find service: nonexistingservice", "output matches") } -func TestCheckServiceLinuxExcludeWildcard(t *testing.T) { - assert.True(t, matchesServiceExclude([]string{"Wildcard*"}, "Wildcard")) - assert.True(t, matchesServiceExclude([]string{"Wildcard*"}, "WildcardTest")) -} - func TestCheckServiceLinuxSystemCtlOutput_1(t *testing.T) { output := `● blah-service.service Loaded: loaded (/usr/lib/blub/blah-service.sh; enabled; preset: enabled) 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_test.go b/pkg/snclient/check_service_windows_test.go index db8731da..b5deec10 100644 --- a/pkg/snclient/check_service_windows_test.go +++ b/pkg/snclient/check_service_windows_test.go @@ -31,8 +31,3 @@ func TestCheckService(t *testing.T) { assert.Equalf(t, CheckExitOK, res.State, "state OK") assert.Containsf(t, string(res.BuildPluginOutput()), "OK - All 1 service", "output matches") } - -func TestCheckServiceWindowsExcludeWildcard(t *testing.T) { - assert.True(t, matchesServiceExclude([]string{"Wildcard*"}, "Wildcard")) - assert.True(t, matchesServiceExclude([]string{"Wildcard*"}, "WildcardTest")) -}