Help us shape the future of Go! Take the 2026 Go Developer Survey

controller

package
v0.16.0 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Overview

Package controller reconciles ClusterScan custom resources by triggering scans on the configured cadence and writing the outcome back to the resource status. It uses an unstructured dynamic client so the operator can ship without code generation steps.

Index

Constants

View Source
const (
	// ConditionReady is True when the most recent scan succeeded.
	ConditionReady = "Ready"
	// ConditionScanning is True while a scan runs.
	ConditionScanning = "Scanning"
	// ConditionFailed is True when the most recent scan or the spec failed.
	ConditionFailed = "Failed"
	// ReasonScanStarted marks a scan in progress.
	ReasonScanStarted = "ScanStarted"
	// ReasonScanSucceeded marks a completed scan.
	ReasonScanSucceeded = "ScanSucceeded"
	// ReasonScanFailed marks a scan that returned an error.
	ReasonScanFailed = "ScanFailed"
	// ReasonInvalidSpec marks a spec the controller cannot act on.
	ReasonInvalidSpec = "InvalidSpec"
	// ReasonPaused marks a resource with spec.paused set.
	ReasonPaused = "Paused"
)

Condition types and reasons written to ClusterScan status.

View Source
const (
	// PhasePending indicates the controller has not yet run a scan for the resource.
	PhasePending = "Pending"
	// PhaseRunning indicates a scan is currently executing.
	PhaseRunning = "Running"
	// PhaseSucceeded indicates the last scan completed without error.
	PhaseSucceeded = "Succeeded"
	// PhaseFailed indicates the last scan ended with an error.
	PhaseFailed = "Failed"
	// PhasePaused indicates spec.paused is true.
	PhasePaused = "Paused"
)

Reconciliation phases.

Variables

View Source
var ClusterScanGVR = schema.GroupVersionResource{
	Group:    "fleetsweeper.io",
	Version:  "v1alpha1",
	Resource: "clusterscans",
}

ClusterScanGVR is the GroupVersionResource for the ClusterScan CRD.

Functions

func Clients added in v0.10.0

func Clients(kubeconfigPath, contextName string) (dynamic.Interface, typedcorev1.EventsGetter, error)

Clients builds the dynamic client the controller watches ClusterScans with and the core client it records Events through. When kubeconfigPath is empty and an in-cluster service-account token exists, the in-cluster configuration is preferred so the operator can run as a Deployment without extra wiring.

func ResetMetrics

func ResetMetrics()

ResetMetrics zeroes every counter. Intended for tests only.

func WriteMetrics

func WriteMetrics(w io.Writer)

WriteMetrics emits the controller's counters in the Prometheus text exposition format. Safe to call from any goroutine; the server's /metrics handler calls this after its own output.

Types

type ClusterScanSpec

type ClusterScanSpec struct {
	// Contexts are kubeconfig context names to include in the scan.
	Contexts []string `json:"contexts,omitempty"`
	// Group is the name of a fleetsweeper group whose members will be scanned.
	Group string `json:"group,omitempty"`
	// Interval is a Go duration string between scans, for example "15m".
	Interval string `json:"interval,omitempty"`
	// Scanners restricts the scan to the named scanners. Empty runs all.
	Scanners []string `json:"scanners,omitempty"`
	// Emit selects which artifacts to emit after each scan.
	Emit EmitOptions `json:"emit"`
	// Paused, when true, makes the controller skip reconciliation.
	Paused bool `json:"paused,omitempty"`
}

ClusterScanSpec mirrors the spec fields declared in deploy/crds/clusterscan.yaml. Only the fields the controller reads are typed; the rest are passed through unstructured maps so additive schema changes do not require code changes.

type ClusterScanStatus

