Skip to content

feat: handle operatorAction commands (annotate + dry run) #383

Open
yugal07 wants to merge 2 commits into
kubescape:mainfrom
yugal07:feat/operator-action-remediation
Open

feat: handle operatorAction commands (annotate + dry run) #383
yugal07 wants to merge 2 commits into
kubescape:mainfrom
yugal07:feat/operator-action-remediation

Conversation

@yugal07

@yugal07 yugal07 commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

operator: handle operatorAction commands — Phase 1 remediation (annotate + dry-run)

Related issue: kubescape/kubescape#1770 — Kubescape CLI control over cluster operations
Design: kubescape/designs-and-proposals#5 — Kubescape CLI Control over Cluster Operations (merged)
Contract: armosec/armoapi-go#655 — operatorAction command contract (merged, shipped in v0.0.720)
Pairs with: kubescape/helm-charts#855

What this PR does

This is Phase 1 of the merged design: it teaches the in-cluster operator to
execute a TypeOperatorAction command end to end, with the lowest-blast-radius
action (annotate) and dry-run as the default. It proves the
CLI → operator → OperatorCommand status pipeline with essentially zero risk,
and lays the extensible Remediator framework that quarantine/cordon
plug into in later phases.

No new transport, no new endpoint: remediation is a new verb on the existing
apis.Command pipeline that already powers kubescape operator scan.

  • go.mod / go.sum — bump armosec/armoapi-go v0.0.673v0.0.720 to
    pick up the merged operatorAction contract (TypeOperatorAction,
    OperatorActionArgs, IsDryRun, ToArgs/OperatorActionArgsFromMap).
  • mainhandler/handlerequests.go — wire dispatch in two places:
    case apis.TypeOperatorAction in runCommand (→ handleOperatorAction), and
    in the itemize switch so an action is handled as a single request (it carries
    its own target) rather than fanned out per pod.
  • mainhandler/actionhandler.go (new)handleOperatorAction: parses the
    typed args, enforces the Phase-1 safety rails, dispatches to the matching
    Remediator, writes the result to the OperatorCommand status payload, and
    emits a best-effort Kubernetes Event for audit.
  • mainhandler/remediators/remediator.go (new) — the Remediator interface
    (Plan/Apply/Revert), the Target/Request/Plan/Result types, and
    NewRegistry (annotate only for now; new actions are added by extending the map,
    not the pipeline).
  • mainhandler/remediators/annotate.go (new)AnnotateRemediator over
    Deployment/StatefulSet/DaemonSet/Pod: a JSON merge patch that sets the
    kubescape.io/remediated, …/remediation-reason, …/remediation-finding-ref
    annotations; Revert deletes them (null-merge); server-side dry-run support.
  • mainhandler/remediators/annotate_test.go, mainhandler/actionhandler_test.go
    (new) — 16 unit tests.

