From be13809e828a5bb627171a5e5f3093cd42453a77 Mon Sep 17 00:00:00 2001 From: Matthias Bertschy Date: Wed, 29 Nov 2023 15:48:41 +0100 Subject: [PATCH] add label with parent resource version Signed-off-by: Matthias Bertschy --- go.mod | 2 +- go.sum | 4 +- .../v1/applicationprofile_manager.go | 1 + pkg/networkmanager/network_neighbors.go | 11 ++-- pkg/networkmanager/network_neighbors_test.go | 66 ++++++++++--------- pkg/relevancymanager/v1/relevancy_manager.go | 27 ++++---- pkg/utils/utils.go | 4 ++ 7 files changed, 65 insertions(+), 50 deletions(-) diff --git a/go.mod b/go.mod index af140cc2..d3216e02 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/kinbiko/jsonassert v1.1.1 github.com/kubescape/backend v0.0.13 github.com/kubescape/go-logger v0.0.21 - github.com/kubescape/k8s-interface v0.0.148 + github.com/kubescape/k8s-interface v0.0.152 github.com/kubescape/storage v0.0.38 github.com/panjf2000/ants/v2 v2.8.1 github.com/spf13/viper v1.17.0 diff --git a/go.sum b/go.sum index 8cded5d7..cbc89fb0 100644 --- a/go.sum +++ b/go.sum @@ -316,8 +316,8 @@ github.com/kubescape/backend v0.0.13 h1:N+fH8giGGqvy3ff2li2AwG5guVduhdiPWyvZaZxr github.com/kubescape/backend v0.0.13/go.mod h1:ug9NFmmxT4DcQx3sgdLRzlLPWMKGHE/fpbcYUm5G5Qo= github.com/kubescape/go-logger v0.0.21 h1:4ZRIEw3UGUH6BG/cH3yiqFipzQSfGAoCrxlsZuk37ys= github.com/kubescape/go-logger v0.0.21/go.mod h1:x3HBpZo3cMT/WIdy18BxvVVd5D0e/PWFVk/HiwBNu3g= -github.com/kubescape/k8s-interface v0.0.148 h1:vtXDUjvCow5wMdDvb5c/Td9SpafeRqsV/LnOd0NVVsE= -github.com/kubescape/k8s-interface v0.0.148/go.mod h1:5sz+5Cjvo98lTbTVDiDA4MmlXxeHSVMW/wR0V3hV4K8= +github.com/kubescape/k8s-interface v0.0.152 h1:1tm2zPYVK7+1fewpca0/MCoK3TgUNButpM3F3uZz6yo= +github.com/kubescape/k8s-interface v0.0.152/go.mod h1:5sz+5Cjvo98lTbTVDiDA4MmlXxeHSVMW/wR0V3hV4K8= github.com/kubescape/storage v0.0.38 h1:LR+QTqjeYw4kM1repIltDLDQGqHgKmG196lQyHP+xUw= github.com/kubescape/storage v0.0.38/go.mod h1:ObCIVOnVyWwRwU0iuKTzOnrJQScqPgkw0FgvSINwosY= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= diff --git a/pkg/applicationprofilemanager/v1/applicationprofile_manager.go b/pkg/applicationprofilemanager/v1/applicationprofile_manager.go index c32614fc..a54d3415 100644 --- a/pkg/applicationprofilemanager/v1/applicationprofile_manager.go +++ b/pkg/applicationprofilemanager/v1/applicationprofile_manager.go @@ -79,6 +79,7 @@ func (am *ApplicationProfileManager) ensureInstanceID(ctx context.Context, conta logger.L().Ctx(ctx).Error("ApplicationProfileManager - failed to validate WLID", helpers.Error(err)) return } + watchedContainer.ParentResourceVersion = w.GetResourceVersion() // find instanceID instanceIDs, err := instanceidhandler.GenerateInstanceID(pod) if err != nil { diff --git a/pkg/networkmanager/network_neighbors.go b/pkg/networkmanager/network_neighbors.go index 368c972c..676c28f7 100644 --- a/pkg/networkmanager/network_neighbors.go +++ b/pkg/networkmanager/network_neighbors.go @@ -63,11 +63,12 @@ func generateNetworkNeighborsLabels(workload k8sinterface.IWorkload) map[string] } return map[string]string{ - instanceidhandlerV1.ApiGroupMetadataKey: apiGroup, - instanceidhandlerV1.ApiVersionMetadataKey: apiVersion, - instanceidhandlerV1.NamespaceMetadataKey: workload.GetNamespace(), - instanceidhandlerV1.KindMetadataKey: strings.ToLower(workload.GetKind()), - instanceidhandlerV1.NameMetadataKey: workload.GetName(), + instanceidhandlerV1.ApiGroupMetadataKey: apiGroup, + instanceidhandlerV1.ApiVersionMetadataKey: apiVersion, + instanceidhandlerV1.NamespaceMetadataKey: workload.GetNamespace(), + instanceidhandlerV1.KindMetadataKey: strings.ToLower(workload.GetKind()), + instanceidhandlerV1.NameMetadataKey: workload.GetName(), + instanceidhandlerV1.ResourceVersionMetadataKey: workload.GetResourceVersion(), } } diff --git a/pkg/networkmanager/network_neighbors_test.go b/pkg/networkmanager/network_neighbors_test.go index 08500fe8..2aa6f857 100644 --- a/pkg/networkmanager/network_neighbors_test.go +++ b/pkg/networkmanager/network_neighbors_test.go @@ -46,11 +46,12 @@ func TestGenerateNetworkNeighborsCRD(t *testing.T) { Name: "deployment-nginx-deployment", Namespace: "default", Labels: map[string]string{ - "kubescape.io/workload-api-group": "apps", - "kubescape.io/workload-api-version": "v1", - "kubescape.io/workload-namespace": "default", - "kubescape.io/workload-kind": "deployment", - "kubescape.io/workload-name": "nginx-deployment", + "kubescape.io/workload-api-group": "apps", + "kubescape.io/workload-api-version": "v1", + "kubescape.io/workload-namespace": "default", + "kubescape.io/workload-kind": "deployment", + "kubescape.io/workload-name": "nginx-deployment", + "kubescape.io/workload-resource-version": "339815", }, }, Spec: v1beta1.NetworkNeighborsSpec{ @@ -80,11 +81,12 @@ func TestGenerateNetworkNeighborsCRD(t *testing.T) { Name: "daemonset-fluentd-elasticsearch", Namespace: "kube-system", Labels: map[string]string{ - "kubescape.io/workload-api-group": "apps", - "kubescape.io/workload-api-version": "v1", - "kubescape.io/workload-namespace": "kube-system", - "kubescape.io/workload-kind": "daemonset", - "kubescape.io/workload-name": "fluentd-elasticsearch", + "kubescape.io/workload-api-group": "apps", + "kubescape.io/workload-api-version": "v1", + "kubescape.io/workload-namespace": "kube-system", + "kubescape.io/workload-kind": "daemonset", + "kubescape.io/workload-name": "fluentd-elasticsearch", + "kubescape.io/workload-resource-version": "266406", }, }, Spec: v1beta1.NetworkNeighborsSpec{ @@ -114,11 +116,12 @@ func TestGenerateNetworkNeighborsCRD(t *testing.T) { Name: "pod-nginx-deployment-fcc867f7-dgjrg", Namespace: "default", Labels: map[string]string{ - "kubescape.io/workload-api-group": "", - "kubescape.io/workload-api-version": "v1", - "kubescape.io/workload-namespace": "default", - "kubescape.io/workload-kind": "pod", - "kubescape.io/workload-name": "nginx-deployment-fcc867f7-dgjrg", + "kubescape.io/workload-api-group": "", + "kubescape.io/workload-api-version": "v1", + "kubescape.io/workload-namespace": "default", + "kubescape.io/workload-kind": "pod", + "kubescape.io/workload-name": "nginx-deployment-fcc867f7-dgjrg", + "kubescape.io/workload-resource-version": "339809", }, }, Spec: v1beta1.NetworkNeighborsSpec{ @@ -225,11 +228,12 @@ func TestGenerateNetworkNeighborsLabels(t *testing.T) { name: "deployment", workload: deploymentJson, expectedLabels: map[string]string{ - "kubescape.io/workload-api-group": "apps", - "kubescape.io/workload-api-version": "v1", - "kubescape.io/workload-namespace": "default", - "kubescape.io/workload-kind": "deployment", - "kubescape.io/workload-name": "nginx-deployment", + "kubescape.io/workload-api-group": "apps", + "kubescape.io/workload-api-version": "v1", + "kubescape.io/workload-namespace": "default", + "kubescape.io/workload-kind": "deployment", + "kubescape.io/workload-name": "nginx-deployment", + "kubescape.io/workload-resource-version": "339815", }, }, @@ -237,11 +241,12 @@ func TestGenerateNetworkNeighborsLabels(t *testing.T) { name: "daemonset", workload: daemonsetJson, expectedLabels: map[string]string{ - "kubescape.io/workload-api-group": "apps", - "kubescape.io/workload-api-version": "v1", - "kubescape.io/workload-namespace": "kube-system", - "kubescape.io/workload-kind": "daemonset", - "kubescape.io/workload-name": "fluentd-elasticsearch", + "kubescape.io/workload-api-group": "apps", + "kubescape.io/workload-api-version": "v1", + "kubescape.io/workload-namespace": "kube-system", + "kubescape.io/workload-kind": "daemonset", + "kubescape.io/workload-name": "fluentd-elasticsearch", + "kubescape.io/workload-resource-version": "266406", }, }, @@ -249,11 +254,12 @@ func TestGenerateNetworkNeighborsLabels(t *testing.T) { name: "pod", workload: podJson, expectedLabels: map[string]string{ - "kubescape.io/workload-api-group": "", - "kubescape.io/workload-api-version": "v1", - "kubescape.io/workload-namespace": "default", - "kubescape.io/workload-kind": "pod", - "kubescape.io/workload-name": "nginx-deployment-fcc867f7-dgjrg", + "kubescape.io/workload-api-group": "", + "kubescape.io/workload-api-version": "v1", + "kubescape.io/workload-namespace": "default", + "kubescape.io/workload-kind": "pod", + "kubescape.io/workload-name": "nginx-deployment-fcc867f7-dgjrg", + "kubescape.io/workload-resource-version": "339809", }, }, } diff --git a/pkg/relevancymanager/v1/relevancy_manager.go b/pkg/relevancymanager/v1/relevancy_manager.go index 00349680..9183634c 100644 --- a/pkg/relevancymanager/v1/relevancy_manager.go +++ b/pkg/relevancymanager/v1/relevancy_manager.go @@ -60,7 +60,7 @@ func (rm *RelevancyManager) deleteResources(watchedContainer *utils.WatchedConta func (rm *RelevancyManager) ensureImageInfo(container *containercollection.Container, watchedContainer *utils.WatchedContainerData) { if watchedContainer.ImageID == "" || watchedContainer.ImageTag == "" || watchedContainer.InstanceID == nil || watchedContainer.Wlid == "" { - imageID, imageTag, parentWlid, instanceID, err := rm.getContainerInfo(container.K8s.Namespace, container.K8s.PodName, container.K8s.ContainerName) + imageID, imageTag, parentWlid, parentResourceVersion, instanceID, err := rm.getContainerInfo(container.K8s.Namespace, container.K8s.PodName, container.K8s.ContainerName) if err != nil { logger.L().Debug("failed to get image info", helpers.String("container ID", container.Runtime.ContainerID), helpers.String("k8s workload", watchedContainer.K8sContainerID), helpers.Error(err)) return @@ -69,39 +69,42 @@ func (rm *RelevancyManager) ensureImageInfo(container *containercollection.Conta watchedContainer.ImageTag = imageTag watchedContainer.InstanceID = instanceID watchedContainer.Wlid = parentWlid + watchedContainer.ParentResourceVersion = parentResourceVersion rm.sbomHandler.IncrementImageUse(watchedContainer.ImageID) } } -func (rm *RelevancyManager) getContainerInfo(namespace, podName, containerName string) (string, string, string, instanceidhandler.IInstanceID, error) { +func (rm *RelevancyManager) getContainerInfo(namespace, podName, containerName string) (string, string, string, string, instanceidhandler.IInstanceID, error) { imageID := "" imageTag := "" parentWlid := "" + parentResourceVersion := "" var instanceID instanceidhandler.IInstanceID wl, err := rm.k8sClient.GetWorkload(namespace, "Pod", podName) if err != nil { - return imageID, imageTag, parentWlid, instanceID, fmt.Errorf("fail to get pod %s in namespace %s with error: %v", podName, namespace, err) + return imageID, imageTag, parentWlid, parentResourceVersion, instanceID, fmt.Errorf("fail to get pod %s in namespace %s with error: %v", podName, namespace, err) } pod := wl.(*workloadinterface.Workload) // find parentWlid kind, name, err := rm.k8sClient.CalculateWorkloadParentRecursive(pod) if err != nil { - return imageID, imageTag, parentWlid, instanceID, fmt.Errorf("fail to get workload owner parent %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) + return imageID, imageTag, parentWlid, parentResourceVersion, instanceID, fmt.Errorf("fail to get workload owner parent %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) } parentWorkload, err := rm.k8sClient.GetWorkload(pod.GetNamespace(), kind, name) if err != nil { - return imageID, imageTag, parentWlid, instanceID, fmt.Errorf("fail to get parent workload %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) + return imageID, imageTag, parentWlid, parentResourceVersion, instanceID, fmt.Errorf("fail to get parent workload %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) } w := parentWorkload.(*workloadinterface.Workload) parentWlid = w.GenerateWlid(rm.clusterName) + parentResourceVersion = w.GetResourceVersion() err = wlid.IsWlidValid(parentWlid) if err != nil { - return imageID, imageTag, parentWlid, instanceID, fmt.Errorf("WLID of parent workload is not in the right %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) + return imageID, imageTag, parentWlid, parentResourceVersion, instanceID, fmt.Errorf("WLID of parent workload is not in the right %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) } // find imageTag containers, err := pod.GetContainers() if err != nil { - return imageID, imageTag, parentWlid, instanceID, fmt.Errorf("fail to get containers for pod %s in namespace %s with error: %v", podName, namespace, err) + return imageID, imageTag, parentWlid, parentResourceVersion, instanceID, fmt.Errorf("fail to get containers for pod %s in namespace %s with error: %v", podName, namespace, err) } for i := range containers { if containers[i].Name == containerName { @@ -109,12 +112,12 @@ func (rm *RelevancyManager) getContainerInfo(namespace, podName, containerName s } } if imageTag == "" { - return imageID, imageTag, parentWlid, instanceID, fmt.Errorf("fail to find container %s in pod %s in namespace %s", containerName, podName, namespace) + return imageID, imageTag, parentWlid, parentResourceVersion, instanceID, fmt.Errorf("fail to find container %s in pod %s in namespace %s", containerName, podName, namespace) } // find imageID status, err := pod.GetPodStatus() // Careful this is not available on container creation if err != nil { - return imageID, imageTag, parentWlid, instanceID, fmt.Errorf("fail to get status for pod %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) + return imageID, imageTag, parentWlid, parentResourceVersion, instanceID, fmt.Errorf("fail to get status for pod %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) } for i := range status.ContainerStatuses { if status.ContainerStatuses[i].Name == containerName { @@ -122,12 +125,12 @@ func (rm *RelevancyManager) getContainerInfo(namespace, podName, containerName s } } if imageID == "" { - return imageID, imageTag, parentWlid, instanceID, fmt.Errorf("fail to find container status %s in pod %s in namespace %s", containerName, podName, namespace) + return imageID, imageTag, parentWlid, parentResourceVersion, instanceID, fmt.Errorf("fail to find container status %s in pod %s in namespace %s", containerName, podName, namespace) } // find instanceID instanceIDs, err := instanceidhandlerV1.GenerateInstanceID(pod) if err != nil { - return imageID, imageTag, parentWlid, instanceID, fmt.Errorf("fail to create InstanceID to pod %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) + return imageID, imageTag, parentWlid, parentResourceVersion, instanceID, fmt.Errorf("fail to create InstanceID to pod %s in namespace %s with error: %v", pod.GetName(), pod.GetNamespace(), err) } instanceID = instanceIDs[0] for i := range instanceIDs { @@ -135,7 +138,7 @@ func (rm *RelevancyManager) getContainerInfo(namespace, podName, containerName s instanceID = instanceIDs[i] } } - return imageID, imageTag, parentWlid, instanceID, nil + return imageID, imageTag, parentWlid, parentResourceVersion, instanceID, nil } // Handle relevant data diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 3a8c79b6..0c0e980c 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -47,6 +47,7 @@ type WatchedContainerData struct { InitialDelayExpired bool InstanceID instanceidhandler.IInstanceID K8sContainerID string + ParentResourceVersion string RelevantRealtimeFilesByPackageSourceInfo map[string]*PackageSourceInfoData RelevantRealtimeFilesBySPDXIdentifier map[v1beta1.ElementID]bool SBOMResourceVersion int @@ -135,6 +136,9 @@ func GetLabels(watchedContainer *WatchedContainerData, stripContainer bool) map[ } } } + if watchedContainer.ParentResourceVersion != "" { + labels[instanceidhandler2.ResourceVersionMetadataKey] = watchedContainer.ParentResourceVersion + } return labels }