type ClusterScanStatus struct {
	// Phase is the current reconciliation phase.
	Phase string `json:"phase,omitempty"`
	// LastScanID is the most recently completed scan identifier.
	LastScanID string `json:"lastScanID,omitempty"`
	// LastScanTime is when the most recent successful scan completed.
	LastScanTime *time.Time `json:"lastScanTime,omitempty"`
	// NextScanTime is when the controller intends to run the next scan.
	NextScanTime *time.Time `json:"nextScanTime,omitempty"`
	// ObservedScore is the fleet score from the most recent scan.
	ObservedScore int `json:"observedScore,omitempty"`
	// ObservedGrade is the letter grade from the most recent scan.
	ObservedGrade string `json:"observedGrade,omitempty"`
	// ObservedCritical is the count of critical findings.
	ObservedCritical int `json:"observedCritical,omitempty"`
	// ObservedWarning is the count of warning findings.
	ObservedWarning int `json:"observedWarning,omitempty"`
	// ObservedClusters is the number of clusters that returned data.
	ObservedClusters int `json:"observedClusters,omitempty"`
	// ObservedGeneration is the resource generation this status was computed from.
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`
	// ConsecutiveFailures counts scans that failed since the last success. It sets the retry delay.
	ConsecutiveFailures int `json:"consecutiveFailures,omitempty"`
	// Message is a human-readable summary of the last reconciliation.
	Message string `json:"message,omitempty"`
	// Conditions are the Ready, Scanning, and Failed status conditions.
	Conditions []metav1.Condition `json:"conditions,omitempty"`
}

ClusterScanStatus mirrors the status fields declared in the CRD.

type Config

type Config struct {
	// Dynamic is the in-cluster dynamic client used to watch ClusterScans.
	Dynamic dynamic.Interface
	// Namespace, when non-empty, restricts the controller to one namespace.
	// Empty watches all namespaces (requires cluster-wide RBAC).
	Namespace string
	// Runner executes scans on the controller's behalf.
	Runner ScanRunner
	// Log is the structured logger.
	Log *zap.Logger
	// PollInterval is how often cached ClusterScans are re-enqueued to check
	// for due scans. Defaults to 15s when zero.
	PollInterval time.Duration
	// Recorder receives the Kubernetes Events the controller emits. When nil, Run builds one
	// on Events, and when both are nil Events are dropped.
	Recorder record.EventRecorder
	// Events is the core client Run uses to build an event recorder when Recorder is nil.
	Events typedcorev1.EventsGetter
}

Config configures a Controller.

type Controller

type Controller struct {
	// contains filtered or unexported fields
}

Controller reconciles ClusterScan resources. One Controller per process.

func New

func New(cfg Config) *Controller

New returns a Controller. Panics when required fields are nil to surface configuration mistakes before the operator quietly does nothing.

func (*Controller) Run

func (c *Controller) Run(ctx context.Context) error

Run reconciles ClusterScan resources until ctx is canceled. A shared informer watches for spec changes so new or edited resources reconcile immediately, and deletions cancel the resource's running scan. A ticker re-enqueues cached resources as a safety net; each reconcile also schedules its own key for the moment its next scan is due. Returns nil on a clean shutdown.

type EmitOptions

type EmitOptions struct {
	// FleetDriftReport emits FleetDriftReport YAMLs to the configured directory.
	FleetDriftReport bool `json:"fleetDriftReport,omitempty"`
	// PolicyReport emits wgpolicyk8s.io PolicyReports to the configured directory.
	PolicyReport bool `json:"policyReport,omitempty"`
	// Slack delivers new critical findings to the configured webhook URL.
	Slack bool `json:"slack,omitempty"`
}

EmitOptions selects which sinks receive scan outputs.

type ScanOptions

type ScanOptions struct {
	// Contexts is the kubeconfig context names to scan.
	Contexts []string
	// Group, when non-empty, supersedes Contexts: members of that group are scanned.
	Group string
	// Scanners restricts the scan to the named scanners. Empty runs all.
	Scanners []string
	// Emit selects which sinks receive outputs.
	Emit EmitOptions
	// ResourceName is the name of the originating ClusterScan, used for logging.
	ResourceName string
}

ScanOptions describes one declarative scan invocation.

type ScanRunner

type ScanRunner interface {
	// ScanOnce executes one scan with the given options and returns the summary.
	// Implementations must be safe to call concurrently from multiple goroutines.
	ScanOnce(ctx context.Context, opts ScanOptions) (ScanSummary, error)
}

ScanRunner is the abstraction the controller uses to actually execute a scan. The server's Server type satisfies this interface; tests can substitute a fake to assert reconciliation behavior without spinning up scanners.

type ScanSummary

type ScanSummary struct {
	// ScanID is the persistent scan record identifier.
	ScanID string
	// Score is the fleet score (0-100).
	Score int
	// Grade is the letter grade (A-F).
	Grade string
	// Critical is the count of critical findings.
	Critical int
	// Warning is the count of warning findings.
	Warning int
	// Clusters is the number of clusters that produced data.
	Clusters int
}

ScanSummary holds the fields the controller writes back to status after a scan completes. Implementations should populate all fields; zero values are rendered as zeros in the CR status.

Jump to

Keyboard shortcuts

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