Skip to content

fix: populate image, imageDigest and clusterUID in admission alerts#359

Merged
slashben merged 1 commit intomainfrom
fix/admission-alert-k8s-enrichment
Mar 16, 2026
Merged

fix: populate image, imageDigest and clusterUID in admission alerts#359
slashben merged 1 commit intomainfrom
fix/admission-alert-k8s-enrichment

Conversation

@slashben
Copy link
Copy Markdown
Contributor

@slashben slashben commented Mar 16, 2026

Summary

  • Admission alerts (exec-to-pod R2000, port-forward R2001) were returning empty strings for containerImage, containerImageDigest, and clusterUID in RuntimeAlertK8sDetails.
  • Added GetClusterUID helper in operator (mirrors node-agent's approach of reading kube-system namespace UID) and wired it through the admission HTTP exporter.
  • Added GetContainerImage / GetContainerImageDigest helpers that extract image info from pod spec/status with container-name-aware fallback, and used them in both rules.

Test plan

  • TestR2000 and TestR2000_EmptyContainerName assert Image and ImageDigest are populated
  • TestR2001 asserts Image and ImageDigest are populated (first-container fallback)
  • TestGetContainerImage covers named, empty, nil, and init container cases
  • TestGetContainerImageDigest covers named, empty, nil, and init container cases
  • TestInitHTTPExporter_ClusterUID verifies ClusterUID is stored in exporter
  • TestSendAdmissionAlert_ClusterUIDPropagated verifies ClusterUID appears in outbound alert
  • All go test ./admission/... pass (22/22)

Made with Cursor

Summary by CodeRabbit

  • New Features

    • Cluster UID is now tracked and included in HTTP exporter alerts for improved cluster identification
    • Container image and image digest information is now captured and propagated in admission alerts
  • Tests

    • Added comprehensive tests for cluster UID initialization and propagation through alert workflows
    • Added tests for container image and digest retrieval from Kubernetes pod metadata

Admission alerts (exec-to-pod R2000, port-forward R2001) were sending
empty strings for containerImage, containerImageDigest and clusterUID.
These fields existed in the RuntimeAlertK8sDetails struct but were never
populated in the operator admission path.

- Add GetClusterUID helper (mirrors node-agent approach via kube-system
  namespace UID) and wire it through the admission HTTP exporter
- Add GetContainerImage/GetContainerImageDigest helpers that extract
  image info from pod spec/status with container-name-aware fallback
- Enrich both R2000 and R2001 rules with Image and ImageDigest fields
- Add comprehensive tests for all new helpers and exporter enrichment

Made-with: Cursor
Signed-off-by: Ben <ben@armosec.io>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 16, 2026

📝 Walkthrough

Walkthrough

This PR adds cluster UID and container image tracking to the admission alert system. It introduces a new ClusterUID field to HTTPExporter, retrieves the cluster identifier from the kube-system namespace, adds helper functions to extract container image and digest information, and propagates these details into admission alert payloads for R2000 and R2001 rules.

Changes

Cohort / File(s) Summary
Cluster UID Infrastructure
admission/exporter/http_exporter.go, admission/exporter/http_exporter_test.go, utils/utils.go, main.go
Added ClusterUID field to HTTPExporter and extended InitHTTPExporter signature. Introduced GetClusterUID function to retrieve cluster identifier from kube-system namespace. Updated main.go to retrieve and pass clusterUID during exporter initialization. Tests verify correct ClusterUID propagation into alert details.
Container Image Helpers
admission/rules/v1/helpers.go, admission/rules/v1/r2000_exec_to_pod_test.go
Added GetContainerImage and GetContainerImageDigest public functions to extract container image names and digests, with support for regular, init, and ephemeral containers. Includes fallback to first container when container name is empty. Tests verify behavior across container types and edge cases.
R2000 Rule Updates
admission/rules/v1/r2000_exec_to_pod.go, admission/rules/v1/r2000_exec_to_pod_test.go
Populated Image and ImageDigest fields in RuntimeAlertK8sDetails using the new helper functions. Tests verify correct image information is captured for specific and default containers.
R2001 Rule Updates
admission/rules/v1/r2001_portforward.go, admission/rules/v1/r2001_portforward_test.go
Modified GetControllerDetails to return pod as first value, enabling access to container image information. Populated Image and ImageDigest fields in RuntimeAlertK8sDetails. Tests assert expected image values in alert details.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Fix exec to pod has no workloadUID and update packages #357: Modifies the same admission rule files and helpers, introducing WorkloadUID/ContainerID alongside this PR's Image/ImageDigest additions and changing GetControllerDetails return signature, creating potential for merge conflicts or functional overlap.

Suggested reviewers

  • matthyx

Poem

🐰 Hopping through clusters with UID in tow,
Container images in bright detail glow,
From kube-system's heart to alerts so keen,
Enriching each rule with context pristine!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: populating image, imageDigest, and clusterUID fields in admission alerts across multiple rules.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/admission-alert-k8s-enrichment
📝 Coding Plan
  • Generate coding plan for human review comments

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.

@slashben slashben requested a review from matthyx March 16, 2026 09:34
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
admission/rules/v1/helpers.go (1)

189-191: Consider reusing utils.ExtractImageID to avoid duplication.

The inline extractDigest function performs the same operation as utils.ExtractImageID in utils/utils.go (stripping the docker-pullable:// prefix). Consider importing and reusing that function for consistency and DRY.

♻️ Proposed refactor
+import (
+	"github.com/kubescape/operator/utils"
+)

 func GetContainerImageDigest(pod *corev1.Pod, containerName string) string {
 	if pod == nil {
 		return ""
 	}

-	extractDigest := func(imageID string) string {
-		return strings.TrimPrefix(imageID, "docker-pullable://")
-	}

 	if containerName == "" {
 		if len(pod.Status.ContainerStatuses) > 0 {
-			return extractDigest(pod.Status.ContainerStatuses[0].ImageID)
+			return utils.ExtractImageID(pod.Status.ContainerStatuses[0].ImageID)
 		}
 		return ""
 	}

 	for _, cs := range pod.Status.ContainerStatuses {
 		if cs.Name == containerName {
-			return extractDigest(cs.ImageID)
+			return utils.ExtractImageID(cs.ImageID)
 		}
 	}
 	// ... apply same change to other usages
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@admission/rules/v1/helpers.go` around lines 189 - 191, Replace the inline
extractDigest closure in helpers.go with a call to the existing
utils.ExtractImageID to avoid duplication: remove the extractDigest definition
and update callers to use utils.ExtractImageID(imageID) instead; add the utils
package import if missing and run tests to ensure no behavior change.
main.go (1)

128-129: Defer cluster UID lookup to the exporter-enabled branch.

Line 128 performs a Kubernetes API lookup even when HttpExporterConfig() is nil. Since clusterUID is only used for exporter init, move this call inside the if exporterConfig != nil block to avoid unnecessary startup dependency/work.

Proposed refactor
-	clusterUID := utils.GetClusterUID(k8sApi.GetKubernetesClient())
-
 	var exporter exporters.Exporter
 	if exporterConfig := operatorConfig.HttpExporterConfig(); exporterConfig != nil {
+		clusterUID := utils.GetClusterUID(k8sApi.GetKubernetesClient())
 		exporter, err = exporters.InitHTTPExporter(*exporterConfig, operatorConfig.ClusterName(), cloudMetadata, clusterUID)
 		if err != nil {
 			logger.L().Ctx(ctx).Fatal("failed to initialize HTTP exporter", helpers.Error(err))
 		}
 	} else {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@main.go` around lines 128 - 129, The call to
utils.GetClusterUID(k8sApi.GetKubernetesClient()) is performed unconditionally
but the resulting clusterUID is only used when exporter configuration exists;
move the clusterUID lookup inside the branch that checks exporterConfig != nil
(i.e., after HttpExporterConfig() is evaluated) so you only call
utils.GetClusterUID when initializing the exporter. Update the code around the
exporter initialization to reference clusterUID from the moved declaration and
remove the now-unneeded early lookup.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@admission/rules/v1/helpers.go`:
- Around line 189-191: Replace the inline extractDigest closure in helpers.go
with a call to the existing utils.ExtractImageID to avoid duplication: remove
the extractDigest definition and update callers to use
utils.ExtractImageID(imageID) instead; add the utils package import if missing
and run tests to ensure no behavior change.

In `@main.go`:
- Around line 128-129: The call to
utils.GetClusterUID(k8sApi.GetKubernetesClient()) is performed unconditionally
but the resulting clusterUID is only used when exporter configuration exists;
move the clusterUID lookup inside the branch that checks exporterConfig != nil
(i.e., after HttpExporterConfig() is evaluated) so you only call
utils.GetClusterUID when initializing the exporter. Update the code around the
exporter initialization to reference clusterUID from the moved declaration and
remove the now-unneeded early lookup.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b73df070-a59a-4e69-b1f1-9b44cffe6b1a

📥 Commits

Reviewing files that changed from the base of the PR and between 1f35536 and e413ac7.

📒 Files selected for processing (9)
  • admission/exporter/http_exporter.go
  • admission/exporter/http_exporter_test.go
  • admission/rules/v1/helpers.go
  • admission/rules/v1/r2000_exec_to_pod.go
  • admission/rules/v1/r2000_exec_to_pod_test.go
  • admission/rules/v1/r2001_portforward.go
  • admission/rules/v1/r2001_portforward_test.go
  • main.go
  • utils/utils.go

@github-actions
Copy link
Copy Markdown

Summary:

  • License scan: success
  • Credentials scan: failure
  • Vulnerabilities scan: success
  • Unit test: success
  • Go linting: failure

@slashben slashben added the release Create release label Mar 16, 2026
@slashben slashben merged commit 19c7096 into main Mar 16, 2026
10 checks passed
@slashben slashben deleted the fix/admission-alert-k8s-enrichment branch March 16, 2026 11:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release Create release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants