Files
Redflag/docs/4_LOG/November_2025/research/code_examples.md

20 KiB

RedFlag Agent - Code Implementation Examples

1. Main Loop (Entry Point)

File: /home/memory/Desktop/Projects/RedFlag/aggregator-agent/cmd/agent/main.go
Lines: 410-549

The agent's main loop runs continuously, checking in with the server at regular intervals:

// Lines 410-549: Main check-in loop
for {
    // Add jitter to prevent thundering herd
    jitter := time.Duration(rand.Intn(30)) * time.Second
    time.Sleep(jitter)

    // Check if we need to send detailed system info update (hourly)
    if time.Since(lastSystemInfoUpdate) >= systemInfoUpdateInterval {
        log.Printf("Updating detailed system information...")
        if err := reportSystemInfo(apiClient, cfg); err != nil {
            log.Printf("Failed to report system info: %v\n", err)
        } else {
            lastSystemInfoUpdate = time.Now()
            log.Printf("✓ System information updated\n")
        }
    }

    log.Printf("Checking in with server... (Agent v%s)", AgentVersion)

    // Collect lightweight system metrics (every check-in)
    sysMetrics, err := system.GetLightweightMetrics()
    var metrics *client.SystemMetrics
    if err == nil {
        metrics = &client.SystemMetrics{
            CPUPercent:    sysMetrics.CPUPercent,
            MemoryPercent: sysMetrics.MemoryPercent,
            MemoryUsedGB:  sysMetrics.MemoryUsedGB,
            MemoryTotalGB: sysMetrics.MemoryTotalGB,
            DiskUsedGB:    sysMetrics.DiskUsedGB,
            DiskTotalGB:   sysMetrics.DiskTotalGB,
            DiskPercent:   sysMetrics.DiskPercent,
            Uptime:        sysMetrics.Uptime,
            Version:       AgentVersion,
        }
    }

    // Get commands from server
    commands, err := apiClient.GetCommands(cfg.AgentID, metrics)
    if err != nil {
        // Handle token renewal if needed
        // ... error handling code ...
    }

    // Process each command
    for _, cmd := range commands {
        log.Printf("Processing command: %s (%s)\n", cmd.Type, cmd.ID)

        switch cmd.Type {
        case "scan_updates":
            if err := handleScanUpdates(...); err != nil {
                log.Printf("Error scanning updates: %v\n", err)
            }
        case "install_updates":
            if err := handleInstallUpdates(...); err != nil {
                log.Printf("Error installing updates: %v\n", err)
            }
        // ... other command types ...
        }
    }

    // Wait for next check-in
    time.Sleep(time.Duration(getCurrentPollingInterval(cfg)) * time.Second)
}

2. The Monolithic handleScanUpdates Function

File: /home/memory/Desktop/Projects/RedFlag/aggregator-agent/cmd/agent/main.go
Lines: 551-709

This function orchestrates all scanner subsystems in a monolithic manner:

