server/internal/handlers/excluded_targets.go
Rama main · réplica de lectura del repositorio original.
package handlers
import (
"encoding/json"
"strings"
"blackbox/server/internal/models"
"blackbox/shared/types"
"gorm.io/gorm"
)
func isExcluded(database *gorm.DB, entry types.Entry) bool {
if database == nil || entry.Source != "docker" {
return false
}
service := strings.ToLower(strings.TrimSpace(entry.Service))
stack := strings.ToLower(strings.TrimSpace(extractComposeProject(entry.Metadata)))
if service == "" && stack == "" {
return false
}
var count int64
tx := database.Model(&models.ExcludedTarget{}).Where(
"(type = ? AND lower(name) = ?) OR (type = ? AND lower(name) = ?)",
"container", service,
"stack", stack,
).Count(&count)
return tx.Error == nil && count > 0
}
func extractComposeProject(metadata string) string {
if strings.TrimSpace(metadata) == "" {
return ""
}
var value any
if err := json.Unmarshal([]byte(metadata), &value); err != nil {
return ""
}
for _, key := range []string{
"com.docker.compose.project",
"compose_project",
"composeProject",
"stack",
} {
if found := findStringValue(value, key, 0); found != "" {
return found
}
}
return ""
}
func findStringValue(value any, key string, depth int) string {
if depth > 6 {
return ""
}
switch v := value.(type) {
case map[string]any:
for k, child := range v {
if strings.EqualFold(k, key) {
if s, ok := child.(string); ok {
return strings.TrimSpace(s)
}
}
if found := findStringValue(child, key, depth+1); found != "" {
return found
}
}
case []any:
for _, child := range v {
if found := findStringValue(child, key, depth+1); found != "" {
return found
}
}
}
return ""
}
// isExcludedInMemory checks whether entry matches any of the pre-fetched
// excluded targets. Use this inside batch loops to avoid N DB queries.
func isExcludedInMemory(excludedTargets []models.ExcludedTarget, entry types.Entry) bool {
if entry.Source != "docker" {
return false
}
service := strings.ToLower(strings.TrimSpace(entry.Service))
stack := strings.ToLower(strings.TrimSpace(extractComposeProject(entry.Metadata)))
if service == "" && stack == "" {
return false
}
for _, t := range excludedTargets {
name := strings.ToLower(t.Name)
if t.Type == "container" && name == service {
return true
}
if t.Type == "stack" && name == stack {
return true
}
}
return false
}