Documentation
¶
Overview ¶
Package controller implements reconcilers for the fathom.skaphos.io CRDs.
Index ¶
Constants ¶
const TracerScope = "github.com/skaphos/fathom/internal/controller"
TracerScope is the OpenTelemetry instrumentation scope shared by the reconcilers in this package (SKA-293). Exported so the manager wiring in internal/app can hand each reconciler a tracer from the same scope.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AddonCheckReconciler ¶
type AddonCheckReconciler struct {
client.Client
Scheme *runtime.Scheme
Adapters addonAdapterLookup
// ProbeImage is the operator-level default container image surfaced to
// adapters that launch probe pods. Forwarded verbatim into adapter.Request.
// Empty when no operator default is configured; adapters then fall back to
// per-AddonCheck thresholds or their own hardcoded default.
ProbeImage string
// Tracer creates the per-Reconcile span. Optional: a nil Tracer falls back
// to the global provider (a no-op unless tracing is enabled). The adapter
// Run span nests under this reconcile span via the context.
Tracer trace.Tracer
// AddonClients builds the per-addon impersonating client handed to an adapter
// as adapter.Request.Client, so the adapter reads under its own least-privilege
// ServiceAccount rather than the operator's (SKA-58). Nil disables
// impersonation — the operator client is used instead (unit tests, and local
// out-of-cluster runs where the manager already uses a privileged kubeconfig).
AddonClients impersonation.ClientFactory
// Namespace is the operator's own namespace, where the per-addon
// ServiceAccounts live. Populated from FATHOM_NAMESPACE (downward API) in
// cluster. Empty is only valid out of cluster (or when AddonClients is nil):
// in-cluster with an empty Namespace fails closed so adapters never run as
// the operator SA (SKA-162).
Namespace string
// Recorder emits the Kubernetes Events contract (result transitions and
// operational failures) on AddonCheck resources. Optional: nil disables
// event recording; the check gauges are unaffected.
Recorder events.EventRecorder
}
AddonCheckReconciler reconciles an AddonCheck object.
func (*AddonCheckReconciler) Reconcile ¶
func (r *AddonCheckReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, err error)
Reconcile resolves the AddonCheck's adapter and, when the check is due (first sight, a spec change, an elapsed interval, or a new run-now trigger), runs the adapter and records a HealthReport plus status. It requeues one interval out so the result tracks the addon's live state.
func (*AddonCheckReconciler) SetupWithManager ¶
func (r *AddonCheckReconciler) SetupWithManager(mgr ctrl.Manager) error
SetupWithManager sets up the controller with the Manager.
type ClusterHealthReconciler ¶
type ClusterHealthReconciler struct {
client.Client
Scheme *runtime.Scheme
// Tracer creates the per-Reconcile span. Optional: a nil Tracer falls back
// to the global provider (a no-op unless tracing is enabled).
Tracer trace.Tracer
// Recorder emits the Kubernetes Events contract (result transitions and
// operational failures) on ClusterHealth resources. Optional: nil disables
// event recording; the check gauges are unaffected.
Recorder events.EventRecorder
}
ClusterHealthReconciler reconciles a ClusterHealth object. It aggregates the Status of selected HealthCheck resources into a single worst-case Result. Per the AGENTS.md invariant and ADR-0004, this controller deliberately never imports or reads HealthReport — its only input is HealthCheck.Status, which the HealthCheckReconciler maintains.
func (*ClusterHealthReconciler) SetupWithManager ¶
func (r *ClusterHealthReconciler) SetupWithManager(mgr ctrl.Manager) error
SetupWithManager sets up the controller with the Manager. It owns ClusterHealth and watches HealthCheck so a member's Status change re-enqueues every ClusterHealth whose selector matches it — and so a label edit that moves a HealthCheck *out* of a selector re-enqueues the ClusterHealth that must drop it (#148).
ResourceVersionChangedPredicate filters inside the source, before handler dispatch, and passes the event through unmodified, so ObjectOld survives. A label-only predicate would be wrong here: status-only changes are the primary reason this watch exists.
type DNSCheckReconciler ¶ added in v0.5.1
type DNSCheckReconciler struct {
client.Client
Scheme *runtime.Scheme
// ProbeClient creates, polls, and deletes probe pods. It MUST be an
// uncached client.
//
// The manager's own client serves structured reads from the shared informer
// cache, and scopedCacheOptions() does not list Pod — so a single cached Pod
// Get would start an unfiltered cluster-wide Pod informer and pull every pod
// in the cluster into memory, the failure removed in #164/SKA-581. The
// adapter path avoids this only incidentally, by handing adapters the
// uncached impersonating client; DNSCheck has no per-addon identity to
// impersonate, so it must be given an uncached client explicitly.
ProbeClient client.Client
// ProbeImage is the container image probe pods run.
ProbeImage string
// MaxConcurrentProbes bounds probe pods in flight for a single check
// (FR-103a). Values below 1 are treated as 1; Options.Validate rejects them
// at startup, so this is only a guard against a zero-valued struct in tests.
MaxConcurrentProbes int
// Launcher runs one probe pod to completion. Optional: nil builds a
// probe.Launcher over ProbeClient. Tests inject a fake.
Launcher dnsProbeRunner
// MinPairBudget overrides the least time worth giving a pair before the run
// stops dispatching. Mostly useful in tests, where the production floor
// would make a truncation case take tens of seconds; production callers
// should leave it zero.
MinPairBudget time.Duration
// Tracer creates the per-Reconcile span. Optional; nil falls back to the
// global provider (a no-op unless tracing is enabled).
Tracer trace.Tracer
// Recorder emits the Events contract on DNSCheck resources. Optional; nil
// disables events without affecting the gauges.
Recorder events.EventRecorder
}
DNSCheckReconciler reconciles a DNSCheck object.
Each run expands the specification into (target, vantage point) pairs, runs one probe pod per pair inside the check's OWN namespace (FR-031), folds the per-pair outcomes into a single verdict with the project-wide fold, and mirrors the result into status, metrics, events, and — only when the verdict changes — a HealthReport.
func (*DNSCheckReconciler) Reconcile ¶ added in v0.5.1
func (r *DNSCheckReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, err error)
Reconcile evaluates a DNSCheck and mirrors the outcome into status, metrics, events, and history.
func (*DNSCheckReconciler) SetupWithManager ¶ added in v0.5.1
func (r *DNSCheckReconciler) SetupWithManager(mgr ctrl.Manager) error
SetupWithManager registers the reconciler.
It deliberately does NOT Own(&corev1.Pod{}): an Owns clause installs an informer for that type, which is precisely the cluster-wide Pod watch ProbeClient exists to avoid. Probe pods are short-lived and polled directly, so nothing needs to watch them — and a pod event could not usefully re-trigger a run that is already in flight.
type HealthCheckReconciler ¶
type HealthCheckReconciler struct {
client.Client
Scheme *runtime.Scheme
// Tracer creates the per-Reconcile span. Optional: a nil Tracer falls back
// to the global provider (a no-op unless tracing is enabled).
Tracer trace.Tracer
// Recorder emits the Kubernetes Events contract (result transitions and
// operational failures) on HealthCheck resources. Optional: nil disables
// event recording; the check gauges are unaffected.
Recorder events.EventRecorder
}
HealthCheckReconciler reconciles a HealthCheck object. It is a wrapper that mirrors a referenced specialized check's status into a uniform shape per docs/adr/0004-healthcheck-as-wrapper.md. It does not execute checks itself.
func (*HealthCheckReconciler) SetupWithManager ¶
func (r *HealthCheckReconciler) SetupWithManager(mgr ctrl.Manager) error
SetupWithManager sets up the controller with the Manager. It owns HealthCheck and watches AddonCheck so a target's status change re-enqueues every HealthCheck that wraps it.
type NodeCertificateCheckReconciler ¶ added in v0.2.0
type NodeCertificateCheckReconciler struct {
client.Client
Scheme *runtime.Scheme
// NodeAgentImage is the dedicated node-agent container image (cmd/node-agent),
// distinct from the operator and probe images. Forwarded into the managed
// DaemonSet's pod spec.
NodeAgentImage string
// NodeAgentRoleName is the ClusterRole the per-check RoleBinding grants to
// the node-agent ServiceAccount. Defaults to defaultNodeAgentRoleName.
NodeAgentRoleName string
// Tracer creates the per-Reconcile span. Optional; a nil Tracer falls back
// to the global provider (a no-op unless tracing is enabled).
Tracer trace.Tracer
// Recorder emits the Kubernetes Events contract (result transitions and
// operational failures) on NodeCertificateCheck resources. Optional: nil
// disables event recording; the check gauges are unaffected.
Recorder events.EventRecorder
}
NodeCertificateCheckReconciler reconciles a NodeCertificateCheck object. It manages a hardened, read-only node-agent DaemonSet (one pod per selected node), aggregates the per-node report ConfigMaps those agents publish into a single HealthReport, and mirrors the aggregate into Status (SKA-49 / SKA-519).
func (*NodeCertificateCheckReconciler) Reconcile ¶ added in v0.2.0
func (r *NodeCertificateCheckReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, err error)
Reconcile ensures the node-agent DaemonSet and its RBAC exist (or are removed while paused), rolls up the per-node report ConfigMaps into a HealthReport, and mirrors the aggregate into Status.
func (*NodeCertificateCheckReconciler) SetupWithManager ¶ added in v0.2.0
func (r *NodeCertificateCheckReconciler) SetupWithManager(mgr ctrl.Manager) error
SetupWithManager wires the reconciler. It owns the DaemonSet, ServiceAccount, and RoleBinding it creates, and watches report ConfigMaps by label so a fresh node report (which may not yet carry the owner reference) triggers a roll-up.