remediators

package
v0.2.159 Latest Latest
Warning

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

Go to latest
Published: Jul 22, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

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

View Source
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).

View Source
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

func IsNamespacedKind(kind string) bool

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

func (r *AnnotateRemediator) Apply(ctx context.Context, p Plan, dryRun bool) (Result, error)

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) Plan

func (r *AnnotateRemediator) Plan(ctx context.Context, req Request) (Plan, error)

Plan computes the annotation patch without applying it.

func (*AnnotateRemediator) Revert

func (r *AnnotateRemediator) Revert(ctx context.Context, t Target, dryRun bool) (Result, error)

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

func (r *QuarantineRemediator) Apply(ctx context.Context, p Plan, dryRun bool) (Result, error)

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

func (r *QuarantineRemediator) Plan(ctx context.Context, req Request) (Plan, error)

Plan reads the target workload's pod selector from the live object and computes the deny-all NetworkPolicy without creating it.

func (*QuarantineRemediator) Revert

func (r *QuarantineRemediator) Revert(ctx context.Context, t Target, dryRun bool) (Result, error)

Revert deletes the deny-all NetworkPolicy that quarantined the target. A missing policy is treated as success (nothing to undo). Like Apply, dryRun=true issues a server-side dry-run delete, so the safe-by-default contract holds for revert too.

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

type Request struct {
	Target     Target
	Reason     string
	FindingRef string
}

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.

type Target

type Target struct {
	Kind      string `json:"kind"`
	Namespace string `json:"namespace,omitempty"`
	Name      string `json:"name"`
}

Target identifies a single concrete object a remediation acts on.

func (Target) String

func (t Target) String() string

String renders the target as kind/namespace/name (kind/name for cluster-scoped objects), used in plans, results, logs and events.

Jump to

Keyboard shortcuts

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