diff --git a/pkg/networkmanager/network_manager.go b/pkg/networkmanager/network_manager.go index 8a543511..419c68da 100644 --- a/pkg/networkmanager/network_manager.go +++ b/pkg/networkmanager/network_manager.go @@ -162,29 +162,11 @@ func (am *NetworkManager) handleContainerStarted(ctx context.Context, container return } - var selector *metav1.LabelSelector - if parentWL.GetKind() == "CronJob" { - obj := parentWL.GetObject() - jsonBytes, err := json.Marshal(obj) - if err != nil { - logger.L().Warning("NetworkManager - failed to marshal cronjob", helpers.String("reason", err.Error()), helpers.String("container ID", container.Runtime.ContainerID), helpers.String("k8s workload", k8sContainerID)) - return - } - var cronjob k8sv1beta1.CronJob - if err = json.Unmarshal(jsonBytes, &cronjob); err != nil { - logger.L().Warning("NetworkManager - failed to unmarshal cronjob", helpers.String("reason", err.Error()), helpers.String("container ID", container.Runtime.ContainerID), helpers.String("k8s workload", k8sContainerID)) - return - } - selector = &metav1.LabelSelector{ - MatchLabels: cronjob.Spec.JobTemplate.Spec.Template.ObjectMeta.Labels, - } - } else { - selector, err = parentWL.GetSelector() - if err != nil { - // if we get not selector, we can't create/update network neighbor - logger.L().Warning("NetworkManager - failed to get selector", helpers.String("reason", err.Error()), helpers.String("container ID", container.Runtime.ContainerID), helpers.String("k8s workload", k8sContainerID)) - return - } + selector, err := getSelectorFromWorkload(parentWL) + if err != nil { + // if we get not selector, we can't create/update network neighbor + logger.L().Warning("NetworkManager - failed to get selector", helpers.String("reason", err.Error()), helpers.String("container ID", container.Runtime.ContainerID), helpers.String("k8s workload", k8sContainerID)) + return } if selector == nil { @@ -226,6 +208,30 @@ func (am *NetworkManager) handleContainerStarted(ctx context.Context, container am.deleteResources(container) } +func getSelectorFromWorkload(parentWL k8sinterface.IWorkload) (*metav1.LabelSelector, error) { + if parentWL.GetKind() == "CronJob" { + obj := parentWL.GetObject() + jsonBytes, err := json.Marshal(obj) + if err != nil { + return nil, err + } + var cronjob k8sv1beta1.CronJob + if err = json.Unmarshal(jsonBytes, &cronjob); err != nil { + return nil, err + } + selector := &metav1.LabelSelector{ + MatchLabels: cronjob.Spec.JobTemplate.Spec.Template.ObjectMeta.Labels, + } + return selector, nil + } + + selector, err := parentWL.GetSelector() + if err != nil { + return nil, err + } + return selector, nil +} + // TODO: use same function in relevancy func (am *NetworkManager) getParentWorkloadFromContainer(container *containercollection.Container) (k8sinterface.IWorkload, error) { wl, err := am.k8sClient.GetWorkload(container.K8s.Namespace, "Pod", container.K8s.PodName) diff --git a/pkg/networkmanager/network_manager_test.go b/pkg/networkmanager/network_manager_test.go index e837e552..aacc11b4 100644 --- a/pkg/networkmanager/network_manager_test.go +++ b/pkg/networkmanager/network_manager_test.go @@ -16,6 +16,7 @@ import ( "github.com/goradd/maps" tracernetworktype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/network/types" "github.com/inspektor-gadget/inspektor-gadget/pkg/types" + "github.com/kubescape/k8s-interface/workloadinterface" "github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1" "github.com/stretchr/testify/assert" ) @@ -1334,3 +1335,48 @@ func TestAddToMap(t *testing.T) { }) } } + +func TestGetSelectorFromWorkload(t *testing.T) { + tests := []struct { + name string + parentWL []byte + expectedSelector *metav1.LabelSelector + }{ + { + name: "deployment", + parentWL: deploymentJson, + expectedSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "nginx"}, + }, + }, + { + name: "daemonset", + parentWL: daemonsetJson, + expectedSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"match": "fluentd-elasticsearch"}, + }, + }, + { + name: "cronjob", + parentWL: cronjobJson, + expectedSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "kubescape-scheduler", + "app.kubernetes.io/name": "kubescape-scheduler", + "armo.tier": "kubescape-scan", + }, + }, + }, + } + + for _, tc := range tests { + parentWL, err := workloadinterface.NewWorkload(tc.parentWL) + assert.NoError(t, err) + + result, err := getSelectorFromWorkload(parentWL) + assert.NoError(t, err) + + assert.Equal(t, tc.expectedSelector, result) + + } +} diff --git a/pkg/networkmanager/network_neighbors_test.go b/pkg/networkmanager/network_neighbors_test.go index 08500fe8..bbb5782c 100644 --- a/pkg/networkmanager/network_neighbors_test.go +++ b/pkg/networkmanager/network_neighbors_test.go @@ -12,6 +12,9 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +//go:embed testdata/cronjob.json +var cronjobJson []byte + //go:embed testdata/deployment.json var deploymentJson []byte diff --git a/pkg/networkmanager/testdata/cronjob.json b/pkg/networkmanager/testdata/cronjob.json new file mode 100644 index 00000000..87a39bd8 --- /dev/null +++ b/pkg/networkmanager/testdata/cronjob.json @@ -0,0 +1,109 @@ +{ + "apiVersion": "batch/v1", + "kind": "CronJob", + "metadata": { + "annotations": { + "meta.helm.sh/release-name": "kubescape", + "meta.helm.sh/release-namespace": "kubescape" + }, + "creationTimestamp": "2023-12-03T16:02:57Z", + "generation": 1, + "labels": { + "app": "kubescape-scheduler", + "app.kubernetes.io/managed-by": "Helm", + "app.kubernetes.io/name": "kubescape-scheduler", + "armo.tier": "kubescape-scan", + "tier": "ks-control-plane" + }, + "name": "kubescape-scheduler", + "namespace": "kubescape", + "resourceVersion": "71390981", + "uid": "4560b643-2667-4f20-9cb8-5d27fc4f42ae" + }, + "spec": { + "concurrencyPolicy": "Allow", + "failedJobsHistoryLimit": 1, + "jobTemplate": { + "metadata": { + "creationTimestamp": null + }, + "spec": { + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "kubescape-scheduler", + "app.kubernetes.io/name": "kubescape-scheduler", + "armo.tier": "kubescape-scan" + } + }, + "spec": { + "automountServiceAccountToken": false, + "containers": [ + { + "args": [ + "-method=post", + "-scheme=http", + "-host=operator:4002", + "-path=v1/triggerAction", + "-headers=\"Content-Type:application/json\"", + "-path-body=/home/ks/request-body.json" + ], + "image": "quay.io/kubescape/http-request:v0.0.14", + "imagePullPolicy": "IfNotPresent", + "name": "kubescape-scheduler", + "resources": { + "limits": { + "cpu": "10m", + "memory": "20Mi" + }, + "requests": { + "cpu": "1m", + "memory": "10Mi" + } + }, + "securityContext": { + "allowPrivilegeEscalation": false, + "readOnlyRootFilesystem": true, + "runAsNonRoot": true, + "runAsUser": 100 + }, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/home/ks/request-body.json", + "name": "kubescape-scheduler", + "readOnly": true, + "subPath": "request-body.json" + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Never", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30, + "volumes": [ + { + "configMap": { + "defaultMode": 420, + "name": "kubescape-scheduler" + }, + "name": "kubescape-scheduler" + } + ] + } + } + } + }, + "schedule": "23 5 * * *", + "successfulJobsHistoryLimit": 3, + "suspend": false + }, + "status": { + "lastScheduleTime": "2023-12-04T05:23:00Z", + "lastSuccessfulTime": "2023-12-04T05:23:16Z" + } +} diff --git a/pkg/networkmanager/testdata/deployment.json b/pkg/networkmanager/testdata/deployment.json index 5df6885d..6113284d 100644 --- a/pkg/networkmanager/testdata/deployment.json +++ b/pkg/networkmanager/testdata/deployment.json @@ -9,7 +9,8 @@ "creationTimestamp": "2023-10-22T10:56:49Z", "generation": 1, "labels": { - "app": "nginx" + "app": "nginx", + "bla3": "blu3" }, "name": "nginx-deployment", "namespace": "default",