func handleScanUpdates(
    apiClient *client.Client, cfg *config.Config, 
    aptScanner *scanner.APTScanner, dnfScanner *scanner.DNFScanner, 
    dockerScanner *scanner.DockerScanner, 
    windowsUpdateScanner *scanner.WindowsUpdateScanner, 
    wingetScanner *scanner.WingetScanner, 
    commandID string) error {
    
    log.Println("Scanning for updates...")

    var allUpdates []client.UpdateReportItem
    var scanErrors []string
    var scanResults []string

    // MONOLITHIC PATTERN 1: APT Scanner (lines 559-574)
    if aptScanner.IsAvailable() {
        log.Println("  - Scanning APT packages...")
        updates, err := aptScanner.Scan()
        if err != nil {
            errorMsg := fmt.Sprintf("APT scan failed: %v", err)
            log.Printf("    %s\n", errorMsg)
            scanErrors = append(scanErrors, errorMsg)
        } else {
            resultMsg := fmt.Sprintf("Found %d APT updates", len(updates))
            log.Printf("    %s\n", resultMsg)
            scanResults = append(scanResults, resultMsg)
            allUpdates = append(allUpdates, updates...)
        }
    } else {
        scanResults = append(scanResults, "APT scanner not available")
    }

    // MONOLITHIC PATTERN 2: DNF Scanner (lines 576-592)
    // [SAME PATTERN REPEATS - lines 576-592]
    if dnfScanner.IsAvailable() {
        log.Println("  - Scanning DNF packages...")
        updates, err := dnfScanner.Scan()
        if err != nil {
            errorMsg := fmt.Sprintf("DNF scan failed: %v", err)
            log.Printf("    %s\n", errorMsg)
            scanErrors = append(scanErrors, errorMsg)
        } else {
            resultMsg := fmt.Sprintf("Found %d DNF updates", len(updates))
            log.Printf("    %s\n", resultMsg)
            scanResults = append(scanResults, resultMsg)
            allUpdates = append(allUpdates, updates...)
        }
    } else {
        scanResults = append(scanResults, "DNF scanner not available")
    }

    // MONOLITHIC PATTERN 3: Docker Scanner (lines 594-610)
    // [SAME PATTERN REPEATS - lines 594-610]
    if dockerScanner != nil && dockerScanner.IsAvailable() {
        log.Println("  - Scanning Docker images...")
        updates, err := dockerScanner.Scan()
        if err != nil {
            errorMsg := fmt.Sprintf("Docker scan failed: %v", err)
            log.Printf("    %s\n", errorMsg)
            scanErrors = append(scanErrors, errorMsg)
        } else {
            resultMsg := fmt.Sprintf("Found %d Docker image updates", len(updates))
            log.Printf("    %s\n", resultMsg)
            scanResults = append(scanResults, resultMsg)
            allUpdates = append(allUpdates, updates...)
        }
    } else {
        scanResults = append(scanResults, "Docker scanner not available")
    }

    // MONOLITHIC PATTERN 4: Windows Update Scanner (lines 612-628)
    // [SAME PATTERN REPEATS - lines 612-628]
    if windowsUpdateScanner.IsAvailable() {
        log.Println("  - Scanning Windows updates...")
        updates, err := windowsUpdateScanner.Scan()
        if err != nil {
            errorMsg := fmt.Sprintf("Windows Update scan failed: %v", err)
            log.Printf("    %s\n", errorMsg)
            scanErrors = append(scanErrors, errorMsg)
        } else {
            resultMsg := fmt.Sprintf("Found %d Windows updates", len(updates))
            log.Printf("    %s\n", resultMsg)
            scanResults = append(scanResults, resultMsg)
            allUpdates = append(allUpdates, updates...)
        }
    } else {
        scanResults = append(scanResults, "Windows Update scanner not available")
    }

    // MONOLITHIC PATTERN 5: Winget Scanner (lines 630-646)
    // [SAME PATTERN REPEATS - lines 630-646]
    if wingetScanner.IsAvailable() {
        log.Println("  - Scanning Winget packages...")
        updates, err := wingetScanner.Scan()
        if err != nil {
            errorMsg := fmt.Sprintf("Winget scan failed: %v", err)
            log.Printf("    %s\n", errorMsg)
            scanErrors = append(scanErrors, errorMsg)
        } else {
            resultMsg := fmt.Sprintf("Found %d Winget package updates", len(updates))
            log.Printf("    %s\n", resultMsg)
            scanResults = append(scanResults, resultMsg)
            allUpdates = append(allUpdates, updates...)
        }
    } else {
        scanResults = append(scanResults, "Winget scanner not available")
    }

    // Report scan results (lines 648-677)
    success := len(allUpdates) > 0 || len(scanErrors) == 0
    var combinedOutput string

    if len(scanResults) > 0 {
        combinedOutput += "Scan Results:\n" + strings.Join(scanResults, "\n")
    }
    if len(scanErrors) > 0 {
        if combinedOutput != "" {
            combinedOutput += "\n"
        }
        combinedOutput += "Scan Errors:\n" + strings.Join(scanErrors, "\n")
    }
    if len(allUpdates) > 0 {
        if combinedOutput != "" {
            combinedOutput += "\n"
        }
        combinedOutput += fmt.Sprintf("Total Updates Found: %d", len(allUpdates))
    }

    // Create scan log entry
    logReport := client.LogReport{
        CommandID:       commandID,
        Action:          "scan_updates",
        Result:          map[bool]string{true: "success", false: "failure"}[success],
        Stdout:          combinedOutput,
        Stderr:          strings.Join(scanErrors, "\n"),
        ExitCode:        map[bool]int{true: 0, false: 1}[success],
        DurationSeconds: 0,
    }

    // Report the scan log
    if err := apiClient.ReportLog(cfg.AgentID, logReport); err != nil {
        log.Printf("Failed to report scan log: %v\n", err)
    }

    // Report updates (lines 686-708)
    if len(allUpdates) > 0 {
        report := client.UpdateReport{
            CommandID: commandID,
            Timestamp: time.Now(),
            Updates:   allUpdates,
        }

        if err := apiClient.ReportUpdates(cfg.AgentID, report); err != nil {
            return fmt.Errorf("failed to report updates: %w", err)
        }

        log.Printf("✓ Reported %d updates to server\n", len(allUpdates))
    } else {
        log.Println("✓ No updates found")
    }

    return nil
}

