feat: separate data classification architecture
- Create separate scanner interfaces for storage, system, and docker data - Add dedicated endpoints for metrics and docker images instead of misclassifying as updates - Implement proper database tables for storage metrics and docker images - Fix storage/system metrics appearing incorrectly as package updates - Add scanner types with proper data structures for each subsystem - Update agent handlers to use correct endpoints for each data type
This commit is contained in:
@@ -2,6 +2,7 @@ package orchestrator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Fimeg/RedFlag/aggregator-agent/internal/client"
|
||||
"github.com/Fimeg/RedFlag/aggregator-agent/internal/system"
|
||||
@@ -24,42 +25,38 @@ func (s *SystemScanner) IsAvailable() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Scan collects system information and returns it as "updates" for reporting
|
||||
func (s *SystemScanner) Scan() ([]client.UpdateReportItem, error) {
|
||||
// ScanSystem collects system information and returns proper system metrics
|
||||
func (s *SystemScanner) ScanSystem() ([]SystemMetric, error) {
|
||||
sysInfo, err := system.GetSystemInfo(s.agentVersion)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get system info: %w", err)
|
||||
}
|
||||
|
||||
// Convert system info to UpdateReportItem format for reporting
|
||||
var items []client.UpdateReportItem
|
||||
// Convert system info to proper SystemMetric format
|
||||
var metrics []SystemMetric
|
||||
|
||||
// CPU info item
|
||||
cpuItem := client.UpdateReportItem{
|
||||
PackageName: "system-cpu",
|
||||
CurrentVersion: fmt.Sprintf("%d cores, %d threads", sysInfo.CPUInfo.Cores, sysInfo.CPUInfo.Threads),
|
||||
AvailableVersion: sysInfo.CPUInfo.ModelName,
|
||||
PackageType: "system",
|
||||
Severity: "low",
|
||||
PackageDescription: fmt.Sprintf("CPU: %s", sysInfo.CPUInfo.ModelName),
|
||||
// CPU info metric
|
||||
cpuMetric := SystemMetric{
|
||||
MetricName: "system-cpu",
|
||||
MetricType: "cpu",
|
||||
CurrentValue: fmt.Sprintf("%d cores, %d threads", sysInfo.CPUInfo.Cores, sysInfo.CPUInfo.Threads),
|
||||
AvailableValue: sysInfo.CPUInfo.ModelName,
|
||||
Severity: "low",
|
||||
Metadata: map[string]interface{}{
|
||||
"cpu_model": sysInfo.CPUInfo.ModelName,
|
||||
"cpu_cores": sysInfo.CPUInfo.Cores,
|
||||
"cpu_threads": sysInfo.CPUInfo.Threads,
|
||||
},
|
||||
}
|
||||
items = append(items, cpuItem)
|
||||
metrics = append(metrics, cpuMetric)
|
||||
|
||||
// Memory info item
|
||||
memItem := client.UpdateReportItem{
|
||||
PackageName: "system-memory",
|
||||
CurrentVersion: fmt.Sprintf("%.1f%% used", sysInfo.MemoryInfo.UsedPercent),
|
||||
AvailableVersion: fmt.Sprintf("%d GB total", sysInfo.MemoryInfo.Total/(1024*1024*1024)),
|
||||
PackageType: "system",
|
||||
Severity: determineMemorySeverity(sysInfo.MemoryInfo.UsedPercent),
|
||||
PackageDescription: fmt.Sprintf("Memory: %.1f GB / %.1f GB used",
|
||||
float64(sysInfo.MemoryInfo.Used)/(1024*1024*1024),
|
||||
float64(sysInfo.MemoryInfo.Total)/(1024*1024*1024)),
|
||||
// Memory info metric
|
||||
memMetric := SystemMetric{
|
||||
MetricName: "system-memory",
|
||||
MetricType: "memory",
|
||||
CurrentValue: fmt.Sprintf("%.1f%% used", sysInfo.MemoryInfo.UsedPercent),
|
||||
AvailableValue: fmt.Sprintf("%d GB total", sysInfo.MemoryInfo.Total/(1024*1024*1024)),
|
||||
Severity: determineMemorySeverity(sysInfo.MemoryInfo.UsedPercent),
|
||||
Metadata: map[string]interface{}{
|
||||
"memory_total": sysInfo.MemoryInfo.Total,
|
||||
"memory_used": sysInfo.MemoryInfo.Used,
|
||||
@@ -67,54 +64,51 @@ func (s *SystemScanner) Scan() ([]client.UpdateReportItem, error) {
|
||||
"memory_used_percent": sysInfo.MemoryInfo.UsedPercent,
|
||||
},
|
||||
}
|
||||
items = append(items, memItem)
|
||||
metrics = append(metrics, memMetric)
|
||||
|
||||
// Process count item
|
||||
processItem := client.UpdateReportItem{
|
||||
PackageName: "system-processes",
|
||||
CurrentVersion: fmt.Sprintf("%d processes", sysInfo.RunningProcesses),
|
||||
AvailableVersion: "n/a",
|
||||
PackageType: "system",
|
||||
Severity: "low",
|
||||
PackageDescription: fmt.Sprintf("Running Processes: %d", sysInfo.RunningProcesses),
|
||||
// Process count metric
|
||||
processMetric := SystemMetric{
|
||||
MetricName: "system-processes",
|
||||
MetricType: "processes",
|
||||
CurrentValue: fmt.Sprintf("%d processes", sysInfo.RunningProcesses),
|
||||
AvailableValue: "n/a",
|
||||
Severity: "low",
|
||||
Metadata: map[string]interface{}{
|
||||
"process_count": sysInfo.RunningProcesses,
|
||||
},
|
||||
}
|
||||
items = append(items, processItem)
|
||||
metrics = append(metrics, processMetric)
|
||||
|
||||
// Uptime item
|
||||
uptimeItem := client.UpdateReportItem{
|
||||
PackageName: "system-uptime",
|
||||
CurrentVersion: sysInfo.Uptime,
|
||||
AvailableVersion: "n/a",
|
||||
PackageType: "system",
|
||||
Severity: "low",
|
||||
PackageDescription: fmt.Sprintf("System Uptime: %s", sysInfo.Uptime),
|
||||
// Uptime metric
|
||||
uptimeMetric := SystemMetric{
|
||||
MetricName: "system-uptime",
|
||||
MetricType: "uptime",
|
||||
CurrentValue: sysInfo.Uptime,
|
||||
AvailableValue: "n/a",
|
||||
Severity: "low",
|
||||
Metadata: map[string]interface{}{
|
||||
"uptime": sysInfo.Uptime,
|
||||
},
|
||||
}
|
||||
items = append(items, uptimeItem)
|
||||
metrics = append(metrics, uptimeMetric)
|
||||
|
||||
// Reboot required item (if applicable)
|
||||
// Reboot required metric (if applicable)
|
||||
if sysInfo.RebootRequired {
|
||||
rebootItem := client.UpdateReportItem{
|
||||
PackageName: "system-reboot",
|
||||
CurrentVersion: "required",
|
||||
AvailableVersion: "n/a",
|
||||
PackageType: "system",
|
||||
Severity: "important",
|
||||
PackageDescription: fmt.Sprintf("Reboot Required: %s", sysInfo.RebootReason),
|
||||
rebootMetric := SystemMetric{
|
||||
MetricName: "system-reboot",
|
||||
MetricType: "reboot",
|
||||
CurrentValue: "required",
|
||||
AvailableValue: "n/a",
|
||||
Severity: "important",
|
||||
Metadata: map[string]interface{}{
|
||||
"reboot_required": true,
|
||||
"reboot_reason": sysInfo.RebootReason,
|
||||
},
|
||||
}
|
||||
items = append(items, rebootItem)
|
||||
metrics = append(metrics, rebootMetric)
|
||||
}
|
||||
|
||||
return items, nil
|
||||
return metrics, nil
|
||||
}
|
||||
|
||||
// Name returns the scanner name
|
||||
@@ -122,6 +116,66 @@ func (s *SystemScanner) Name() string {
|
||||
return "System Metrics Reporter"
|
||||
}
|
||||
|
||||
// --- Legacy Compatibility Methods ---
|
||||
|
||||
// Scan collects system information and returns it as "updates" for reporting (LEGACY)
|
||||
// This method is kept for backwards compatibility with the old Scanner interface
|
||||
func (s *SystemScanner) Scan() ([]client.UpdateReportItem, error) {
|
||||
metrics, err := s.ScanSystem()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert proper SystemMetric back to legacy UpdateReportItem format
|
||||
var items []client.UpdateReportItem
|
||||
|
||||
for _, metric := range metrics {
|
||||
item := client.UpdateReportItem{
|
||||
PackageName: metric.MetricName,
|
||||
CurrentVersion: metric.CurrentValue,
|
||||
AvailableVersion: metric.AvailableValue,
|
||||
PackageType: "system",
|
||||
Severity: metric.Severity,
|
||||
PackageDescription: fmt.Sprintf("System %s: %s", metric.MetricType, metric.MetricName),
|
||||
Metadata: metric.Metadata,
|
||||
}
|
||||
items = append(items, item)
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
||||
// --- Typed Scanner Implementation ---
|
||||
|
||||
// GetType returns the scanner type
|
||||
func (s *SystemScanner) GetType() ScannerType {
|
||||
return ScannerTypeSystem
|
||||
}
|
||||
|
||||
// ScanTyped returns typed results (new implementation)
|
||||
func (s *SystemScanner) ScanTyped() (TypedScannerResult, error) {
|
||||
startTime := time.Now()
|
||||
|
||||
metrics, err := s.ScanSystem()
|
||||
if err != nil {
|
||||
return TypedScannerResult{
|
||||
ScannerName: s.Name(),
|
||||
ScannerType: ScannerTypeSystem,
|
||||
Error: err,
|
||||
Status: "failed",
|
||||
Duration: time.Since(startTime).Milliseconds(),
|
||||
}, err
|
||||
}
|
||||
|
||||
return TypedScannerResult{
|
||||
ScannerName: s.Name(),
|
||||
ScannerType: ScannerTypeSystem,
|
||||
SystemData: metrics,
|
||||
Status: "success",
|
||||
Duration: time.Since(startTime).Milliseconds(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// determineMemorySeverity returns severity based on memory usage percentage
|
||||
func determineMemorySeverity(usedPercent float64) string {
|
||||
switch {
|
||||
|
||||
Reference in New Issue
Block a user