Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Register ¶
func Register(a PanelAdapter)
Register adds a PanelAdapter to the package registry. Adapter packages call this from init(); the framework iterates the registry in registration order during Evaluate.
Duplicate IDs are not enforced — the first detected panel wins regardless. Adapter authors are responsible for non-overlapping detection criteria.
Types ¶
type PanelAdapter ¶
type PanelAdapter interface {
// ID returns the canonical adapter identifier.
ID() PanelID
// Detect inspects the host and returns whether this adapter's
// panel is present, with evidence and required ports.
Detect(ctx context.Context, exec executor.Executor) PanelDetection
// RequiredPorts returns the TCP and UDP port lists the panel
// must keep reachable for its control surface to survive an
// nftban lifecycle operation. Returns an error if the adapter
// cannot enumerate them (e.g., panel config unreadable).
RequiredPorts(ctx context.Context, exec executor.Executor) (tcp []int, udp []int, err error)
// ValidateReachability confirms the panel's control surface is
// reachable in the current ruleset. Read-only: it MUST NOT
// mutate ports, services, or rules. Returns nil on success or
// a structured error describing the missing-port/timeout/etc.
// condition.
ValidateReachability(ctx context.Context, exec executor.Executor) error
}
PanelAdapter is the contract every panel plugin implements. All methods MUST be read-only — the framework guarantees that calling Detect, RequiredPorts, or ValidateReachability never mutates host state. Adapters that need to write configuration (e.g., to apply ports to the canonical ports model) do that through a separate host-controlled write path; the framework only consults the adapter for facts and validates outcomes.
func RegisteredAdapters ¶
func RegisteredAdapters() []PanelAdapter
RegisteredAdapters returns a copy of the current registry. Stable in registration order. Returns an empty slice when nothing has been registered (the PR26.2 default — no adapters compiled in).
type PanelDetection ¶
type PanelDetection struct {
ID PanelID
Detected bool
Confidence string
Evidence []string
RequiredTCP []int
RequiredUDP []int
Warnings []string
}
PanelDetection is the structured outcome of an adapter's Detect() call. Adapters set Detected=true only when their evidence list is non-empty; Confidence is "strong" when the adapter is sure (e.g., canonical install dir + listening port + active service) and "weak" when only one indicator was found.
type PanelID ¶
type PanelID string
PanelID is the canonical identifier for a hosting panel adapter. Matches the lower-case panel-name convention used throughout the installer (e.g., "directadmin", "cpanel", "plesk", "fakepanel").
type PanelPolicy ¶
type PanelPolicy struct {
// RequirePanelSuccess: when an adapter detects a panel and either
// RequiredPorts or ValidateReachability errors, the result is
// Fatal. Default true. The "non-fatal warning" path that let
// dns2's panel-enable failure slip through StateCommitted is
// removed by setting this to true.
RequirePanelSuccess bool
// AllowPanelAbsent: when no adapter detects a panel, treat as
// healthy (the common no-panel case). Default true.
AllowPanelAbsent bool
// OperatorDisabled: operator passed --no-panel (or equivalent
// supported flag) to opt out of panel-survival enforcement on
// this run. The framework still runs adapters for diagnostic
// purposes but always returns Fatal=false.
OperatorDisabled bool
}
PanelPolicy controls how the framework converts adapter outcomes into a Fatal/non-fatal verdict.
func DefaultPolicy ¶
func DefaultPolicy() PanelPolicy
DefaultPolicy returns the production-default policy: RequirePanelSuccess=true, AllowPanelAbsent=true, OperatorDisabled=false.
type PanelResult ¶
type PanelResult struct {
// Detection is the first adapter's detection record (or a
// zero-value detection with ID="" when no adapter detected
// anything).
Detection PanelDetection
// PortsTCP / PortsUDP mirror the RequiredPorts result for the
// detected panel (nil when no panel detected or RequiredPorts
// errored).
PortsTCP []int
PortsUDP []int
// PortsApplied indicates whether the adapter's RequiredPorts
// call succeeded. It does NOT confirm ports were written to the
// canonical ports model — that is a separate framework
// responsibility outside PR26.2 scope. The flag exists so the
// assertion message can distinguish "couldn't determine ports"
// from "ports known and reachability validated".
PortsApplied bool
// ReachableAfter is true when ValidateReachability returned nil.
// False on adapter error or when the framework did not reach
// the reachability check (e.g., RequiredPorts errored first).
ReachableAfter bool
// Fatal is the policy-derived verdict. When true, the caller
// (validate.assertion) MUST block StateCommitted.
Fatal bool
// Reason carries a human-readable summary suitable for the
// AssertionResult.Detail field. Empty when not Fatal.
Reason string
}
PanelResult is the structured outcome of Evaluate.
func Evaluate ¶
func Evaluate(ctx context.Context, exec executor.Executor, log *logging.Logger, policy PanelPolicy) PanelResult
Evaluate runs the registered adapters and returns the first detected panel's PanelResult. Pure framework call — relies entirely on the adapter contract; no panel-specific knowledge in this function.
func EvaluateAdapters ¶
func EvaluateAdapters(ctx context.Context, exec executor.Executor, log *logging.Logger, adapters []PanelAdapter, policy PanelPolicy) PanelResult
EvaluateAdapters is the test-callable variant of Evaluate. Callers pass an explicit adapter slice so they can inject FakePanelAdapter without touching the global registry.