mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-21 02:33:32 +00:00
89 lines
3.0 KiB
Go
89 lines
3.0 KiB
Go
package monitoring
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/alerts"
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/unifiedresources"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
const backupIntentEvidenceMaxAge = 5 * time.Minute
|
|
|
|
type resourceOperatorIntentReader interface {
|
|
GetResourceOperatorState(canonicalID string) (unifiedresources.ResourceOperatorState, bool, error)
|
|
}
|
|
|
|
type resourceIntentIdentityReader interface {
|
|
ResolveCanonicalResourceID(ref string) (string, bool)
|
|
}
|
|
|
|
func (m *Monitor) installOperatorIntentResolver(store ResourceStoreInterface) {
|
|
if m == nil || m.alertManager == nil {
|
|
return
|
|
}
|
|
identityReader, hasIdentityReader := store.(resourceIntentIdentityReader)
|
|
if hasIdentityReader && identityReader != nil {
|
|
m.alertManager.SetResourceIntentIdentityResolver(identityReader.ResolveCanonicalResourceID)
|
|
} else {
|
|
m.alertManager.SetResourceIntentIdentityResolver(nil)
|
|
}
|
|
reader, ok := store.(resourceOperatorIntentReader)
|
|
if !ok || reader == nil {
|
|
m.alertManager.SetOperatorIntentContextResolver(nil)
|
|
return
|
|
}
|
|
m.alertManager.SetOperatorIntentContextResolver(func(resourceID string, _ time.Time) (alerts.OperatorIntentContext, bool) {
|
|
if hasIdentityReader {
|
|
if canonicalID, found := identityReader.ResolveCanonicalResourceID(resourceID); found {
|
|
resourceID = canonicalID
|
|
}
|
|
}
|
|
state, found, err := reader.GetResourceOperatorState(resourceID)
|
|
if err != nil {
|
|
log.Warn().Err(err).Str("resourceID", resourceID).Msg("Failed to read operator state for alert intent")
|
|
return alerts.OperatorIntentContext{}, false
|
|
}
|
|
if !found {
|
|
return alerts.OperatorIntentContext{}, false
|
|
}
|
|
return alerts.OperatorIntentContext{
|
|
IntentionallyOffline: state.IntentionallyOffline,
|
|
MaintenanceStartAt: state.MaintenanceStartAt,
|
|
MaintenanceEndAt: state.MaintenanceEndAt,
|
|
MaintenanceReason: state.MaintenanceReason,
|
|
}, true
|
|
})
|
|
}
|
|
|
|
func (m *Monitor) resolveBackupIntentContext(_ string, instance, node string, vmid int, now time.Time) (alerts.BackupIntentContext, bool) {
|
|
if m == nil || m.state == nil || vmid <= 0 {
|
|
return alerts.BackupIntentContext{}, false
|
|
}
|
|
instance = strings.TrimSpace(instance)
|
|
node = strings.TrimSpace(node)
|
|
if now.IsZero() {
|
|
now = time.Now().UTC()
|
|
}
|
|
|
|
for _, task := range m.state.GetSnapshot().PVEBackups.BackupTasks {
|
|
if task.VMID != vmid || (instance != "" && task.Instance != instance) || (node != "" && task.Node != "" && task.Node != node) {
|
|
continue
|
|
}
|
|
if task.ObservedAt.IsZero() || now.Sub(task.ObservedAt) > backupIntentEvidenceMaxAge || task.ObservedAt.After(now.Add(time.Minute)) {
|
|
continue
|
|
}
|
|
status := strings.ToLower(strings.TrimSpace(task.Status))
|
|
if !task.EndTime.IsZero() || status == "ok" || status == "stopped" || status == "error" || status == "warning" {
|
|
continue
|
|
}
|
|
return alerts.BackupIntentContext{
|
|
Active: true,
|
|
ObservedAt: task.ObservedAt,
|
|
Evidence: "pve_vzdump_task:" + task.ID,
|
|
}, true
|
|
}
|
|
return alerts.BackupIntentContext{}, false
|
|
}
|