fix: populate image, imageDigest and clusterUID in admission alerts#359
fix: populate image, imageDigest and clusterUID in admission alerts#359
Conversation
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>
📝 WalkthroughWalkthroughThis 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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
admission/rules/v1/helpers.go (1)
189-191: Consider reusingutils.ExtractImageIDto avoid duplication.The inline
extractDigestfunction performs the same operation asutils.ExtractImageIDinutils/utils.go(stripping thedocker-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. SinceclusterUIDis only used for exporter init, move this call inside theif exporterConfig != nilblock 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
📒 Files selected for processing (9)
admission/exporter/http_exporter.goadmission/exporter/http_exporter_test.goadmission/rules/v1/helpers.goadmission/rules/v1/r2000_exec_to_pod.goadmission/rules/v1/r2000_exec_to_pod_test.goadmission/rules/v1/r2001_portforward.goadmission/rules/v1/r2001_portforward_test.gomain.goutils/utils.go
|
Summary:
|
Summary
containerImage,containerImageDigest, andclusterUIDinRuntimeAlertK8sDetails.GetClusterUIDhelper in operator (mirrors node-agent's approach of readingkube-systemnamespace UID) and wired it through the admission HTTP exporter.GetContainerImage/GetContainerImageDigesthelpers that extract image info from pod spec/status with container-name-aware fallback, and used them in both rules.Test plan
TestR2000andTestR2000_EmptyContainerNameassertImageandImageDigestare populatedTestR2001assertsImageandImageDigestare populated (first-container fallback)TestGetContainerImagecovers named, empty, nil, and init container casesTestGetContainerImageDigestcovers named, empty, nil, and init container casesTestInitHTTPExporter_ClusterUIDverifies ClusterUID is stored in exporterTestSendAdmissionAlert_ClusterUIDPropagatedverifies ClusterUID appears in outbound alertgo test ./admission/...pass (22/22)Made with Cursor
Summary by CodeRabbit
New Features
Tests