Safe-by-default behaviour

  • Dry-run is the default. OperatorActionArgs.IsDryRun() returns true
    unless the caller set dryRun=false explicitly (the CLI's --confirm), so a
    missing flag can never silently perform a real write.
  • Two-layer dry-run, matching the design. A dry-run still issues the patch
    with server-side metav1.DryRunAll so the change is validated against
    admission controllers, never persisted.
  • Namespace safety rail. Targets in excluded/protected namespaces
    (config.SkipNamespace) are rejected before any client call.
  • No default-install power. The operator gates real writes on RBAC, which the
    default install does not grant (see the paired helm-charts PR). Without it,
    annotate returns a clean Forbidden that is recorded on the command status —
    nothing is mutated.
  • Explicit scope fences. quarantine/cordon return a clear
    "not implemented yet (later phase)" error; selector-driven (findings) targeting
    returns a clear "phase 2" error; unknown actions error explicitly. Phase 1 acts
    only on an explicit target.

Audit trail

Every action records its Plan/Result (action, target, dryRun, applied) on the
OperatorCommand status payload (the GitOps- and Headlamp-friendly channel) and
emits a KubescapeRemediation Kubernetes Event on the target's namespace.

Testing

  • go build ./... and go vet ./... — clean.
  • New tests pass (mainhandler, mainhandler/remediators); dry-run assertions use
    a pass-through reactor to verify the PatchOptions.DryRun actually sent —
    necessary because the fake clientset's tracker ignores server-side dry-run and
    always persists, so "did not persist" cannot be asserted directly.
  • Cross-component check with helm-charts: the chart-rendered capabilities.json
    (now carrying the new remediation key) parses cleanly through the operator's
    real LoadCapabilitiesConfig; unknown keys are tolerated (viper default), exactly
    as the existing riskAcceptance key already is.

Phasing

This is Phase 1 of the merged design. Next: the kubescape CLI
operator remediate annotate subcommand (completes the user-facing loop), then
Phase 2 quarantine + findings-driven targeting, then Phase 3 cordon +
operator-native auto-remediation. The Remediator registry is designed so each
adds an implementation without touching the command pipeline.

Summary by CodeRabbit

  • New Features

    • Operator actions: Annotate and Revert workflows for workloads, with server-side dry-run and explicit-target enforcement.
    • Audit events emitted for action tracking.
    • Phase‑1 safety: excluded namespaces blocked and selector-based targeting disallowed.
  • Tests

    • Added coverage for operator actions and annotate remediator behaviors, including dry-run, confirm, revert and error cases.
  • Chores

    • Updated dependency to a newer pinned version.

…+ dry-run)

Signed-off-by: yugal07 <yashsadhwani544@gmail.com>
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 033fc9c3-9322-41c5-bfc7-365d046227d6

📥 Commits

Reviewing files that changed from the base of the PR and between 872b355 and 85df9a1.

📒 Files selected for processing (2)
  • mainhandler/actionhandler.go
  • mainhandler/actionhandler_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • mainhandler/actionhandler.go
  • mainhandler/actionhandler_test.go

📝 Walkthrough

Walkthrough

Defines remediator contracts, adds an AnnotateRemediator (plan/apply/revert with server-side dry-run), integrates operator-action routing, enforces Phase‑1 safety checks (explicit target, no selectors, excluded namespaces), records results and emits audit events, and adds tests plus a dependency bump.

Changes

Operator Action Remediation Implementation

Layer / File(s) Summary
Remediator abstractions and registry
mainhandler/remediators/remediator.go
Target, Request, Plan, Result types and Remediator interface; NewRegistry registers remediators by action type.
AnnotateRemediator implementation and tests
mainhandler/remediators/annotate.go, mainhandler/remediators/annotate_test.go
Annotate remediator builds JSON merge patches for metadata.annotations, Plan returns patch payload, Apply sends patches with optional metav1.DryRunAll, Revert deletes remediation keys; tests cover planning, dry-run vs confirm, supported kinds, unsupported-kind errors, and revert preservation of unrelated annotations.
Action handler execution with Phase-1 constraints and audit
mainhandler/actionhandler.go, mainhandler/actionhandler_test.go
Parses operator action args, requires action and explicit target, rejects selector targeting and TTL/auto-revert inputs, blocks excluded namespaces, dispatches Annotate/Revert to remediators, records JSON payload into OperatorCommand status, emits best-effort Kubernetes Events, and logs outcomes; tests cover dry-run defaulting, confirm writes, revert, error cases, and TTL validation.
Request routing for operator actions
mainhandler/handlerequests.go
Treats operator actions as non-itemized requests and routes apis.TypeOperatorAction to the action handler.
Dependency update
go.mod
Bumps github.com/armosec/armoapi-go from v0.0.673 to v0.0.720.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • kubescape/operator#353: Both PRs update the same dependency github.com/armosec/armoapi-go to provide operator action APIs.

Poem

🐰 I hop through patches and marshal the plan,
I nudge annotations with a careful hand,
Phase‑one guards watch every little hop,
Events whisper audits that never stop,
Remediations taped — then I softly stand.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding operator action command handling with support for annotate operations and dry-run functionality, which matches the core deliverable across all modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Signed-off-by: yugal07 <yashsadhwani544@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants