mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-09 19:32:24 +00:00
106 lines
3.1 KiB
Go
106 lines
3.1 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/unifiedresources"
|
|
)
|
|
|
|
// MonitoredSystemLedgerEntry represents a single counted top-level monitored
|
|
// system.
|
|
type MonitoredSystemLedgerEntry struct {
|
|
Name string `json:"name"`
|
|
Type string `json:"type"`
|
|
Status string `json:"status"` // "online", "offline", "unknown"
|
|
LastSeen string `json:"last_seen"` // RFC3339 or empty
|
|
Source string `json:"source"`
|
|
}
|
|
|
|
// MonitoredSystemLedgerResponse is the response for GET /api/license/monitored-system-ledger.
|
|
type MonitoredSystemLedgerResponse struct {
|
|
Systems []MonitoredSystemLedgerEntry `json:"systems"`
|
|
Total int `json:"total"`
|
|
Limit int `json:"limit"` // 0 = unlimited
|
|
}
|
|
|
|
func EmptyMonitoredSystemLedgerResponse() MonitoredSystemLedgerResponse {
|
|
return MonitoredSystemLedgerResponse{}.NormalizeCollections()
|
|
}
|
|
|
|
func (r MonitoredSystemLedgerResponse) NormalizeCollections() MonitoredSystemLedgerResponse {
|
|
if r.Systems == nil {
|
|
r.Systems = []MonitoredSystemLedgerEntry{}
|
|
}
|
|
return r
|
|
}
|
|
|
|
func (r *Router) handleMonitoredSystemLedger(w http.ResponseWriter, req *http.Request) {
|
|
orgID := GetOrgID(req.Context())
|
|
|
|
// Get canonical monitored systems from the unified ReadState surface.
|
|
var systems []unifiedresources.MonitoredSystemRecord
|
|
var monitorResolved bool
|
|
if r.mtMonitor != nil {
|
|
monitor, monErr := r.mtMonitor.GetMonitor(orgID)
|
|
if monErr != nil {
|
|
log.Warn().Err(monErr).Str("org", orgID).Msg("monitored-system-ledger: failed to resolve tenant monitor")
|
|
}
|
|
if monitor != nil {
|
|
if rs := monitor.GetUnifiedReadState(); rs != nil {
|
|
systems = unifiedresources.MonitoredSystems(rs)
|
|
}
|
|
monitorResolved = true
|
|
}
|
|
}
|
|
// Fallback to the default monitor only for the default org to avoid cross-tenant data leaks.
|
|
if !monitorResolved && orgID == "default" && r.monitor != nil {
|
|
if rs := r.monitor.GetUnifiedReadState(); rs != nil {
|
|
systems = unifiedresources.MonitoredSystems(rs)
|
|
}
|
|
}
|
|
|
|
entries := make([]MonitoredSystemLedgerEntry, 0, len(systems))
|
|
for _, system := range systems {
|
|
entries = append(entries, MonitoredSystemLedgerEntry{
|
|
Name: system.Name,
|
|
Type: system.Type,
|
|
Status: normalizeStatus(string(system.Status)),
|
|
LastSeen: formatLastSeen(system.LastSeen),
|
|
Source: system.Source,
|
|
})
|
|
}
|
|
|
|
limit := maxMonitoredSystemsLimitForContext(req.Context())
|
|
|
|
resp := EmptyMonitoredSystemLedgerResponse()
|
|
resp.Systems = entries
|
|
resp.Total = len(entries)
|
|
resp.Limit = limit
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(resp.NormalizeCollections())
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Status helpers
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func normalizeStatus(s string) string {
|
|
switch s {
|
|
case "online", "offline":
|
|
return s
|
|
default:
|
|
return "unknown"
|
|
}
|
|
}
|
|
|
|
func formatLastSeen(t time.Time) string {
|
|
if t.IsZero() {
|
|
return ""
|
|
}
|
|
return t.UTC().Format(time.RFC3339)
|
|
}
|