Ctrl K
ComunidadGuías…

server/internal/handlers/excluded_targets.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
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
}