WAU Compliance: agent collector, backend endpoints, frontend badge + panel
- Agent: WAU registry config check (include/exclude URLs), pending updates count - Backend: /wau/compliance per customer, /wau/compliance/summary all customers - Frontend: compliance badge in customer list, compliance panel in WAU tab - config.js: no longer gitignored (secrets-free, reads from env/window.__RMM_CONFIG__) - vite.config.js: reads backend URL from .env instead of hardcoded value - .env.example added for clean setup
This commit is contained in:
@@ -31,6 +31,7 @@ type WindowsData struct {
|
||||
Disks []DiskInfo `json:"disks"`
|
||||
Services []SvcInfo `json:"services,omitempty"`
|
||||
InstalledSoftware []SoftwareInfo `json:"installed_software,omitempty"`
|
||||
WAU *WAUInfo `json:"wau,omitempty"`
|
||||
Domain string `json:"domain,omitempty"`
|
||||
LastUpdate time.Time `json:"last_update"`
|
||||
}
|
||||
@@ -123,6 +124,10 @@ func Collect() (*SystemData, error) {
|
||||
// Installierte Software (Registry)
|
||||
wd.InstalledSoftware = getInstalledSoftware()
|
||||
|
||||
// WAU-Status (Installation + Konfiguration + Pending Updates)
|
||||
wauInfo := getWAUInfo(wd.InstalledSoftware)
|
||||
wd.WAU = &wauInfo
|
||||
|
||||
return &SystemData{Windows: wd}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
//go:build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
// WAUInfo enthält den Status von Winget-AutoUpdate auf diesem Gerät
|
||||
type WAUInfo struct {
|
||||
Installed bool `json:"installed"`
|
||||
Version string `json:"version,omitempty"`
|
||||
IncludeURL string `json:"include_url,omitempty"`
|
||||
ExcludeURL string `json:"exclude_url,omitempty"`
|
||||
PendingCount int `json:"pending_updates"`
|
||||
}
|
||||
|
||||
// getWAUInfo liest WAU-Installations- und Konfigurationsstatus
|
||||
func getWAUInfo(software []SoftwareInfo) WAUInfo {
|
||||
info := WAUInfo{}
|
||||
|
||||
// WAU in installierter Software suchen
|
||||
for _, s := range software {
|
||||
lower := strings.ToLower(s.Name)
|
||||
if strings.Contains(lower, "winget-autoupdate") || lower == "wau" {
|
||||
info.Installed = true
|
||||
info.Version = s.Version
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// WAU-Konfiguration aus Registry lesen
|
||||
// WAU speichert seine Einstellungen unter HKLM\SOFTWARE\Winget-AutoUpdate
|
||||
regPaths := []string{
|
||||
`SOFTWARE\Winget-AutoUpdate`,
|
||||
`SOFTWARE\Policies\Microsoft\Windows\Winget-AutoUpdate`,
|
||||
}
|
||||
for _, path := range regPaths {
|
||||
k, err := registry.OpenKey(registry.LOCAL_MACHINE, path, registry.QUERY_VALUE)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if url, _, err := k.GetStringValue("WAU_IncludeListURL"); err == nil && url != "" {
|
||||
info.IncludeURL = url
|
||||
}
|
||||
if url, _, err := k.GetStringValue("WAU_ExcludeListURL"); err == nil && url != "" {
|
||||
info.ExcludeURL = url
|
||||
}
|
||||
k.Close()
|
||||
if info.IncludeURL != "" || info.ExcludeURL != "" {
|
||||
info.Installed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Pending updates via winget upgrade --list zählen
|
||||
wp := findWingetExe()
|
||||
if wp != "" {
|
||||
out, err := runPS(`& "` + wp + `" upgrade --list --accept-source-agreements 2>&1`)
|
||||
if err == nil {
|
||||
info.PendingCount = countWingetUpgradeLines(out)
|
||||
}
|
||||
}
|
||||
|
||||
return info
|
||||
}
|
||||
|
||||
// findWingetExe sucht winget.exe im System
|
||||
func findWingetExe() string {
|
||||
if path, err := exec.LookPath("winget"); err == nil {
|
||||
return path
|
||||
}
|
||||
script := `Get-ChildItem "C:\Program Files\WindowsApps" -Filter winget.exe -Recurse -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object -First 1 -ExpandProperty FullName`
|
||||
out, err := runPS(script)
|
||||
if err == nil && strings.TrimSpace(out) != "" {
|
||||
return strings.TrimSpace(out)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// countWingetUpgradeLines zählt Pakete mit Updates aus "winget upgrade --list" Output
|
||||
func countWingetUpgradeLines(output string) int {
|
||||
lines := strings.Split(output, "\n")
|
||||
count := 0
|
||||
pastSeparator := false
|
||||
for _, line := range lines {
|
||||
trimmed := strings.TrimSpace(line)
|
||||
if strings.Contains(trimmed, "---") {
|
||||
pastSeparator = true
|
||||
continue
|
||||
}
|
||||
if pastSeparator && trimmed != "" {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
"github.com/cynfo/rmm-agent-windows/ws"
|
||||
)
|
||||
|
||||
var Version = "1.1.0"
|
||||
var Version = "1.2.0"
|
||||
|
||||
const (
|
||||
ServiceName = "RMMAgent"
|
||||
|
||||
Reference in New Issue
Block a user