Session 4 complete - RedFlag update management platform
🚩 Private development - version retention only ✅ Complete web dashboard (React + TypeScript + TailwindCSS) ✅ Production-ready server backend (Go + Gin + PostgreSQL) ✅ Linux agent with APT + Docker scanning + local CLI tools ✅ JWT authentication and REST API ✅ Update discovery and approval workflow 🚧 Status: Alpha software - active development 📦 Purpose: Version retention during development ⚠️ Not for public use or deployment
This commit is contained in:
90
aggregator-agent/internal/scanner/apt.go
Normal file
90
aggregator-agent/internal/scanner/apt.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package scanner
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/aggregator-project/aggregator-agent/internal/client"
|
||||
)
|
||||
|
||||
// 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 since we might not have sudo
|
||||
|
||||
// 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:
|
||||
// package/repo version arch [upgradable from: old_version]
|
||||
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 - in production, query Ubuntu Security Advisories)
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user