156 lines
5.6 KiB
Go
156 lines
5.6 KiB
Go
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package main
|
|
|
|
import "encoding/json"
|
|
|
|
// StateSnapshot is the full JSON snapshot served for a single maglevd.
|
|
type StateSnapshot struct {
|
|
Maglevd MaglevdInfo `json:"maglevd"`
|
|
Frontends []*FrontendSnapshot `json:"frontends"`
|
|
Backends []*BackendSnapshot `json:"backends"`
|
|
HealthChecks []*HealthCheckSnapshot `json:"healthchecks"`
|
|
VPPInfo *VPPInfoSnapshot `json:"vpp_info,omitempty"`
|
|
// VPPState is "connected", "disconnected", or "" (unknown). Updated
|
|
// from vpp-connect / vpp-disconnect / vpp-api-{send,recv} log
|
|
// events and re-seeded on every refreshAll tick.
|
|
VPPState string `json:"vpp_state,omitempty"`
|
|
// LBState is the most recent VPP LB plugin view of buckets-per-backend,
|
|
// keyed by frontend name → backend name → bucket count. nil when VPP is
|
|
// disconnected or no fetch has succeeded yet.
|
|
LBState *LBStateSnapshot `json:"lb_state,omitempty"`
|
|
}
|
|
|
|
// LBStateSnapshot is a per-(frontend, backend) view of VPP's bucket
|
|
// allocation. The frontend collects this with GetVPPLBState and matches
|
|
// VPP's VIP records back to maglev frontend/backend names so the SPA
|
|
// never has to know about VPP-side prefixes or AS addresses.
|
|
type LBStateSnapshot struct {
|
|
PerFrontend map[string]map[string]int32 `json:"per_frontend"`
|
|
}
|
|
|
|
// MaglevdInfo is the per-maglevd connection status record.
|
|
type MaglevdInfo struct {
|
|
Name string `json:"name"`
|
|
Address string `json:"address"`
|
|
Connected bool `json:"connected"`
|
|
LastError string `json:"last_error,omitempty"`
|
|
}
|
|
|
|
// VersionInfo is the build metadata of this maglevd-frontend binary
|
|
// plus runtime capability flags the SPA needs to know at mount time.
|
|
type VersionInfo struct {
|
|
Version string `json:"version"`
|
|
Commit string `json:"commit"`
|
|
Date string `json:"date"`
|
|
AdminEnabled bool `json:"admin_enabled"`
|
|
}
|
|
|
|
type FrontendSnapshot struct {
|
|
Name string `json:"name"`
|
|
Address string `json:"address"`
|
|
Protocol string `json:"protocol"`
|
|
Port uint32 `json:"port"`
|
|
Description string `json:"description,omitempty"`
|
|
SrcIPSticky bool `json:"src_ip_sticky"`
|
|
Pools []*PoolSnapshot `json:"pools"`
|
|
// State is the aggregated frontend state ("up" | "down" | "unknown")
|
|
// populated from FrontendEvent messages, including the synthetic
|
|
// from==to replay that maglevd sends on WatchEvents subscribe.
|
|
State string `json:"state,omitempty"`
|
|
}
|
|
|
|
type PoolSnapshot struct {
|
|
Name string `json:"name"`
|
|
Backends []*PoolBackendSnapshot `json:"backends"`
|
|
}
|
|
|
|
type PoolBackendSnapshot struct {
|
|
Name string `json:"name"`
|
|
Weight int32 `json:"weight"`
|
|
EffectiveWeight int32 `json:"effective_weight"`
|
|
}
|
|
|
|
type BackendSnapshot struct {
|
|
Name string `json:"name"`
|
|
Address string `json:"address"`
|
|
State string `json:"state"`
|
|
Enabled bool `json:"enabled"`
|
|
HealthCheck string `json:"healthcheck"`
|
|
LastTransition *TransitionRecord `json:"last_transition,omitempty"`
|
|
Transitions []*TransitionRecord `json:"transitions,omitempty"`
|
|
}
|
|
|
|
type TransitionRecord struct {
|
|
From string `json:"from"`
|
|
To string `json:"to"`
|
|
AtUnixNs int64 `json:"at_unix_ns"`
|
|
}
|
|
|
|
type HealthCheckSnapshot struct {
|
|
Name string `json:"name"`
|
|
Type string `json:"type"`
|
|
Port uint32 `json:"port"`
|
|
IntervalNs int64 `json:"interval_ns"`
|
|
FastIntervalNs int64 `json:"fast_interval_ns"`
|
|
DownIntervalNs int64 `json:"down_interval_ns"`
|
|
TimeoutNs int64 `json:"timeout_ns"`
|
|
Rise int32 `json:"rise"`
|
|
Fall int32 `json:"fall"`
|
|
}
|
|
|
|
type VPPInfoSnapshot struct {
|
|
Version string `json:"version"`
|
|
BuildDate string `json:"build_date"`
|
|
PID uint32 `json:"pid"`
|
|
BoottimeNs int64 `json:"boottime_ns"`
|
|
ConnecttimeNs int64 `json:"connecttime_ns"`
|
|
}
|
|
|
|
// BrowserEvent is the wire shape sent over SSE to the browser.
|
|
type BrowserEvent struct {
|
|
Maglevd string `json:"maglevd"`
|
|
Type string `json:"type"` // log|backend|frontend|maglevd-status|vpp-status|lb-state|resync
|
|
AtUnixNs int64 `json:"at_unix_ns"`
|
|
Payload json.RawMessage `json:"payload"`
|
|
}
|
|
|
|
// LBStatePayload rides on a "lb-state" BrowserEvent and carries the
|
|
// freshly-fetched bucket map. PerFrontend may be nil (or empty) to
|
|
// signal "no LB state available" — the SPA renders such backends
|
|
// with an em-dash in the buckets column.
|
|
type LBStatePayload struct {
|
|
PerFrontend map[string]map[string]int32 `json:"per_frontend"`
|
|
}
|
|
|
|
// BackendEventPayload is what we ship inside BrowserEvent.Payload for
|
|
// type == "backend".
|
|
type BackendEventPayload struct {
|
|
Backend string `json:"backend"`
|
|
Transition TransitionRecord `json:"transition"`
|
|
}
|
|
|
|
type FrontendEventPayload struct {
|
|
Frontend string `json:"frontend"`
|
|
Transition TransitionRecord `json:"transition"`
|
|
}
|
|
|
|
type LogEventPayload struct {
|
|
Level string `json:"level"`
|
|
Msg string `json:"msg"`
|
|
Attrs map[string]string `json:"attrs,omitempty"`
|
|
}
|
|
|
|
type MaglevdStatusPayload struct {
|
|
Connected bool `json:"connected"`
|
|
LastError string `json:"last_error,omitempty"`
|
|
}
|
|
|
|
// VPPStatusPayload rides on a "vpp-status" BrowserEvent and tells the
|
|
// SPA when the maglevd↔VPP connection flips. Emitted by the frontend's
|
|
// log-event handler on vpp-connect / vpp-disconnect, and on the first
|
|
// sighting of vpp-api-send/recv (which implies VPP is up).
|
|
type VPPStatusPayload struct {
|
|
State string `json:"state"` // "connected" | "disconnected"
|
|
}
|