Documentation
¶
Overview ¶
Package apply contains server-side apply and prune integration points.
Index ¶
Constants ¶
const ( // FieldManager is the SSA field manager name used by the controller. // Distinguishes from "opm-cli", "kubectl", "helm", etc. // From docs/design/ssa-ownership-and-drift-policy.md. FieldManager = "opm-controller" )
Variables ¶
This section is empty.
Functions ¶
func NewImpersonatedClient ¶
func NewImpersonatedClient( ctx context.Context, cfg *rest.Config, reader client.Reader, scheme *runtime.Scheme, namespace, saName string, ) (client.Client, error)
NewImpersonatedClient builds a controller-runtime client that impersonates the given ServiceAccount for all API calls. The SA must exist in the specified namespace; if it does not, an error is returned so the caller can stall the reconcile.
reader is used only for the SA existence check. Pass an uncached reader (e.g. manager.GetAPIReader()) so that a single Get does not provision a cluster-wide ServiceAccount informer and thereby require list/watch RBAC. scheme is used to build the impersonated client.
The returned client is suitable for Apply and Prune operations scoped to the SA's RBAC bindings.
func NewResourceManager ¶
func NewResourceManager(c client.Client, owner string) *fluxssa.ResourceManager
NewResourceManager constructs a Flux SSA ResourceManager with the opm-controller field manager. The owner string is used for SSA ownership labels.
Types ¶
type ApplyResult ¶
type ApplyResult struct {
// Created is the number of resources created (did not exist before).
Created int
// Updated is the number of resources updated (existed, fields changed).
Updated int
// Unchanged is the number of resources unchanged (existed, no field diff).
Unchanged int
}
ApplyResult carries counts of apply outcomes.
func Apply ¶
func Apply( ctx context.Context, rm *fluxssa.ResourceManager, resources []*unstructured.Unstructured, force bool, ) (*ApplyResult, error)
Apply applies the given resources to the cluster using Server-Side Apply. Staging is handled by Flux's ApplyAllStaged, which applies cluster definitions (CRDs, Namespaces, ClusterRoles) first with readiness waits, then class definitions, then everything else. See docs/design/flux-ssa-staging.md.
When force is true, immutable field conflicts are resolved by recreating the object (maps to ApplyOptions.Force, not SSA field-ownership conflicts — Flux always applies with ForceOwnership).
Returns an ApplyResult with counts, or an error on any apply failure.
type DriftResult ¶
type DriftResult struct {
// Drifted is true if any resource has drifted from desired state.
Drifted bool
// Resources lists the resources that have drifted.
Resources []DriftedResource
}
DriftResult holds the outcome of drift detection across a resource set.
func DetectDrift ¶
func DetectDrift( ctx context.Context, rm *fluxssa.ResourceManager, resources []*unstructured.Unstructured, ) (*DriftResult, error)
DetectDrift performs SSA dry-run diffs for each resource and returns which resources have drifted from desired state. Uses Flux's ResourceManager.Diff which performs a server-side apply dry-run and compares the result.
A resource is considered drifted when the dry-run result differs from the desired state (Flux returns ConfiguredAction). Resources that don't exist yet (CreatedAction) or are unchanged are not considered drifted.
Returns an error only when the dry-run API call itself fails (transient). Drift detection results are not errors — drift is an expected operational signal.
type DriftedResource ¶
DriftedResource identifies a single resource that has drifted from desired state.
type PruneResult ¶
type PruneResult struct {
// Deleted is the number of stale resources successfully deleted.
Deleted int
// Skipped is the number of stale resources skipped due to safety exclusions.
Skipped int
}
PruneResult carries counts of prune outcomes.
func Prune ¶
func Prune( ctx context.Context, c client.Client, ownerUUID string, stale []releasesv1alpha1.InventoryEntry, ) (*PruneResult, error)
Prune deletes stale resources from the cluster. Uses direct client.Delete per resource rather than Flux's DeleteAll to allow per-resource error control and safety exclusion logic (design decision 1).
Safety exclusions (design decision 3: hard-coded, not configurable):
- Namespace: never auto-deleted (cascades to all resources inside)
- CustomResourceDefinition: never auto-deleted (deletes all instances globally)
Live-state ownership guard (defense-in-depth): before each delete, Prune GETs the live object and skips the delete if the live object is not OPM-managed (missing/unrecognized app.kubernetes.io/managed-by label) or carries a module-release.opmodel.dev/uuid label that disagrees with ownerUUID. An empty live UUID label is tolerated (legacy resources predate UUID stamping). An empty ownerUUID disables the UUID comparison — callers that cannot supply a UUID (e.g. the Release reconciler, or a freshly-created ModuleRelease whose Status.ReleaseUUID is not yet persisted) fall back to the managed-by check alone.
Skipped resources are logged as warnings and counted in PruneResult.Skipped.
If a stale resource is already gone (NotFound), it is treated as success. Individual failures (Get or Delete) are collected and returned as a joined error; remaining entries continue (design decision 2: continue-on-error / fail-slow).
The caller is responsible for:
- Computing the stale set via internal/inventory.ComputeStaleSet
- Checking spec.prune before calling this function
- Ensuring apply succeeded before calling prune
- Supplying ownerUUID from the freshly-rendered resources or ModuleReleaseStatus.ReleaseUUID