Key Issues:

  1. Pattern repeats 5 times verbatim (lines 559-646)
  2. No abstraction for common scanner pattern
  3. Sequential execution (each scanner waits for previous)
  4. Tight coupling between orchestrator and individual scanners
  5. All error handling mixed with business logic

3. Modular Scanner - APT Implementation

File: /home/memory/Desktop/Projects/RedFlag/aggregator-agent/internal/scanner/apt.go
Lines: 1-91

Individual scanners ARE modular:

package scanner

// APTScanner scans for APT package updates
type APTScanner struct{}

// NewAPTScanner creates a new APT scanner
func NewAPTScanner() *APTScanner {
    return &APTScanner{}
}

// IsAvailable checks if APT is available on this system
func (s *APTScanner) IsAvailable() bool {
    _, err := exec.LookPath("apt")
    return err == nil
}

// Scan scans for available APT updates
func (s *APTScanner) Scan() ([]client.UpdateReportItem, error) {
    // Update package cache (sudo may be required, but try anyway)
    updateCmd := exec.Command("apt-get", "update")
    updateCmd.Run() // Ignore errors

    // Get upgradable packages
    cmd := exec.Command("apt", "list", "--upgradable")
    output, err := cmd.Output()
    if err != nil {
        return nil, fmt.Errorf("failed to run apt list: %w", err)
    }

    return parseAPTOutput(output)
}

func parseAPTOutput(output []byte) ([]client.UpdateReportItem, error) {
    var updates []client.UpdateReportItem
    scanner := bufio.NewScanner(bytes.NewReader(output))

    // Regex to parse apt output
    re := regexp.MustCompile(`^([^\s/]+)/([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+\[upgradable from:\s+([^\]]+)\]`)

    for scanner.Scan() {
        line := scanner.Text()
        if strings.HasPrefix(line, "Listing...") {
            continue
        }

        matches := re.FindStringSubmatch(line)
        if len(matches) < 6 {
            continue
        }

        packageName := matches[1]
        repository := matches[2]
        newVersion := matches[3]
        oldVersion := matches[5]

        // Determine severity (simplified)
        severity := "moderate"
        if strings.Contains(repository, "security") {
            severity = "important"
        }

        update := client.UpdateReportItem{
            PackageType:      "apt",
            PackageName:      packageName,
            CurrentVersion:   oldVersion,
            AvailableVersion: newVersion,
            Severity:         severity,
            RepositorySource: repository,
            Metadata: map[string]interface{}{
                "architecture": matches[4],
            },
        }

        updates = append(updates, update)
    }

    return updates, nil
}

Good Aspects:

  • Self-contained in single file
  • Clear interface (IsAvailable, Scan)
  • No dependencies on other scanners
  • Error handling encapsulated
  • Could be swapped out easily

4. Complex Scanner - Windows Update (WUA API)

File: /home/memory/Desktop/Projects/RedFlag/aggregator-agent/internal/scanner/windows_wua.go
Lines: 33-67, 70-211

