Documentation
¶
Index ¶
- Constants
- Variables
- func AtomicReplaceBinary(currentPath, newPath string) error
- func CompareVersions(a, b string) int
- func DownloadArchive(ctx context.Context, url, token string) (string, error)
- func DownloadChecksum(ctx context.Context, url, token string) (string, error)
- func DownloadSignature(ctx context.Context, url, token string) ([]byte, error)
- func ExtractBinaryFromArchive(archivePath string) (string, error)
- func NewSlogContextHandler(inner slog.Handler) slog.Handler
- func ParseReleaseTag(tag string) (component, version string, ok bool)
- func ResolveAssetURLs(release *GitHubRelease, component string) (binaryURL, checksumURL, signatureURL string)
- func VerifyChecksum(path, expected string) error
- type Agent
- type AgentRuntime
- type AuditEvent
- type BulkAdoptResult
- type FleetScopeAccess
- type GitHubAsset
- type GitHubRelease
- type Instance
- type Intervals
- type MetricSnapshot
- type Options
- type PanelRuntime
- type PanelSettings
- type RetentionSettings
- type RuntimeDC
- type RuntimeEvent
- type RuntimeMeWritersSummary
- type RuntimeSystemLoad
- type RuntimeUpstream
- type Server
- func (s *Server) Close()
- func (s *Server) Connect(stream gatewayrpc.AgentGateway_ConnectServer) error
- func (s *Server) GRPCTLSConfig() *tls.Config
- func (s *Server) Handler() http.Handler
- func (s *Server) RenewCertificate(ctx context.Context, request *gatewayrpc.RenewCertificateRequest) (*gatewayrpc.RenewCertificateResponse, error)
- func (s *Server) StartupError() error
- type UpdateSettings
- type UpdateState
- type UserAppearance
Constants ¶
const ( // PanelRuntimeSourceLegacy reports that runtime values come from the legacy flag-based startup path. PanelRuntimeSourceLegacy = "legacy" // PanelRuntimeSourceConfigFile reports that runtime values come from config.toml. PanelRuntimeSourceConfigFile = "config_file" )
const EnvForceSecureCookie = "PANVEX_FORCE_SECURE_COOKIE"
EnvForceSecureCookie unconditionally marks the session cookie Secure, regardless of TLS heuristics (Q3.U-S-13). Operators set this in any production deployment fronted by HTTPS so a misconfigured proxy or a missing X-Forwarded-Proto cannot leak the cookie over plain HTTP.
const EnvWSDevLoopback = "PANVEX_WS_DEV_LOOPBACK"
EnvWSDevLoopback opts into the development-only behaviour that allows WebSocket upgrade requests from any port on 127.0.0.1/::1/localhost. Without this env set we fall back to the strict policy: the Origin must match the exact request Host, even for loopback clients. The Vite dev server proxies /api to :8080 with Origin matching :5173, so developers must set PANVEX_WS_DEV_LOOPBACK=1 explicitly when running split-port.
Variables ¶
var ErrAlreadyAdopted = errors.New("client already adopted")
ErrAlreadyAdopted is returned by adoptDiscoveredClient when the discovered record has already been adopted. Previously this was a generic fmt.Errorf("client already adopted"); the sentinel lets tests and HTTP handlers detect the condition reliably via errors.Is (P2-LOG-03 / L-11).
var ErrLegacyEnc1RequiresKey = errors.New("legacy ENC:v1 key requires --encryption-key-file to migrate")
ErrLegacyEnc1RequiresKey is returned when the persisted CA private key is stored in the legacy "ENC:v1" format but no encryption passphrase is configured to migrate it. P2-SEC-05: legacy ENC:v1 uses SHA-256 without a salt and must not be silently accepted — the operator must either provide the encryption key so we can re-encrypt as "ENC2:" or remove the stored key to regenerate the CA.
Functions ¶
func AtomicReplaceBinary ¶
AtomicReplaceBinary replaces the binary at currentPath with the one at newPath. See updates.AtomicReplaceBinary for details.
func CompareVersions ¶
CompareVersions delegates to updates.CompareVersions.
func DownloadArchive ¶
DownloadArchive fetches a .tar.gz archive from url. See updates.DownloadArchive for details.
func DownloadChecksum ¶
DownloadChecksum fetches a .sha256 checksum file and returns the hex digest. See updates.DownloadChecksum for details.
func DownloadSignature ¶
DownloadSignature fetches a detached signature file and returns its bytes. See updates.DownloadSignature for details.
func ExtractBinaryFromArchive ¶
ExtractBinaryFromArchive extracts the first file from a .tar.gz archive into a temporary executable. See updates.ExtractBinaryFromArchive for details.
func NewSlogContextHandler ¶
NewSlogContextHandler wraps an existing handler so emitted records carry request_id when present in ctx. Returns the inner handler unchanged when given nil so callers can compose unconditionally. Exported for cmd/control-plane to install at startup.
func ParseReleaseTag ¶
ParseReleaseTag delegates to updates.ParseReleaseTag.
func ResolveAssetURLs ¶
func ResolveAssetURLs(release *GitHubRelease, component string) (binaryURL, checksumURL, signatureURL string)
ResolveAssetURLs delegates to updates.ResolveAssetURLs.
func VerifyChecksum ¶
VerifyChecksum computes the SHA256 of the file at path and compares it to the expected hex digest. See updates.VerifyChecksum for details.
Types ¶
type Agent ¶
type Agent struct {
ID string `json:"id"`
NodeName string `json:"node_name"`
FleetGroupID string `json:"fleet_group_id"`
Version string `json:"version"`
ReadOnly bool `json:"read_only"`
PresenceState string `json:"presence_state"`
CertificateRecovery *agentCertificateRecoveryGrantResponse `json:"certificate_recovery,omitempty"`
CertIssuedAt *time.Time `json:"cert_issued_at,omitempty"`
CertExpiresAt *time.Time `json:"cert_expires_at,omitempty"`
// CertSerial is the serial of the most recently issued client cert.
// Used to pin agent identity at gRPC connect time (Q4.U-S-04). Not
// exposed in the public JSON shape — operators don't need it and
// it's noise in the dashboard.
CertSerial string `json:"-"`
Runtime AgentRuntime `json:"runtime"`
LastSeenAt time.Time `json:"last_seen_at"`
}
Agent stores the control-plane view of a connected host agent.
type AgentRuntime ¶
type AgentRuntime struct {
AcceptingNewConnections bool `json:"accepting_new_connections"`
MERuntimeReady bool `json:"me_runtime_ready"`
ME2DCFallbackEnabled bool `json:"me2dc_fallback_enabled"`
UseMiddleProxy bool `json:"use_middle_proxy"`
StartupStatus string `json:"startup_status"`
StartupStage string `json:"startup_stage"`
StartupProgressPct float64 `json:"startup_progress_pct"`
InitializationStatus string `json:"initialization_status"`
Degraded bool `json:"degraded"`
LifecycleState string `json:"lifecycle_state"`
InitializationStage string `json:"initialization_stage"`
InitializationProgressPct float64 `json:"initialization_progress_pct"`
TransportMode string `json:"transport_mode"`
CurrentConnections int `json:"current_connections"`
CurrentConnectionsME int `json:"current_connections_me"`
CurrentConnectionsDirect int `json:"current_connections_direct"`
ActiveUsers int `json:"active_users"`
UptimeSeconds float64 `json:"uptime_seconds"`
ConnectionsTotal uint64 `json:"connections_total"`
ConnectionsBadTotal uint64 `json:"connections_bad_total"`
HandshakeTimeoutsTotal uint64 `json:"handshake_timeouts_total"`
ConfiguredUsers int `json:"configured_users"`
DCCoveragePct float64 `json:"dc_coverage_pct"`
HealthyUpstreams int `json:"healthy_upstreams"`
TotalUpstreams int `json:"total_upstreams"`
DCs []RuntimeDC `json:"dcs"`
Upstreams []RuntimeUpstream `json:"upstreams"`
RecentEvents []RuntimeEvent `json:"recent_events"`
SystemLoad RuntimeSystemLoad `json:"system_load"`
MeWritersSummary *RuntimeMeWritersSummary `json:"me_writers_summary,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
}
AgentRuntime stores the normalized Telemt operator overview for one agent.
type AuditEvent ¶
type AuditEvent struct {
ID string `json:"id"`
ActorID string `json:"actor_id"`
Action string `json:"action"`
TargetID string `json:"target_id"`
CreatedAt time.Time `json:"created_at"`
Details map[string]any `json:"details"`
}
AuditEvent stores an immutable operator or security event emitted by the control-plane.
type BulkAdoptResult ¶
type BulkAdoptResult struct {
ID string `json:"id"`
Status string `json:"status"`
ClientID string `json:"client_id,omitempty"`
Name string `json:"name,omitempty"`
Message string `json:"message,omitempty"`
}
BulkAdoptResult is the per-id outcome from bulkAdoptDiscoveredClients. Status is one of: "adopted" (new client or merged into existing), "already_adopted" (resolved via a sibling earlier in the batch or by a concurrent caller), "error" (Message holds details).
type FleetScopeAccess ¶
FleetScopeAccess captures the operator's effective fleet-group scope for one request. R-S-14 introduced this as the foundation for per-resource authorization: handlers that touch a fleet-group-scoped resource (clients, fleet groups, discovered clients, jobs targeting agents) consult the access set before reading or mutating.
Semantics:
- Global == true → no per-group restriction; admin role always resolves to global, and an operator with no scope rows behaves the same way (single-tenant default).
- Global == false → only fleet-group ids in Allowed are visible.
Methods on this struct are the only path callers should use; do not inspect Allowed directly so a future migration to a different scope model (regex, hierarchical) lands in one place.
func (FleetScopeAccess) Filter ¶
func (a FleetScopeAccess) Filter(fleetGroupIDs []string) []string
Filter returns the subset of input ids the operator can access. Useful for narrowing list responses and bulk-job target lists in one pass without per-id allocation.
func (FleetScopeAccess) IsAllowed ¶
func (a FleetScopeAccess) IsAllowed(fleetGroupID string) bool
IsAllowed reports whether the operator can act on the given fleet group id. Global access always passes; otherwise the id must be in the explicit allow-set.
func (FleetScopeAccess) IsAllowedAny ¶
func (a FleetScopeAccess) IsAllowedAny(fleetGroupIDs []string) bool
IsAllowedAny reports whether at least one of the supplied fleet group ids is in scope. Used by client-side checks where a managed client may live in multiple groups — operator access is granted as long as ONE of those groups is in scope. An empty input means "no group affiliation"; we treat that as deny-by-default for non-global scopes (the operator cannot see fleet-orphan clients).
type GitHubAsset ¶
type GitHubAsset = updates.GitHubReleaseAsset
GitHubRelease re-exported for handlers/tests that still reference the short name through this package.
type GitHubRelease ¶
type GitHubRelease = updates.GitHubRelease
GitHubRelease re-exported for handlers/tests that still reference the short name through this package.
func FetchLatestVersions ¶
func FetchLatestVersions(ctx context.Context, repo, token string) (panel, agent *GitHubRelease, err error)
FetchLatestVersions delegates to updates.FetchLatestVersions.
type Instance ¶
type Instance struct {
ID string `json:"id"`
AgentID string `json:"agent_id"`
Name string `json:"name"`
Version string `json:"version"`
ConfigFingerprint string `json:"config_fingerprint"`
ConnectedUsers int `json:"connected_users"`
ReadOnly bool `json:"read_only"`
UpdatedAt time.Time `json:"updated_at"`
}
Instance stores the Telemt runtime metadata discovered through an agent.
type Intervals ¶
type Intervals struct {
// JobsKeyEviction is how often the jobs service scans for
// terminal-state idempotency keys to evict.
JobsKeyEviction time.Duration
// JobsKeyEvictionTTL is the age at which a terminal-state key is
// evicted.
JobsKeyEvictionTTL time.Duration
// JobsAckExpiry is how often the jobs service scans for
// acknowledged-but-result-less targets.
JobsAckExpiry time.Duration
// JobsAckExpiryTTL is the threshold after which an acknowledged
// target with no result is transitioned to expired. Must match
// the agent-side idempotency cache.
JobsAckExpiryTTL time.Duration
// Rollup is how often the timeseries rollup worker fires.
Rollup time.Duration
// MetricsPoller is the cadence for sampling derived gauges
// (agent connected count, event-hub subscribers, job queue depth,
// lockout count, DB pool stats).
MetricsPoller time.Duration
}
Intervals bundles the worker / poller cadences that are inherent to the control-plane lifecycle (not tied to a single feature).
Q5.U-Q-04 introduced this struct; R-Q-04 wires it through Options and Server so operators (and tests) can override individual cadences without rebuilding the binary or threading new constants through every callsite. The defaults match the legacy package-level values.
func DefaultIntervals ¶
func DefaultIntervals() Intervals
DefaultIntervals returns the values matching the legacy package-level constants. Tests that need a fast clock can construct an Intervals literal directly and pass it through Options.Intervals.
type MetricSnapshot ¶
type MetricSnapshot struct {
ID string `json:"id"`
AgentID string `json:"agent_id"`
InstanceID string `json:"instance_id"`
CapturedAt time.Time `json:"captured_at"`
Values map[string]uint64 `json:"values"`
}
MetricSnapshot stores an aggregated view of a single agent or instance metric set.
type Options ¶
type Options struct {
Now func() time.Time
Users []auth.User
Store storage.Store
UIFiles fs.FS
PanelRuntime PanelRuntime
RequestRestart func() error
// TrustedProxyCIDRs lists additional CIDR ranges whose X-Forwarded-For
// header is trusted for rate-limit key extraction. Loopback addresses
// are always trusted regardless of this setting.
//
// WARNING: When the control-plane runs behind a non-loopback reverse
// proxy and this list is empty, every inbound request resolves to the
// proxy's IP for rate-limit keying. All clients then share a single
// bucket and will be throttled collectively. Always configure this
// field to include every intermediate proxy/load-balancer CIDR.
TrustedProxyCIDRs []*net.IPNet
// EncryptionKey, when set, encrypts the CA private key at rest using
// AES-256-GCM. The key is derived from this passphrase via SHA-256.
// Existing unencrypted keys are transparently migrated on next save.
EncryptionKey string
// Logger is the structured logger for the server. If nil, slog.Default() is used.
Logger *slog.Logger
// Version is the panel version string (e.g. "v1.2.3" or "dev").
Version string
// CommitSHA is the git commit hash baked in at build time.
CommitSHA string
// BuildTime is the RFC3339 build timestamp baked in at build time.
BuildTime string
// MetricsScrapeToken, when non-empty, enables the GET /metrics endpoint
// and requires callers to present `Authorization: Bearer <token>` with a
// byte-for-byte match. When empty, the /metrics route is not registered
// at all (silent opt-in) so production deployments that never set the env
// var cannot accidentally expose runtime telemetry.
MetricsScrapeToken string
// Intervals overrides the default worker / poller cadences. Zero-valued
// fields fall back to DefaultIntervals(). Tests use this to compress
// retention sweeps and rollup scans into milliseconds.
Intervals Intervals
// LoginTimingFloor sets the wall-clock minimum every login response
// (success or failure) is padded to (R-S-19). Zero (unset) falls
// back to the production default of 150ms. Pass any negative value
// to disable the pad entirely — tests use this to avoid burning
// real wall-clock seconds in the suite.
LoginTimingFloor time.Duration
}
Options defines the runtime dependencies used by the control-plane server.
type PanelRuntime ¶
type PanelRuntime struct {
HTTPListenAddress string
HTTPRootPath string
AgentHTTPRootPath string
PanelAllowedCIDRs []*net.IPNet
GRPCListenAddress string
TLSMode string
TLSCertFile string
TLSKeyFile string
RestartSupported bool
ConfigSource string
ConfigPath string
}
PanelRuntime describes the currently applied network and restart runtime.
type PanelSettings ¶
type PanelSettings struct {
HTTPPublicURL string `json:"http_public_url"`
GRPCPublicEndpoint string `json:"grpc_public_endpoint"`
UpdatedAt int64 `json:"updated_at_unix"`
}
PanelSettings stores operator-managed public access settings for the panel.
type RetentionSettings ¶
type RetentionSettings struct {
TSRawSeconds int `json:"ts_raw_seconds"`
TSHourlySeconds int `json:"ts_hourly_seconds"`
TSDCSeconds int `json:"ts_dc_seconds"`
IPHistorySeconds int `json:"ip_history_seconds"`
EventSeconds int `json:"event_history_seconds"`
AuditEventSeconds int `json:"audit_event_seconds"`
MetricSnapshotSeconds int `json:"metric_snapshot_seconds"`
// JobsSeconds bounds how long terminal jobs (succeeded/failed/
// expired) live in the jobs table before the rollup loop deletes
// them via PruneTerminalJobs (Q2.U-P-02).
JobsSeconds int `json:"jobs_seconds"`
}
RetentionSettings controls how long timeseries data is kept before pruning.
type RuntimeDC ¶
type RuntimeDC struct {
DC int `json:"dc"`
AvailableEndpoints int `json:"available_endpoints"`
AvailablePct float64 `json:"available_pct"`
RequiredWriters int `json:"required_writers"`
AliveWriters int `json:"alive_writers"`
CoveragePct float64 `json:"coverage_pct"`
FreshAliveWriters int `json:"fresh_alive_writers"`
FreshCoveragePct float64 `json:"fresh_coverage_pct"`
RTTMs float64 `json:"rtt_ms"`
Load int `json:"load"`
}
RuntimeDC stores one DC health row reported by the local Telemt runtime.
type RuntimeEvent ¶
type RuntimeEvent struct {
Sequence uint64 `json:"sequence"`
TimestampUnix int64 `json:"timestamp_unix"`
EventType string `json:"event_type"`
Context string `json:"context"`
}
RuntimeEvent stores one recent Telemt runtime event normalized by the agent.
type RuntimeMeWritersSummary ¶
type RuntimeMeWritersSummary struct {
ConfiguredEndpoints int `json:"configured_endpoints"`
AvailableEndpoints int `json:"available_endpoints"`
CoveragePct float64 `json:"coverage_pct"`
FreshAliveWriters int `json:"fresh_alive_writers"`
FreshCoveragePct float64 `json:"fresh_coverage_pct"`
RequiredWriters int `json:"required_writers"`
AliveWriters int `json:"alive_writers"`
}
RuntimeMeWritersSummary carries the ME writers pool aggregate returned by Telemt.
type RuntimeSystemLoad ¶
type RuntimeSystemLoad struct {
CPUUsagePct float64 `json:"cpu_usage_pct"`
MemoryUsedBytes uint64 `json:"memory_used_bytes"`
MemoryTotalBytes uint64 `json:"memory_total_bytes"`
MemoryUsagePct float64 `json:"memory_usage_pct"`
DiskUsedBytes uint64 `json:"disk_used_bytes"`
DiskTotalBytes uint64 `json:"disk_total_bytes"`
DiskUsagePct float64 `json:"disk_usage_pct"`
Load1M float64 `json:"load_1m"`
Load5M float64 `json:"load_5m"`
Load15M float64 `json:"load_15m"`
NetBytesSent uint64 `json:"net_bytes_sent"`
NetBytesRecv uint64 `json:"net_bytes_recv"`
}
RuntimeSystemLoad carries server resource utilization metrics.
type RuntimeUpstream ¶
type RuntimeUpstream struct {
UpstreamID int `json:"upstream_id"`
RouteKind string `json:"route_kind"`
Address string `json:"address"`
Healthy bool `json:"healthy"`
Fails int `json:"fails"`
EffectiveLatencyMs float64 `json:"effective_latency_ms"`
Weight int `json:"weight"`
LastCheckAgeSecs int `json:"last_check_age_secs"`
Scopes []string `json:"scopes,omitempty"`
}
RuntimeUpstream stores one upstream health row reported by the local Telemt runtime.
type Server ¶
type Server struct {
gatewayrpc.UnimplementedAgentGatewayServer
// contains filtered or unexported fields
}
Server wires local-auth, inventory, jobs, and operator APIs into one HTTP surface.
func (*Server) Close ¶
func (s *Server) Close()
Close stops background workers and drains pending writes. It should be called before closing the storage backend.
Shutdown ordering (P2-LOG-10 / M-R4 / P7-R6):
- batchWriter.StopWithTimeout(10s) FIRST — drains the audit-events queue (and the 7 other streams) before any background goroutine that might still be producing audits is shut down. This bounds the worst-case shutdown time at 10s so a wedged DB cannot hang the process indefinitely, while still giving the DB a realistic window to absorb in-flight rows.
- metrics / rollup goroutines stop afterwards.
Events enqueued AFTER this point may race with the final drain and can be dropped — upstream callers (HTTP handlers, gRPC streams) must stop before Close() runs to guarantee zero loss.
func (*Server) Connect ¶
func (s *Server) Connect(stream gatewayrpc.AgentGateway_ConnectServer) error
func (*Server) GRPCTLSConfig ¶
GRPCTLSConfig returns the TLS configuration used by the agent gateway listener.
func (*Server) RenewCertificate ¶
func (s *Server) RenewCertificate(ctx context.Context, request *gatewayrpc.RenewCertificateRequest) (*gatewayrpc.RenewCertificateResponse, error)
RenewCertificate rotates the short-lived mTLS material for an authenticated agent.
func (*Server) StartupError ¶
StartupError reports the first initialization error encountered while restoring persisted state.
type UpdateSettings ¶
type UpdateSettings struct {
CheckIntervalHours int `json:"check_interval_hours"`
AutoUpdatePanel bool `json:"auto_update_panel"`
AutoUpdateAgents bool `json:"auto_update_agents"`
GitHubRepo string `json:"github_repo"`
GitHubToken string `json:"github_token,omitempty"`
AgentDownloadSource string `json:"agent_download_source"`
}
UpdateSettings controls how the panel checks for and applies updates.
type UpdateState ¶
type UpdateState struct {
LatestPanelVersion string `json:"latest_panel_version"`
LatestAgentVersion string `json:"latest_agent_version"`
PanelDownloadURL string `json:"panel_download_url"`
PanelChecksumURL string `json:"panel_checksum_url"`
PanelSignatureURL string `json:"panel_signature_url"`
AgentDownloadURL string `json:"agent_download_url"`
AgentChecksumURL string `json:"agent_checksum_url"`
AgentSignatureURL string `json:"agent_signature_url"`
PanelChangelog string `json:"panel_changelog"`
AgentChangelog string `json:"agent_changelog"`
LastCheckedAt int64 `json:"last_checked_at"`
}
UpdateState caches the latest known versions from GitHub.
Source Files
¶
- account_lockout.go
- agent_flow.go
- agent_sessions.go
- audit_trail.go
- authority.go
- authz_middleware.go
- batch_writer.go
- clients_discovery.go
- clients_flow.go
- clients_types.go
- csrf_token.go
- fleet_scope.go
- grpc_gateway.go
- http_agents.go
- http_auth.go
- http_clients.go
- http_clients_discovery.go
- http_control_room.go
- http_enrollment.go
- http_events.go
- http_fleet_groups.go
- http_fleet_integrations.go
- http_health.go
- http_helpers.go
- http_history.go
- http_inventory.go
- http_jobs.go
- http_messages.go
- http_pprof.go
- http_recovery.go
- http_retention.go
- http_security.go
- http_settings_appearance.go
- http_settings_panel.go
- http_telemetry.go
- http_updates.go
- http_users.go
- intervals.go
- ip_whitelist.go
- keyencrypt.go
- lifecycle.go
- logging_redact.go
- metrics.go
- options.go
- panel_settings.go
- rate_limit.go
- request_id.go
- request_timeout.go
- routes.go
- self_update.go
- server.go
- state_restore.go
- telemetry_runtime.go
- timeseries_rollup.go
- trusted_proxy.go
- types.go
- ui.go
- update_checker.go
- update_security.go
- user_appearance.go