mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-11 02:55:51 +00:00
feat(alerts): wildcard forms in docker ignored-container patterns
Bare entries keep their historical prefix semantics. Entries may now also use the wildcard forms already established by the PBS datastore excluder, so *-dev matches a suffix, *staging* a substring, and runner-* an explicit prefix. Wildcard-only entries are skipped, that job belongs to DisableAllDockerContainers. Suffix matching is what the reporter on #1601 was approximating with hundreds of per-container disable toggles, which is also what pushed their config past the old request body cap. Refs #1601 Contract-Neutral: extend docker ignored-prefix matching with wildcard forms; no schema or payload changes
This commit is contained in:
@@ -3639,6 +3639,16 @@ func TestMatchesDockerIgnoredPrefix(t *testing.T) {
|
||||
{name: "empty name matches id", containerName: "", containerID: "runner-123", prefixes: []string{"runner-"}, want: true},
|
||||
{name: "empty id matches name", containerName: "runner-job", containerID: "", prefixes: []string{"runner-"}, want: true},
|
||||
{name: "both empty no match", containerName: "", containerID: "", prefixes: []string{"runner-"}, want: false},
|
||||
{name: "suffix wildcard matches name", containerName: "worker-dev", containerID: "abc", prefixes: []string{"*-dev"}, want: true},
|
||||
{name: "suffix wildcard rejects prefix position", containerName: "dev-worker", containerID: "abc", prefixes: []string{"*-dev"}, want: false},
|
||||
{name: "suffix wildcard case insensitive", containerName: "Worker-DEV", containerID: "abc", prefixes: []string{"*-dev"}, want: true},
|
||||
{name: "contains wildcard matches middle", containerName: "app-staging-eu", containerID: "abc", prefixes: []string{"*staging*"}, want: true},
|
||||
{name: "contains wildcard no match", containerName: "app-prod-eu", containerID: "abc", prefixes: []string{"*staging*"}, want: false},
|
||||
{name: "explicit prefix wildcard", containerName: "runner-job", containerID: "abc", prefixes: []string{"runner-*"}, want: true},
|
||||
{name: "bare token still prefix only", containerName: "job-runner", containerID: "abc", prefixes: []string{"runner"}, want: false},
|
||||
{name: "suffix wildcard matches id", containerName: "app", containerID: "abc123-dev", prefixes: []string{"*-dev"}, want: true},
|
||||
{name: "lone star ignored", containerName: "anything", containerID: "abc", prefixes: []string{"*"}, want: false},
|
||||
{name: "double star ignored", containerName: "anything", containerID: "abc", prefixes: []string{"**"}, want: false},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
|
||||
@@ -164,6 +164,11 @@ func dockerServiceResourceID(hostID, serviceID, serviceName string) string {
|
||||
return fmt.Sprintf("docker:%s/service/%s", hostID, normalizedServiceID)
|
||||
}
|
||||
|
||||
// matchesDockerIgnoredPrefix reports whether a container name or ID matches
|
||||
// any entry in the ignore list. A bare entry keeps its historical
|
||||
// prefix-match semantics. Entries may also use the wildcard forms shared
|
||||
// with the other ignore lists: "*token" matches a suffix, "*token*" a
|
||||
// substring, "token*" an explicit prefix.
|
||||
func matchesDockerIgnoredPrefix(name, id string, prefixes []string) bool {
|
||||
if len(prefixes) == 0 {
|
||||
return false
|
||||
@@ -173,14 +178,13 @@ func matchesDockerIgnoredPrefix(name, id string, prefixes []string) bool {
|
||||
id = strings.ToLower(strings.TrimSpace(id))
|
||||
|
||||
for _, raw := range prefixes {
|
||||
prefix := strings.ToLower(strings.TrimSpace(raw))
|
||||
if prefix == "" {
|
||||
pattern := strings.ToLower(strings.TrimSpace(raw))
|
||||
// A pattern that is nothing but wildcards would ignore every
|
||||
// container, which is what DisableAllDockerContainers is for.
|
||||
if pattern == "" || strings.Trim(pattern, "*") == "" {
|
||||
continue
|
||||
}
|
||||
if name != "" && strings.HasPrefix(name, prefix) {
|
||||
return true
|
||||
}
|
||||
if id != "" && strings.HasPrefix(id, prefix) {
|
||||
if matchesIgnoredContainerPattern(name, pattern) || matchesIgnoredContainerPattern(id, pattern) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -188,6 +192,24 @@ func matchesDockerIgnoredPrefix(name, id string, prefixes []string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func matchesIgnoredContainerPattern(value, pattern string) bool {
|
||||
if value == "" {
|
||||
return false
|
||||
}
|
||||
leading := strings.HasPrefix(pattern, "*")
|
||||
trailing := strings.HasSuffix(pattern, "*")
|
||||
switch {
|
||||
case leading && trailing:
|
||||
return strings.Contains(value, pattern[1:len(pattern)-1])
|
||||
case leading:
|
||||
return strings.HasSuffix(value, pattern[1:])
|
||||
case trailing:
|
||||
return strings.HasPrefix(value, pattern[:len(pattern)-1])
|
||||
default:
|
||||
return strings.HasPrefix(value, pattern)
|
||||
}
|
||||
}
|
||||
|
||||
// CheckDockerHost evaluates Docker host telemetry and container metrics for alerts.
|
||||
func (m *Manager) CheckDockerHost(host models.DockerHost) {
|
||||
if host.ID == "" {
|
||||
|
||||
Reference in New Issue
Block a user