// Scan scans for available Windows updates using WUA API
func (s *WindowsUpdateScannerWUA) Scan() ([]client.UpdateReportItem, error) {
    if !s.IsAvailable() {
        return nil, fmt.Errorf("WUA scanner is only available on Windows")
    }

    // Initialize COM
    comshim.Add(1)
    defer comshim.Done()

    ole.CoInitializeEx(0, ole.COINIT_APARTMENTTHREADED|ole.COINIT_SPEED_OVER_MEMORY)
    defer ole.CoUninitialize()

    // Create update session
    session, err := windowsupdate.NewUpdateSession()
    if err != nil {
        return nil, fmt.Errorf("failed to create Windows Update session: %w", err)
    }

    // Create update searcher
    searcher, err := session.CreateUpdateSearcher()
    if err != nil {
        return nil, fmt.Errorf("failed to create update searcher: %w", err)
    }

    // Search for available updates (IsInstalled=0 means not installed)
    searchCriteria := "IsInstalled=0 AND IsHidden=0"
    result, err := searcher.Search(searchCriteria)
    if err != nil {
        return nil, fmt.Errorf("failed to search for updates: %w", err)
    }

    // Convert results to our format
    updates := s.convertWUAResult(result)
    return updates, nil
}

// Convert results - rich metadata extraction (lines 70-211)
func (s *WindowsUpdateScannerWUA) convertWUAUpdate(update *windowsupdate.IUpdate) *client.UpdateReportItem {
    // Get update information
    title := update.Title
    description := update.Description
    kbArticles := s.getKBArticles(update)
    updateIdentity := update.Identity

    // Use MSRC severity if available
    severity := s.mapMsrcSeverity(update.MsrcSeverity)
    if severity == "" {
        severity = s.determineSeverityFromCategories(update)
    }

    // Create metadata with WUA-specific information
    metadata := map[string]interface{}{
        "package_manager": "windows_update",
        "detected_via":    "wua_api",
        "kb_articles":     kbArticles,
        "update_identity": updateIdentity.UpdateID,
        "revision_number": updateIdentity.RevisionNumber,
        "download_size":   update.MaxDownloadSize,
        "api_source":      "windows_update_agent",
        "scan_timestamp":  time.Now().Format(time.RFC3339),
    }

    // Add MSRC severity if available
    if update.MsrcSeverity != "" {
        metadata["msrc_severity"] = update.MsrcSeverity
    }

    // Add security bulletin IDs (includes CVEs)
    if len(update.SecurityBulletinIDs) > 0 {
        metadata["security_bulletins"] = update.SecurityBulletinIDs
        cveList := make([]string, 0)
        for _, bulletin := range update.SecurityBulletinIDs {
            if strings.HasPrefix(bulletin, "CVE-") {
                cveList = append(cveList, bulletin)
            }
        }
        if len(cveList) > 0 {
            metadata["cve_list"] = cveList
        }
    }

    // ... more metadata extraction ...

    updateItem := &client.UpdateReportItem{
        PackageType:        "windows_update",
        PackageName:        title,
        PackageDescription: description,
        CurrentVersion:     currentVersion,
        AvailableVersion:   availableVersion,
        Severity:           severity,
        RepositorySource:   "Microsoft Update",
        Metadata:           metadata,
    }

    return updateItem
}

Key Characteristics:

  • Complex internal logic but clean external interface
  • Rich metadata extraction (KB articles, CVEs, MSRC severity)
  • Windows-specific (COM interop)
  • Still follows IsAvailable/Scan pattern
  • Encapsulates complexity

5. System Info Reporting (Hourly)

File: /home/memory/Desktop/Projects/RedFlag/aggregator-agent/cmd/agent/main.go
Lines: 1357-1407

