feat: patch models, scoped collections and indexes; pin vantage-shared v0.5.0

This commit is contained in:
2026-09-15 08:27:04 +00:00
parent e63e773cda
commit 8f1ea6d5a0
7 changed files with 185 additions and 3 deletions
+112
View File
@@ -0,0 +1,112 @@
package models
import (
"time"
"go.mongodb.org/mongo-driver/v2/bson"
)
const (
PatchScopeAll = "all"
PatchScopeSecurity = "security"
PatchRebootNever = "never"
PatchRebootIfRequired = "if_required"
PatchRunRunning = "running"
PatchRunSucceeded = "succeeded"
PatchRunPartial = "partial"
PatchRunFailed = "failed"
PatchRunCancelled = "cancelled"
PatchSrvQueued = "queued"
PatchSrvWaitingOffline = "waiting_offline"
PatchSrvPatching = "patching"
PatchSrvRebooting = "rebooting"
PatchSrvSucceeded = "succeeded"
PatchSrvFailed = "failed"
PatchSrvUnsupported = "unsupported"
PatchSrvAgentTooOld = "agent_too_old"
PatchSrvMissedOffline = "missed_offline"
PatchSrvWindowClosed = "window_closed"
PatchSrvCancelled = "cancelled"
PatchSourceSchedule = "schedule"
PatchSourceRunNow = "run_now"
PatchSourceServer = "server"
PatchSourceVulnerabilities = "vulnerabilities"
PatchSourceMCP = "mcp"
)
// MaintenanceWindow answers "when" and nothing else. Policies reference it by
// ID, so one window can later serve alert muting and status page maintenance
// without a second definition of the same Sunday morning.
type MaintenanceWindow struct {
ID bson.ObjectID `bson:"_id,omitempty" json:"-"`
InstanceID string `bson:"instance_id" json:"instance_id"`
WindowID string `bson:"window_id" json:"window_id"`
Name string `bson:"name" json:"name"`
Cron string `bson:"cron" json:"cron"` // 5-field, window start
TZ string `bson:"tz" json:"tz"` // IANA name
DurationMinutes int `bson:"duration_minutes" json:"duration_minutes"`
CreatedAt time.Time `bson:"created_at" json:"created_at"`
UpdatedAt time.Time `bson:"updated_at" json:"updated_at"`
}
type PatchPolicy struct {
ID bson.ObjectID `bson:"_id,omitempty" json:"-"`
InstanceID string `bson:"instance_id" json:"instance_id"`
PolicyID string `bson:"policy_id" json:"policy_id"`
Name string `bson:"name" json:"name"`
Enabled bool `bson:"enabled" json:"enabled"`
WindowID string `bson:"window_id" json:"window_id"`
TargetServerIDs []string `bson:"target_server_ids" json:"target_server_ids"`
TargetTags map[string]string `bson:"target_tags,omitempty" json:"target_tags,omitempty"`
Scope string `bson:"scope" json:"scope"`
Reboot string `bson:"reboot" json:"reboot"`
MaxConcurrent int `bson:"max_concurrent" json:"max_concurrent"` // 0 = no cap
NotifyChannelIDs []string `bson:"notify_channel_ids,omitempty" json:"notify_channel_ids,omitempty"`
NextRunAt *time.Time `bson:"next_run_at,omitempty" json:"next_run_at,omitempty"`
LastRunAt *time.Time `bson:"last_run_at,omitempty" json:"last_run_at,omitempty"`
LastSkipped *Skip `bson:"last_skipped,omitempty" json:"last_skipped,omitempty"`
DisabledReason string `bson:"disabled_reason,omitempty" json:"disabled_reason,omitempty"`
CreatedAt time.Time `bson:"created_at" json:"created_at"`
UpdatedAt time.Time `bson:"updated_at" json:"updated_at"`
}
// PatchRun is one firing of a policy, or one manual Apply updates. Scope,
// reboot and concurrency are copied from the policy at fire time so editing
// the policy never rewrites what a past run shows.
type PatchRun struct {
ID bson.ObjectID `bson:"_id,omitempty" json:"-"`
InstanceID string `bson:"instance_id" json:"instance_id"`
RunID string `bson:"run_id" json:"run_id"`
PolicyID string `bson:"policy_id,omitempty" json:"policy_id,omitempty"`
PolicyName string `bson:"policy_name,omitempty" json:"policy_name,omitempty"`
TriggeredBy string `bson:"triggered_by" json:"triggered_by"`
Source string `bson:"source" json:"source"`
Scope string `bson:"scope" json:"scope"`
Reboot string `bson:"reboot" json:"reboot"`
MaxConcurrent int `bson:"max_concurrent" json:"max_concurrent"`
WindowEnd *time.Time `bson:"window_end,omitempty" json:"window_end,omitempty"`
Status string `bson:"status" json:"status"`
CancelledAt *time.Time `bson:"cancelled_at,omitempty" json:"cancelled_at,omitempty"`
StartedAt time.Time `bson:"started_at" json:"started_at"`
FinishedAt *time.Time `bson:"finished_at,omitempty" json:"finished_at,omitempty"`
Servers []PatchServerRun `bson:"servers" json:"servers"`
}
type PatchServerRun struct {
ServerID string `bson:"server_id" json:"server_id"`
Hostname string `bson:"hostname" json:"hostname"`
Status string `bson:"status" json:"status"`
CommandID string `bson:"command_id,omitempty" json:"-"`
PendingBefore int `bson:"pending_before" json:"pending_before"`
PendingAfter *int `bson:"pending_after,omitempty" json:"pending_after,omitempty"`
RebootedAt *time.Time `bson:"rebooted_at,omitempty" json:"rebooted_at,omitempty"`
VerifiedAt *time.Time `bson:"verified_at,omitempty" json:"verified_at,omitempty"`
Output string `bson:"output,omitempty" json:"output,omitempty"`
Error string `bson:"error,omitempty" json:"error,omitempty"`
StartedAt *time.Time `bson:"started_at,omitempty" json:"started_at,omitempty"`
FinishedAt *time.Time `bson:"finished_at,omitempty" json:"finished_at,omitempty"`
}