controller

package
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Jul 8, 2026 License: MIT Imports: 20 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 (
	// 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 DynamicClient

func DynamicClient(kubeconfigPath, contextName string) (dynamic.Interface, error)

DynamicClient builds a dynamic.Interface suitable for the controller. 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 artefacts 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 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"`
	// Message is a human-readable summary of the last reconciliation.
	Message string `json:"message,omitempty"`
	// Conditions are standard Kubernetes status conditions.
	Conditions []Condition `json:"conditions,omitempty"`
}

ClusterScanStatus mirrors the status fields declared in the CRD.

type Condition

type Condition struct {
	// Type names the condition (for example "Ready").
	Type string `json:"type"`
	// Status is "True", "False", or "Unknown".
	Status string `json:"status"`
	// Reason is a CamelCase reason for the transition.
	Reason string `json:"reason,omitempty"`
	// Message is human-readable detail.
	Message string `json:"message,omitempty"`
	// LastTransitionTime is when the condition last changed.
	LastTransitionTime time.Time `json:"lastTransitionTime"`
}

Condition is a standard Kubernetes status condition.

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
}

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; a ticker re-enqueues cached resources so interval-due scans fire without a watch event. 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