// reportSystemInfo collects and reports detailed system information
func reportSystemInfo(apiClient *client.Client, cfg *config.Config) error {
    // Collect detailed system information
    sysInfo, err := system.GetSystemInfo(AgentVersion)
    if err != nil {
        return fmt.Errorf("failed to get system info: %w", err)
    }

    // Create system info report
    report := client.SystemInfoReport{
        Timestamp:   time.Now(),
        CPUModel:    sysInfo.CPUInfo.ModelName,
        CPUCores:    sysInfo.CPUInfo.Cores,
        CPUThreads:  sysInfo.CPUInfo.Threads,
        MemoryTotal: sysInfo.MemoryInfo.Total,
        DiskTotal:   uint64(0),
        DiskUsed:    uint64(0),
        IPAddress:   sysInfo.IPAddress,
        Processes:   sysInfo.RunningProcesses,
        Uptime:      sysInfo.Uptime,
        Metadata:    make(map[string]interface{}),
    }

    // Add primary disk info
    if len(sysInfo.DiskInfo) > 0 {
        primaryDisk := sysInfo.DiskInfo[0]
        report.DiskTotal = primaryDisk.Total
        report.DiskUsed = primaryDisk.Used
        report.Metadata["disk_mount"] = primaryDisk.Mountpoint
        report.Metadata["disk_filesystem"] = primaryDisk.Filesystem
    }

    // Add metadata
    report.Metadata["collected_at"] = time.Now().Format(time.RFC3339)
    report.Metadata["hostname"] = sysInfo.Hostname
    report.Metadata["os_type"] = sysInfo.OSType
    report.Metadata["os_version"] = sysInfo.OSVersion
    report.Metadata["os_architecture"] = sysInfo.OSArchitecture

    // Report to server
    if err := apiClient.ReportSystemInfo(cfg.AgentID, report); err != nil {
        return fmt.Errorf("failed to report system info: %w", err)
    }

    return nil
}

Timing:

  • Runs hourly (line 407-408: const systemInfoUpdateInterval = 1 * time.Hour)
  • Triggered in main loop (lines 417-425)
  • Separate from scan operations

6. System Info Data Structures

File: /home/memory/Desktop/Projects/RedFlag/aggregator-agent/internal/system/info.go
Lines: 13-57

// SystemInfo contains detailed system information
type SystemInfo struct {
    Hostname       string            `json:"hostname"`
    OSType         string            `json:"os_type"`
    OSVersion      string            `json:"os_version"`
    OSArchitecture string            `json:"os_architecture"`
    AgentVersion   string            `json:"agent_version"`
    IPAddress      string            `json:"ip_address"`
    CPUInfo        CPUInfo           `json:"cpu_info"`
    MemoryInfo     MemoryInfo        `json:"memory_info"`
    DiskInfo       []DiskInfo        `json:"disk_info"`  // MULTIPLE DISKS!
    RunningProcesses int             `json:"running_processes"`
    Uptime         string            `json:"uptime"`
    RebootRequired bool              `json:"reboot_required"`
    RebootReason   string            `json:"reboot_reason"`
    Metadata       map[string]string `json:"metadata"`
}

// CPUInfo contains CPU information
type CPUInfo struct {
    ModelName string `json:"model_name"`
    Cores     int    `json:"cores"`
    Threads   int    `json:"threads"`
}

// MemoryInfo contains memory information
type MemoryInfo struct {
    Total       uint64  `json:"total"`
    Available   uint64  `json:"available"`
    Used        uint64  `json:"used"`
    UsedPercent float64 `json:"used_percent"`
}

// DiskInfo contains disk information for modular storage management
type DiskInfo struct {
    Mountpoint    string  `json:"mountpoint"`
    Total         uint64  `json:"total"`
    Available     uint64  `json:"available"`
    Used          uint64  `json:"used"`
    UsedPercent   float64 `json:"used_percent"`
    Filesystem    string  `json:"filesystem"`
    IsRoot        bool    `json:"is_root"`        // Primary system disk
    IsLargest     bool    `json:"is_largest"`     // Largest storage disk
    DiskType      string  `json:"disk_type"`      // SSD, HDD, NVMe, etc.
    Device        string  `json:"device"`         // Block device name
}

Important Notes:

  • Supports multiple disks (DiskInfo is a slice)
  • Each disk tracked separately (mount point, filesystem type, device)
  • Reports primary (IsRoot) and largest (IsLargest) disk separately
  • Well-structured for expansion

Summary

Monolithic: The orchestration function (handleScanUpdates) that combines all scanners
Modular: Individual scanner implementations and system info collection
Missing: Formal subsystem abstraction layer and lifecycle management