model

package
v0.213.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 3, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package model holds the view-facing data the TUI renders: an Agent (an op:list row enriched with the op:agent counters) and a unified Event (the µs-normalised join of the SSE stream and the op:logs poll). Both surfaces decode the control-plane envelope into these, so the views never reason about wire shapes or unit splits.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func TenantFromFQDN added in v0.128.0

func TenantFromFQDN(fqdn string) string

TenantFromFQDN extracts the opaque tenant handle from an agent fqdn of the form <agent>.<t-handle>.agents.<zone> - the second label. The fleet a caller already holds IS the tenant answer (derive, don't fetch). Returns "" when the shape does not match (never a wrong guess).

Types

type Agent

type Agent struct {
	ID      string // the LIST id ("agent-…") - used for op:agent / op:logs / kill
	Address string // the /128 - the identity, and the SSE ?agent= narrow selector
	Label   string
	FQDN    string
	PTR     string
	State   string // active / pending / released / …
	Contact string // opt-in public contact (may be empty - never fabricate)
	Created int64  // epoch ms (allocated_at)

	// Counters from op:agent (zero until detail is fetched; fail-open to zero, never 500).
	LastSeen          int64
	DNSQueries        int64
	DNSBlocked        int64
	DNSNxdomain       int64
	Packets           int64
	BytesUp           int64
	BytesDown         int64
	ConnectionsActive int64
	ConnectionsTotal  int64

	// Detailed reports whether op:agent has populated the counters (vs. a list-only row).
	Detailed bool
	// SeenInStream marks an agent discovered via the live stream / logs but possibly
	// absent from op:list (the caveat: op:list may miss connect-created agents).
	SeenInStream bool
}

Agent is one fleet member: the op:list summary, optionally enriched with the op:agent detail + live counters. Zero values are fine (a freshly-seen agent from the stream has only Address until op:agent fills the rest).

func AgentFromListItem

func AgentFromListItem(rec map[string]any) Agent

AgentFromListItem builds an Agent from an op:list row's `item` map (or the row itself if it is already the item). It is liberal in the field names it accepts.

func (Agent) BlockedPct

func (a Agent) BlockedPct() float64

BlockedPct is the share of DNS queries that were blocked, as a percent (0 when no queries). Used in the selected-agent panel.

func (Agent) HasIdentity

func (a Agent) HasIdentity() bool

HasIdentity reports whether the agent has an allocated /128 (so the SSE narrow can pin it; a history-only agent shows "(no /128)").

func (Agent) Key

func (a Agent) Key() string

Key is the stable identity key for de-duplication across list/stream/logs: the /128 when known, else the id. Two sources for the same agent collapse to one row.

func (*Agent) MergeDetail

func (a *Agent) MergeDetail(rec map[string]any)

MergeDetail folds an op:agent detail record into a (typically list-derived) Agent, filling the 17 columns. Empty/zero detail fields never clobber a known summary value.

func (Agent) Name

func (a Agent) Name() string

Name is the best human handle: the label if present, else the id, else the address.

func (Agent) String

func (a Agent) String() string

String renders a one-line summary (debug / drill-down fallback).

type Event

type Event struct {
	TsMicros int64  // epoch microseconds (native stream unit; ms sources are scaled up)
	Kind     string // dns | conn | alloc | hb
	Node     string // emitting ns box (e.g. "ns1")
	Agent    string // the agent id
	Addr128  string // the /128 (the join key for the dns→conn chain)

	// dns
	QName    string
	QType    string
	RCode    string
	Decision string // lowercase: allow/block/sinkhole/rewrite/refused
	Source   string // cache/graph/upstream/tenant-block/authoritative
	Answer   string // null today - render "-"
	LatUS    int64  // dns latency, microseconds

	// conn (egress)
	Proto     string
	PeerHost  string
	PeerPort  int
	BytesUp   int64
	BytesDown int64
	PktUp     int64 // relay read/write EVENT counts (chattiness), not wire packets
	PktDown   int64
	DurUS     int64 // conn duration, microseconds
	Reason    string
	ClientSrc string // masked original-client source prefix

	// alloc
	Action string // allocate | release
	// contains filtered or unexported fields
}

Event is the ONE internal activity model, normalised so views never reason about the µs-vs-ms split between the two surfaces:

- the SSE stream carries ts/latency/duration in MICROSECONDS (and alloc.allocated_at in ms); a live conn event has NO qname (the chain is split across two events). - the op:logs poll carries latency_ms/duration_ms in MILLISECONDS and a single `peer` column, with the whole chain (client_src + qname + peer) on ONE row.

We store time in microseconds internally (TsMicros) and format on render. The monitor (step C) stitches a live conn's qname from a per-agent dns join cache; an op:logs conn row already carries qname, so the same Event type serves both.

func FromLogRecord

func FromLogRecord(rec map[string]any) Event

FromLogRecord converts an op:logs row (ms units; whole chain on one row) into the unified Event. The poll carries latency_ms/duration_ms and a single `peer` column, which we scale to µs so the internal model has one unit. Liberal-in on field names.

func FromStream

func FromStream(m client.MonitorEvent) Event

FromStream converts a live SSE MonitorEvent (µs units) into the unified Event.

func (Event) DurationMS

func (e Event) DurationMS() int64

func (Event) FlashTick

func (e Event) FlashTick() int

FlashTick / SetFlashTick expose the render-only arrival stamp to the tui package (which lives in a different package) without leaking it onto the wire.

func (Event) LatencyMS

func (e Event) LatencyMS() int64

LatencyMS / DurationMS expose the derived ms forms (rounded), for compact display.

func (*Event) SetFlashTick

func (e *Event) SetFlashTick(t int)

func (Event) Time

func (e Event) Time() time.Time

Time returns the event time as a Go time (UTC).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL