From c3e80ea669ea19f8e6a8cd5072fafc8862f0de94 Mon Sep 17 00:00:00 2001 From: Amir Malka Date: Thu, 4 Apr 2024 11:37:47 +0300 Subject: [PATCH] support ephemeral containers Signed-off-by: Amir Malka --- pkg/apis/softwarecomposition/types.go | 5 ++-- pkg/apis/softwarecomposition/v1beta1/types.go | 3 ++ .../v1beta1/zz_generated.conversion.go | 2 ++ .../v1beta1/zz_generated.deepcopy.go | 7 +++++ .../zz_generated.deepcopy.go | 7 +++++ pkg/cleanup/discovery.go | 29 +++++++++++++++++++ pkg/generated/openapi/zz_generated.openapi.go | 19 ++++++++++++ pkg/registry/file/processor.go | 6 ++-- pkg/registry/file/processor_test.go | 25 ++++++++++++++-- 9 files changed, 96 insertions(+), 7 deletions(-) diff --git a/pkg/apis/softwarecomposition/types.go b/pkg/apis/softwarecomposition/types.go index 57a268352..f0bcd03a1 100644 --- a/pkg/apis/softwarecomposition/types.go +++ b/pkg/apis/softwarecomposition/types.go @@ -268,8 +268,9 @@ type ApplicationProfile struct { } type ApplicationProfileSpec struct { - Containers []ApplicationProfileContainer - InitContainers []ApplicationProfileContainer + Containers []ApplicationProfileContainer + InitContainers []ApplicationProfileContainer + EphemeralContainers []ApplicationProfileContainer } type ApplicationProfileContainer struct { diff --git a/pkg/apis/softwarecomposition/v1beta1/types.go b/pkg/apis/softwarecomposition/v1beta1/types.go index 716512692..1a9f4d8be 100644 --- a/pkg/apis/softwarecomposition/v1beta1/types.go +++ b/pkg/apis/softwarecomposition/v1beta1/types.go @@ -248,6 +248,9 @@ type ApplicationProfileSpec struct { // +patchMergeKey=name // +patchStrategy=merge InitContainers []ApplicationProfileContainer `json:"initContainers,omitempty" patchStrategy:"merge" patchMergeKey:"name"` + // +patchMergeKey=name + // +patchStrategy=merge + EphemeralContainers []ApplicationProfileContainer `json:"ephemeralContainers,omitempty" patchStrategy:"merge" patchMergeKey:"name"` } type ApplicationProfileContainer struct { diff --git a/pkg/apis/softwarecomposition/v1beta1/zz_generated.conversion.go b/pkg/apis/softwarecomposition/v1beta1/zz_generated.conversion.go index fab57e210..2818fbffb 100644 --- a/pkg/apis/softwarecomposition/v1beta1/zz_generated.conversion.go +++ b/pkg/apis/softwarecomposition/v1beta1/zz_generated.conversion.go @@ -1989,6 +1989,7 @@ func Convert_softwarecomposition_ApplicationProfileList_To_v1beta1_ApplicationPr func autoConvert_v1beta1_ApplicationProfileSpec_To_softwarecomposition_ApplicationProfileSpec(in *ApplicationProfileSpec, out *softwarecomposition.ApplicationProfileSpec, s conversion.Scope) error { out.Containers = *(*[]softwarecomposition.ApplicationProfileContainer)(unsafe.Pointer(&in.Containers)) out.InitContainers = *(*[]softwarecomposition.ApplicationProfileContainer)(unsafe.Pointer(&in.InitContainers)) + out.EphemeralContainers = *(*[]softwarecomposition.ApplicationProfileContainer)(unsafe.Pointer(&in.EphemeralContainers)) return nil } @@ -2000,6 +2001,7 @@ func Convert_v1beta1_ApplicationProfileSpec_To_softwarecomposition_ApplicationPr func autoConvert_softwarecomposition_ApplicationProfileSpec_To_v1beta1_ApplicationProfileSpec(in *softwarecomposition.ApplicationProfileSpec, out *ApplicationProfileSpec, s conversion.Scope) error { out.Containers = *(*[]ApplicationProfileContainer)(unsafe.Pointer(&in.Containers)) out.InitContainers = *(*[]ApplicationProfileContainer)(unsafe.Pointer(&in.InitContainers)) + out.EphemeralContainers = *(*[]ApplicationProfileContainer)(unsafe.Pointer(&in.EphemeralContainers)) return nil } diff --git a/pkg/apis/softwarecomposition/v1beta1/zz_generated.deepcopy.go b/pkg/apis/softwarecomposition/v1beta1/zz_generated.deepcopy.go index bc6960f34..3740ccc87 100644 --- a/pkg/apis/softwarecomposition/v1beta1/zz_generated.deepcopy.go +++ b/pkg/apis/softwarecomposition/v1beta1/zz_generated.deepcopy.go @@ -295,6 +295,13 @@ func (in *ApplicationProfileSpec) DeepCopyInto(out *ApplicationProfileSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.EphemeralContainers != nil { + in, out := &in.EphemeralContainers, &out.EphemeralContainers + *out = make([]ApplicationProfileContainer, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } diff --git a/pkg/apis/softwarecomposition/zz_generated.deepcopy.go b/pkg/apis/softwarecomposition/zz_generated.deepcopy.go index 148c45f48..62c797b6b 100644 --- a/pkg/apis/softwarecomposition/zz_generated.deepcopy.go +++ b/pkg/apis/softwarecomposition/zz_generated.deepcopy.go @@ -295,6 +295,13 @@ func (in *ApplicationProfileSpec) DeepCopyInto(out *ApplicationProfileSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.EphemeralContainers != nil { + in, out := &in.EphemeralContainers, &out.EphemeralContainers + *out = make([]ApplicationProfileContainer, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } diff --git a/pkg/cleanup/discovery.go b/pkg/cleanup/discovery.go index 7306c375c..3a5ef28e0 100644 --- a/pkg/cleanup/discovery.go +++ b/pkg/cleanup/discovery.go @@ -139,6 +139,21 @@ func (h *KubernetesAPI) fetchWlidsFromRunningWorkloads(resourceMaps *ResourceMap resourceMaps.RunningWlidsToContainerNames.Get(wlid).Add(nameStr) } + ephemeralC, ok := workloadinterface.InspectMap(workload.Object, append(workloadinterface.PodSpec(workload.GetKind()), "ephemeralContainers")...) + if !ok { + continue + } + ephemralContainers := ephemeralC.([]interface{}) + for _, container := range ephemralContainers { + name, ok := workloadinterface.InspectMap(container, "name") + if !ok { + logger.L().Debug("container has no name", helpers.String("resource", resource)) + continue + } + nameStr := name.(string) + resourceMaps.RunningWlidsToContainerNames.Get(wlid).Add(nameStr) + } + } } return nil @@ -192,6 +207,20 @@ func (h *KubernetesAPI) fetchInstanceIdsAndImageIdsAndReplicasFromRunningPods(re imageIdStr := containerImageId.(string) resourceMaps.RunningContainerImageIds.Add(imageIdStr) } + + ephemeralC, ok := workloadinterface.InspectMap(p.Object, "status", "ephemeralContainerStatuses") + if !ok { + continue + } + ephemeralContainers := ephemeralC.([]interface{}) + for _, cs := range ephemeralContainers { + containerImageId, ok := workloadinterface.InspectMap(cs, "imageID") + if !ok { + continue + } + imageIdStr := containerImageId.(string) + resourceMaps.RunningContainerImageIds.Add(imageIdStr) + } } return nil } diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index 4ed3da0d7..4b7323d74 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -712,6 +712,25 @@ func schema_pkg_apis_softwarecomposition_v1beta1_ApplicationProfileSpec(ref comm }, }, }, + "ephemeralContainers": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1.ApplicationProfileContainer"), + }, + }, + }, + }, + }, }, }, }, diff --git a/pkg/registry/file/processor.go b/pkg/registry/file/processor.go index c6e5c651b..f2d827115 100644 --- a/pkg/registry/file/processor.go +++ b/pkg/registry/file/processor.go @@ -2,11 +2,12 @@ package file import ( "fmt" + "strconv" + sets "github.com/deckarep/golang-set/v2" "github.com/kubescape/k8s-interface/instanceidhandler/v1/helpers" "github.com/kubescape/storage/pkg/apis/softwarecomposition" "k8s.io/apimachinery/pkg/runtime" - "strconv" ) type Processor interface { @@ -46,7 +47,8 @@ func (a ApplicationProfileProcessor) PreSave(object runtime.Object) error { return containers } - // Use the function for both InitContainers and Containers + // Use the function for InitContainers, EphemeralContainers and Containers + profile.Spec.EphemeralContainers = processContainers(profile.Spec.EphemeralContainers) profile.Spec.InitContainers = processContainers(profile.Spec.InitContainers) profile.Spec.Containers = processContainers(profile.Spec.Containers) diff --git a/pkg/registry/file/processor_test.go b/pkg/registry/file/processor_test.go index 481dabd82..8e6fea419 100644 --- a/pkg/registry/file/processor_test.go +++ b/pkg/registry/file/processor_test.go @@ -2,12 +2,13 @@ package file import ( "fmt" + "testing" + "github.com/kubescape/k8s-interface/instanceidhandler/v1/helpers" "github.com/kubescape/storage/pkg/apis/softwarecomposition" "github.com/stretchr/testify/assert" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "testing" ) func TestApplicationProfileProcessor_PreSave(t *testing.T) { @@ -18,12 +19,20 @@ func TestApplicationProfileProcessor_PreSave(t *testing.T) { wantErr assert.ErrorAssertionFunc }{ { - name: "ApplicationProfile with initContainers", + name: "ApplicationProfile with initContainers and ephemeralContainers", object: &softwarecomposition.ApplicationProfile{ ObjectMeta: v1.ObjectMeta{ Annotations: map[string]string{}, }, Spec: softwarecomposition.ApplicationProfileSpec{ + EphemeralContainers: []softwarecomposition.ApplicationProfileContainer{ + { + Name: "ephemeralContainer", + Execs: []softwarecomposition.ExecCalls{ + {Path: "/bin/bash", Args: []string{"-c", "echo abc"}}, + }, + }, + }, InitContainers: []softwarecomposition.ApplicationProfileContainer{ { Name: "initContainer", @@ -56,10 +65,20 @@ func TestApplicationProfileProcessor_PreSave(t *testing.T) { want: &softwarecomposition.ApplicationProfile{ ObjectMeta: v1.ObjectMeta{ Annotations: map[string]string{ - helpers.ResourceSizeMetadataKey: "5", + helpers.ResourceSizeMetadataKey: "6", }, }, Spec: softwarecomposition.ApplicationProfileSpec{ + EphemeralContainers: []softwarecomposition.ApplicationProfileContainer{ + { + Name: "ephemeralContainer", + Capabilities: []string{}, + Execs: []softwarecomposition.ExecCalls{ + {Path: "/bin/bash", Args: []string{"-c", "echo abc"}}, + }, + Syscalls: []string{}, + }, + }, InitContainers: []softwarecomposition.ApplicationProfileContainer{ { Name: "initContainer",