- Add GET /api/v1/agents/:id/config endpoint for server configuration - Agent fetches config during check-in and applies updates - Add version tracking to prevent unnecessary config applications - Clean separation: config sync independent of commands - Fix agent UI subsystem settings to actually control agent behavior - Update Security Health UI with frosted glass styling and tooltips
147 lines
3.9 KiB
Go
147 lines
3.9 KiB
Go
package orchestrator
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/Fimeg/RedFlag/aggregator-agent/internal/client"
|
|
"github.com/Fimeg/RedFlag/aggregator-agent/internal/system"
|
|
)
|
|
|
|
// StorageScanner scans disk usage metrics
|
|
type StorageScanner struct {
|
|
agentVersion string
|
|
}
|
|
|
|
// NewStorageScanner creates a new storage scanner
|
|
func NewStorageScanner(agentVersion string) *StorageScanner {
|
|
return &StorageScanner{
|
|
agentVersion: agentVersion,
|
|
}
|
|
}
|
|
|
|
// IsAvailable always returns true since storage scanning is always available
|
|
func (s *StorageScanner) IsAvailable() bool {
|
|
return true
|
|
}
|
|
|
|
// ScanStorage collects disk usage information and returns proper storage metrics
|
|
func (s *StorageScanner) ScanStorage() ([]StorageMetric, error) {
|
|
sysInfo, err := system.GetSystemInfo(s.agentVersion)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get system info: %w", err)
|
|
}
|
|
|
|
if len(sysInfo.DiskInfo) == 0 {
|
|
return nil, fmt.Errorf("no disk information available")
|
|
}
|
|
|
|
// Convert disk info to proper StorageMetric format
|
|
var metrics []StorageMetric
|
|
|
|
for _, disk := range sysInfo.DiskInfo {
|
|
metric := StorageMetric{
|
|
Mountpoint: disk.Mountpoint,
|
|
Filesystem: disk.Filesystem,
|
|
Device: disk.Device,
|
|
DiskType: disk.DiskType,
|
|
TotalBytes: int64(disk.Total),
|
|
UsedBytes: int64(disk.Used),
|
|
AvailableBytes: int64(disk.Available),
|
|
UsedPercent: disk.UsedPercent,
|
|
IsRoot: disk.IsRoot,
|
|
IsLargest: disk.IsLargest,
|
|
Severity: determineDiskSeverity(disk.UsedPercent),
|
|
Metadata: map[string]interface{}{
|
|
"agent_version": s.agentVersion,
|
|
"collected_at": time.Now().Format(time.RFC3339),
|
|
},
|
|
}
|
|
metrics = append(metrics, metric)
|
|
}
|
|
|
|
return metrics, nil
|
|
}
|
|
|
|
// Name returns the scanner name
|
|
func (s *StorageScanner) Name() string {
|
|
return "Disk Usage Reporter"
|
|
}
|
|
|
|
// --- Legacy Compatibility Methods ---
|
|
|
|
// Scan collects disk usage information and returns it as "updates" for reporting (LEGACY)
|
|
// This method is kept for backwards compatibility with the old Scanner interface
|
|
func (s *StorageScanner) Scan() ([]client.UpdateReportItem, error) {
|
|
metrics, err := s.ScanStorage()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Convert proper StorageMetric back to legacy UpdateReportItem format
|
|
var items []client.UpdateReportItem
|
|
|
|
for _, metric := range metrics {
|
|
item := client.UpdateReportItem{
|
|
PackageName: fmt.Sprintf("disk-%s", metric.Mountpoint),
|
|
CurrentVersion: fmt.Sprintf("%.1f%% used", metric.UsedPercent),
|
|
AvailableVersion: fmt.Sprintf("%d GB available", metric.AvailableBytes/(1024*1024*1024)),
|
|
PackageType: "storage",
|
|
Severity: metric.Severity,
|
|
PackageDescription: fmt.Sprintf("Disk: %s (%s) - %s", metric.Mountpoint, metric.Filesystem, metric.Device),
|
|
Metadata: metric.Metadata,
|
|
}
|
|
items = append(items, item)
|
|
}
|
|
|
|
return items, nil
|
|
}
|
|
|
|
// --- Typed Scanner Implementation ---
|
|
|
|
// GetType returns the scanner type
|
|
func (s *StorageScanner) GetType() ScannerType {
|
|
return ScannerTypeStorage
|
|
}
|
|
|
|
// ScanTyped returns typed results (new implementation)
|
|
func (s *StorageScanner) ScanTyped() (TypedScannerResult, error) {
|
|
startTime := time.Now()
|
|
defer func() {
|
|
// Duration will be set at the end
|
|
}()
|
|
|
|
metrics, err := s.ScanStorage()
|
|
if err != nil {
|
|
return TypedScannerResult{
|
|
ScannerName: s.Name(),
|
|
ScannerType: ScannerTypeStorage,
|
|
Error: err,
|
|
Status: "failed",
|
|
Duration: time.Since(startTime).Milliseconds(),
|
|
}, err
|
|
}
|
|
|
|
return TypedScannerResult{
|
|
ScannerName: s.Name(),
|
|
ScannerType: ScannerTypeStorage,
|
|
StorageData: metrics,
|
|
Status: "success",
|
|
Duration: time.Since(startTime).Milliseconds(),
|
|
}, nil
|
|
}
|
|
|
|
// determineDiskSeverity returns severity based on disk usage percentage
|
|
func determineDiskSeverity(usedPercent float64) string {
|
|
switch {
|
|
case usedPercent >= 95:
|
|
return "critical"
|
|
case usedPercent >= 90:
|
|
return "important"
|
|
case usedPercent >= 80:
|
|
return "moderate"
|
|
default:
|
|
return "low"
|
|
}
|
|
}
|