Documentation
¶
Overview ¶
Package remediators implements the individual cluster operations ("actions") that the operator performs in response to a TypeOperatorAction command.
Each action is a Remediator: it can Plan a change (without touching the cluster), Apply it (optionally as a server-side dry-run), and Revert it. New actions are added by implementing Remediator and registering them in NewRegistry — the command pipeline in mainhandler does not change.
Index ¶
Constants ¶
const ( AnnotationRemediated = "kubescape.io/remediated" AnnotationReason = "kubescape.io/remediation-reason" AnnotationFindingRef = "kubescape.io/remediation-finding-ref" )
Annotation keys written by the annotate action. They mark a workload as having been acted on by Kubescape and carry the audit context (the reason and the finding that justified the action).
const ( // LabelQuarantine marks the deny-all NetworkPolicy created by the quarantine // action, so it can be found and removed on revert. LabelQuarantine = "kubescape.io/quarantine" // AnnotationQuarantineTarget records, on the NetworkPolicy, the workload it // isolates — part of the audit trail. AnnotationQuarantineTarget = "kubescape.io/quarantine-target" )
Variables ¶
This section is empty.
Functions ¶
func IsNamespacedKind ¶
IsNamespacedKind reports whether kind is one of the namespaced workload kinds Phase-1 actions operate on. The action handler uses it to enforce the namespace safety rail up front: a namespaced target with no namespace would otherwise skip the excluded-namespace check and fail late at the API server.
func NewRegistry ¶
func NewRegistry(client kubernetes.Interface) map[apis.OperatorActionType]Remediator
NewRegistry builds the set of remediators backed by the given client. New actions are added by extending this map; the command pipeline does not change. cordon is added in a later phase.
Types ¶
type AnnotateRemediator ¶
type AnnotateRemediator struct {
// contains filtered or unexported fields
}
AnnotateRemediator is the lowest-blast-radius action: it adds Kubescape remediation annotations to a workload. It is the first action shipped, to prove the CLI -> operator -> status pipeline end to end.
func NewAnnotateRemediator ¶
func NewAnnotateRemediator(client kubernetes.Interface) *AnnotateRemediator
NewAnnotateRemediator returns an annotate remediator backed by client.
func (*AnnotateRemediator) Apply ¶
Apply sends the planned patch. With dryRun=true it is a server-side dry-run (validated against admission, never persisted); only dryRun=false writes.
func (*AnnotateRemediator) Revert ¶
Revert removes the Kubescape remediation annotations from the target. Like Apply, dryRun=true issues a server-side dry-run (validated against admission, never persisted); only dryRun=false performs a real write — so the safe-by-default contract is honored for revert too.
The contract's revert verb undoes every reversible action without naming which one was applied, so revert runs annotate even on a workload that was only quarantined. To keep the audit trail honest, a workload carrying none of the remediation annotations is reported as a no-op ("nothing to revert", Applied=false) rather than claiming annotations were removed.
type Plan ¶
type Plan struct {
Action string `json:"action"`
Target Target `json:"target"`
Description string `json:"description"`
// Patch is the exact patch body Apply would send, included for transparency
// in the dry-run preview.
Patch string `json:"patch,omitempty"`
}
Plan is the computed, not-yet-applied effect of a remediation. It is returned to the caller (CLI / OperatorCommand status) so a change can be previewed before any cluster write happens.
type QuarantineRemediator ¶
type QuarantineRemediator struct {
// contains filtered or unexported fields
}
QuarantineRemediator isolates a workload by creating a deny-all NetworkPolicy that selects the workload's pods (both ingress and egress denied). It does not mutate or recreate the pods, so container state is preserved for forensic investigation (the design's resolved default; scale-to-zero is a future, explicit opt-in). Revert deletes the NetworkPolicy.
Isolation semantics and preconditions (surfaced in the plan/result via quarantineCaveat):
- CNI enforcement: a NetworkPolicy only isolates traffic on a CNI that enforces NetworkPolicy. On a non-enforcing CNI the policy is created but has no effect; the action still reports success because the desired object was applied — enforcement is a cluster property the operator cannot verify.
- Blast radius: the policy selects by the workload's selector labels, so it isolates every pod matching them — including pods owned by other workloads that reuse the same labels (blue/green, canary, a second Deployment reusing "app="). Quarantine assumes the selector identifies the intended pods.
- Pod targets: a NetworkPolicy selects pods by label, not by name. A controller-managed pod's labels are shared by every replica of its template (pod-template-hash, etc.), so quarantining a Pod isolates the whole ReplicaSet/template, not the single named pod. Single-pod isolation is not achievable with a NetworkPolicy.
func NewQuarantineRemediator ¶
func NewQuarantineRemediator(client kubernetes.Interface) *QuarantineRemediator
NewQuarantineRemediator returns a quarantine remediator backed by client.
func (*QuarantineRemediator) Apply ¶
Apply creates the planned deny-all NetworkPolicy. With dryRun=true it is sent as a server-side dry-run (validated against admission, never persisted); only dryRun=false performs a real write. If a policy already exists (a prior quarantine), it is reconciled to the freshly planned spec so that a selector that drifted since the first quarantine (the workload was edited/redeployed) still isolates the currently-running pods, rather than leaving a stale policy in place while reporting success.
func (*QuarantineRemediator) Plan ¶
Plan reads the target workload's pod selector from the live object and computes the deny-all NetworkPolicy without creating it.
type Remediator ¶
type Remediator interface {
// Plan computes the intended change without mutating the cluster.
Plan(ctx context.Context, req Request) (Plan, error)
// Apply executes a plan. When dryRun is true the write is sent with
// server-side dry-run (validated against admission, never persisted).
Apply(ctx context.Context, p Plan, dryRun bool) (Result, error)
// Revert undoes a previously applied action on the target. Like Apply, a
// dryRun=true revert is a server-side dry-run (validated, never persisted),
// so the safe-by-default contract holds for revert too.
Revert(ctx context.Context, t Target, dryRun bool) (Result, error)
}
Remediator computes and performs a single class of cluster operation.
type Request ¶
Request carries a single remediation's target plus the audit metadata that some actions (e.g. annotate) record on the mutated object.
type Result ¶
type Result struct {
Action string `json:"action"`
Target Target `json:"target"`
DryRun bool `json:"dryRun"`
Applied bool `json:"applied"`
Description string `json:"description"`
}
Result is the outcome of Apply or Revert.