MCPcopy Index your code
hub / github.com/PatchMon/PatchMon / ProcessAgentUpdate

Function ProcessAgentUpdate

server-source-code/internal/alerts/agent_update.go:24–92  ·  view source on GitHub ↗

ProcessAgentUpdate runs the agent version check: binary version + DNS latest, then create/resolve alerts. Called by the version-update-check queue job. The Go server reads the agent binary version by executing patchmon-agent (same as Agent Version tab in Settings).

(ctx context.Context, d *database.DB, agentsDir string, tenantHost string, emit *notifications.Emitter, log *slog.Logger)

Source from the content-addressed store, hash-verified

22// Called by the version-update-check queue job.
23// The Go server reads the agent binary version by executing patchmon-agent (same as Agent Version tab in Settings).
24func ProcessAgentUpdate(ctx context.Context, d *database.DB, agentsDir string, tenantHost string, emit *notifications.Emitter, log *slog.Logger) error {
25 enabled, err := IsAlertsEnabled(ctx, d)
26 if err != nil || !enabled {
27 log.Debug("agent_update: alerts disabled")
28 return nil
29 }
30
31 // Current version from binary (same logic as /agent/version handler)
32 currentVersion := util.GetCurrentAgentVersionFromBinary(ctx, agentsDir)
33
34 // Latest version from DNS
35 latest, dnsErr := util.LookupVersionFromDNS(agentVersionDNS)
36 if dnsErr != nil {
37 log.Warn("agent_update: DNS lookup failed", "error", dnsErr)
38 } else if latest != "" {
39 latest = strings.TrimSpace(strings.Trim(latest, "\"'"))
40 if !agentSemverRe.MatchString(latest) {
41 latest = ""
42 }
43 }
44
45 // Create/resolve alerts (only when agent_update config is enabled)
46 cfg, _ := GetConfigForType(ctx, d, "agent_update")
47 if cfg == nil || !cfg.IsEnabled {
48 return nil
49 }
50
51 alertsStore := store.NewAlertsStore(d)
52 severity := DefaultSeverity(cfg.DefaultSeverity, "informational")
53
54 if currentVersion != "" && latest != "" && util.CompareVersions(latest, currentVersion) > 0 {
55 title := "Agent Files Update Available"
56 msg := fmt.Sprintf("A new agent version (%s) is available. Current version: %s", latest, currentVersion)
57 meta := map[string]interface{}{"current_version": currentVersion, "latest_version": latest}
58
59 // Skip if an active alert for this version already exists.
60 active, _ := d.Queries.ListActiveAlertsByType(ctx, "agent_update")
61 hasMatching := false
62 for _, a := range active {
63 var m map[string]interface{}
64 if len(a.Metadata) > 0 && json.Unmarshal(a.Metadata, &m) == nil {
65 if lv, _ := m["latest_version"].(string); lv == latest {
66 hasMatching = true
67 break
68 }
69 }
70 }
71 if !hasMatching {
72 // Emit event — notification routing decides which destinations receive it
73 // (including internal alerts if that destination is enabled).
74 if emit != nil {
75 emit.EmitEvent(ctx, d, tenantHost, notifications.Event{
76 Type: "agent_update", Severity: severity, Title: title, Message: msg,
77 ReferenceType: "host", ReferenceID: "",
78 Metadata: meta,
79 })
80 }
81 }

Callers

nothing calls this directly

Calls 7

UpdateResolvedMethod · 0.95
IsAlertsEnabledFunction · 0.85
GetConfigForTypeFunction · 0.85
DefaultSeverityFunction · 0.85
UnmarshalMethod · 0.80
EmitEventMethod · 0.80

Tested by

no test coverage detected