package db import "time" // Validator and IP lifecycle states. Kept as typed string constants rather // than a Go enum type so they round-trip through SQLite TEXT columns and // JSON without conversion. const ( ValidatorUnregistered = "unregistered" ValidatorIdle = "idle" ValidatorAssigned = "assigned" ValidatorChecking = "checking" ValidatorUnreachable = "unreachable" // Site (prober) availability states — no assigned/checking equivalent, // since a prober isn't bound to one IP at a time. SiteUnregistered = "unregistered" SiteIdle = "idle" SiteUnreachable = "unreachable" IPQueued = "queued" IPAssigningFIP = "assigning_fip" IPAwaitingSelfCheck = "awaiting_self_check" IPChecking = "checking" IPAggregating = "aggregating" IPDone = "done" IPFailed = "failed" // IPOccupied is a terminal state distinct from IPFailed: the floating IP // was found already associated to a different port at claim time, so the // check cycle never started for this attempt. See // Orchestrator.associateFIP and db.MarkFIPOccupied. IPOccupied = "occupied" ResultPass = "pass" ResultPartial = "partial" ResultFail = "fail" ResultCancelled = "cancelled" SourceEgress = "egress" ) // InboundSource returns the checks.source value for the given prober site // index (1-based), e.g. InboundSource(1) == "inbound-site-1". func InboundSource(siteIndex int) string { return "inbound-site-" + itoa(siteIndex) } func itoa(n int) string { if n == 0 { return "0" } neg := n < 0 if neg { n = -n } var buf [20]byte i := len(buf) for n > 0 { i-- buf[i] = byte('0' + n%10) n /= 10 } if neg { i-- buf[i] = '-' } return string(buf[i:]) } type Validator struct { ValidatorID string Hostname string OSPortID string State string CurrentIPID *int64 AgentVersion string LastHeartbeatAt *time.Time CreatedAt time.Time UpdatedAt time.Time } type IPQueueItem struct { ID int64 IPAddress string Sequence int State string OwnerValidatorID *string FIPID string AttemptNumber int RetryCount int LeaseExpiresAt *time.Time EgressComplete bool OverallResult string AssignedAt *time.Time FIPAssociatedAt *time.Time AggregatedAt *time.Time FIPReleasedAt *time.Time RegistryID int64 CycleID int CreatedAt time.Time UpdatedAt time.Time } type Check struct { ID int64 RegistryID int64 CycleID int // IPID is the ip_queue row this check was originally recorded against. // It's cleared to 0 (SQL NULL) if that row was later deleted — history // stays reachable via RegistryID/CycleID regardless (see // migrations/0007_ip_registry.sql). 0 is never a valid ip_queue id // (AUTOINCREMENT starts at 1), so it unambiguously means "orphaned." IPID int64 IPAddress string AttemptNumber int ValidatorID string Source string CheckType string Target string Success bool LatencyMS int64 Detail string CheckedAt time.Time CreatedAt time.Time } // RegistryItem is a durable per-address record that survives an address // being removed from ip_queue and later re-added — see // migrations/0007_ip_registry.sql. NextCycle is the cycle_id that will be // assigned the next time this address is (re)submitted; it only ever // increases, so cycle_id stays unique for this address even across // ip_queue row deletion/recreation. type RegistryItem struct { ID int64 IPAddress string FirstSeenAt time.Time LastSeenAt time.Time NextCycle int CreatedAt time.Time UpdatedAt time.Time } type Event struct { ID int64 SourceType string SourceID string IPID *int64 // RegistryID/CycleID are resolved from IPID at insert time (see // InsertEvent) and stay set even after the ip_queue row IPID pointed to // is later deleted, so retention pruning can cut events at the same // cycle boundary as checks — see migrations/0007_ip_registry.sql. RegistryID int64 CycleID int EventType string Payload string OccurredAt time.Time CreatedAt time.Time } type Site struct { Index int SiteID string Hostname string State string LastHeartbeatAt *time.Time CreatedAt time.Time UpdatedAt time.Time } type TargetGroup struct { Name string Targets []string CreatedAt time.Time UpdatedAt time.Time } type CheckType struct { Name string Enabled bool TargetGroups []string CreatedAt time.Time UpdatedAt time.Time } // ResolvedCheckType is a check type with its target groups already expanded // into a flat target list — what AssignmentForValidator hands to an agent. type ResolvedCheckType struct { Type string Targets []string } // SubmitIPsResult categorizes how each address in a SubmitIPs call was // handled. type SubmitIPsResult struct { Added []string Requeued []string Reordered []string SkippedInProgress []string } // DeleteIPsResult categorizes how each address in a DeleteIPs call (or a // ClearQueue call, which is DeleteIPs given every currently queued address) // was handled. type DeleteIPsResult struct { Deleted []string NotFound []string } // Settings is the singleton row of orchestrator-wide scalar knobs that are // admin-configurable at runtime (see queries_settings.go). type Settings struct { FIPSettleSeconds int // HistoryRetentionCycles caps how many recent check cycles are kept per // registry address (see PruneRegistryHistory); 0 means unlimited. HistoryRetentionCycles int CreatedAt time.Time UpdatedAt time.Time } // InboundChecksSettings is the singleton row describing what the prober // checks on every site for every in-flight IP (TCP ports + optional ICMP). // Admin-configurable at runtime (see queries_inbound.go). type InboundChecksSettings struct { Ports []int ICMP bool CreatedAt time.Time UpdatedAt time.Time } // Auto-cycle phases and outcomes (see AutoCycle). const ( AutoCyclePhaseIdle = "idle" AutoCyclePhaseRunning = "running" AutoCyclePhaseWaiting = "waiting" AutoCycleOutcomeCompleted = "completed" AutoCycleOutcomeNoFreeIPs = "no_free_ips" AutoCycleOutcomeTimeout = "timeout" AutoCycleOutcomeError = "error" AutoCycleOutcomeStopped = "stopped" ) // AutoCycle is the singleton row describing the automatic check cycle: // its configuration (Enabled, IntervalSeconds, MaxRunSeconds) and its // persisted runtime state (Phase and timestamps). MaxRunSeconds == 0 means // no limit on how long a run may wait for checks to finish. type AutoCycle struct { Enabled bool IntervalSeconds int MaxRunSeconds int Phase string RunStartedAt *time.Time NextRunAt *time.Time LastRunStartedAt *time.Time LastRunFinishedAt *time.Time LastOutcome string LastError string LastScannedFree int RunsTotal int } // AutoCycleState is a full replacement of the runtime-state columns of the // auto_cycle row (everything except configuration and enabled flag). type AutoCycleState struct { Phase string RunStartedAt *time.Time NextRunAt *time.Time LastRunStartedAt *time.Time LastRunFinishedAt *time.Time LastOutcome string LastError string LastScannedFree int RunsTotal int }