diff --git a/cmd/main.go b/cmd/main.go index dd953ab47..551df1a95 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -10,7 +10,7 @@ import ( "strings" "syscall" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" utilsmetadata "github.com/armosec/utils-k8s-go/armometadata" "github.com/cilium/ebpf/rlimit" mapset "github.com/deckarep/golang-set/v2" @@ -35,7 +35,7 @@ import ( "github.com/kubescape/node-agent/pkg/exporters" "github.com/kubescape/node-agent/pkg/fimmanager" "github.com/kubescape/node-agent/pkg/healthmanager" - hostsensormanager "github.com/kubescape/node-agent/pkg/hostsensormanager" + "github.com/kubescape/node-agent/pkg/hostsensormanager" "github.com/kubescape/node-agent/pkg/malwaremanager" malwaremanagerv1 "github.com/kubescape/node-agent/pkg/malwaremanager/v1" "github.com/kubescape/node-agent/pkg/metricsmanager" @@ -260,7 +260,7 @@ func main() { var processTreeManager processtree.ProcessTreeManager var objCache objectcache.ObjectCache var ruleBindingNotify chan rulebinding.RuleBindingNotify - var cloudMetadata *apitypes.CloudMetadata + var cloudMetadata *armotypes.CloudMetadata // Create the container process tree containerProcessTree := containerprocesstree.NewContainerProcessTree() @@ -287,7 +287,7 @@ func main() { if cfg.EnableRuntimeDetection { // create exporter - exporter := exporters.InitExporters(cfg.Exporters, clusterData.ClusterName, cfg.NodeName, cloudMetadata, clusterUID) + exporter := exporters.InitExporters(cfg.Exporters, clusterData.ClusterName, cfg.NodeName, cloudMetadata, clusterUID, armotypes.AlertSourcePlatformK8sAgent) dWatcher.AddAdaptor(ruleBindingCache) ruleBindingNotify = make(chan rulebinding.RuleBindingNotify, 100) @@ -353,7 +353,7 @@ func main() { var malwareManager malwaremanager.MalwareManagerClient if cfg.EnableMalwareDetection { // create exporter - exporter := exporters.InitExporters(cfg.Exporters, clusterData.ClusterName, cfg.NodeName, cloudMetadata, clusterUID) + exporter := exporters.InitExporters(cfg.Exporters, clusterData.ClusterName, cfg.NodeName, cloudMetadata, clusterUID, armotypes.AlertSourcePlatformK8sAgent) malwareManager, err = malwaremanagerv1.CreateMalwareManager(cfg, k8sClient, cfg.NodeName, clusterData.ClusterName, exporter, prometheusExporter, k8sObjectCache) if err != nil { logger.L().Ctx(ctx).Fatal("error creating MalwareManager", helpers.Error(err)) @@ -395,7 +395,7 @@ func main() { if cfg.EnableFIM { // Initialize FIM-specific exporters fimExportersConfig := cfg.FIM.GetFIMExportersConfig() - fimExporter := exporters.InitExporters(fimExportersConfig, clusterData.ClusterName, cfg.NodeName, cloudMetadata, clusterUID) + fimExporter := exporters.InitExporters(fimExportersConfig, clusterData.ClusterName, cfg.NodeName, cloudMetadata, clusterUID, armotypes.AlertSourcePlatformK8sAgent) fimManager, err = fimmanager.NewFIMManager(cfg, clusterData.ClusterName, fimExporter, cloudMetadata) if err != nil { diff --git a/docs/ALERT_BULKING.md b/docs/ALERT_BULKING.md index 914e8e3ae..c7d4365de 100644 --- a/docs/ALERT_BULKING.md +++ b/docs/ALERT_BULKING.md @@ -102,9 +102,9 @@ type AlertBulkManager struct { type containerBulk struct { sync.Mutex containerID string - alerts []apitypes.RuntimeAlert - processMap map[uint32]*apitypes.Process // PID → Process - rootProcess *apitypes.Process // Container init + alerts []armotypes.RuntimeAlert + processMap map[uint32]*armotypes.Process // PID → Process + rootProcess *armotypes.Process // Container init cloudServices []string firstAlertTime time.Time maxSize int @@ -113,8 +113,8 @@ type containerBulk struct { type bulkQueueItem struct { containerID string - alerts []apitypes.RuntimeAlert - processTree apitypes.ProcessTree + alerts []armotypes.RuntimeAlert + processTree armotypes.ProcessTree cloudServices []string retryCount int enqueuedAt time.Time diff --git a/docs/PROCESS_TREE_CHAIN_OPTIMIZATION.md b/docs/PROCESS_TREE_CHAIN_OPTIMIZATION.md index 9bf069dae..dbbd77196 100644 --- a/docs/PROCESS_TREE_CHAIN_OPTIMIZATION.md +++ b/docs/PROCESS_TREE_CHAIN_OPTIMIZATION.md @@ -53,8 +53,8 @@ type containerBulk struct { // ... other fields ... // NEW: Maintain incrementally instead of rebuilding - processMap map[uint32]*apitypes.Process // PID -> Process for O(1) lookup - rootProcess *apitypes.Process // Root of merged tree + processMap map[uint32]*armotypes.Process // PID -> Process for O(1) lookup + rootProcess *armotypes.Process // Root of merged tree } ``` @@ -69,9 +69,9 @@ Instead of recursively merging arbitrary trees, we: - If new: **create and link** to parent in tree ```go -func (cb *containerBulk) mergeProcessChain(chain *apitypes.Process) { +func (cb *containerBulk) mergeProcessChain(chain *armotypes.Process) { if cb.processMap == nil { - cb.processMap = make(map[uint32]*apitypes.Process) + cb.processMap = make(map[uint32]*armotypes.Process) } // Flatten chain: O(k) where k = chain length @@ -92,7 +92,7 @@ func (cb *containerBulk) mergeProcessChain(chain *apitypes.Process) { } if parent, ok := cb.processMap[newNode.PPID]; ok { - parent.ChildrenMap[apitypes.CommPID{PID: newNode.PID}] = newNode + parent.ChildrenMap[armotypes.CommPID{PID: newNode.PID}] = newNode } } } @@ -207,4 +207,3 @@ By recognizing that runtime alerts provide **chains, not arbitrary trees**, we a - ✅ **Thread-safe** (race detector clean) This optimization addresses matthyx's performance concern and makes the alert bulking feature production-ready. - diff --git a/go.mod b/go.mod index 0f4316336..d5a5b412b 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Masterminds/semver/v3 v3.4.0 github.com/anchore/syft v1.32.0 github.com/aquilax/truncate v1.0.0 - github.com/armosec/armoapi-go v0.0.678 + github.com/armosec/armoapi-go v0.0.682 github.com/armosec/utils-k8s-go v0.0.35 github.com/cenkalti/backoff v2.2.1+incompatible github.com/cenkalti/backoff/v4 v4.3.0 diff --git a/go.sum b/go.sum index edc6f5456..d81485b14 100644 --- a/go.sum +++ b/go.sum @@ -761,8 +761,8 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/armosec/armoapi-go v0.0.678 h1:trltW2KxO5OqrB2zHIPx8jqe82AFvdRryo2XgBEyJw8= -github.com/armosec/armoapi-go v0.0.678/go.mod h1:9jAH0g8ZsryhiBDd/aNMX4+n10bGwTx/doWCyyjSxts= +github.com/armosec/armoapi-go v0.0.682 h1:H/bMUS3ESNrcun16iS9ficCkE1mWyOIkZJXokauuI6U= +github.com/armosec/armoapi-go v0.0.682/go.mod h1:9jAH0g8ZsryhiBDd/aNMX4+n10bGwTx/doWCyyjSxts= github.com/armosec/gojay v1.2.17 h1:VSkLBQzD1c2V+FMtlGFKqWXNsdNvIKygTKJI9ysY8eM= github.com/armosec/gojay v1.2.17/go.mod h1:vuvX3DlY0nbVrJ0qCklSS733AWMoQboq3cFyuQW9ybc= github.com/armosec/utils-go v0.0.58 h1:g9RnRkxZAmzTfPe2ruMo2OXSYLwVSegQSkSavOfmaIE= diff --git a/pkg/containerprofilemanager/v1/containerprofile_manager.go b/pkg/containerprofilemanager/v1/containerprofile_manager.go index 76816f69c..484ff4f9c 100644 --- a/pkg/containerprofilemanager/v1/containerprofile_manager.go +++ b/pkg/containerprofilemanager/v1/containerprofile_manager.go @@ -32,6 +32,8 @@ type ContainerEntry struct { mu sync.RWMutex // ready channel is used to signal when the container entry is fully initialized ready chan struct{} + // readyOnce ensures the ready channel is closed exactly once + readyOnce sync.Once } // containerData contains all the monitored data for a single container diff --git a/pkg/containerprofilemanager/v1/lifecycle.go b/pkg/containerprofilemanager/v1/lifecycle.go index d3c7046bb..68e0682e1 100644 --- a/pkg/containerprofilemanager/v1/lifecycle.go +++ b/pkg/containerprofilemanager/v1/lifecycle.go @@ -17,6 +17,9 @@ import ( func (cpm *ContainerProfileManager) ContainerCallback(notif containercollection.PubSubEvent) { switch notif.Type { case containercollection.EventTypeAddContainer: + if utils.IsHostContainer(notif.Container) { + return + } if cpm.cfg.IgnoreContainer(notif.Container.K8s.Namespace, notif.Container.K8s.PodName, notif.Container.K8s.PodLabels) { return } @@ -52,6 +55,11 @@ func (cpm *ContainerProfileManager) addContainerWithTimeout(container *container case err := <-done: if err != nil { logger.L().Error("failed to add container to the container profile manager", helpers.Error(err)) + // Close ready channel and remove entry on error + entry.readyOnce.Do(func() { + close(entry.ready) + }) + cpm.removeContainerEntry(containerID) } case <-ctx.Done(): logger.L().Error("timeout while adding container to the container profile manager", @@ -59,6 +67,11 @@ func (cpm *ContainerProfileManager) addContainerWithTimeout(container *container helpers.String("containerName", container.Runtime.ContainerName), helpers.String("podName", container.K8s.PodName), helpers.String("namespace", container.K8s.Namespace)) + // Close ready channel and remove entry on timeout + entry.readyOnce.Do(func() { + close(entry.ready) + }) + cpm.removeContainerEntry(containerID) } } @@ -69,7 +82,12 @@ func (cpm *ContainerProfileManager) addContainer(container *containercollection. // Wait for shared container data with timeout sharedData, err := cpm.waitForSharedContainerData(containerID, ctx) if err != nil { - // Remove the container entry and all stacked events if we fail + // Close ready channel and remove the container entry if we fail + if entry, exists := cpm.getContainerEntry(containerID); exists { + entry.readyOnce.Do(func() { + close(entry.ready) + }) + } cpm.removeContainerEntry(containerID) return fmt.Errorf("failed to get shared data for container %s: %w", containerID, err) } @@ -82,6 +100,12 @@ func (cpm *ContainerProfileManager) addContainer(container *containercollection. helpers.String("podName", container.K8s.PodName), helpers.String("namespace", container.K8s.Namespace), helpers.String("userDefinedProfile", sharedData.UserDefinedProfile)) + // Close ready channel before removing entry + if entry, exists := cpm.getContainerEntry(containerID); exists { + entry.readyOnce.Do(func() { + close(entry.ready) + }) + } cpm.removeContainerEntry(containerID) return nil } @@ -93,6 +117,12 @@ func (cpm *ContainerProfileManager) addContainer(container *containercollection. helpers.String("containerName", container.Runtime.ContainerName), helpers.String("podName", container.K8s.PodName), helpers.String("namespace", container.K8s.Namespace)) + // Close ready channel before removing entry + if entry, exists := cpm.getContainerEntry(containerID); exists { + entry.readyOnce.Do(func() { + close(entry.ready) + }) + } cpm.removeContainerEntry(containerID) return nil } @@ -103,6 +133,12 @@ func (cpm *ContainerProfileManager) addContainer(container *containercollection. helpers.String("containerName", container.Runtime.ContainerName), helpers.String("podName", container.K8s.PodName), helpers.String("namespace", container.K8s.Namespace)) + // Close ready channel before removing entry + if entry, exists := cpm.getContainerEntry(containerID); exists { + entry.readyOnce.Do(func() { + close(entry.ready) + }) + } cpm.removeContainerEntry(containerID) return nil } @@ -135,7 +171,9 @@ func (cpm *ContainerProfileManager) addContainer(container *containercollection. go cpm.startContainerMonitoring(container, sharedData) // Signal that the container entry is ready - close(entry.ready) + entry.readyOnce.Do(func() { + close(entry.ready) + }) logger.L().Debug("container added to container profile manager", helpers.String("containerID", containerID), diff --git a/pkg/containerwatcher/v2/container_watcher_collection.go b/pkg/containerwatcher/v2/container_watcher_collection.go index 8065a3702..834ecb412 100644 --- a/pkg/containerwatcher/v2/container_watcher_collection.go +++ b/pkg/containerwatcher/v2/container_watcher_collection.go @@ -5,6 +5,7 @@ import ( "fmt" "time" + "github.com/armosec/armoapi-go/armotypes" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" containerutils "github.com/inspektor-gadget/inspektor-gadget/pkg/container-utils" "github.com/inspektor-gadget/inspektor-gadget/pkg/operators/socketenricher" @@ -186,6 +187,7 @@ func GetHostAsContainer() (*containercollection.Container, error) { return &containercollection.Container{ Runtime: containercollection.RuntimeMetadata{ BasicRuntimeMetadata: eventtypes.BasicRuntimeMetadata{ + ContainerID: armotypes.HostContainerID, ContainerPID: uint32(hostInitPID), }, }, diff --git a/pkg/containerwatcher/v2/containercallback.go b/pkg/containerwatcher/v2/containercallback.go index 0fb5ce08c..4ee7ea6e6 100644 --- a/pkg/containerwatcher/v2/containercallback.go +++ b/pkg/containerwatcher/v2/containercallback.go @@ -60,8 +60,7 @@ func (cw *ContainerWatcher) containerCallbackAsync(notif containercollection.Pub helpers.String("ContainerImageName", notif.Container.Runtime.ContainerImageName)) cw.metrics.ReportContainerStart() - // Skip shared data setup for virtual host container (identified by ContainerPID == 1) - if notif.Container.Runtime.ContainerPID == 1 { + if utils.IsHostContainer(notif.Container) { logger.L().Debug("ContainerWatcher.containerCallback - skipping shared data setup for virtual host container") return } diff --git a/pkg/containerwatcher/v2/event_enricher.go b/pkg/containerwatcher/v2/event_enricher.go index 74aee76a1..853be9302 100644 --- a/pkg/containerwatcher/v2/event_enricher.go +++ b/pkg/containerwatcher/v2/event_enricher.go @@ -3,7 +3,7 @@ package containerwatcher import ( "fmt" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/kubescape/go-logger" "github.com/kubescape/go-logger/helpers" ebpfevents "github.com/kubescape/node-agent/pkg/ebpf/events" @@ -26,7 +26,7 @@ func NewEventEnricher( } func (ee *EventEnricher) EnrichEvents(entry EventEntry) *ebpfevents.EnrichedEvent { - var processTree apitypes.Process + var processTree armotypes.Process eventType := entry.EventType event := entry.Event diff --git a/pkg/containerwatcher/v2/tracers/procfs.go b/pkg/containerwatcher/v2/tracers/procfs.go index 16c357d8a..eefaca660 100644 --- a/pkg/containerwatcher/v2/tracers/procfs.go +++ b/pkg/containerwatcher/v2/tracers/procfs.go @@ -5,6 +5,7 @@ import ( "fmt" "time" + "github.com/armosec/armoapi-go/armotypes" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" tracercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/tracer-collection" "github.com/inspektor-gadget/inspektor-gadget/pkg/types" @@ -183,7 +184,7 @@ func (pt *ProcfsTracer) handleProcfsEvent(event conversion.ProcessEvent) { if container != nil { procfsEvent.ContainerID = container.Runtime.ContainerID } else { - procfsEvent.ContainerID = "host" + procfsEvent.ContainerID = armotypes.HostContainerID } processID := event.PID containerID := procfsEvent.ContainerID diff --git a/pkg/ebpf/events/enriched_event.go b/pkg/ebpf/events/enriched_event.go index 9d869ef59..c158e3be5 100644 --- a/pkg/ebpf/events/enriched_event.go +++ b/pkg/ebpf/events/enriched_event.go @@ -3,13 +3,13 @@ package events import ( "time" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/kubescape/node-agent/pkg/contextdetection" "github.com/kubescape/node-agent/pkg/utils" ) // NewEnrichedEvent creates a new enriched event -func NewEnrichedEvent(event utils.K8sEvent, timestamp time.Time, containerID string, processTree apitypes.Process) *EnrichedEvent { +func NewEnrichedEvent(event utils.K8sEvent, timestamp time.Time, containerID string, processTree armotypes.Process) *EnrichedEvent { return &EnrichedEvent{ Event: event, Timestamp: timestamp, @@ -19,18 +19,18 @@ func NewEnrichedEvent(event utils.K8sEvent, timestamp time.Time, containerID str } type EnrichedEvent struct { - Event utils.K8sEvent - Timestamp time.Time - ContainerID string - ProcessTree apitypes.Process - PID uint32 - PPID uint32 + Event utils.K8sEvent + Timestamp time.Time + ContainerID string + ProcessTree armotypes.Process + PID uint32 + PPID uint32 // SourceContext holds the context information for this event (K8s, Host, or Standalone). // This is populated during event enrichment if the feature is enabled. // May be nil for legacy K8s-only events or when feature is disabled. - SourceContext contextdetection.ContextInfo + SourceContext contextdetection.ContextInfo // MountNamespaceID is the mount namespace ID from the container. // This uniquely identifies the container/host and is used for context lookup. // May be 0 if unavailable. - MountNamespaceID uint64 + MountNamespaceID uint64 } diff --git a/pkg/ebpf/events/enriched_event_test.go b/pkg/ebpf/events/enriched_event_test.go index a677efa38..31c9bb610 100644 --- a/pkg/ebpf/events/enriched_event_test.go +++ b/pkg/ebpf/events/enriched_event_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/kubescape/node-agent/pkg/utils" "github.com/stretchr/testify/assert" ) @@ -14,7 +14,7 @@ func TestNewEnrichedEvent(t *testing.T) { mockEvent := &utils.StructEvent{ID: "test-event"} timestamp := time.Now() containerID := "test-container-123" - processTree := apitypes.Process{ + processTree := armotypes.Process{ PID: 1234, Comm: "test-process", Path: "/usr/bin/test", @@ -35,7 +35,7 @@ func TestEnrichedEvent_Structure(t *testing.T) { Event: &utils.StructEvent{ID: "open-event", EventType: utils.OpenEventType}, Timestamp: time.Now(), ContainerID: "container-456", - ProcessTree: apitypes.Process{ + ProcessTree: armotypes.Process{ PID: 5678, Comm: "open-process", Path: "/bin/open", @@ -72,7 +72,7 @@ func TestEnrichedEvent_EventTypes(t *testing.T) { timestamp := time.Now() containerID := "test-container" - processTree := apitypes.Process{PID: 1000, Comm: "test"} + processTree := armotypes.Process{PID: 1000, Comm: "test"} for i, eventType := range eventTypes { t.Run(string(eventType), func(t *testing.T) { @@ -87,14 +87,14 @@ func TestEnrichedEvent_EventTypes(t *testing.T) { func TestEnrichedEvent_ProcessTreeIntegration(t *testing.T) { // Test process tree integration - processTree := apitypes.Process{ + processTree := armotypes.Process{ PID: 9999, PPID: 1, Comm: "parent-process", Path: "/usr/bin/parent", Cmdline: "parent-process --arg1 --arg2", Cwd: "/home/user", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "child1", PID: 10001}: { PID: 10001, PPID: 9999, @@ -122,12 +122,12 @@ func TestEnrichedEvent_ProcessTreeIntegration(t *testing.T) { assert.Len(t, enrichedEvent.ProcessTree.ChildrenMap, 2) // Verify children - child1, exists := enrichedEvent.ProcessTree.ChildrenMap[apitypes.CommPID{Comm: "child1", PID: 10001}] + child1, exists := enrichedEvent.ProcessTree.ChildrenMap[armotypes.CommPID{Comm: "child1", PID: 10001}] assert.True(t, exists) assert.Equal(t, uint32(10001), child1.PID) assert.Equal(t, uint32(9999), child1.PPID) - child2, exists := enrichedEvent.ProcessTree.ChildrenMap[apitypes.CommPID{Comm: "child2", PID: 10002}] + child2, exists := enrichedEvent.ProcessTree.ChildrenMap[armotypes.CommPID{Comm: "child2", PID: 10002}] assert.True(t, exists) assert.Equal(t, uint32(10002), child2.PID) assert.Equal(t, uint32(9999), child2.PPID) @@ -138,9 +138,9 @@ func TestEnrichedEvent_TimestampOrdering(t *testing.T) { baseTime := time.Now() events := []*EnrichedEvent{ - NewEnrichedEvent(&utils.StructEvent{ID: "third"}, baseTime.Add(2*time.Second), "container", apitypes.Process{}), - NewEnrichedEvent(&utils.StructEvent{ID: "first"}, baseTime, "container", apitypes.Process{}), - NewEnrichedEvent(&utils.StructEvent{ID: "second"}, baseTime.Add(1*time.Second), "container", apitypes.Process{}), + NewEnrichedEvent(&utils.StructEvent{ID: "third"}, baseTime.Add(2*time.Second), "container", armotypes.Process{}), + NewEnrichedEvent(&utils.StructEvent{ID: "first"}, baseTime, "container", armotypes.Process{}), + NewEnrichedEvent(&utils.StructEvent{ID: "second"}, baseTime.Add(1*time.Second), "container", armotypes.Process{}), } // Sort by timestamp (manually for test) @@ -179,7 +179,7 @@ func TestEnrichedEvent_ContainerIDMatching(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - enrichedEvent := NewEnrichedEvent(&utils.StructEvent{ID: "test"}, time.Now(), tc.containerID, apitypes.Process{}) + enrichedEvent := NewEnrichedEvent(&utils.StructEvent{ID: "test"}, time.Now(), tc.containerID, armotypes.Process{}) assert.Equal(t, tc.expected, enrichedEvent.ContainerID) }) @@ -196,7 +196,7 @@ func TestEnrichedEvent_EventMetadata(t *testing.T) { Timestamp: time.Now().UnixNano(), } - enrichedEvent := NewEnrichedEvent(mockEvent, time.Now(), "test-container", apitypes.Process{PID: 1234}) + enrichedEvent := NewEnrichedEvent(mockEvent, time.Now(), "test-container", armotypes.Process{PID: 1234}) // Verify original event metadata is preserved originalEvent := enrichedEvent.Event.(*utils.StructEvent) @@ -213,7 +213,7 @@ func TestEnrichedEvent_EventMetadata(t *testing.T) { func TestEnrichedEvent_EmptyProcessTree(t *testing.T) { // Test handling of empty process tree - enrichedEvent := NewEnrichedEvent(&utils.StructEvent{ID: "no-process-tree", EventType: utils.OpenEventType}, time.Now(), "container-123", apitypes.Process{}) + enrichedEvent := NewEnrichedEvent(&utils.StructEvent{ID: "no-process-tree", EventType: utils.OpenEventType}, time.Now(), "container-123", armotypes.Process{}) assert.Equal(t, utils.OpenEventType, enrichedEvent.Event.GetEventType()) assert.Equal(t, "container-123", enrichedEvent.ContainerID) diff --git a/pkg/exporters/alert_bulk_manager.go b/pkg/exporters/alert_bulk_manager.go index eb3da130e..8510ad505 100644 --- a/pkg/exporters/alert_bulk_manager.go +++ b/pkg/exporters/alert_bulk_manager.go @@ -6,7 +6,7 @@ import ( "sync" "time" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/kubescape/go-logger" "github.com/kubescape/go-logger/helpers" "github.com/kubescape/node-agent/pkg/utils" @@ -16,9 +16,9 @@ import ( type containerBulk struct { sync.Mutex containerID string - alerts []apitypes.RuntimeAlert - processMap map[uint32]*apitypes.Process // Incremental map for O(1) lookup - rootProcess *apitypes.Process // Root of merged tree + alerts []armotypes.RuntimeAlert + processMap map[uint32]*armotypes.Process // Incremental map for O(1) lookup + rootProcess *armotypes.Process // Root of merged tree cloudServices []string firstAlertTime time.Time maxSize int @@ -45,7 +45,7 @@ func (cb *containerBulk) shouldFlush() bool { // addAlert adds an alert to the bulk and merges its process chain // Optimized for chain-structured process trees (container init -> parent -> ... -> offending process) -func (cb *containerBulk) addAlert(alert apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) { +func (cb *containerBulk) addAlert(alert armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) { cb.Lock() defer cb.Unlock() @@ -69,14 +69,14 @@ func (cb *containerBulk) addAlert(alert apitypes.RuntimeAlert, processTree apity // mergeProcessChain merges a chain-structured process tree into the accumulated tree // This is optimized for chains: ContainerInit -> Parent1 -> ... -> OffendingProcess // Complexity: O(k) where k is chain length, vs O(n) for full tree merge -func (cb *containerBulk) mergeProcessChain(chain *apitypes.Process) { +func (cb *containerBulk) mergeProcessChain(chain *armotypes.Process) { if chain == nil || chain.PID == 0 { return } // Lazy initialization if cb.processMap == nil { - cb.processMap = make(map[uint32]*apitypes.Process) + cb.processMap = make(map[uint32]*armotypes.Process) } // Ensure chain uses map structure @@ -106,9 +106,9 @@ func (cb *containerBulk) mergeProcessChain(chain *apitypes.Process) { if newNode.PPID != 0 { if parent, ok := cb.processMap[newNode.PPID]; ok { if parent.ChildrenMap == nil { - parent.ChildrenMap = make(map[apitypes.CommPID]*apitypes.Process) + parent.ChildrenMap = make(map[armotypes.CommPID]*armotypes.Process) } - parent.ChildrenMap[apitypes.CommPID{PID: newNode.PID}] = newNode + parent.ChildrenMap[armotypes.CommPID{PID: newNode.PID}] = newNode } else { // Parent doesn't exist in tree - this is a new root // We need to handle multiple roots by creating a synthetic parent @@ -128,23 +128,23 @@ func (cb *containerBulk) mergeProcessChain(chain *apitypes.Process) { } // attachToSyntheticRoot creates a synthetic root (PID 1) to hold multiple independent process trees -func (cb *containerBulk) attachToSyntheticRoot(newRoot *apitypes.Process) { +func (cb *containerBulk) attachToSyntheticRoot(newRoot *armotypes.Process) { const syntheticRootPID = 1 // Check if we need to convert existing root to use synthetic parent if cb.rootProcess.PID != syntheticRootPID { // Create synthetic root if it doesn't exist if _, exists := cb.processMap[syntheticRootPID]; !exists { - syntheticRoot := &apitypes.Process{ + syntheticRoot := &armotypes.Process{ PID: syntheticRootPID, PPID: 0, Comm: "container-root", - ChildrenMap: make(map[apitypes.CommPID]*apitypes.Process), + ChildrenMap: make(map[armotypes.CommPID]*armotypes.Process), } cb.processMap[syntheticRootPID] = syntheticRoot // Attach current root to synthetic root - syntheticRoot.ChildrenMap[apitypes.CommPID{PID: cb.rootProcess.PID}] = cb.rootProcess + syntheticRoot.ChildrenMap[armotypes.CommPID{PID: cb.rootProcess.PID}] = cb.rootProcess // Update root reference cb.rootProcess = syntheticRoot @@ -152,18 +152,18 @@ func (cb *containerBulk) attachToSyntheticRoot(newRoot *apitypes.Process) { } // Attach new root to synthetic root - cb.rootProcess.ChildrenMap[apitypes.CommPID{PID: newRoot.PID}] = newRoot + cb.rootProcess.ChildrenMap[armotypes.CommPID{PID: newRoot.PID}] = newRoot } // flush returns the bulk data and resets the bulk -func (cb *containerBulk) flush() ([]apitypes.RuntimeAlert, apitypes.ProcessTree, []string) { +func (cb *containerBulk) flush() ([]armotypes.RuntimeAlert, armotypes.ProcessTree, []string) { cb.Lock() defer cb.Unlock() alerts := cb.alerts // Build result from root process - processTree := apitypes.ProcessTree{} + processTree := armotypes.ProcessTree{} if cb.rootProcess != nil { processTree.ProcessTree = *cb.rootProcess } @@ -183,8 +183,8 @@ func (cb *containerBulk) flush() ([]apitypes.RuntimeAlert, apitypes.ProcessTree, // bulkQueueItem represents a bulk waiting to be sent type bulkQueueItem struct { containerID string - alerts []apitypes.RuntimeAlert - processTree apitypes.ProcessTree + alerts []armotypes.RuntimeAlert + processTree armotypes.ProcessTree cloudServices []string retryCount int enqueuedAt time.Time @@ -207,7 +207,7 @@ type AlertBulkManager struct { retryMaxDelay time.Duration sendWorkerCount int - sendFunc func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error + sendFunc func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error stopChan chan struct{} wg sync.WaitGroup } @@ -220,7 +220,7 @@ func NewAlertBulkManager( maxRetries int, retryBaseDelayMs int, retryMaxDelayMs int, - sendFunc func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error, + sendFunc func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error, ) *AlertBulkManager { // Set defaults if sendQueueSize == 0 { @@ -281,7 +281,7 @@ func (abm *AlertBulkManager) Stop() { } // AddAlert adds an alert to the appropriate container bulk -func (abm *AlertBulkManager) AddAlert(alert apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) { +func (abm *AlertBulkManager) AddAlert(alert armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) { containerID := alert.RuntimeAlertK8sDetails.ContainerID if containerID == "" { logger.L().Warning("AlertBulkManager.AddAlert - containerID is empty, cannot add to bulk") @@ -294,7 +294,7 @@ func (abm *AlertBulkManager) AddAlert(alert apitypes.RuntimeAlert, processTree a if !exists { bulk = &containerBulk{ containerID: containerID, - alerts: make([]apitypes.RuntimeAlert, 0, abm.bulkMaxAlerts), + alerts: make([]armotypes.RuntimeAlert, 0, abm.bulkMaxAlerts), cloudServices: make([]string, 0), maxSize: abm.bulkMaxAlerts, timeoutDuration: abm.bulkTimeoutDuration, @@ -571,7 +571,7 @@ func (abm *AlertBulkManager) GetBulkCount() int { } // sendBulkWrapper is a helper to adapt the bulk send to HTTPExporter's sendAlert method -func (e *HTTPExporter) sendBulkWrapper(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { +func (e *HTTPExporter) sendBulkWrapper(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { ctx, cancel := context.WithTimeout(context.Background(), time.Duration(e.config.TimeoutSeconds)*time.Second) defer cancel() diff --git a/pkg/exporters/alert_bulk_manager_test.go b/pkg/exporters/alert_bulk_manager_test.go index fd4b20a43..4b8a4925d 100644 --- a/pkg/exporters/alert_bulk_manager_test.go +++ b/pkg/exporters/alert_bulk_manager_test.go @@ -5,29 +5,29 @@ import ( "testing" "time" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/stretchr/testify/assert" ) -func createTestAlert(containerID string, alertName string) apitypes.RuntimeAlert { - return apitypes.RuntimeAlert{ +func createTestAlert(containerID string, alertName string) armotypes.RuntimeAlert { + return armotypes.RuntimeAlert{ Message: alertName, - RuntimeAlertK8sDetails: apitypes.RuntimeAlertK8sDetails{ + RuntimeAlertK8sDetails: armotypes.RuntimeAlertK8sDetails{ ContainerID: containerID, ContainerName: "test-container", PodName: "test-pod", Namespace: "test-ns", }, - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ AlertName: alertName, Timestamp: time.Now(), }, } } -func createTestProcessTree(pid uint32) apitypes.ProcessTree { - return apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ +func createTestProcessTree(pid uint32) armotypes.ProcessTree { + return armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ PID: pid, PPID: 1, Comm: "test-process", @@ -39,7 +39,7 @@ func createTestProcessTree(pid uint32) apitypes.ProcessTree { func TestContainerBulk_AddAlert(t *testing.T) { bulk := &containerBulk{ containerID: "container-123", - alerts: make([]apitypes.RuntimeAlert, 0), + alerts: make([]armotypes.RuntimeAlert, 0), cloudServices: make([]string, 0), maxSize: 50, timeoutDuration: 10 * time.Second, @@ -62,7 +62,7 @@ func TestContainerBulk_AddAlert(t *testing.T) { func TestContainerBulk_AddMultipleAlerts(t *testing.T) { bulk := &containerBulk{ containerID: "container-123", - alerts: make([]apitypes.RuntimeAlert, 0), + alerts: make([]armotypes.RuntimeAlert, 0), cloudServices: make([]string, 0), maxSize: 50, timeoutDuration: 10 * time.Second, @@ -96,29 +96,29 @@ func TestContainerBulk_AddMultipleAlerts(t *testing.T) { func TestContainerBulk_ChainMerging(t *testing.T) { bulk := &containerBulk{ containerID: "container-123", - alerts: make([]apitypes.RuntimeAlert, 0), + alerts: make([]armotypes.RuntimeAlert, 0), cloudServices: make([]string, 0), maxSize: 50, timeoutDuration: 10 * time.Second, } // Create a chain: PID 1 (init) -> PID 10 (bash) -> PID 100 (curl) - chain1 := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + chain1 := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ PID: 1, PPID: 0, Comm: "init", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {PID: 10}: { PID: 10, PPID: 1, Comm: "bash", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {PID: 100}: { PID: 100, PPID: 10, Comm: "curl", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, }, }, }, @@ -134,22 +134,22 @@ func TestContainerBulk_ChainMerging(t *testing.T) { assert.Equal(t, uint32(1), bulk.rootProcess.PID, "Root should be PID 1") // Create a second chain with a branch: PID 1 -> PID 10 -> PID 101 (wget) - chain2 := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + chain2 := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ PID: 1, PPID: 0, Comm: "init", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {PID: 10}: { PID: 10, PPID: 1, Comm: "bash", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {PID: 101}: { PID: 101, PPID: 10, Comm: "wget", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, }, }, }, @@ -168,26 +168,26 @@ func TestContainerBulk_ChainMerging(t *testing.T) { bash := bulk.processMap[10] assert.NotNil(t, bash, "Bash process should exist") assert.Equal(t, 2, len(bash.ChildrenMap), "Bash should have 2 children") - assert.NotNil(t, bash.ChildrenMap[apitypes.CommPID{PID: 100}], "Should have curl child") - assert.NotNil(t, bash.ChildrenMap[apitypes.CommPID{PID: 101}], "Should have wget child") + assert.NotNil(t, bash.ChildrenMap[armotypes.CommPID{PID: 100}], "Should have curl child") + assert.NotNil(t, bash.ChildrenMap[armotypes.CommPID{PID: 101}], "Should have wget child") } func TestContainerBulk_ProcessEnrichment(t *testing.T) { bulk := &containerBulk{ containerID: "container-123", - alerts: make([]apitypes.RuntimeAlert, 0), + alerts: make([]armotypes.RuntimeAlert, 0), cloudServices: make([]string, 0), maxSize: 50, timeoutDuration: 10 * time.Second, } // First chain with minimal info - chain1 := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + chain1 := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ PID: 100, PPID: 1, Comm: "bash", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, }, } @@ -195,14 +195,14 @@ func TestContainerBulk_ProcessEnrichment(t *testing.T) { bulk.addAlert(alert1, chain1, nil) // Second chain with additional info for same process - chain2 := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + chain2 := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ PID: 100, PPID: 1, Comm: "bash", Path: "/bin/bash", Cmdline: "bash -c 'echo test'", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, }, } @@ -221,7 +221,7 @@ func TestContainerBulk_ProcessEnrichment(t *testing.T) { func TestContainerBulk_ShouldFlushSize(t *testing.T) { bulk := &containerBulk{ containerID: "container-123", - alerts: make([]apitypes.RuntimeAlert, 0, 5), + alerts: make([]armotypes.RuntimeAlert, 0, 5), cloudServices: make([]string, 0), maxSize: 5, timeoutDuration: 10 * time.Second, @@ -245,7 +245,7 @@ func TestContainerBulk_ShouldFlushSize(t *testing.T) { func TestContainerBulk_ShouldFlushTimeout(t *testing.T) { bulk := &containerBulk{ containerID: "container-123", - alerts: make([]apitypes.RuntimeAlert, 0), + alerts: make([]armotypes.RuntimeAlert, 0), cloudServices: make([]string, 0), maxSize: 50, timeoutDuration: 100 * time.Millisecond, @@ -264,7 +264,7 @@ func TestContainerBulk_ShouldFlushTimeout(t *testing.T) { func TestContainerBulk_Flush(t *testing.T) { bulk := &containerBulk{ containerID: "container-123", - alerts: make([]apitypes.RuntimeAlert, 0), + alerts: make([]armotypes.RuntimeAlert, 0), cloudServices: make([]string, 0), maxSize: 50, timeoutDuration: 10 * time.Second, @@ -294,7 +294,7 @@ func TestContainerBulk_Flush(t *testing.T) { func TestAlertBulkManager_AddAlert(t *testing.T) { sendCount := 0 var sendMutex sync.Mutex - sendFunc := func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { + sendFunc := func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { sendMutex.Lock() defer sendMutex.Unlock() sendCount++ @@ -316,8 +316,8 @@ func TestAlertBulkManager_AddAlert(t *testing.T) { func TestAlertBulkManager_FlushOnSizeLimit(t *testing.T) { sendCount := 0 var sendMutex sync.Mutex - var sentAlerts []apitypes.RuntimeAlert - sendFunc := func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { + var sentAlerts []armotypes.RuntimeAlert + sendFunc := func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { sendMutex.Lock() defer sendMutex.Unlock() sendCount++ @@ -353,7 +353,7 @@ func TestAlertBulkManager_FlushOnSizeLimit(t *testing.T) { func TestAlertBulkManager_FlushOnTimeout(t *testing.T) { sendCount := 0 var sendMutex sync.Mutex - sendFunc := func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { + sendFunc := func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { sendMutex.Lock() defer sendMutex.Unlock() sendCount++ @@ -386,7 +386,7 @@ func TestAlertBulkManager_MultipleContainers(t *testing.T) { var sendMutex sync.Mutex containerSends := make(map[string]int) - sendFunc := func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { + sendFunc := func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { sendMutex.Lock() defer sendMutex.Unlock() sendCount++ @@ -427,7 +427,7 @@ func TestAlertBulkManager_FlushContainer(t *testing.T) { var sendMutex sync.Mutex var flushedContainerID string - sendFunc := func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { + sendFunc := func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { sendMutex.Lock() defer sendMutex.Unlock() sendCount++ @@ -468,7 +468,7 @@ func TestAlertBulkManager_FlushAll(t *testing.T) { sendCount := 0 var sendMutex sync.Mutex - sendFunc := func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { + sendFunc := func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { sendMutex.Lock() defer sendMutex.Unlock() sendCount++ @@ -506,7 +506,7 @@ func TestAlertBulkManager_FlushAll(t *testing.T) { func TestAlertBulkManager_EmptyContainerID(t *testing.T) { sendCount := 0 - sendFunc := func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { + sendFunc := func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { sendCount++ return nil } @@ -532,7 +532,7 @@ func TestAlertBulkManager_RaceConditionProtection(t *testing.T) { var sendMutex sync.Mutex sentBulks := make(map[string]int) // containerID -> number of times flushed - sendFunc := func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { + sendFunc := func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { sendMutex.Lock() defer sendMutex.Unlock() sendCount++ @@ -598,7 +598,7 @@ func TestSendQueue_SuccessfulSendThroughQueue(t *testing.T) { var sendMutex sync.Mutex receivedContainers := make([]string, 0) - sendFunc := func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { + sendFunc := func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { sendMutex.Lock() defer sendMutex.Unlock() sendCount++ @@ -633,7 +633,7 @@ func TestSendQueue_RetryOnFailure(t *testing.T) { var sendMutex sync.Mutex failUntilAttempt := 2 // Fail first 2 attempts, succeed on 3rd - sendFunc := func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { + sendFunc := func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { sendMutex.Lock() defer sendMutex.Unlock() sendAttempts++ @@ -668,7 +668,7 @@ func TestSendQueue_MaxRetriesExceeded(t *testing.T) { sendAttempts := 0 var sendMutex sync.Mutex - sendFunc := func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { + sendFunc := func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { sendMutex.Lock() defer sendMutex.Unlock() sendAttempts++ @@ -700,7 +700,7 @@ func TestSendQueue_QueueFullHandling(t *testing.T) { var blockMutex sync.Mutex blockMutex.Lock() // Lock to block sending - sendFunc := func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { + sendFunc := func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { blockMutex.Lock() defer blockMutex.Unlock() return nil @@ -734,7 +734,7 @@ func TestSendQueue_GracefulShutdownWithDrain(t *testing.T) { var sendMutex sync.Mutex receivedContainers := make([]string, 0) - sendFunc := func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { + sendFunc := func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { time.Sleep(50 * time.Millisecond) // Simulate slow send sendMutex.Lock() defer sendMutex.Unlock() @@ -772,7 +772,7 @@ func TestSendQueue_ConcurrentEnqueueing(t *testing.T) { sendCount := 0 var sendMutex sync.Mutex - sendFunc := func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { + sendFunc := func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { sendMutex.Lock() defer sendMutex.Unlock() sendCount++ @@ -817,7 +817,7 @@ func TestSendQueue_ExponentialBackoff(t *testing.T) { attemptTimes := make([]time.Time, 0) var sendMutex sync.Mutex - sendFunc := func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { + sendFunc := func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { sendMutex.Lock() defer sendMutex.Unlock() sendAttempts++ @@ -869,7 +869,7 @@ func TestSendQueue_FIFOOrderingWithRetry(t *testing.T) { var sendMutex sync.Mutex failFirstBulk := true - sendFunc := func(containerID string, alerts []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { + sendFunc := func(containerID string, alerts []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { sendMutex.Lock() defer sendMutex.Unlock() @@ -918,18 +918,18 @@ func TestContainerBulk_MultipleIndependentRoots(t *testing.T) { bulk := &containerBulk{ maxSize: 10, timeoutDuration: 10 * time.Second, - alerts: make([]apitypes.RuntimeAlert, 0), - processMap: make(map[uint32]*apitypes.Process), + alerts: make([]armotypes.RuntimeAlert, 0), + processMap: make(map[uint32]*armotypes.Process), } // Add first alert with process chain starting from PID 1000 alert1 := createTestAlert("container-1", "alert-1") - processTree1 := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + processTree1 := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ PID: 1000, PPID: 0, Comm: "init-1", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {PID: 1001}: { PID: 1001, PPID: 1000, @@ -942,12 +942,12 @@ func TestContainerBulk_MultipleIndependentRoots(t *testing.T) { // Add second alert with INDEPENDENT process chain starting from PID 2000 alert2 := createTestAlert("container-1", "alert-2") - processTree2 := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + processTree2 := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ PID: 2000, PPID: 0, Comm: "init-2", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {PID: 2001}: { PID: 2001, PPID: 2000, @@ -960,12 +960,12 @@ func TestContainerBulk_MultipleIndependentRoots(t *testing.T) { // Add third alert with ANOTHER independent process chain starting from PID 3000 alert3 := createTestAlert("container-1", "alert-3") - processTree3 := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + processTree3 := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ PID: 3000, PPID: 0, Comm: "init-3", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {PID: 3001}: { PID: 3001, PPID: 3000, @@ -991,22 +991,22 @@ func TestContainerBulk_MultipleIndependentRoots(t *testing.T) { assert.Equal(t, 3, len(mergedTree.ProcessTree.ChildrenMap), "Synthetic root should have 3 children (the 3 independent roots)") // Verify each independent root is present - root1, has1 := mergedTree.ProcessTree.ChildrenMap[apitypes.CommPID{PID: 1000}] + root1, has1 := mergedTree.ProcessTree.ChildrenMap[armotypes.CommPID{PID: 1000}] assert.True(t, has1, "PID 1000 should be child of synthetic root") assert.Equal(t, "init-1", root1.Comm, "PID 1000 should have correct comm") - root2, has2 := mergedTree.ProcessTree.ChildrenMap[apitypes.CommPID{PID: 2000}] + root2, has2 := mergedTree.ProcessTree.ChildrenMap[armotypes.CommPID{PID: 2000}] assert.True(t, has2, "PID 2000 should be child of synthetic root") assert.Equal(t, "init-2", root2.Comm, "PID 2000 should have correct comm") - root3, has3 := mergedTree.ProcessTree.ChildrenMap[apitypes.CommPID{PID: 3000}] + root3, has3 := mergedTree.ProcessTree.ChildrenMap[armotypes.CommPID{PID: 3000}] assert.True(t, has3, "PID 3000 should be child of synthetic root") assert.Equal(t, "init-3", root3.Comm, "PID 3000 should have correct comm") // Verify children of each root are preserved assert.NotNil(t, root1.ChildrenMap, "PID 1000 should have children") assert.Equal(t, 1, len(root1.ChildrenMap), "PID 1000 should have 1 child") - child1, hasChild1 := root1.ChildrenMap[apitypes.CommPID{PID: 1001}] + child1, hasChild1 := root1.ChildrenMap[armotypes.CommPID{PID: 1001}] assert.True(t, hasChild1, "PID 1001 should be child of 1000") assert.Equal(t, "child-1", child1.Comm, "Child should have correct comm") diff --git a/pkg/exporters/alert_manager.go b/pkg/exporters/alert_manager.go index d275b29d1..d87c3be25 100644 --- a/pkg/exporters/alert_manager.go +++ b/pkg/exporters/alert_manager.go @@ -12,7 +12,7 @@ import ( "strconv" "time" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/cenkalti/backoff/v5" "github.com/go-openapi/strfmt" "github.com/kubescape/go-logger" @@ -65,8 +65,8 @@ func (ame *AlertManagerExporter) SendRuleAlert(failedRule types.RuleFailure) { trace = "" } - var processTree apitypes.Process - operation := func() (*apitypes.Process, error) { + var processTree armotypes.Process + operation := func() (*armotypes.Process, error) { processTree = failedRule.GetRuntimeProcessDetails().ProcessTree process := utils.GetProcessFromProcessTree(&processTree, failedRule.GetBaseRuntimeAlert().InfectedPID) if process == nil { @@ -195,7 +195,7 @@ func (ame *AlertManagerExporter) SendFimAlerts(fimEvents []hostfimsensor.FimEven // TODO: Implement FIM alerts sending logic } -func traceToString(t apitypes.Trace) (string, error) { +func traceToString(t armotypes.Trace) (string, error) { bytes, err := json.Marshal(t) if err != nil { return "", fmt.Errorf("error marshaling trace: %v", err) diff --git a/pkg/exporters/alert_manager_test.go b/pkg/exporters/alert_manager_test.go index 5a0748d1c..b1802cec3 100644 --- a/pkg/exporters/alert_manager_test.go +++ b/pkg/exporters/alert_manager_test.go @@ -9,7 +9,7 @@ import ( "strings" "testing" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" mmtypes "github.com/kubescape/node-agent/pkg/malwaremanager/v1/types" "github.com/kubescape/node-agent/pkg/rulemanager/types" "github.com/kubescape/node-agent/pkg/utils" @@ -37,16 +37,16 @@ func TestSendAlert(t *testing.T) { // Call SendAlert exporter.SendRuleAlert(&types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ AlertName: "testrule", }, - RuntimeAlertK8sDetails: apitypes.RuntimeAlertK8sDetails{ + RuntimeAlertK8sDetails: armotypes.RuntimeAlertK8sDetails{ ContainerID: "testcontainerid", ContainerName: "testcontainer", Namespace: "testnamespace", PodName: "testpodname", }, - RuleAlert: apitypes.RuleAlert{ + RuleAlert: armotypes.RuleAlert{ RuleDescription: "Application profile is missing", }, }) @@ -94,7 +94,7 @@ func TestSendMalwareAlert(t *testing.T) { } // Call SendAlert exporter.SendMalwareAlert(&mmtypes.GenericMalwareResult{ - BasicRuntimeAlert: apitypes.BaseRuntimeAlert{ + BasicRuntimeAlert: armotypes.BaseRuntimeAlert{ AlertName: "testmalware", Size: "2MiB", MD5Hash: "testmalwarehash", @@ -107,7 +107,7 @@ func TestSendMalwareAlert(t *testing.T) { Namespace: "testmalwarenamespace", Pod: "testmalwarepodname", }, - MalwareRuntimeAlert: apitypes.MalwareAlert{ + MalwareRuntimeAlert: armotypes.MalwareAlert{ MalwareDescription: "testmalwaredescription", }, }) diff --git a/pkg/exporters/csv_exporter_test.go b/pkg/exporters/csv_exporter_test.go index 8fd087253..79836b91f 100644 --- a/pkg/exporters/csv_exporter_test.go +++ b/pkg/exporters/csv_exporter_test.go @@ -10,7 +10,7 @@ import ( "github.com/kubescape/node-agent/pkg/rulemanager/types" "github.com/kubescape/node-agent/pkg/utils" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" ) func TestCsvExporter(t *testing.T) { @@ -24,21 +24,21 @@ func TestCsvExporter(t *testing.T) { } csvExporter.SendRuleAlert(&types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ AlertName: "testrule", }, - RuntimeAlertK8sDetails: apitypes.RuntimeAlertK8sDetails{ + RuntimeAlertK8sDetails: armotypes.RuntimeAlertK8sDetails{ ContainerID: "testcontainerid", ContainerName: "testcontainer", Namespace: "testnamespace", PodName: "testpodname", }, - RuleAlert: apitypes.RuleAlert{ + RuleAlert: armotypes.RuleAlert{ RuleDescription: "Application profile is missing", }, }) csvExporter.SendMalwareAlert(&mmtypes.GenericMalwareResult{ - BasicRuntimeAlert: apitypes.BaseRuntimeAlert{ + BasicRuntimeAlert: armotypes.BaseRuntimeAlert{ AlertName: "testmalware", Size: "2MiB", MD5Hash: "testmalwarehash", @@ -53,7 +53,7 @@ func TestCsvExporter(t *testing.T) { Namespace: "testmalwarenamespace", Pod: "testmalwarepodname", }, - MalwareRuntimeAlert: apitypes.MalwareAlert{ + MalwareRuntimeAlert: armotypes.MalwareAlert{ MalwareDescription: "testmalwaredescription", }, }) diff --git a/pkg/exporters/exporters_bus.go b/pkg/exporters/exporters_bus.go index b969dc3e3..f6f346bc5 100644 --- a/pkg/exporters/exporters_bus.go +++ b/pkg/exporters/exporters_bus.go @@ -29,7 +29,7 @@ type ExporterBus struct { } // InitExporters initializes all exporters. -func InitExporters(exportersConfig ExportersConfig, clusterName string, nodeName string, cloudMetadata *armotypes.CloudMetadata, clusterUID string) *ExporterBus { +func InitExporters(exportersConfig ExportersConfig, clusterName string, nodeName string, cloudMetadata *armotypes.CloudMetadata, clusterUID string, alertSourcePlatform armotypes.AlertSourcePlatform) *ExporterBus { var exporters []Exporter for _, url := range exportersConfig.AlertManagerExporterUrls { alertMan := InitAlertManagerExporter(url) @@ -56,7 +56,7 @@ func InitExporters(exportersConfig ExportersConfig, clusterName string, nodeName } } if exportersConfig.HTTPExporterConfig != nil { - httpExporter, err := NewHTTPExporter(*exportersConfig.HTTPExporterConfig, clusterName, nodeName, cloudMetadata, clusterUID) + httpExporter, err := NewHTTPExporter(*exportersConfig.HTTPExporterConfig, clusterName, nodeName, cloudMetadata, clusterUID, alertSourcePlatform) if err == nil { exporters = append(exporters, httpExporter) } else { diff --git a/pkg/exporters/http_exporter.go b/pkg/exporters/http_exporter.go index e83491a22..416bfd912 100644 --- a/pkg/exporters/http_exporter.go +++ b/pkg/exporters/http_exporter.go @@ -19,7 +19,7 @@ import ( "github.com/kubescape/go-logger" "github.com/kubescape/go-logger/helpers" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" ) const ( @@ -63,15 +63,16 @@ type HTTPExporterConfig struct { } type HTTPExporter struct { - config HTTPExporterConfig - host string - nodeName string - clusterName string - clusterUID string - httpClient *http.Client - alertMetrics *alertMetrics - cloudMetadata *apitypes.CloudMetadata - bulkManager *AlertBulkManager + config HTTPExporterConfig + host string + nodeName string + clusterName string + clusterUID string + httpClient *http.Client + alertMetrics *alertMetrics + cloudMetadata *armotypes.CloudMetadata + bulkManager *AlertBulkManager + alertSourcePlatform armotypes.AlertSourcePlatform } type alertMetrics struct { @@ -84,18 +85,18 @@ type alertMetrics struct { type HTTPAlertsList struct { Kind string `json:"kind"` APIVersion string `json:"apiVersion"` - Metadata apitypes.Metadata `json:"metadata"` + Metadata armotypes.Metadata `json:"metadata"` Spec HTTPAlertsListSpec `json:"spec"` } type HTTPAlertsListSpec struct { - Alerts []apitypes.RuntimeAlert `json:"alerts"` - ProcessTree apitypes.ProcessTree `json:"processTree"` - CloudMetadata apitypes.CloudMetadata `json:"cloudMetadata"` + Alerts []armotypes.RuntimeAlert `json:"alerts"` + ProcessTree armotypes.ProcessTree `json:"processTree"` + CloudMetadata armotypes.CloudMetadata `json:"cloudMetadata"` } // NewHTTPExporter creates a new HTTPExporter instance -func NewHTTPExporter(config HTTPExporterConfig, clusterName, nodeName string, cloudMetadata *apitypes.CloudMetadata, clusterUID string) (*HTTPExporter, error) { +func NewHTTPExporter(config HTTPExporterConfig, clusterName, nodeName string, cloudMetadata *armotypes.CloudMetadata, clusterUID string, alertSourcePlatform armotypes.AlertSourcePlatform) (*HTTPExporter, error) { if err := config.Validate(); err != nil { return nil, fmt.Errorf("invalid config: %w", err) } @@ -108,8 +109,9 @@ func NewHTTPExporter(config HTTPExporterConfig, clusterName, nodeName string, cl httpClient: &http.Client{ Timeout: time.Duration(config.TimeoutSeconds) * time.Second, }, - alertMetrics: &alertMetrics{}, - cloudMetadata: cloudMetadata, + alertMetrics: &alertMetrics{}, + cloudMetadata: cloudMetadata, + alertSourcePlatform: alertSourcePlatform, } // Initialize bulk manager if bulking is enabled @@ -313,7 +315,7 @@ func (e *HTTPExporter) createFimAlertPayload(fimEvents []hostfimsensor.FimEvent) return report } -func (e *HTTPExporter) createRuleAlert(failedRule types.RuleFailure) apitypes.RuntimeAlert { +func (e *HTTPExporter) createRuleAlert(failedRule types.RuleFailure) armotypes.RuntimeAlert { k8sDetails := failedRule.GetRuntimeAlertK8sDetails() k8sDetails.NodeName = e.nodeName k8sDetails.ClusterName = e.clusterName @@ -323,10 +325,11 @@ func (e *HTTPExporter) createRuleAlert(failedRule types.RuleFailure) apitypes.Ru httpDetails.SourcePodInfo.ClusterName = e.clusterName httpDetails.SourcePodInfo.ClusterUID = e.clusterUID - return apitypes.RuntimeAlert{ + return armotypes.RuntimeAlert{ Message: failedRule.GetRuleAlert().RuleDescription, HostName: e.host, AlertType: failedRule.GetAlertType(), + AlertSourcePlatform: e.alertSourcePlatform, BaseRuntimeAlert: failedRule.GetBaseRuntimeAlert(), RuntimeAlertK8sDetails: k8sDetails, RuleAlert: failedRule.GetRuleAlert(), @@ -336,16 +339,17 @@ func (e *HTTPExporter) createRuleAlert(failedRule types.RuleFailure) apitypes.Ru } } -func (e *HTTPExporter) createMalwareAlert(result malwaremanager.MalwareResult) apitypes.RuntimeAlert { +func (e *HTTPExporter) createMalwareAlert(result malwaremanager.MalwareResult) armotypes.RuntimeAlert { k8sDetails := result.GetRuntimeAlertK8sDetails() k8sDetails.NodeName = e.nodeName k8sDetails.ClusterName = e.clusterName k8sDetails.ClusterUID = e.clusterUID - return apitypes.RuntimeAlert{ + return armotypes.RuntimeAlert{ Message: fmt.Sprintf("Malware detected: %s", result.GetBasicRuntimeAlert().AlertName), HostName: e.host, - AlertType: apitypes.AlertTypeMalware, + AlertType: armotypes.AlertTypeMalware, + AlertSourcePlatform: e.alertSourcePlatform, BaseRuntimeAlert: result.GetBasicRuntimeAlert(), RuntimeAlertK8sDetails: k8sDetails, MalwareAlert: result.GetMalwareRuntimeAlert(), @@ -353,12 +357,12 @@ func (e *HTTPExporter) createMalwareAlert(result malwaremanager.MalwareResult) a } } -func (e *HTTPExporter) sendAlert(ctx context.Context, alert apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) error { - payload := e.createAlertPayload([]apitypes.RuntimeAlert{alert}, processTree, cloudServices) +func (e *HTTPExporter) sendAlert(ctx context.Context, alert armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) error { + payload := e.createAlertPayload([]armotypes.RuntimeAlert{alert}, processTree, cloudServices) return e.sendHTTPRequest(ctx, payload) } -func (e *HTTPExporter) createAlertPayload(alertList []apitypes.RuntimeAlert, processTree apitypes.ProcessTree, cloudServices []string) HTTPAlertsList { +func (e *HTTPExporter) createAlertPayload(alertList []armotypes.RuntimeAlert, processTree armotypes.ProcessTree, cloudServices []string) HTTPAlertsList { cloudMetadata := e.getCloudMetadata(cloudServices) var name string @@ -370,7 +374,7 @@ func (e *HTTPExporter) createAlertPayload(alertList []apitypes.RuntimeAlert, pro return HTTPAlertsList{ Kind: runtimeAlertsKind, APIVersion: apiVersion, - Metadata: apitypes.Metadata{ + Metadata: armotypes.Metadata{ Name: name, Namespace: namespace, }, @@ -382,9 +386,9 @@ func (e *HTTPExporter) createAlertPayload(alertList []apitypes.RuntimeAlert, pro } } -func (e *HTTPExporter) getCloudMetadata(cloudServices []string) apitypes.CloudMetadata { +func (e *HTTPExporter) getCloudMetadata(cloudServices []string) armotypes.CloudMetadata { if e.cloudMetadata == nil { - return apitypes.CloudMetadata{} + return armotypes.CloudMetadata{} } metadata := *e.cloudMetadata @@ -486,16 +490,17 @@ func (e *HTTPExporter) sendAlertLimitReached(ctx context.Context) error { e.alertMetrics.isNotified = true e.alertMetrics.Unlock() - alert := apitypes.RuntimeAlert{ - Message: "Alert limit reached", - HostName: e.host, - AlertType: apitypes.AlertTypeRule, - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + alert := armotypes.RuntimeAlert{ + Message: "Alert limit reached", + HostName: e.host, + AlertType: armotypes.AlertTypeRule, + AlertSourcePlatform: e.alertSourcePlatform, + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ AlertName: string(AlertTypeLimitReached), // Severity: ruleengine.RulePrioritySystemIssue, FixSuggestions: "Check logs for more information", }, - RuntimeAlertK8sDetails: apitypes.RuntimeAlertK8sDetails{ + RuntimeAlertK8sDetails: armotypes.RuntimeAlertK8sDetails{ NodeName: e.nodeName, ClusterName: e.clusterName, }, @@ -505,7 +510,7 @@ func (e *HTTPExporter) sendAlertLimitReached(ctx context.Context) error { helpers.Int("alerts", e.alertMetrics.count), helpers.String("since", e.alertMetrics.startTime.Format(time.RFC3339))) - return e.sendAlert(ctx, alert, apitypes.ProcessTree{}, nil) + return e.sendAlert(ctx, alert, armotypes.ProcessTree{}, nil) } // Close stops the bulk manager and flushes all pending bulks diff --git a/pkg/exporters/http_exporter_test.go b/pkg/exporters/http_exporter_test.go index 8b52a0bba..764cd1404 100644 --- a/pkg/exporters/http_exporter_test.go +++ b/pkg/exporters/http_exporter_test.go @@ -12,7 +12,7 @@ import ( "github.com/kubescape/node-agent/pkg/rulemanager/types" "github.com/kubescape/node-agent/pkg/utils" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/stretchr/testify/assert" ) @@ -32,22 +32,22 @@ func TestSendRuleAlert(t *testing.T) { // Create an HTTPExporter with the mock server URL exporter, err := NewHTTPExporter(HTTPExporterConfig{ URL: server.URL, - }, "", "", nil, "") + }, "", "", nil, "", armotypes.AlertSourcePlatformK8sAgent) assert.NoError(t, err) // Create a mock rule failure failedRule := &types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ AlertName: "testrule", }, - RuntimeAlertK8sDetails: apitypes.RuntimeAlertK8sDetails{ + RuntimeAlertK8sDetails: armotypes.RuntimeAlertK8sDetails{ ContainerID: "testcontainerid", ContainerName: "testcontainer", Namespace: "testnamespace", PodNamespace: "testnamespace", PodName: "testpodname", }, - RuleAlert: apitypes.RuleAlert{ + RuleAlert: armotypes.RuleAlert{ RuleDescription: "Application profile is missing", }, } @@ -93,21 +93,21 @@ func TestSendRuleAlertRateReached(t *testing.T) { exporter, err := NewHTTPExporter(HTTPExporterConfig{ URL: server.URL, MaxAlertsPerMinute: 1, - }, "", "", nil, "") + }, "", "", nil, "", armotypes.AlertSourcePlatformK8sAgent) assert.NoError(t, err) // Create a mock rule failure failedRule := &types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ AlertName: "testrule", }, - RuntimeAlertK8sDetails: apitypes.RuntimeAlertK8sDetails{ + RuntimeAlertK8sDetails: armotypes.RuntimeAlertK8sDetails{ ContainerID: "testcontainerid", ContainerName: "testcontainer", Namespace: "testnamespace", PodName: "testpodname", }, - RuleAlert: apitypes.RuleAlert{ + RuleAlert: armotypes.RuleAlert{ RuleDescription: "Application profile is missing", }, } @@ -159,12 +159,12 @@ func TestSendMalwareAlertHTTPExporter(t *testing.T) { // Create an HTTPExporter with the mock server URL exporter, err := NewHTTPExporter(HTTPExporterConfig{ URL: server.URL, - }, "", "", nil, "") + }, "", "", nil, "", armotypes.AlertSourcePlatformK8sAgent) assert.NoError(t, err) // Create a mock malware description malwareDesc := &mmtypes.GenericMalwareResult{ - BasicRuntimeAlert: apitypes.BaseRuntimeAlert{ + BasicRuntimeAlert: armotypes.BaseRuntimeAlert{ AlertName: "testmalware", Size: "2MiB", MD5Hash: "testmalwarehash", @@ -172,10 +172,10 @@ func TestSendMalwareAlertHTTPExporter(t *testing.T) { SHA256Hash: "testmalwarehash", }, TriggerEvent: &utils.StructEvent{}, - MalwareRuntimeAlert: apitypes.MalwareAlert{ + MalwareRuntimeAlert: armotypes.MalwareAlert{ MalwareDescription: "testmalwaredescription", }, - RuntimeAlertK8sDetails: apitypes.RuntimeAlertK8sDetails{ + RuntimeAlertK8sDetails: armotypes.RuntimeAlertK8sDetails{ ContainerID: "testmalwarecontainerid", Namespace: "testmalwarenamespace", PodName: "testmalwarepodname", @@ -213,13 +213,13 @@ func TestSendMalwareAlertHTTPExporter(t *testing.T) { func TestValidateHTTPExporterConfig(t *testing.T) { // Test case: URL is empty - _, err := NewHTTPExporter(HTTPExporterConfig{}, "", "", nil, "") + _, err := NewHTTPExporter(HTTPExporterConfig{}, "", "", nil, "", armotypes.AlertSourcePlatformK8sAgent) assert.Error(t, err) // Test case: URL is not empty exp, err := NewHTTPExporter(HTTPExporterConfig{ URL: "http://localhost:9093", - }, "cluster", "node", nil, "test-cluster-uid") + }, "cluster", "node", nil, "test-cluster-uid", armotypes.AlertSourcePlatformK8sAgent) assert.NoError(t, err) assert.Equal(t, "POST", exp.config.Method) assert.Equal(t, 5, exp.config.TimeoutSeconds) @@ -241,7 +241,7 @@ func TestValidateHTTPExporterConfig(t *testing.T) { Value: "Bearer token", }, }, - }, "", "", nil, "") + }, "", "", nil, "", armotypes.AlertSourcePlatformK8sAgent) assert.NoError(t, err) assert.Equal(t, "PUT", exp.config.Method) assert.Equal(t, 2, exp.config.TimeoutSeconds) @@ -252,6 +252,6 @@ func TestValidateHTTPExporterConfig(t *testing.T) { _, err = NewHTTPExporter(HTTPExporterConfig{ URL: "http://localhost:9093", Method: "DELETE", - }, "", "", nil, "") + }, "", "", nil, "", armotypes.AlertSourcePlatformK8sAgent) assert.Error(t, err) } diff --git a/pkg/exporters/stdout_exporter.go b/pkg/exporters/stdout_exporter.go index f7ad65d4f..78f32ce27 100644 --- a/pkg/exporters/stdout_exporter.go +++ b/pkg/exporters/stdout_exporter.go @@ -4,7 +4,7 @@ import ( "fmt" "os" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/kubescape/node-agent/pkg/hostfimsensor" "github.com/kubescape/node-agent/pkg/malwaremanager" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -15,10 +15,10 @@ import ( type StdoutExporter struct { logger *log.Logger - cloudmetadata *apitypes.CloudMetadata + cloudmetadata *armotypes.CloudMetadata } -func InitStdoutExporter(useStdout *bool, cloudmetadata *apitypes.CloudMetadata) *StdoutExporter { +func InitStdoutExporter(useStdout *bool, cloudmetadata *armotypes.CloudMetadata) *StdoutExporter { if useStdout == nil { useStdout = new(bool) *useStdout = os.Getenv("STDOUT_ENABLED") != "false" diff --git a/pkg/exporters/stdout_exporter_test.go b/pkg/exporters/stdout_exporter_test.go index f37dfceeb..150f0799a 100644 --- a/pkg/exporters/stdout_exporter_test.go +++ b/pkg/exporters/stdout_exporter_test.go @@ -6,7 +6,7 @@ import ( "github.com/kubescape/node-agent/pkg/rulemanager/types" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/stretchr/testify/assert" ) @@ -52,16 +52,16 @@ func TestStdoutExporter_SendAlert(t *testing.T) { assert.NotNil(t, exporter) exporter.SendRuleAlert(&types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ AlertName: "testrule", }, - RuntimeAlertK8sDetails: apitypes.RuntimeAlertK8sDetails{ + RuntimeAlertK8sDetails: armotypes.RuntimeAlertK8sDetails{ ContainerID: "testcontainerid", ContainerName: "testcontainer", Namespace: "testnamespace", PodName: "testpodname", }, - RuleAlert: apitypes.RuleAlert{ + RuleAlert: armotypes.RuleAlert{ RuleDescription: "Application profile is missing", }, }) @@ -70,15 +70,15 @@ func TestStdoutExporter_SendAlert(t *testing.T) { type MockFileHashResult struct { } -func (m *MockFileHashResult) GetBasicRuntimeAlert() apitypes.BaseRuntimeAlert { - return apitypes.BaseRuntimeAlert{ +func (m *MockFileHashResult) GetBasicRuntimeAlert() armotypes.BaseRuntimeAlert { + return armotypes.BaseRuntimeAlert{ AlertName: "testrule", } } -func (m *MockFileHashResult) GetRuntimeProcessDetails() apitypes.ProcessTree { - return apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ +func (m *MockFileHashResult) GetRuntimeProcessDetails() armotypes.ProcessTree { + return armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ PID: 1, }, ContainerID: "testcontainerid", @@ -86,14 +86,14 @@ func (m *MockFileHashResult) GetRuntimeProcessDetails() apitypes.ProcessTree { } } -func (m *MockFileHashResult) GetMalwareRuntimeAlert() apitypes.MalwareAlert { - return apitypes.MalwareAlert{ +func (m *MockFileHashResult) GetMalwareRuntimeAlert() armotypes.MalwareAlert { + return armotypes.MalwareAlert{ MalwareDescription: "testmalware", } } -func (m *MockFileHashResult) GetRuntimeAlertK8sDetails() apitypes.RuntimeAlertK8sDetails { - return apitypes.RuntimeAlertK8sDetails{ +func (m *MockFileHashResult) GetRuntimeAlertK8sDetails() armotypes.RuntimeAlertK8sDetails { + return armotypes.RuntimeAlertK8sDetails{ ContainerID: "testcontainerid", ContainerName: "testcontainer", Namespace: "testnamespace", diff --git a/pkg/exporters/syslog_exporter_test.go b/pkg/exporters/syslog_exporter_test.go index aa4d46d06..668d0c8aa 100644 --- a/pkg/exporters/syslog_exporter_test.go +++ b/pkg/exporters/syslog_exporter_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" mmtypes "github.com/kubescape/node-agent/pkg/malwaremanager/v1/types" "github.com/kubescape/node-agent/pkg/rulemanager/types" "github.com/kubescape/node-agent/pkg/utils" @@ -64,37 +64,37 @@ func TestSyslogExporter(t *testing.T) { // Send an alert syslogExp.SendRuleAlert(&types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ AlertName: "testrule", }, - RuntimeAlertK8sDetails: apitypes.RuntimeAlertK8sDetails{ + RuntimeAlertK8sDetails: armotypes.RuntimeAlertK8sDetails{ ContainerID: "testcontainerid", ContainerName: "testcontainer", Namespace: "testnamespace", PodName: "testpodname", }, - RuleAlert: apitypes.RuleAlert{ + RuleAlert: armotypes.RuleAlert{ RuleDescription: "Application profile is missing", }, }) syslogExp.SendRuleAlert(&types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ AlertName: "testrule", }, - RuntimeAlertK8sDetails: apitypes.RuntimeAlertK8sDetails{ + RuntimeAlertK8sDetails: armotypes.RuntimeAlertK8sDetails{ ContainerID: "testcontainerid", ContainerName: "testcontainer", Namespace: "testnamespace", PodName: "testpodname", }, - RuleAlert: apitypes.RuleAlert{ + RuleAlert: armotypes.RuleAlert{ RuleDescription: "Application profile is missing", }, }) syslogExp.SendMalwareAlert(&mmtypes.GenericMalwareResult{ - BasicRuntimeAlert: apitypes.BaseRuntimeAlert{ + BasicRuntimeAlert: armotypes.BaseRuntimeAlert{ AlertName: "testmalware", Size: "2MiB", MD5Hash: "testmalwarehash", @@ -102,7 +102,7 @@ func TestSyslogExporter(t *testing.T) { SHA256Hash: "testmalwarehash", }, TriggerEvent: &utils.StructEvent{}, - MalwareRuntimeAlert: apitypes.MalwareAlert{ + MalwareRuntimeAlert: armotypes.MalwareAlert{ MalwareDescription: "testmalwaredescription", }, }) diff --git a/pkg/fimmanager/fim_manager.go b/pkg/fimmanager/fim_manager.go index 5dc63aaa1..af9424523 100644 --- a/pkg/fimmanager/fim_manager.go +++ b/pkg/fimmanager/fim_manager.go @@ -5,12 +5,12 @@ import ( "fmt" "os" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/kubescape/go-logger" "github.com/kubescape/go-logger/helpers" "github.com/kubescape/node-agent/pkg/config" "github.com/kubescape/node-agent/pkg/exporters" - hostfimsensor "github.com/kubescape/node-agent/pkg/hostfimsensor/v1" + "github.com/kubescape/node-agent/pkg/hostfimsensor/v1" ) // FIMManager manages the File Integrity Monitoring functionality @@ -20,12 +20,12 @@ type FIMManager struct { exporter exporters.Exporter clusterName string nodeName string - cloudMetadata *apitypes.CloudMetadata + cloudMetadata *armotypes.CloudMetadata running bool } // NewFIMManager creates a new FIM manager -func NewFIMManager(cfg config.Config, clusterName string, exporter exporters.Exporter, cloudMetadata *apitypes.CloudMetadata) (*FIMManager, error) { +func NewFIMManager(cfg config.Config, clusterName string, exporter exporters.Exporter, cloudMetadata *armotypes.CloudMetadata) (*FIMManager, error) { if !cfg.EnableFIM { logger.L().Info("FIM is disabled in configuration") return &FIMManager{ diff --git a/pkg/malwaremanager/malware_manager_interface.go b/pkg/malwaremanager/malware_manager_interface.go index 1a2e3ada0..fcee6a7bd 100644 --- a/pkg/malwaremanager/malware_manager_interface.go +++ b/pkg/malwaremanager/malware_manager_interface.go @@ -3,7 +3,7 @@ package malwaremanager import ( "github.com/kubescape/node-agent/pkg/utils" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" ) @@ -14,28 +14,28 @@ type MalwareManagerClient interface { type MalwareResult interface { // Get Basic Runtime Alert - GetBasicRuntimeAlert() apitypes.BaseRuntimeAlert + GetBasicRuntimeAlert() armotypes.BaseRuntimeAlert // Get Runtime Process Details - GetRuntimeProcessDetails() apitypes.ProcessTree + GetRuntimeProcessDetails() armotypes.ProcessTree // Get Trigger Event GetTriggerEvent() utils.EnrichEvent // Get Malware Description - GetMalwareRuntimeAlert() apitypes.MalwareAlert + GetMalwareRuntimeAlert() armotypes.MalwareAlert // Get K8s Runtime Details - GetRuntimeAlertK8sDetails() apitypes.RuntimeAlertK8sDetails + GetRuntimeAlertK8sDetails() armotypes.RuntimeAlertK8sDetails // Set Workload Details SetWorkloadDetails(workloadDetails string) // Set Basic Runtime Alert - SetBasicRuntimeAlert(basicRuntimeAlert apitypes.BaseRuntimeAlert) + SetBasicRuntimeAlert(basicRuntimeAlert armotypes.BaseRuntimeAlert) // Set Runtime Process Details - SetRuntimeProcessDetails(processTree apitypes.ProcessTree) + SetRuntimeProcessDetails(processTree armotypes.ProcessTree) // Set Trigger Event SetTriggerEvent(event utils.EnrichEvent) // Set Malware Description - SetMalwareRuntimeAlert(malwareRuntimeAlert apitypes.MalwareAlert) + SetMalwareRuntimeAlert(malwareRuntimeAlert armotypes.MalwareAlert) // Set K8s Runtime Details - SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails apitypes.RuntimeAlertK8sDetails) + SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails armotypes.RuntimeAlertK8sDetails) } type MalwareScanner interface { diff --git a/pkg/malwaremanager/v1/malware_manager.go b/pkg/malwaremanager/v1/malware_manager.go index 6f8b78345..c5462d935 100644 --- a/pkg/malwaremanager/v1/malware_manager.go +++ b/pkg/malwaremanager/v1/malware_manager.go @@ -73,6 +73,9 @@ func CreateMalwareManager(cfg config.Config, k8sClient k8sclient.K8sClientInterf } func (mm *MalwareManager) ContainerCallback(notif containercollection.PubSubEvent) { + if utils.IsHostContainer(notif.Container) { + return + } // check if the container should be ignored if mm.cfg.IgnoreContainer(notif.Container.K8s.Namespace, notif.Container.K8s.PodName, notif.Container.K8s.PodLabels) { return diff --git a/pkg/malwaremanager/v1/types/malwareresult.go b/pkg/malwaremanager/v1/types/malwareresult.go index ea1aa506c..f9d0d94e1 100644 --- a/pkg/malwaremanager/v1/types/malwareresult.go +++ b/pkg/malwaremanager/v1/types/malwareresult.go @@ -4,27 +4,27 @@ import ( "github.com/kubescape/node-agent/pkg/malwaremanager" "github.com/kubescape/node-agent/pkg/utils" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/utils-k8s-go/wlid" ) var _ malwaremanager.MalwareResult = (*GenericMalwareResult)(nil) type GenericMalwareResult struct { - BasicRuntimeAlert apitypes.BaseRuntimeAlert - RuntimeProcessDetails apitypes.ProcessTree + BasicRuntimeAlert armotypes.BaseRuntimeAlert + RuntimeProcessDetails armotypes.ProcessTree TriggerEvent utils.EnrichEvent - MalwareRuntimeAlert apitypes.MalwareAlert - RuntimeAlertK8sDetails apitypes.RuntimeAlertK8sDetails + MalwareRuntimeAlert armotypes.MalwareAlert + RuntimeAlertK8sDetails armotypes.RuntimeAlertK8sDetails } // Get Basic Runtime Alert -func (gmr *GenericMalwareResult) GetBasicRuntimeAlert() apitypes.BaseRuntimeAlert { +func (gmr *GenericMalwareResult) GetBasicRuntimeAlert() armotypes.BaseRuntimeAlert { return gmr.BasicRuntimeAlert } // Get Runtime Process Details -func (gmr *GenericMalwareResult) GetRuntimeProcessDetails() apitypes.ProcessTree { +func (gmr *GenericMalwareResult) GetRuntimeProcessDetails() armotypes.ProcessTree { return gmr.RuntimeProcessDetails } @@ -34,12 +34,12 @@ func (gmr *GenericMalwareResult) GetTriggerEvent() utils.EnrichEvent { } // Get Malware Description -func (gmr *GenericMalwareResult) GetMalwareRuntimeAlert() apitypes.MalwareAlert { +func (gmr *GenericMalwareResult) GetMalwareRuntimeAlert() armotypes.MalwareAlert { return gmr.MalwareRuntimeAlert } // Get K8s Runtime Details -func (gmr *GenericMalwareResult) GetRuntimeAlertK8sDetails() apitypes.RuntimeAlertK8sDetails { +func (gmr *GenericMalwareResult) GetRuntimeAlertK8sDetails() armotypes.RuntimeAlertK8sDetails { return gmr.RuntimeAlertK8sDetails } @@ -56,12 +56,12 @@ func (gmr *GenericMalwareResult) SetWorkloadDetails(workloadDetails string) { } // Set Basic Runtime Alert -func (gmr *GenericMalwareResult) SetBasicRuntimeAlert(bra apitypes.BaseRuntimeAlert) { +func (gmr *GenericMalwareResult) SetBasicRuntimeAlert(bra armotypes.BaseRuntimeAlert) { gmr.BasicRuntimeAlert = bra } // Set Runtime Process Details -func (gmr *GenericMalwareResult) SetRuntimeProcessDetails(rpd apitypes.ProcessTree) { +func (gmr *GenericMalwareResult) SetRuntimeProcessDetails(rpd armotypes.ProcessTree) { gmr.RuntimeProcessDetails = rpd } @@ -71,11 +71,11 @@ func (gmr *GenericMalwareResult) SetTriggerEvent(te utils.EnrichEvent) { } // Set Malware Description -func (gmr *GenericMalwareResult) SetMalwareRuntimeAlert(mra apitypes.MalwareAlert) { +func (gmr *GenericMalwareResult) SetMalwareRuntimeAlert(mra armotypes.MalwareAlert) { gmr.MalwareRuntimeAlert = mra } // Set K8s Runtime Details -func (gmr *GenericMalwareResult) SetRuntimeAlertK8sDetails(rakd apitypes.RuntimeAlertK8sDetails) { +func (gmr *GenericMalwareResult) SetRuntimeAlertK8sDetails(rakd armotypes.RuntimeAlertK8sDetails) { gmr.RuntimeAlertK8sDetails = rakd } diff --git a/pkg/networkstream/v1/network_stream.go b/pkg/networkstream/v1/network_stream.go index d7e267d25..c71037c13 100644 --- a/pkg/networkstream/v1/network_stream.go +++ b/pkg/networkstream/v1/network_stream.go @@ -12,7 +12,7 @@ import ( "sync" "time" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/utils-k8s-go/wlid" "github.com/cenkalti/backoff/v5" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" @@ -32,7 +32,7 @@ const ( ) type NetworkStream struct { - networkEventsStorage apitypes.NetworkStream + networkEventsStorage armotypes.NetworkStream eventsStorageMutex sync.RWMutex // Mutex to protect access to networkEventsStorage.Containers cfg config.Config ctx context.Context @@ -41,12 +41,12 @@ type NetworkStream struct { k8sInventory common.K8sInventoryCache nodeName string httpClient *http.Client - eventsNotificationChannel chan apitypes.NetworkStream + eventsNotificationChannel chan armotypes.NetworkStream dnsSupport bool processTreeManager processtree.ProcessTreeManager } -func NewNetworkStream(ctx context.Context, cfg config.Config, k8sObjectCache objectcache.K8sObjectCache, dnsResolver dnsmanager.DNSResolver, nodeName string, eventsNotificationChannel chan apitypes.NetworkStream, dnsSupport bool, processTreeManager processtree.ProcessTreeManager) (*NetworkStream, error) { +func NewNetworkStream(ctx context.Context, cfg config.Config, k8sObjectCache objectcache.K8sObjectCache, dnsResolver dnsmanager.DNSResolver, nodeName string, eventsNotificationChannel chan armotypes.NetworkStream, dnsSupport bool, processTreeManager processtree.ProcessTreeManager) (*NetworkStream, error) { var k8sInventory common.K8sInventoryCache if cfg.KubernetesMode { @@ -66,8 +66,8 @@ func NewNetworkStream(ctx context.Context, cfg config.Config, k8sObjectCache obj } ns := NetworkStream{ - networkEventsStorage: apitypes.NetworkStream{ - Entities: make(map[string]apitypes.NetworkStreamEntity), + networkEventsStorage: armotypes.NetworkStream{ + Entities: make(map[string]armotypes.NetworkStreamEntity), }, cfg: cfg, ctx: ctx, @@ -84,10 +84,10 @@ func NewNetworkStream(ctx context.Context, cfg config.Config, k8sObjectCache obj } // Create the host entity - ns.networkEventsStorage.Entities[nodeName] = apitypes.NetworkStreamEntity{ - Kind: apitypes.NetworkStreamEntityKindHost, - Inbound: make(map[string]apitypes.NetworkStreamEvent), - Outbound: make(map[string]apitypes.NetworkStreamEvent), + ns.networkEventsStorage.Entities[nodeName] = armotypes.NetworkStreamEntity{ + Kind: armotypes.NetworkStreamEntityKindHost, + Inbound: make(map[string]armotypes.NetworkStreamEvent), + Outbound: make(map[string]armotypes.NetworkStreamEvent), } return &ns, nil @@ -97,24 +97,33 @@ func (ns *NetworkStream) ContainerCallback(notif containercollection.PubSubEvent switch notif.Type { case containercollection.EventTypeAddContainer: ns.eventsStorageMutex.Lock() - ns.networkEventsStorage.Entities[notif.Container.Runtime.ContainerID] = apitypes.NetworkStreamEntity{ - Kind: apitypes.NetworkStreamEntityKindContainer, - NetworkStreamEntityContainer: apitypes.NetworkStreamEntityContainer{ + // Normalize host container ID to nodeName for consistent entity mapping + containerID := notif.Container.Runtime.ContainerID + if utils.IsHostContainer(notif.Container) { + containerID = ns.nodeName + } + ns.networkEventsStorage.Entities[containerID] = armotypes.NetworkStreamEntity{ + Kind: armotypes.NetworkStreamEntityKindContainer, + NetworkStreamEntityContainer: armotypes.NetworkStreamEntityContainer{ ContainerName: notif.Container.Runtime.ContainerName, ContainerID: notif.Container.Runtime.ContainerID, PodNamespace: notif.Container.K8s.Namespace, PodName: notif.Container.K8s.PodName, }, - Inbound: make(map[string]apitypes.NetworkStreamEvent), - Outbound: make(map[string]apitypes.NetworkStreamEvent), + Inbound: make(map[string]armotypes.NetworkStreamEvent), + Outbound: make(map[string]armotypes.NetworkStreamEvent), } ns.eventsStorageMutex.Unlock() - if ns.k8sObjectCache != nil { + if ns.k8sObjectCache != nil && !utils.IsHostContainer(notif.Container) { go ns.enrichWorkloadDetails(notif.Container.Runtime.ContainerID) } case containercollection.EventTypeRemoveContainer: ns.eventsStorageMutex.Lock() - delete(ns.networkEventsStorage.Entities, notif.Container.Runtime.ContainerID) + containerID := notif.Container.Runtime.ContainerID + if utils.IsHostContainer(notif.Container) { + containerID = ns.nodeName + } + delete(ns.networkEventsStorage.Entities, containerID) ns.eventsStorageMutex.Unlock() } } @@ -185,15 +194,15 @@ func (ns *NetworkStream) Start() { // Clear the storage for entityId := range ns.networkEventsStorage.Entities { entity := ns.networkEventsStorage.Entities[entityId] - entity.Inbound = make(map[string]apitypes.NetworkStreamEvent) - entity.Outbound = make(map[string]apitypes.NetworkStreamEvent) + entity.Inbound = make(map[string]armotypes.NetworkStreamEvent) + entity.Outbound = make(map[string]armotypes.NetworkStreamEvent) ns.networkEventsStorage.Entities[entityId] = entity } // Re-create the host entity - ns.networkEventsStorage.Entities[ns.nodeName] = apitypes.NetworkStreamEntity{ - Kind: apitypes.NetworkStreamEntityKindHost, - Inbound: make(map[string]apitypes.NetworkStreamEvent), - Outbound: make(map[string]apitypes.NetworkStreamEvent), + ns.networkEventsStorage.Entities[ns.nodeName] = armotypes.NetworkStreamEntity{ + Kind: armotypes.NetworkStreamEntityKindHost, + Inbound: make(map[string]armotypes.NetworkStreamEvent), + Outbound: make(map[string]armotypes.NetworkStreamEvent), } ns.eventsStorageMutex.Unlock() logger.L().Debug("NetworkStream - sent network events") @@ -216,7 +225,7 @@ func (ns *NetworkStream) ReportEnrichedEvent(enrichedEvent *events.EnrichedEvent return // Ignore localhost events } - ns.handleNetworkEvent(networkEvent, &apitypes.ProcessTree{ProcessTree: enrichedEvent.ProcessTree, ContainerID: enrichedEvent.ContainerID}) + ns.handleNetworkEvent(networkEvent, &armotypes.ProcessTree{ProcessTree: enrichedEvent.ProcessTree, ContainerID: enrichedEvent.ContainerID}) case utils.DnsEventType: if !ns.dnsSupport { return @@ -230,7 +239,7 @@ func (ns *NetworkStream) ReportEnrichedEvent(enrichedEvent *events.EnrichedEvent return } - ns.handleDnsEvent(dnsEvent, &apitypes.ProcessTree{ProcessTree: enrichedEvent.ProcessTree, ContainerID: enrichedEvent.ContainerID}) + ns.handleDnsEvent(dnsEvent, &armotypes.ProcessTree{ProcessTree: enrichedEvent.ProcessTree, ContainerID: enrichedEvent.ContainerID}) default: logger.L().Error("NetworkStream - unknown event type", helpers.String("event type", string(eventType))) @@ -271,11 +280,15 @@ func (ns *NetworkStream) ReportEvent(eventType utils.EventType, event utils.K8sE } } -func (ns *NetworkStream) handleDnsEvent(event utils.DNSEvent, processTree *apitypes.ProcessTree) { +func (ns *NetworkStream) handleDnsEvent(event utils.DNSEvent, processTree *armotypes.ProcessTree) { ns.eventsStorageMutex.Lock() defer ns.eventsStorageMutex.Unlock() entityId := event.GetContainerID() + // Normalize host container ID to nodeName + if entityId == armotypes.HostContainerID { + entityId = ns.nodeName + } if entityId == "" || ns.k8sObjectCache == nil { entityId = ns.nodeName } @@ -292,12 +305,12 @@ func (ns *NetworkStream) handleDnsEvent(event utils.DNSEvent, processTree *apity return } - networkEvent := apitypes.NetworkStreamEvent{ + networkEvent := armotypes.NetworkStreamEvent{ Timestamp: time.Unix(0, int64(event.GetTimestamp())), DNSName: event.GetDNSName(), Port: int32(event.GetDstPort()), - Protocol: apitypes.NetworkStreamEventProtocolDNS, - Kind: apitypes.EndpointKindRaw, + Protocol: armotypes.NetworkStreamEventProtocolDNS, + Kind: armotypes.EndpointKindRaw, } processTree = ns.getProcessTreeByPid(event.GetPID(), event.GetComm(), processTree) @@ -325,13 +338,17 @@ func (ns *NetworkStream) shouldReportDnsEvent(dnsEvent utils.DNSEvent) bool { return true } -func (ns *NetworkStream) handleNetworkEvent(event utils.NetworkEvent, processTree *apitypes.ProcessTree) { +func (ns *NetworkStream) handleNetworkEvent(event utils.NetworkEvent, processTree *armotypes.ProcessTree) { endpointID := getNetworkEndpointIdentifier(event) ns.eventsStorageMutex.Lock() defer ns.eventsStorageMutex.Unlock() entityId := event.GetContainerID() + // Normalize host container ID to nodeName + if entityId == armotypes.HostContainerID { + entityId = ns.nodeName + } if entityId == "" || ns.k8sObjectCache == nil { entityId = ns.nodeName } @@ -360,7 +377,7 @@ func (ns *NetworkStream) handleNetworkEvent(event utils.NetworkEvent, processTre ns.networkEventsStorage.Entities[entityId] = entity } -func (ns *NetworkStream) buildNetworkEvent(event utils.NetworkEvent, processTree *apitypes.ProcessTree) apitypes.NetworkStreamEvent { +func (ns *NetworkStream) buildNetworkEvent(event utils.NetworkEvent, processTree *armotypes.ProcessTree) armotypes.NetworkStreamEvent { var domain string var ok bool dstEndpoint := event.GetDstEndpoint() @@ -381,15 +398,15 @@ func (ns *NetworkStream) buildNetworkEvent(event utils.NetworkEvent, processTree domain, _ = ns.dnsResolver.ResolveIPAddress(dstEndpoint.Addr) } - networkEvent := apitypes.NetworkStreamEvent{ + networkEvent := armotypes.NetworkStreamEvent{ Timestamp: time.Unix(0, int64(event.GetTimestamp())), IPAddress: dstEndpoint.Addr, DNSName: domain, Port: int32(event.GetDstPort()), - Protocol: apitypes.NetworkStreamEventProtocol(event.GetProto()), + Protocol: armotypes.NetworkStreamEventProtocol(event.GetProto()), } - if apitypes.EndpointKind(dstEndpoint.Kind) == apitypes.EndpointKindPod { + if armotypes.EndpointKind(dstEndpoint.Kind) == armotypes.EndpointKindPod { slimPod := ns.k8sInventory.GetPodByIp(dstEndpoint.Addr) if slimPod != nil { networkEvent.PodName = slimPod.Name @@ -411,7 +428,7 @@ func (ns *NetworkStream) buildNetworkEvent(event utils.NetworkEvent, processTree networkEvent.WorkloadKind = workloadKind networkEvent.WorkloadNamespace = slimPod.Namespace } - } else if apitypes.EndpointKind(dstEndpoint.Kind) == apitypes.EndpointKindService { + } else if armotypes.EndpointKind(dstEndpoint.Kind) == armotypes.EndpointKindService { slimService := ns.k8sInventory.GetSvcByIp(dstEndpoint.Addr) if slimService != nil { networkEvent.ServiceName = slimService.Name @@ -419,7 +436,7 @@ func (ns *NetworkStream) buildNetworkEvent(event utils.NetworkEvent, processTree } } - networkEvent.Kind = apitypes.EndpointKind(dstEndpoint.Kind) + networkEvent.Kind = armotypes.EndpointKind(dstEndpoint.Kind) processTree = ns.getProcessTreeByPid(event.GetPID(), event.GetComm(), processTree) networkEvent.ProcessTree = processTree @@ -427,7 +444,7 @@ func (ns *NetworkStream) buildNetworkEvent(event utils.NetworkEvent, processTree return networkEvent } -func (ns *NetworkStream) sendNetworkEvent(networkStream *apitypes.NetworkStream) error { +func (ns *NetworkStream) sendNetworkEvent(networkStream *armotypes.NetworkStream) error { if !ns.cfg.KubernetesMode || ns.cfg.Exporters.HTTPExporterConfig == nil { return nil } @@ -437,10 +454,10 @@ func (ns *NetworkStream) sendNetworkEvent(networkStream *apitypes.NetworkStream) } // create a GenericCRD with NetworkStream as Spec - crd := apitypes.GenericCRD[apitypes.NetworkStream]{ + crd := armotypes.GenericCRD[armotypes.NetworkStream]{ Kind: "NetworkStreams", ApiVersion: "kubescape.io/v1", - Metadata: apitypes.Metadata{ + Metadata: armotypes.Metadata{ Name: ns.nodeName, }, Spec: *networkStream, @@ -482,7 +499,7 @@ func getNetworkEndpointIdentifier(event utils.NetworkEvent) string { return fmt.Sprintf("%s/%d/%s", event.GetDstEndpoint().Addr, event.GetDstPort(), event.GetProto()) } -func isEmptyNetworkStream(networkStream *apitypes.NetworkStream) bool { +func isEmptyNetworkStream(networkStream *armotypes.NetworkStream) bool { if len(networkStream.Entities) == 0 { return true } @@ -494,7 +511,7 @@ func isEmptyNetworkStream(networkStream *apitypes.NetworkStream) bool { return true } -func removeProcessTreeFromEvents(networkStream *apitypes.NetworkStream) { +func removeProcessTreeFromEvents(networkStream *armotypes.NetworkStream) { for entityId, entity := range networkStream.Entities { for eventId, event := range entity.Inbound { event.ProcessTree = nil @@ -508,15 +525,15 @@ func removeProcessTreeFromEvents(networkStream *apitypes.NetworkStream) { } } -func (ns *NetworkStream) getProcessTreeByPid(pid uint32, comm string, processTree *apitypes.ProcessTree) *apitypes.ProcessTree { +func (ns *NetworkStream) getProcessTreeByPid(pid uint32, comm string, processTree *armotypes.ProcessTree) *armotypes.ProcessTree { if processTree != nil { return processTree } logger.L().Debug("NetworkStream - getting process tree by pid", helpers.Int("pid", int(pid)), helpers.String("comm", comm)) - return &apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + return &armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ PID: pid, Comm: comm, }, diff --git a/pkg/networkstream/v1/network_stream_test.go b/pkg/networkstream/v1/network_stream_test.go index d8dd4454d..9f5b6eae4 100644 --- a/pkg/networkstream/v1/network_stream_test.go +++ b/pkg/networkstream/v1/network_stream_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/kubescape/node-agent/pkg/config" "github.com/kubescape/node-agent/pkg/exporters" ) @@ -63,7 +63,7 @@ func TestNewNetworkStream(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctx := context.Background() nodeName := "test-node" - eventsChannel := make(chan apitypes.NetworkStream, 1) + eventsChannel := make(chan armotypes.NetworkStream, 1) ns, err := NewNetworkStream( ctx, @@ -100,8 +100,8 @@ func TestNewNetworkStream(t *testing.T) { t.Errorf("Host entity for node %s should exist", nodeName) } - if hostEntity.Kind != apitypes.NetworkStreamEntityKindHost { - t.Errorf("Expected host entity kind %v, got %v", apitypes.NetworkStreamEntityKindHost, hostEntity.Kind) + if hostEntity.Kind != armotypes.NetworkStreamEntityKindHost { + t.Errorf("Expected host entity kind %v, got %v", armotypes.NetworkStreamEntityKindHost, hostEntity.Kind) } if hostEntity.Inbound == nil || hostEntity.Outbound == nil { diff --git a/pkg/objectcache/applicationprofilecache/applicationprofilecache.go b/pkg/objectcache/applicationprofilecache/applicationprofilecache.go index 65fe19895..c159ee867 100644 --- a/pkg/objectcache/applicationprofilecache/applicationprofilecache.go +++ b/pkg/objectcache/applicationprofilecache/applicationprofilecache.go @@ -410,6 +410,9 @@ func (apc *ApplicationProfileCacheImpl) indexContainerCallStacks(containerID, co func (apc *ApplicationProfileCacheImpl) ContainerCallback(notif containercollection.PubSubEvent) { switch notif.Type { case containercollection.EventTypeAddContainer: + if utils.IsHostContainer(notif.Container) { + return + } if apc.cfg.IgnoreContainer(notif.Container.K8s.Namespace, notif.Container.K8s.PodName, notif.Container.K8s.PodLabels) { return } diff --git a/pkg/objectcache/networkneighborhoodcache/networkneighborhoodcache.go b/pkg/objectcache/networkneighborhoodcache/networkneighborhoodcache.go index 3c82d917c..254f6ae64 100644 --- a/pkg/objectcache/networkneighborhoodcache/networkneighborhoodcache.go +++ b/pkg/objectcache/networkneighborhoodcache/networkneighborhoodcache.go @@ -333,6 +333,9 @@ func (nnc *NetworkNeighborhoodCacheImpl) handleUserManagedNetworkNeighborhood(nn func (nnc *NetworkNeighborhoodCacheImpl) ContainerCallback(notif containercollection.PubSubEvent) { switch notif.Type { case containercollection.EventTypeAddContainer: + if utils.IsHostContainer(notif.Container) { + return + } if nnc.cfg.IgnoreContainer(notif.Container.K8s.Namespace, notif.Container.K8s.PodName, notif.Container.K8s.PodLabels) { return } diff --git a/pkg/processtree/container/container_processtree.go b/pkg/processtree/container/container_processtree.go index 4e22d31e1..67cf1ab8b 100644 --- a/pkg/processtree/container/container_processtree.go +++ b/pkg/processtree/container/container_processtree.go @@ -4,7 +4,7 @@ import ( "fmt" "sync" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/goradd/maps" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" "github.com/kubescape/go-logger" @@ -58,42 +58,42 @@ func (c *containerProcessTreeImpl) ContainerCallback(notif containercollection.P } } -func (c *containerProcessTreeImpl) GetPidBranch(containerID string, targetPID uint32, fullTree *maps.SafeMap[uint32, *apitypes.Process]) (apitypes.Process, error) { +func (c *containerProcessTreeImpl) GetPidBranch(containerID string, targetPID uint32, fullTree *maps.SafeMap[uint32, *armotypes.Process]) (armotypes.Process, error) { c.mutex.RLock() shimPID, ok := c.containerIdToShimPid[containerID] c.mutex.RUnlock() if !ok { - return apitypes.Process{}, fmt.Errorf("container %s not found", containerID) + return armotypes.Process{}, fmt.Errorf("container %s not found", containerID) } // Find the process node for the shim PID shimNode, ok := fullTree.Load(shimPID) if !ok { - return apitypes.Process{}, fmt.Errorf("shim process %d not found in process tree", shimPID) + return armotypes.Process{}, fmt.Errorf("shim process %d not found in process tree", shimPID) } // Find the target process node targetNode, ok := fullTree.Load(targetPID) if !ok { - return apitypes.Process{}, fmt.Errorf("target process %d not found in process tree", targetPID) + return armotypes.Process{}, fmt.Errorf("target process %d not found in process tree", targetPID) } // Check if the target PID is within the shim's subtree if !c.isProcessInSubtree(targetNode, shimNode, fullTree) { - return apitypes.Process{}, fmt.Errorf("target process %d is not within container %s subtree", targetPID, containerID) + return armotypes.Process{}, fmt.Errorf("target process %d is not within container %s subtree", targetPID, containerID) } // Build the branch from target PID up to (but not including) shim branch := c.buildBranchToShim(targetNode, shimPID, fullTree) if branch == nil { - return apitypes.Process{}, fmt.Errorf("failed to build branch for target %d", targetPID) + return armotypes.Process{}, fmt.Errorf("failed to build branch for target %d", targetPID) } return *branch, nil } -func (c *containerProcessTreeImpl) GetShimPIDForProcess(pid uint32, fullTree *maps.SafeMap[uint32, *apitypes.Process]) (uint32, bool) { +func (c *containerProcessTreeImpl) GetShimPIDForProcess(pid uint32, fullTree *maps.SafeMap[uint32, *armotypes.Process]) (uint32, bool) { c.mutex.RLock() shimPIDs := make([]uint32, 0, len(c.containerIdToShimPid)) for _, shimPID := range c.containerIdToShimPid { @@ -131,7 +131,7 @@ func (c *containerProcessTreeImpl) GetPidByContainerID(containerID string) (uint return shimPID, nil } -func (c *containerProcessTreeImpl) IsProcessUnderAnyContainerSubtree(pid uint32, fullTree *maps.SafeMap[uint32, *apitypes.Process]) bool { +func (c *containerProcessTreeImpl) IsProcessUnderAnyContainerSubtree(pid uint32, fullTree *maps.SafeMap[uint32, *armotypes.Process]) bool { c.mutex.RLock() containerIDs := make([]string, 0, len(c.containerIdToShimPid)) for containerID := range c.containerIdToShimPid { @@ -147,7 +147,7 @@ func (c *containerProcessTreeImpl) IsProcessUnderAnyContainerSubtree(pid uint32, return false } -func (c *containerProcessTreeImpl) IsProcessUnderContainer(pid uint32, containerID string, fullTree *maps.SafeMap[uint32, *apitypes.Process]) bool { +func (c *containerProcessTreeImpl) IsProcessUnderContainer(pid uint32, containerID string, fullTree *maps.SafeMap[uint32, *armotypes.Process]) bool { c.mutex.RLock() shimPID, ok := c.containerIdToShimPid[containerID] c.mutex.RUnlock() @@ -173,7 +173,7 @@ func (c *containerProcessTreeImpl) IsProcessUnderContainer(pid uint32, container return false } -func (c *containerProcessTreeImpl) isProcessInSubtree(targetNode, rootNode *apitypes.Process, fullTree *maps.SafeMap[uint32, *apitypes.Process]) bool { +func (c *containerProcessTreeImpl) isProcessInSubtree(targetNode, rootNode *armotypes.Process, fullTree *maps.SafeMap[uint32, *armotypes.Process]) bool { if targetNode == nil || rootNode == nil { return false } @@ -199,16 +199,16 @@ func (c *containerProcessTreeImpl) isProcessInSubtree(targetNode, rootNode *apit // buildBranchToShim builds a process tree branch from targetNode up to (but not including) shimPID // This creates a new process tree containing only the nodes along the path from target to shim -func (c *containerProcessTreeImpl) buildBranchToShim(targetNode *apitypes.Process, shimPID uint32, fullTree *maps.SafeMap[uint32, *apitypes.Process]) *apitypes.Process { +func (c *containerProcessTreeImpl) buildBranchToShim(targetNode *armotypes.Process, shimPID uint32, fullTree *maps.SafeMap[uint32, *armotypes.Process]) *armotypes.Process { // Create a map to store the branch nodes - branchNodes := make(map[uint32]*apitypes.Process) + branchNodes := make(map[uint32]*armotypes.Process) if targetNode == nil { return nil } - var pathNodes []*apitypes.Process + var pathNodes []*armotypes.Process current := targetNode for current.PPID != 0 { pathNodes = append(pathNodes, current) @@ -230,7 +230,7 @@ func (c *containerProcessTreeImpl) buildBranchToShim(targetNode *apitypes.Proces } for _, node := range pathNodes { - branchNodes[node.PID] = &apitypes.Process{ + branchNodes[node.PID] = &armotypes.Process{ PID: node.PID, PPID: node.PPID, Comm: node.Comm, @@ -240,7 +240,7 @@ func (c *containerProcessTreeImpl) buildBranchToShim(targetNode *apitypes.Proces Gid: node.Gid, Cwd: node.Cwd, Path: node.Path, - ChildrenMap: make(map[apitypes.CommPID]*apitypes.Process), + ChildrenMap: make(map[armotypes.CommPID]*armotypes.Process), } } @@ -248,7 +248,7 @@ func (c *containerProcessTreeImpl) buildBranchToShim(targetNode *apitypes.Proces branchNode := branchNodes[node.PID] if branchNode.PPID != 0 && branchNode.PPID != shimPID { if parentBranch, exists := branchNodes[branchNode.PPID]; exists { - key := apitypes.CommPID{Comm: branchNode.Comm, PID: branchNode.PID} + key := armotypes.CommPID{Comm: branchNode.Comm, PID: branchNode.PID} parentBranch.ChildrenMap[key] = branchNode } } @@ -265,7 +265,7 @@ func (c *containerProcessTreeImpl) buildBranchToShim(targetNode *apitypes.Proces // getProcessFromProc retrieves process information from the /proc filesystem // for a given PID. This is a simplified version of the process manager's implementation. -func (c *containerProcessTreeImpl) getProcessFromProc(pid int) (*apitypes.Process, error) { +func (c *containerProcessTreeImpl) getProcessFromProc(pid int) (*armotypes.Process, error) { proc, err := procfs.NewProc(pid) if err != nil { return nil, fmt.Errorf("failed to get process info: %v", err) @@ -276,7 +276,7 @@ func (c *containerProcessTreeImpl) getProcessFromProc(pid int) (*apitypes.Proces return nil, fmt.Errorf("failed to get process stat: %v", err) } - return &apitypes.Process{ + return &armotypes.Process{ PID: uint32(pid), PPID: uint32(stat.PPID), Comm: stat.Comm, diff --git a/pkg/processtree/container/container_processtree_interface.go b/pkg/processtree/container/container_processtree_interface.go index f7fd6d1ce..7f37f20b1 100644 --- a/pkg/processtree/container/container_processtree_interface.go +++ b/pkg/processtree/container/container_processtree_interface.go @@ -1,16 +1,16 @@ package containerprocesstree import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/goradd/maps" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" ) type ContainerProcessTree interface { ContainerCallback(notif containercollection.PubSubEvent) - GetPidBranch(containerID string, targetPID uint32, fullTree *maps.SafeMap[uint32, *apitypes.Process]) (apitypes.Process, error) - IsProcessUnderAnyContainerSubtree(pid uint32, fullTree *maps.SafeMap[uint32, *apitypes.Process]) bool - IsProcessUnderContainer(pid uint32, containerID string, fullTree *maps.SafeMap[uint32, *apitypes.Process]) bool + GetPidBranch(containerID string, targetPID uint32, fullTree *maps.SafeMap[uint32, *armotypes.Process]) (armotypes.Process, error) + IsProcessUnderAnyContainerSubtree(pid uint32, fullTree *maps.SafeMap[uint32, *armotypes.Process]) bool + IsProcessUnderContainer(pid uint32, containerID string, fullTree *maps.SafeMap[uint32, *armotypes.Process]) bool GetPidByContainerID(containerID string) (uint32, error) - GetShimPIDForProcess(pid uint32, fullTree *maps.SafeMap[uint32, *apitypes.Process]) (uint32, bool) + GetShimPIDForProcess(pid uint32, fullTree *maps.SafeMap[uint32, *armotypes.Process]) (uint32, bool) } diff --git a/pkg/processtree/container/container_processtree_test.go b/pkg/processtree/container/container_processtree_test.go index bed0fb363..72dd99f00 100644 --- a/pkg/processtree/container/container_processtree_test.go +++ b/pkg/processtree/container/container_processtree_test.go @@ -3,7 +3,7 @@ package containerprocesstree import ( "testing" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/goradd/maps" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" eventtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types" @@ -11,8 +11,8 @@ import ( ) // Helper function to create a SafeMap from regular map data -func createSafeMapFromData(data map[uint32]*apitypes.Process) *maps.SafeMap[uint32, *apitypes.Process] { - safeMap := &maps.SafeMap[uint32, *apitypes.Process]{} +func createSafeMapFromData(data map[uint32]*armotypes.Process) *maps.SafeMap[uint32, *armotypes.Process] { + safeMap := &maps.SafeMap[uint32, *armotypes.Process]{} for pid, proc := range data { safeMap.Set(pid, proc) } @@ -79,32 +79,32 @@ func TestContainerProcessTreeImpl_GetPidBranch_Success(t *testing.T) { cpt.containerIdToShimPid[containerID] = shimPID // Create a tree structure: shim (50) -> nginx (100) -> nginx-worker (101) - nginxWorker := &apitypes.Process{ + nginxWorker := &armotypes.Process{ PID: 101, PPID: 100, Comm: "nginx-worker", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, } - nginxProcess := &apitypes.Process{ + nginxProcess := &armotypes.Process{ PID: 100, PPID: 50, // parent is shim Comm: "nginx", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "nginx-worker", PID: 101}: nginxWorker, }, } - shimProcess := &apitypes.Process{ + shimProcess := &armotypes.Process{ PID: 50, // shim PPID: 1, Comm: "containerd-shim", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "nginx", PID: 100}: nginxProcess, }, } - fullTree := map[uint32]*apitypes.Process{ + fullTree := map[uint32]*armotypes.Process{ 1: { PID: 1, PPID: 0, @@ -122,7 +122,7 @@ func TestContainerProcessTreeImpl_GetPidBranch_Success(t *testing.T) { assert.Equal(t, uint32(100), result.PID) assert.Equal(t, "nginx", result.Comm) assert.Len(t, result.ChildrenMap, 1) - assert.Contains(t, result.ChildrenMap, apitypes.CommPID{Comm: "nginx-worker", PID: 101}) + assert.Contains(t, result.ChildrenMap, armotypes.CommPID{Comm: "nginx-worker", PID: 101}) // Test getting branch for nginx (PID 100) // Should return nginx (PID 100) as the root with no children (since nginx itself is the target) @@ -136,7 +136,7 @@ func TestContainerProcessTreeImpl_GetPidBranch_Success(t *testing.T) { func TestContainerProcessTreeImpl_GetPidBranch_ContainerNotFound(t *testing.T) { cpt := NewContainerProcessTree().(*containerProcessTreeImpl) - fullTree := map[uint32]*apitypes.Process{ + fullTree := map[uint32]*armotypes.Process{ 1: { PID: 1, PPID: 0, @@ -148,7 +148,7 @@ func TestContainerProcessTreeImpl_GetPidBranch_ContainerNotFound(t *testing.T) { result, err := cpt.GetPidBranch("non-existent", 100, createSafeMapFromData(fullTree)) assert.Error(t, err) assert.Contains(t, err.Error(), "container non-existent not found") - assert.Equal(t, apitypes.Process{}, result) + assert.Equal(t, armotypes.Process{}, result) } func TestContainerProcessTreeImpl_GetPidBranch_ShimNotFound(t *testing.T) { @@ -159,7 +159,7 @@ func TestContainerProcessTreeImpl_GetPidBranch_ShimNotFound(t *testing.T) { shimPID := uint32(999) // Non-existent PID cpt.containerIdToShimPid[containerID] = shimPID - fullTree := map[uint32]*apitypes.Process{ + fullTree := map[uint32]*armotypes.Process{ 1: { PID: 1, PPID: 0, @@ -171,7 +171,7 @@ func TestContainerProcessTreeImpl_GetPidBranch_ShimNotFound(t *testing.T) { result, err := cpt.GetPidBranch(containerID, 100, createSafeMapFromData(fullTree)) assert.Error(t, err) assert.Contains(t, err.Error(), "shim process 999 not found in process tree") - assert.Equal(t, apitypes.Process{}, result) + assert.Equal(t, armotypes.Process{}, result) } func TestContainerProcessTreeImpl_GetPidBranch_TargetNotFound(t *testing.T) { @@ -182,14 +182,14 @@ func TestContainerProcessTreeImpl_GetPidBranch_TargetNotFound(t *testing.T) { shimPID := uint32(50) cpt.containerIdToShimPid[containerID] = shimPID - shimProcess := &apitypes.Process{ + shimProcess := &armotypes.Process{ PID: 50, // shim PPID: 1, Comm: "containerd-shim", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, } - fullTree := map[uint32]*apitypes.Process{ + fullTree := map[uint32]*armotypes.Process{ 1: { PID: 1, PPID: 0, @@ -202,7 +202,7 @@ func TestContainerProcessTreeImpl_GetPidBranch_TargetNotFound(t *testing.T) { result, err := cpt.GetPidBranch(containerID, 999, createSafeMapFromData(fullTree)) assert.Error(t, err) assert.Contains(t, err.Error(), "target process 999 not found in process tree") - assert.Equal(t, apitypes.Process{}, result) + assert.Equal(t, armotypes.Process{}, result) } func TestContainerProcessTreeImpl_GetPidBranch_TargetNotInContainer(t *testing.T) { @@ -214,21 +214,21 @@ func TestContainerProcessTreeImpl_GetPidBranch_TargetNotInContainer(t *testing.T cpt.containerIdToShimPid[containerID] = shimPID // Create a process that's not in the container's subtree - outsideProcess := &apitypes.Process{ + outsideProcess := &armotypes.Process{ PID: 200, PPID: 1, // Direct child of init, not of shim Comm: "outside-process", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, } - shimProcess := &apitypes.Process{ + shimProcess := &armotypes.Process{ PID: 50, // shim PPID: 1, Comm: "containerd-shim", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, } - fullTree := map[uint32]*apitypes.Process{ + fullTree := map[uint32]*armotypes.Process{ 1: { PID: 1, PPID: 0, @@ -242,7 +242,7 @@ func TestContainerProcessTreeImpl_GetPidBranch_TargetNotInContainer(t *testing.T result, err := cpt.GetPidBranch(containerID, 200, createSafeMapFromData(fullTree)) assert.Error(t, err) assert.Contains(t, err.Error(), "target process 200 is not within container test-container-123 subtree") - assert.Equal(t, apitypes.Process{}, result) + assert.Equal(t, armotypes.Process{}, result) } func TestContainerProcessTreeImpl_GetPidBranch_DeepTree(t *testing.T) { @@ -254,50 +254,50 @@ func TestContainerProcessTreeImpl_GetPidBranch_DeepTree(t *testing.T) { cpt.containerIdToShimPid[containerID] = shimPID // Create a deep tree: shim (50) -> nginx (100) -> worker (101) -> child (102) -> grandchild (103) - grandchild := &apitypes.Process{ + grandchild := &armotypes.Process{ PID: 103, PPID: 102, Comm: "grandchild", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, } - child := &apitypes.Process{ + child := &armotypes.Process{ PID: 102, PPID: 101, Comm: "child", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "grandchild", PID: 103}: grandchild, }, } - worker := &apitypes.Process{ + worker := &armotypes.Process{ PID: 101, PPID: 100, Comm: "worker", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "child", PID: 102}: child, }, } - nginx := &apitypes.Process{ + nginx := &armotypes.Process{ PID: 100, PPID: 50, // parent is shim Comm: "nginx", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "worker", PID: 101}: worker, }, } - shim := &apitypes.Process{ + shim := &armotypes.Process{ PID: 50, // shim PPID: 1, Comm: "containerd-shim", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "nginx", PID: 100}: nginx, }, } - fullTree := map[uint32]*apitypes.Process{ + fullTree := map[uint32]*armotypes.Process{ 1: { PID: 1, PPID: 0, @@ -319,17 +319,17 @@ func TestContainerProcessTreeImpl_GetPidBranch_DeepTree(t *testing.T) { // Verify the branch structure: nginx -> worker -> child -> grandchild (path only) assert.Len(t, result.ChildrenMap, 1) - workerNode := result.ChildrenMap[apitypes.CommPID{Comm: "worker", PID: 101}] + workerNode := result.ChildrenMap[armotypes.CommPID{Comm: "worker", PID: 101}] assert.NotNil(t, workerNode) assert.Equal(t, uint32(101), workerNode.PID) assert.Len(t, workerNode.ChildrenMap, 1) // Only the path child, not all children - childNode := workerNode.ChildrenMap[apitypes.CommPID{Comm: "child", PID: 102}] + childNode := workerNode.ChildrenMap[armotypes.CommPID{Comm: "child", PID: 102}] assert.NotNil(t, childNode) assert.Equal(t, uint32(102), childNode.PID) assert.Len(t, childNode.ChildrenMap, 1) // Only the path child, not all children - grandchildNode := childNode.ChildrenMap[apitypes.CommPID{Comm: "grandchild", PID: 103}] + grandchildNode := childNode.ChildrenMap[armotypes.CommPID{Comm: "grandchild", PID: 103}] assert.NotNil(t, grandchildNode) assert.Equal(t, uint32(103), grandchildNode.PID) assert.Len(t, grandchildNode.ChildrenMap, 0) // Leaf node @@ -344,23 +344,23 @@ func TestContainerProcessTreeImpl_GetPidBranch_TargetIsShimChild(t *testing.T) { cpt.containerIdToShimPid[containerID] = shimPID // Create a simple tree: shim (50) -> nginx (100) - nginx := &apitypes.Process{ + nginx := &armotypes.Process{ PID: 100, PPID: 50, // direct child of shim Comm: "nginx", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, } - shim := &apitypes.Process{ + shim := &armotypes.Process{ PID: 50, // shim PPID: 1, Comm: "containerd-shim", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "nginx", PID: 100}: nginx, }, } - fullTree := map[uint32]*apitypes.Process{ + fullTree := map[uint32]*armotypes.Process{ 1: { PID: 1, PPID: 0, @@ -428,57 +428,57 @@ func TestContainerProcessTreeImpl_GetShimPIDForProcess_Success(t *testing.T) { // Container 1: shim1 (50) -> nginx (100) -> worker (101) // Container 2: shim2 (60) -> redis (200) -> child (201) - worker := &apitypes.Process{ + worker := &armotypes.Process{ PID: 101, PPID: 100, Comm: "nginx-worker", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, } - nginx := &apitypes.Process{ + nginx := &armotypes.Process{ PID: 100, PPID: 50, // parent is shim1 Comm: "nginx", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "nginx-worker", PID: 101}: worker, }, } - shim1 := &apitypes.Process{ + shim1 := &armotypes.Process{ PID: 50, // shim1 PPID: 1, Comm: "containerd-shim", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "nginx", PID: 100}: nginx, }, } - child := &apitypes.Process{ + child := &armotypes.Process{ PID: 201, PPID: 200, Comm: "redis-child", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, } - redis := &apitypes.Process{ + redis := &armotypes.Process{ PID: 200, PPID: 60, // parent is shim2 Comm: "redis", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "redis-child", PID: 201}: child, }, } - shim2 := &apitypes.Process{ + shim2 := &armotypes.Process{ PID: 60, // shim2 PPID: 1, Comm: "containerd-shim", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "redis", PID: 200}: redis, }, } - fullTree := map[uint32]*apitypes.Process{ + fullTree := map[uint32]*armotypes.Process{ 1: { PID: 1, PPID: 0, @@ -520,14 +520,14 @@ func TestContainerProcessTreeImpl_GetShimPIDForProcess_NotFound(t *testing.T) { cpt.containerIdToShimPid[containerID] = shimPID // Create process tree - shim := &apitypes.Process{ + shim := &armotypes.Process{ PID: 50, // shim PPID: 1, Comm: "containerd-shim", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, } - fullTree := map[uint32]*apitypes.Process{ + fullTree := map[uint32]*armotypes.Process{ 1: { PID: 1, PPID: 0, @@ -542,11 +542,11 @@ func TestContainerProcessTreeImpl_GetShimPIDForProcess_NotFound(t *testing.T) { assert.Equal(t, uint32(0), shimPIDResult) // Test with process that exists but is not under any container - outsideProcess := &apitypes.Process{ + outsideProcess := &armotypes.Process{ PID: 200, PPID: 1, // Direct child of init, not of shim Comm: "outside-process", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, } fullTree[200] = outsideProcess @@ -564,32 +564,32 @@ func TestContainerProcessTreeImpl_IsProcessUnderContainer_Success(t *testing.T) cpt.containerIdToShimPid[containerID] = shimPID // Create process tree: shim (50) -> nginx (100) -> worker (101) - worker := &apitypes.Process{ + worker := &armotypes.Process{ PID: 101, PPID: 100, Comm: "nginx-worker", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, } - nginx := &apitypes.Process{ + nginx := &armotypes.Process{ PID: 100, PPID: 50, // parent is shim Comm: "nginx", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "nginx-worker", PID: 101}: worker, }, } - shim := &apitypes.Process{ + shim := &armotypes.Process{ PID: 50, // shim PPID: 1, Comm: "containerd-shim", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "nginx", PID: 100}: nginx, }, } - fullTree := map[uint32]*apitypes.Process{ + fullTree := map[uint32]*armotypes.Process{ 1: { PID: 1, PPID: 0, @@ -613,7 +613,7 @@ func TestContainerProcessTreeImpl_IsProcessUnderContainer_Success(t *testing.T) func TestContainerProcessTreeImpl_IsProcessUnderContainer_ContainerNotFound(t *testing.T) { cpt := NewContainerProcessTree().(*containerProcessTreeImpl) - fullTree := map[uint32]*apitypes.Process{ + fullTree := map[uint32]*armotypes.Process{ 1: { PID: 1, PPID: 0, @@ -633,7 +633,7 @@ func TestContainerProcessTreeImpl_IsProcessUnderContainer_ShimNotFound(t *testin shimPID := uint32(999) // Non-existent PID cpt.containerIdToShimPid[containerID] = shimPID - fullTree := map[uint32]*apitypes.Process{ + fullTree := map[uint32]*armotypes.Process{ 1: { PID: 1, PPID: 0, @@ -653,14 +653,14 @@ func TestContainerProcessTreeImpl_IsProcessUnderContainer_ProcessNotFound(t *tes shimPID := uint32(50) cpt.containerIdToShimPid[containerID] = shimPID - shim := &apitypes.Process{ + shim := &armotypes.Process{ PID: 50, // shim PPID: 1, Comm: "containerd-shim", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, } - fullTree := map[uint32]*apitypes.Process{ + fullTree := map[uint32]*armotypes.Process{ 1: { PID: 1, PPID: 0, @@ -689,57 +689,57 @@ func TestContainerProcessTreeImpl_IsProcessUnderAnyContainerSubtree_Success(t *t // Container 1: shim1 (50) -> nginx (100) -> worker (101) // Container 2: shim2 (60) -> redis (200) -> child (201) - worker := &apitypes.Process{ + worker := &armotypes.Process{ PID: 101, PPID: 100, Comm: "nginx-worker", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, } - nginx := &apitypes.Process{ + nginx := &armotypes.Process{ PID: 100, PPID: 50, // parent is shim1 Comm: "nginx", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "nginx-worker", PID: 101}: worker, }, } - shim1 := &apitypes.Process{ + shim1 := &armotypes.Process{ PID: 50, // shim1 PPID: 1, Comm: "containerd-shim", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "nginx", PID: 100}: nginx, }, } - child := &apitypes.Process{ + child := &armotypes.Process{ PID: 201, PPID: 200, Comm: "redis-child", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, } - redis := &apitypes.Process{ + redis := &armotypes.Process{ PID: 200, PPID: 60, // parent is shim2 Comm: "redis", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "redis-child", PID: 201}: child, }, } - shim2 := &apitypes.Process{ + shim2 := &armotypes.Process{ PID: 60, // shim2 PPID: 1, Comm: "containerd-shim", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "redis", PID: 200}: redis, }, } - fullTree := map[uint32]*apitypes.Process{ + fullTree := map[uint32]*armotypes.Process{ 1: { PID: 1, PPID: 0, @@ -770,7 +770,7 @@ func TestContainerProcessTreeImpl_IsProcessUnderAnyContainerSubtree_NoContainers cpt := NewContainerProcessTree().(*containerProcessTreeImpl) // No containers registered - fullTree := map[uint32]*apitypes.Process{ + fullTree := map[uint32]*armotypes.Process{ 1: { PID: 1, PPID: 0, @@ -792,21 +792,21 @@ func TestContainerProcessTreeImpl_IsProcessUnderAnyContainerSubtree_OutsideProce cpt.containerIdToShimPid[containerID] = shimPID // Create process tree with a process outside the container - shim := &apitypes.Process{ + shim := &armotypes.Process{ PID: 50, // shim PPID: 1, Comm: "containerd-shim", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, } - outsideProcess := &apitypes.Process{ + outsideProcess := &armotypes.Process{ PID: 200, PPID: 1, // Direct child of init, not of shim Comm: "outside-process", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{}, + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{}, } - fullTree := map[uint32]*apitypes.Process{ + fullTree := map[uint32]*armotypes.Process{ 1: { PID: 1, PPID: 0, diff --git a/pkg/processtree/creator/exit_manager.go b/pkg/processtree/creator/exit_manager.go index f0616982e..69a29e5ff 100644 --- a/pkg/processtree/creator/exit_manager.go +++ b/pkg/processtree/creator/exit_manager.go @@ -5,7 +5,7 @@ import ( "sort" "time" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/kubescape/go-logger" "github.com/kubescape/go-logger/helpers" "github.com/kubescape/node-agent/pkg/processtree/conversion" @@ -16,7 +16,7 @@ type pendingExit struct { StartTimeNs uint64 Comm string Timestamp time.Time - Children []*apitypes.Process + Children []*armotypes.Process } func (pt *processTreeCreatorImpl) startExitManager() { @@ -132,7 +132,7 @@ func (pt *processTreeCreatorImpl) exitByPid(pid uint32) { } // Collect children for reparenting - children := make([]*apitypes.Process, 0, len(proc.ChildrenMap)) + children := make([]*armotypes.Process, 0, len(proc.ChildrenMap)) for _, child := range proc.ChildrenMap { if child != nil { children = append(children, child) @@ -172,8 +172,8 @@ func (pt *processTreeCreatorImpl) exitByPid(pid uint32) { if proc.PPID != 0 { if parent, ok := pt.processMap.Load(proc.PPID); ok { - if _, ok := parent.ChildrenMap[apitypes.CommPID{PID: pid}]; ok { - delete(parent.ChildrenMap, apitypes.CommPID{PID: pid}) + if _, ok := parent.ChildrenMap[armotypes.CommPID{PID: pid}]; ok { + delete(parent.ChildrenMap, armotypes.CommPID{PID: pid}) } else { logger.L().Warning("exitByPid: process not found in parent's children map", helpers.String("pid", fmt.Sprintf("%d", pid))) } diff --git a/pkg/processtree/creator/exit_manager_test.go b/pkg/processtree/creator/exit_manager_test.go index fa3900505..1f0688d0d 100644 --- a/pkg/processtree/creator/exit_manager_test.go +++ b/pkg/processtree/creator/exit_manager_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/goradd/maps" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" "github.com/kubescape/node-agent/pkg/config" @@ -21,23 +21,23 @@ import ( type mockContainerProcessTree struct{} func (m *mockContainerProcessTree) ContainerCallback(notif containercollection.PubSubEvent) {} -func (m *mockContainerProcessTree) GetContainerTreeNodes(containerID string, fullTree *maps.SafeMap[uint32, *apitypes.Process]) ([]apitypes.Process, error) { - return []apitypes.Process{}, nil +func (m *mockContainerProcessTree) GetContainerTreeNodes(containerID string, fullTree *maps.SafeMap[uint32, *armotypes.Process]) ([]armotypes.Process, error) { + return []armotypes.Process{}, nil } -func (m *mockContainerProcessTree) GetPidBranch(containerID string, targetPID uint32, fullTree *maps.SafeMap[uint32, *apitypes.Process]) (apitypes.Process, error) { - return apitypes.Process{}, nil +func (m *mockContainerProcessTree) GetPidBranch(containerID string, targetPID uint32, fullTree *maps.SafeMap[uint32, *armotypes.Process]) (armotypes.Process, error) { + return armotypes.Process{}, nil } func (m *mockContainerProcessTree) ListContainers() []string { return []string{} } -func (m *mockContainerProcessTree) IsProcessUnderAnyContainerSubtree(pid uint32, fullTree *maps.SafeMap[uint32, *apitypes.Process]) bool { +func (m *mockContainerProcessTree) IsProcessUnderAnyContainerSubtree(pid uint32, fullTree *maps.SafeMap[uint32, *armotypes.Process]) bool { return false } -func (m *mockContainerProcessTree) IsProcessUnderContainer(pid uint32, containerID string, fullTree *maps.SafeMap[uint32, *apitypes.Process]) bool { +func (m *mockContainerProcessTree) IsProcessUnderContainer(pid uint32, containerID string, fullTree *maps.SafeMap[uint32, *armotypes.Process]) bool { return false } -func (m *mockContainerProcessTree) GetShimPIDForProcess(pid uint32, fullTree *maps.SafeMap[uint32, *apitypes.Process]) (uint32, bool) { +func (m *mockContainerProcessTree) GetShimPIDForProcess(pid uint32, fullTree *maps.SafeMap[uint32, *armotypes.Process]) (uint32, bool) { return 0, false } func (m *mockContainerProcessTree) GetPidByContainerID(containerID string) (uint32, error) { @@ -47,7 +47,7 @@ func (m *mockContainerProcessTree) GetPidByContainerID(containerID string) (uint // Mock reparenting logic type mockReparentingLogic struct{} -func (m *mockReparentingLogic) Reparent(exitingPID uint32, children []*apitypes.Process, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *apitypes.Process]) (uint32, error) { +func (m *mockReparentingLogic) Reparent(exitingPID uint32, children []*armotypes.Process, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *armotypes.Process]) (uint32, error) { return 1, nil // Always reparent to init } func (m *mockReparentingLogic) AddStrategy(strategy reparenting.ReparentingStrategy) {} @@ -67,7 +67,7 @@ func createTestProcessTreeCreator() *processTreeCreatorImpl { } return &processTreeCreatorImpl{ - processMap: maps.SafeMap[uint32, *apitypes.Process]{}, + processMap: maps.SafeMap[uint32, *armotypes.Process]{}, containerTree: &mockContainerProcessTree{}, reparentingStrategies: &mockReparentingLogic{}, pendingExits: make(map[uint32]*pendingExit), @@ -76,12 +76,12 @@ func createTestProcessTreeCreator() *processTreeCreatorImpl { } // Helper function to create a test process -func createTestProcess(pid uint32, ppid uint32, comm string) *apitypes.Process { - return &apitypes.Process{ +func createTestProcess(pid uint32, ppid uint32, comm string) *armotypes.Process { + return &armotypes.Process{ PID: pid, PPID: ppid, Comm: comm, - ChildrenMap: make(map[apitypes.CommPID]*apitypes.Process), + ChildrenMap: make(map[armotypes.CommPID]*armotypes.Process), } } @@ -118,7 +118,7 @@ func TestExitManager_AddPendingExit(t *testing.T) { // Create a test process parent := createTestProcess(100, 1, "parent") child := createTestProcess(200, 100, "child") - parent.ChildrenMap[apitypes.CommPID{PID: 200}] = child + parent.ChildrenMap[armotypes.CommPID{PID: 200}] = child pt.processMap.Set(100, parent) pt.processMap.Set(200, child) @@ -159,7 +159,7 @@ func TestExitManager_MaxPendingExits(t *testing.T) { PID: pid, StartTimeNs: uint64(i), Timestamp: time.Now().Add(-10 * time.Minute), // Old timestamp - Children: []*apitypes.Process{}, + Children: []*armotypes.Process{}, } } @@ -184,8 +184,8 @@ func TestExitManager_RemoveProcessFromPending(t *testing.T) { child1 := createTestProcess(200, 100, "child1") child2 := createTestProcess(300, 100, "child2") - parent.ChildrenMap[apitypes.CommPID{PID: 200}] = child1 - parent.ChildrenMap[apitypes.CommPID{PID: 300}] = child2 + parent.ChildrenMap[armotypes.CommPID{PID: 200}] = child1 + parent.ChildrenMap[armotypes.CommPID{PID: 300}] = child2 pt.processMap.Set(100, parent) pt.processMap.Set(200, child1) @@ -197,7 +197,7 @@ func TestExitManager_RemoveProcessFromPending(t *testing.T) { PID: 100, StartTimeNs: 12345, Timestamp: time.Now(), - Children: []*apitypes.Process{child1, child2}, + Children: []*armotypes.Process{child1, child2}, } pt.mutex.Unlock() @@ -239,7 +239,7 @@ func TestExitManager_PerformExitCleanup(t *testing.T) { PID: 100, StartTimeNs: 12345, Timestamp: oldTime, - Children: []*apitypes.Process{}, + Children: []*armotypes.Process{}, } // Add recent pending exit (should NOT be cleaned up) @@ -247,7 +247,7 @@ func TestExitManager_PerformExitCleanup(t *testing.T) { PID: 200, StartTimeNs: 67890, Timestamp: recentTime, - Children: []*apitypes.Process{}, + Children: []*armotypes.Process{}, } pt.mutex.Unlock() @@ -302,13 +302,13 @@ func TestExitManager_ForceCleanupAllPendingExits(t *testing.T) { PID: 100, StartTimeNs: 12345, Timestamp: time.Now(), - Children: []*apitypes.Process{}, + Children: []*armotypes.Process{}, } pt.pendingExits[200] = &pendingExit{ PID: 200, StartTimeNs: 67890, Timestamp: time.Now(), - Children: []*apitypes.Process{}, + Children: []*armotypes.Process{}, } pt.mutex.Unlock() @@ -400,8 +400,8 @@ func TestExitManager_HandleExitEventFlow(t *testing.T) { child1 := createTestProcess(200, 100, "child1") child2 := createTestProcess(300, 100, "child2") - parent.ChildrenMap[apitypes.CommPID{PID: 200}] = child1 - parent.ChildrenMap[apitypes.CommPID{PID: 300}] = child2 + parent.ChildrenMap[armotypes.CommPID{PID: 200}] = child1 + parent.ChildrenMap[armotypes.CommPID{PID: 300}] = child2 pt.processMap.Set(100, parent) pt.processMap.Set(200, child1) @@ -443,10 +443,10 @@ func TestExitManager_ReparentingDuringCleanup(t *testing.T) { grandchild := createTestProcess(400, 300, "grandchild") // Set up relationships - grandparent.ChildrenMap[apitypes.CommPID{PID: 100}] = parent - parent.ChildrenMap[apitypes.CommPID{PID: 200}] = child1 - parent.ChildrenMap[apitypes.CommPID{PID: 300}] = child2 - child2.ChildrenMap[apitypes.CommPID{PID: 400}] = grandchild + grandparent.ChildrenMap[armotypes.CommPID{PID: 100}] = parent + parent.ChildrenMap[armotypes.CommPID{PID: 200}] = child1 + parent.ChildrenMap[armotypes.CommPID{PID: 300}] = child2 + child2.ChildrenMap[armotypes.CommPID{PID: 400}] = grandchild // Add all to process map pt.processMap.Set(1, grandparent) @@ -461,7 +461,7 @@ func TestExitManager_ReparentingDuringCleanup(t *testing.T) { PID: 100, StartTimeNs: 12345, Timestamp: time.Now().Add(-10 * time.Minute), // Old enough to be cleaned up - Children: []*apitypes.Process{child1, child2}, + Children: []*armotypes.Process{child1, child2}, } pt.mutex.Unlock() @@ -503,7 +503,7 @@ func TestExitManager_CleanupLoop(t *testing.T) { PID: 100, StartTimeNs: 12345, Timestamp: time.Now().Add(-cleanupDelay - time.Minute), // Old enough to be cleaned up - Children: []*apitypes.Process{}, + Children: []*armotypes.Process{}, } pt.mutex.Unlock() @@ -526,8 +526,8 @@ func TestExitManager_CleanupChildrenMapWithEmptyComm(t *testing.T) { child2 := createTestProcess(300, 100, "child2") // Add children to parent's ChildrenMap using only PID (Comm is empty) - parent.ChildrenMap[apitypes.CommPID{PID: 200}] = child1 - parent.ChildrenMap[apitypes.CommPID{PID: 300}] = child2 + parent.ChildrenMap[armotypes.CommPID{PID: 200}] = child1 + parent.ChildrenMap[armotypes.CommPID{PID: 300}] = child2 pt.processMap.Set(100, parent) pt.processMap.Set(200, child1) @@ -578,9 +578,9 @@ func TestExitManager_CleanupChildrenMapWithMixedCommValues(t *testing.T) { // Add children with mixed Comm values (some empty, some not) // This tests that the cleanup works regardless of Comm values - parent.ChildrenMap[apitypes.CommPID{PID: 200}] = child1 // Empty Comm - parent.ChildrenMap[apitypes.CommPID{PID: 300}] = child2 // Empty Comm - parent.ChildrenMap[apitypes.CommPID{PID: 400}] = child3 // Empty Comm + parent.ChildrenMap[armotypes.CommPID{PID: 200}] = child1 // Empty Comm + parent.ChildrenMap[armotypes.CommPID{PID: 300}] = child2 // Empty Comm + parent.ChildrenMap[armotypes.CommPID{PID: 400}] = child3 // Empty Comm pt.processMap.Set(100, parent) pt.processMap.Set(200, child1) @@ -628,8 +628,8 @@ func TestExitManager_RemoveFromParentChildrenMap(t *testing.T) { grandchild := createTestProcess(300, 200, "grandchild") // Set up parent-child relationships - parent.ChildrenMap[apitypes.CommPID{PID: 200}] = child - child.ChildrenMap[apitypes.CommPID{PID: 300}] = grandchild + parent.ChildrenMap[armotypes.CommPID{PID: 200}] = child + child.ChildrenMap[armotypes.CommPID{PID: 300}] = grandchild // Add all processes to the process map pt.processMap.Set(100, parent) @@ -639,8 +639,8 @@ func TestExitManager_RemoveFromParentChildrenMap(t *testing.T) { // Verify initial state assert.Len(t, parent.ChildrenMap, 1, "Parent should have 1 child initially") assert.Len(t, child.ChildrenMap, 1, "Child should have 1 grandchild initially") - assert.Contains(t, parent.ChildrenMap, apitypes.CommPID{PID: 200}, "Parent should contain child") - assert.Contains(t, child.ChildrenMap, apitypes.CommPID{PID: 300}, "Child should contain grandchild") + assert.Contains(t, parent.ChildrenMap, armotypes.CommPID{PID: 200}, "Parent should contain child") + assert.Contains(t, child.ChildrenMap, armotypes.CommPID{PID: 300}, "Child should contain grandchild") // Test case 1: Exit the child process - should remove it from parent's ChildrenMap // First, add the child to pending exits @@ -649,7 +649,7 @@ func TestExitManager_RemoveFromParentChildrenMap(t *testing.T) { PID: 200, StartTimeNs: 12345, Timestamp: time.Now(), - Children: []*apitypes.Process{grandchild}, + Children: []*armotypes.Process{grandchild}, } pt.mutex.Unlock() @@ -661,7 +661,7 @@ func TestExitManager_RemoveFromParentChildrenMap(t *testing.T) { // Verify child was removed from parent's ChildrenMap pt.mutex.RLock() assert.Len(t, parent.ChildrenMap, 0, "Parent should have no children after child exit") - assert.NotContains(t, parent.ChildrenMap, apitypes.CommPID{PID: 200}, "Parent should not contain child anymore") + assert.NotContains(t, parent.ChildrenMap, armotypes.CommPID{PID: 200}, "Parent should not contain child anymore") // Child process should be removed from process map assert.Nil(t, pt.processMap.Get(200), "Child process should be removed from process map") @@ -677,7 +677,7 @@ func TestExitManager_RemoveFromParentChildrenMap(t *testing.T) { PID: 300, StartTimeNs: 12346, Timestamp: time.Now(), - Children: []*apitypes.Process{}, + Children: []*armotypes.Process{}, } pt.mutex.Unlock() @@ -701,9 +701,9 @@ func TestExitManager_RemoveFromParentChildrenMapWithMultipleChildren(t *testing. child3 := createTestProcess(400, 100, "child3") // Set up parent-child relationships - parent.ChildrenMap[apitypes.CommPID{PID: 200}] = child1 - parent.ChildrenMap[apitypes.CommPID{PID: 300}] = child2 - parent.ChildrenMap[apitypes.CommPID{PID: 400}] = child3 + parent.ChildrenMap[armotypes.CommPID{PID: 200}] = child1 + parent.ChildrenMap[armotypes.CommPID{PID: 300}] = child2 + parent.ChildrenMap[armotypes.CommPID{PID: 400}] = child3 // Add all processes to the process map pt.processMap.Set(100, parent) @@ -713,9 +713,9 @@ func TestExitManager_RemoveFromParentChildrenMapWithMultipleChildren(t *testing. // Verify initial state assert.Len(t, parent.ChildrenMap, 3, "Parent should have 3 children initially") - assert.Contains(t, parent.ChildrenMap, apitypes.CommPID{PID: 200}, "Parent should contain child1") - assert.Contains(t, parent.ChildrenMap, apitypes.CommPID{PID: 300}, "Parent should contain child2") - assert.Contains(t, parent.ChildrenMap, apitypes.CommPID{PID: 400}, "Parent should contain child3") + assert.Contains(t, parent.ChildrenMap, armotypes.CommPID{PID: 200}, "Parent should contain child1") + assert.Contains(t, parent.ChildrenMap, armotypes.CommPID{PID: 300}, "Parent should contain child2") + assert.Contains(t, parent.ChildrenMap, armotypes.CommPID{PID: 400}, "Parent should contain child3") // Test case: Exit child2 - should remove it from parent's ChildrenMap // First, add child2 to pending exits @@ -724,7 +724,7 @@ func TestExitManager_RemoveFromParentChildrenMapWithMultipleChildren(t *testing. PID: 300, StartTimeNs: 12345, Timestamp: time.Now(), - Children: []*apitypes.Process{}, + Children: []*armotypes.Process{}, } pt.mutex.Unlock() @@ -735,9 +735,9 @@ func TestExitManager_RemoveFromParentChildrenMapWithMultipleChildren(t *testing. // Verify child2 was removed from parent's ChildrenMap pt.mutex.RLock() assert.Len(t, parent.ChildrenMap, 2, "Parent should have 2 children after child2 exit") - assert.Contains(t, parent.ChildrenMap, apitypes.CommPID{PID: 200}, "Parent should still contain child1") - assert.NotContains(t, parent.ChildrenMap, apitypes.CommPID{PID: 300}, "Parent should not contain child2 anymore") - assert.Contains(t, parent.ChildrenMap, apitypes.CommPID{PID: 400}, "Parent should still contain child3") + assert.Contains(t, parent.ChildrenMap, armotypes.CommPID{PID: 200}, "Parent should still contain child1") + assert.NotContains(t, parent.ChildrenMap, armotypes.CommPID{PID: 300}, "Parent should not contain child2 anymore") + assert.Contains(t, parent.ChildrenMap, armotypes.CommPID{PID: 400}, "Parent should still contain child3") // Child2 process should be removed from process map assert.Nil(t, pt.processMap.Get(300), "Child2 process should be removed from process map") @@ -754,7 +754,7 @@ func TestExitManager_RemoveFromParentChildrenMapWithMultipleChildren(t *testing. PID: 200, StartTimeNs: 12346, Timestamp: time.Now(), - Children: []*apitypes.Process{}, + Children: []*armotypes.Process{}, } pt.mutex.Unlock() @@ -765,8 +765,8 @@ func TestExitManager_RemoveFromParentChildrenMapWithMultipleChildren(t *testing. // Verify child1 was removed from parent's ChildrenMap pt.mutex.RLock() assert.Len(t, parent.ChildrenMap, 1, "Parent should have 1 child after child1 exit") - assert.NotContains(t, parent.ChildrenMap, apitypes.CommPID{PID: 200}, "Parent should not contain child1 anymore") - assert.Contains(t, parent.ChildrenMap, apitypes.CommPID{PID: 400}, "Parent should still contain child3") + assert.NotContains(t, parent.ChildrenMap, armotypes.CommPID{PID: 200}, "Parent should not contain child1 anymore") + assert.Contains(t, parent.ChildrenMap, armotypes.CommPID{PID: 400}, "Parent should still contain child3") // Child1 process should be removed from process map assert.Nil(t, pt.processMap.Get(200), "Child1 process should be removed from process map") diff --git a/pkg/processtree/creator/processtree_creator.go b/pkg/processtree/creator/processtree_creator.go index 961514530..2f79a3a51 100644 --- a/pkg/processtree/creator/processtree_creator.go +++ b/pkg/processtree/creator/processtree_creator.go @@ -4,7 +4,7 @@ import ( "fmt" "sync" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/goradd/maps" "github.com/kubescape/go-logger" "github.com/kubescape/go-logger/helpers" @@ -15,7 +15,7 @@ import ( ) type processTreeCreatorImpl struct { - processMap maps.SafeMap[uint32, *apitypes.Process] // PID -> Process + processMap maps.SafeMap[uint32, *armotypes.Process] // PID -> Process containerTree containerprocesstree.ContainerProcessTree reparentingStrategies reparenting.ReparentingStrategies mutex sync.RWMutex // Protects process tree modifications @@ -35,7 +35,7 @@ func NewProcessTreeCreator(containerTree containerprocesstree.ContainerProcessTr } creator := &processTreeCreatorImpl{ - processMap: maps.SafeMap[uint32, *apitypes.Process]{}, + processMap: maps.SafeMap[uint32, *armotypes.Process]{}, reparentingStrategies: reparentingLogic, containerTree: containerTree, pendingExits: make(map[uint32]*pendingExit), @@ -68,12 +68,12 @@ func (pt *processTreeCreatorImpl) FeedEvent(event conversion.ProcessEvent) { } } -func (pt *processTreeCreatorImpl) GetRootTree() ([]apitypes.Process, error) { +func (pt *processTreeCreatorImpl) GetRootTree() ([]armotypes.Process, error) { pt.mutex.RLock() defer pt.mutex.RUnlock() // Find root processes (those whose parent is not in the map or PPID==0) - roots := []apitypes.Process{} + roots := []armotypes.Process{} for _, proc := range pt.processMap.Values() { _, ok := pt.processMap.Load(proc.PPID) if proc.PPID == 0 || !ok { @@ -83,11 +83,11 @@ func (pt *processTreeCreatorImpl) GetRootTree() ([]apitypes.Process, error) { return roots, nil } -func (pt *processTreeCreatorImpl) GetProcessMap() *maps.SafeMap[uint32, *apitypes.Process] { +func (pt *processTreeCreatorImpl) GetProcessMap() *maps.SafeMap[uint32, *armotypes.Process] { return &pt.processMap } -func (pt *processTreeCreatorImpl) GetProcessNode(pid int) (*apitypes.Process, error) { +func (pt *processTreeCreatorImpl) GetProcessNode(pid int) (*armotypes.Process, error) { pt.mutex.RLock() defer pt.mutex.RUnlock() @@ -99,21 +99,21 @@ func (pt *processTreeCreatorImpl) GetProcessNode(pid int) (*apitypes.Process, er } // GetPidBranch performs container branch operation (no longer needs to be atomic) -func (pt *processTreeCreatorImpl) GetPidBranch(containerTree interface{}, containerID string, targetPID uint32) (apitypes.Process, error) { +func (pt *processTreeCreatorImpl) GetPidBranch(containerTree interface{}, containerID string, targetPID uint32) (armotypes.Process, error) { pt.mutex.RLock() defer pt.mutex.RUnlock() // Type assert the container tree ct, ok := containerTree.(containerprocesstree.ContainerProcessTree) if !ok { - return apitypes.Process{}, fmt.Errorf("invalid container tree type") + return armotypes.Process{}, fmt.Errorf("invalid container tree type") } return ct.GetPidBranch(containerID, targetPID, &pt.processMap) } // UpdatePPID handles PPID updates using the new reparenting strategy -func (pt *processTreeCreatorImpl) UpdatePPID(proc *apitypes.Process, event conversion.ProcessEvent) { +func (pt *processTreeCreatorImpl) UpdatePPID(proc *armotypes.Process, event conversion.ProcessEvent) { if event.PPID != proc.PPID && event.PPID != 0 { // New reparenting strategy: // 1. If new PPID is under container subtree, update regardless of current state @@ -174,7 +174,7 @@ func (pt *processTreeCreatorImpl) handleForkEvent(event conversion.ProcessEvent) } if proc.ChildrenMap == nil { - proc.ChildrenMap = make(map[apitypes.CommPID]*apitypes.Process) + proc.ChildrenMap = make(map[armotypes.CommPID]*armotypes.Process) } } @@ -184,7 +184,7 @@ func (pt *processTreeCreatorImpl) handleProcfsEvent(event conversion.ProcessEven proc, ok := pt.processMap.Load(event.PID) if !ok { - if pt.config.KubernetesMode && event.ContainerID == "host" { // If we are in Kubernetes mode and the container ID is "host", don't create the process. + if pt.config.KubernetesMode && event.ContainerID == armotypes.HostContainerID { // If we are in Kubernetes mode and the container ID is "host", don't create the process. return } @@ -218,7 +218,7 @@ func (pt *processTreeCreatorImpl) handleProcfsEvent(event conversion.ProcessEven } if proc.ChildrenMap == nil { - proc.ChildrenMap = make(map[apitypes.CommPID]*apitypes.Process) + proc.ChildrenMap = make(map[armotypes.CommPID]*armotypes.Process) } } @@ -265,7 +265,7 @@ func (pt *processTreeCreatorImpl) handleExecEvent(event conversion.ProcessEvent) proc.Path = event.Path } if proc.ChildrenMap == nil { - proc.ChildrenMap = make(map[apitypes.CommPID]*apitypes.Process) + proc.ChildrenMap = make(map[armotypes.CommPID]*armotypes.Process) } } @@ -277,19 +277,19 @@ func (pt *processTreeCreatorImpl) handleExitEvent(event conversion.ProcessEvent) pt.addPendingExit(event) } -func (pt *processTreeCreatorImpl) getOrCreateProcess(pid uint32) *apitypes.Process { +func (pt *processTreeCreatorImpl) getOrCreateProcess(pid uint32) *armotypes.Process { proc, ok := pt.processMap.Load(pid) if ok { return proc } - proc = &apitypes.Process{PID: pid, ChildrenMap: make(map[apitypes.CommPID]*apitypes.Process)} + proc = &armotypes.Process{PID: pid, ChildrenMap: make(map[armotypes.CommPID]*armotypes.Process)} pt.processMap.Set(pid, proc) return proc } // linkProcessToParent ensures proc is added as a child to its parent (if PPID != 0) -func (pt *processTreeCreatorImpl) linkProcessToParent(proc *apitypes.Process) { +func (pt *processTreeCreatorImpl) linkProcessToParent(proc *armotypes.Process) { if proc == nil || proc.PPID == 0 { return } @@ -301,15 +301,15 @@ func (pt *processTreeCreatorImpl) linkProcessToParent(proc *apitypes.Process) { parent := pt.getOrCreateProcess(proc.PPID) if parent.ChildrenMap == nil { - parent.ChildrenMap = make(map[apitypes.CommPID]*apitypes.Process) + parent.ChildrenMap = make(map[armotypes.CommPID]*armotypes.Process) } - key := apitypes.CommPID{PID: proc.PID} + key := armotypes.CommPID{PID: proc.PID} parent.ChildrenMap[key] = proc } // updateProcessPPID safely updates a process's PPID by removing it from the old parent's // children map and adding it to the new parent's children map -func (pt *processTreeCreatorImpl) updateProcessPPID(proc *apitypes.Process, newPPID uint32) { +func (pt *processTreeCreatorImpl) updateProcessPPID(proc *armotypes.Process, newPPID uint32) { if proc == nil || proc.PPID == newPPID { return // No change needed } @@ -327,7 +327,7 @@ func (pt *processTreeCreatorImpl) updateProcessPPID(proc *apitypes.Process, newP // Remove from old parent's children map if proc.PPID != 0 { if oldParent, ok := pt.processMap.Load(proc.PPID); ok && oldParent.ChildrenMap != nil { - key := apitypes.CommPID{PID: proc.PID} + key := armotypes.CommPID{PID: proc.PID} if _, ok := oldParent.ChildrenMap[key]; ok { delete(oldParent.ChildrenMap, key) } else { @@ -368,7 +368,7 @@ func (pt *processTreeCreatorImpl) isDescendant(parentPID, targetPID uint32) bool return false } -func (pt *processTreeCreatorImpl) shallowCopyProcess(proc *apitypes.Process) *apitypes.Process { +func (pt *processTreeCreatorImpl) shallowCopyProcess(proc *armotypes.Process) *armotypes.Process { if proc == nil { return nil } diff --git a/pkg/processtree/creator/processtree_creator_interface.go b/pkg/processtree/creator/processtree_creator_interface.go index 2637b6dff..01a7f2328 100644 --- a/pkg/processtree/creator/processtree_creator_interface.go +++ b/pkg/processtree/creator/processtree_creator_interface.go @@ -1,7 +1,7 @@ package processtreecreator import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/goradd/maps" "github.com/kubescape/node-agent/pkg/processtree/conversion" ) @@ -10,11 +10,11 @@ type ProcessTreeCreator interface { // Feed a new event into the process tree FeedEvent(event conversion.ProcessEvent) // Get the full process tree (returns the root or all processes) - GetRootTree() ([]apitypes.Process, error) + GetRootTree() ([]armotypes.Process, error) // Get the process map - GetProcessMap() *maps.SafeMap[uint32, *apitypes.Process] + GetProcessMap() *maps.SafeMap[uint32, *armotypes.Process] // Optionally: Query for a process node by PID - GetProcessNode(pid int) (*apitypes.Process, error) + GetProcessNode(pid int) (*armotypes.Process, error) // Start the process tree creator and begin background tasks Start() // Stop the process tree creator and cleanup resources diff --git a/pkg/processtree/creator/processtree_creator_test.go b/pkg/processtree/creator/processtree_creator_test.go index f9ebbf08d..23dac920a 100644 --- a/pkg/processtree/creator/processtree_creator_test.go +++ b/pkg/processtree/creator/processtree_creator_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/goradd/maps" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" "github.com/kubescape/node-agent/pkg/config" @@ -22,17 +22,17 @@ type MockContainerProcessTree struct { mock.Mock } -func (m *MockContainerProcessTree) GetPidBranch(containerID string, targetPID uint32, processMap *maps.SafeMap[uint32, *apitypes.Process]) (apitypes.Process, error) { +func (m *MockContainerProcessTree) GetPidBranch(containerID string, targetPID uint32, processMap *maps.SafeMap[uint32, *armotypes.Process]) (armotypes.Process, error) { args := m.Called(containerID, targetPID, processMap) - return args.Get(0).(apitypes.Process), args.Error(1) + return args.Get(0).(armotypes.Process), args.Error(1) } -func (m *MockContainerProcessTree) IsProcessUnderAnyContainerSubtree(pid uint32, processMap *maps.SafeMap[uint32, *apitypes.Process]) bool { +func (m *MockContainerProcessTree) IsProcessUnderAnyContainerSubtree(pid uint32, processMap *maps.SafeMap[uint32, *armotypes.Process]) bool { args := m.Called(pid, processMap) return args.Bool(0) } -func (m *MockContainerProcessTree) IsProcessUnderContainer(pid uint32, containerID string, processMap *maps.SafeMap[uint32, *apitypes.Process]) bool { +func (m *MockContainerProcessTree) IsProcessUnderContainer(pid uint32, containerID string, processMap *maps.SafeMap[uint32, *armotypes.Process]) bool { args := m.Called(pid, containerID, processMap) return args.Bool(0) } @@ -41,9 +41,9 @@ func (m *MockContainerProcessTree) ContainerCallback(notif containercollection.P m.Called(notif) } -func (m *MockContainerProcessTree) GetContainerTreeNodes(containerID string, fullTree *maps.SafeMap[uint32, *apitypes.Process]) ([]apitypes.Process, error) { +func (m *MockContainerProcessTree) GetContainerTreeNodes(containerID string, fullTree *maps.SafeMap[uint32, *armotypes.Process]) ([]armotypes.Process, error) { args := m.Called(containerID, fullTree) - return args.Get(0).([]apitypes.Process), args.Error(1) + return args.Get(0).([]armotypes.Process), args.Error(1) } func (m *MockContainerProcessTree) ListContainers() []string { @@ -51,7 +51,7 @@ func (m *MockContainerProcessTree) ListContainers() []string { return args.Get(0).([]string) } -func (m *MockContainerProcessTree) GetShimPIDForProcess(pid uint32, fullTree *maps.SafeMap[uint32, *apitypes.Process]) (uint32, bool) { +func (m *MockContainerProcessTree) GetShimPIDForProcess(pid uint32, fullTree *maps.SafeMap[uint32, *armotypes.Process]) (uint32, bool) { args := m.Called(pid, fullTree) return args.Get(0).(uint32), args.Bool(1) } @@ -453,7 +453,7 @@ func TestGetPidBranch(t *testing.T) { impl := creator.(*processTreeCreatorImpl) // Mock container tree methods - expectedProcess := apitypes.Process{ + expectedProcess := armotypes.Process{ PID: 1234, Comm: "container-process", } @@ -533,7 +533,7 @@ func TestLinkProcessToParent(t *testing.T) { // Verify link assert.Len(t, parent.ChildrenMap, 1) - key := apitypes.CommPID{PID: 1234} + key := armotypes.CommPID{PID: 1234} assert.Contains(t, parent.ChildrenMap, key) assert.Equal(t, child, parent.ChildrenMap[key]) @@ -571,7 +571,7 @@ func TestUpdateProcessPPID(t *testing.T) { assert.Len(t, oldParent.ChildrenMap, 0) // Removed from old parent assert.Len(t, newParent.ChildrenMap, 1) // Added to new parent - key := apitypes.CommPID{PID: 1234} + key := armotypes.CommPID{PID: 1234} assert.Contains(t, newParent.ChildrenMap, key) assert.Equal(t, child, newParent.ChildrenMap[key]) @@ -591,17 +591,17 @@ func TestShallowCopyProcess(t *testing.T) { impl := creator.(*processTreeCreatorImpl) // Create original process - original := &apitypes.Process{ + original := &armotypes.Process{ PID: 1234, PPID: 1000, Comm: "test-process", Cmdline: "test-process --arg", - ChildrenMap: make(map[apitypes.CommPID]*apitypes.Process), + ChildrenMap: make(map[armotypes.CommPID]*armotypes.Process), } // Add a child to the original - child := &apitypes.Process{PID: 5678, Comm: "child"} - key := apitypes.CommPID{PID: 5678} + child := &armotypes.Process{PID: 5678, Comm: "child"} + key := armotypes.CommPID{PID: 5678} original.ChildrenMap[key] = child // Create shallow copy @@ -686,7 +686,7 @@ func TestConcurrentAccess(t *testing.T) { // Note: The process tree may contain additional processes (like PPID=1) that are auto-created // so we check that we have at least the expected number of processes by counting non-nil entries count := 0 - processMap.Range(func(pid uint32, proc *apitypes.Process) bool { + processMap.Range(func(pid uint32, proc *armotypes.Process) bool { if proc != nil { count++ } @@ -822,7 +822,7 @@ func TestReparentingLogicDirect(t *testing.T) { assert.Equal(t, uint32(1234), grandchild.PPID) // Test reparenting logic directly - children := []*apitypes.Process{grandchild} + children := []*armotypes.Process{grandchild} newParentPID, err := impl.reparentingStrategies.Reparent(1234, children, containerTree, &impl.processMap) assert.NoError(t, err) @@ -866,7 +866,7 @@ func TestReparentingLogicDirect(t *testing.T) { assert.Equal(t, uint32(1234), child.PPID) // Test reparenting logic directly - children := []*apitypes.Process{child} + children := []*armotypes.Process{child} newParentPID, err := impl.reparentingStrategies.Reparent(1234, children, containerTree, &impl.processMap) assert.NoError(t, err) @@ -926,7 +926,7 @@ func TestReparentingLogicDirect(t *testing.T) { assert.Equal(t, uint32(100), worker.PPID) // Test reparenting logic directly - children := []*apitypes.Process{worker} + children := []*armotypes.Process{worker} newParentPID, err := impl.reparentingStrategies.Reparent(100, children, mockContainerTree, &impl.processMap) assert.NoError(t, err) @@ -975,7 +975,7 @@ func TestComplexProcessTree(t *testing.T) { // Count entries manually since SafeMap doesn't support len() count := 0 - processMap.Range(func(pid uint32, proc *apitypes.Process) bool { + processMap.Range(func(pid uint32, proc *armotypes.Process) bool { if proc != nil { count++ } @@ -1086,7 +1086,7 @@ func TestPerformanceWithManyProcesses(t *testing.T) { // Verify all processes were created (plus the parent process with PID 1) processMap := creator.GetProcessMap() count := 0 - processMap.Range(func(pid uint32, proc *apitypes.Process) bool { + processMap.Range(func(pid uint32, proc *armotypes.Process) bool { if proc != nil { count++ } diff --git a/pkg/processtree/process_tree_manager.go b/pkg/processtree/process_tree_manager.go index d164e48e4..989771754 100644 --- a/pkg/processtree/process_tree_manager.go +++ b/pkg/processtree/process_tree_manager.go @@ -6,7 +6,7 @@ import ( "sync" "time" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/hashicorp/golang-lru/v2/expirable" "github.com/kubescape/node-agent/pkg/config" containerprocesstree "github.com/kubescape/node-agent/pkg/processtree/container" @@ -19,7 +19,7 @@ import ( type ProcessTreeManagerImpl struct { creator processtreecreator.ProcessTreeCreator containerTree containerprocesstree.ContainerProcessTree - containerProcessTreeCache *expirable.LRU[string, apitypes.Process] // containerID:pid -> cached result + containerProcessTreeCache *expirable.LRU[string, armotypes.Process] // containerID:pid -> cached result mutex sync.RWMutex config config.Config } @@ -31,7 +31,7 @@ func NewProcessTreeManager( config config.Config, ) ProcessTreeManager { - containerProcessTreeCache := expirable.NewLRU[string, apitypes.Process](10000, nil, 1*time.Minute) + containerProcessTreeCache := expirable.NewLRU[string, armotypes.Process](10000, nil, 1*time.Minute) ptm := &ProcessTreeManagerImpl{ creator: creator, @@ -67,14 +67,14 @@ func (ptm *ProcessTreeManagerImpl) ReportEvent(eventType utils.EventType, event return nil } -func (ptm *ProcessTreeManagerImpl) GetContainerProcessTree(containerID string, pid uint32, useCache bool) (apitypes.Process, error) { +func (ptm *ProcessTreeManagerImpl) GetContainerProcessTree(containerID string, pid uint32, useCache bool) (armotypes.Process, error) { cacheKey := containerID + ":" + strconv.FormatUint(uint64(pid), 10) if cached, exists := ptm.containerProcessTreeCache.Get(cacheKey); exists && useCache { return cached, nil } // Get process node first (minimal lock scope) - var processNode *apitypes.Process + var processNode *armotypes.Process var err error func() { ptm.mutex.RLock() @@ -83,15 +83,15 @@ func (ptm *ProcessTreeManagerImpl) GetContainerProcessTree(containerID string, p }() if err != nil { - return apitypes.Process{}, &GetProcessNodeError{Err: err} + return armotypes.Process{}, &GetProcessNodeError{Err: err} } if processNode == nil { - return apitypes.Process{}, &ProcessNotFoundError{Pid: pid, ContainerID: containerID} + return armotypes.Process{}, &ProcessNotFoundError{Pid: pid, ContainerID: containerID} } // Get container subtree (separate lock scope) - var containerSubtree apitypes.Process + var containerSubtree armotypes.Process var subtreeErr error func() { ptm.mutex.RLock() @@ -100,7 +100,7 @@ func (ptm *ProcessTreeManagerImpl) GetContainerProcessTree(containerID string, p }() if subtreeErr != nil { - return apitypes.Process{}, &GetContainerSubtreeError{Err: subtreeErr} + return armotypes.Process{}, &GetContainerSubtreeError{Err: subtreeErr} } // Cache the result diff --git a/pkg/processtree/process_tree_manager_interface.go b/pkg/processtree/process_tree_manager_interface.go index 9121b60f5..fd98715bc 100644 --- a/pkg/processtree/process_tree_manager_interface.go +++ b/pkg/processtree/process_tree_manager_interface.go @@ -1,14 +1,14 @@ package processtree import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/kubescape/node-agent/pkg/utils" ) type ProcessTreeManager interface { Start() Stop() - GetContainerProcessTree(containerID string, pid uint32, useCache bool) (apitypes.Process, error) + GetContainerProcessTree(containerID string, pid uint32, useCache bool) (armotypes.Process, error) ReportEvent(eventType utils.EventType, event utils.K8sEvent) error GetPidList() []uint32 } diff --git a/pkg/processtree/process_tree_manager_mock.go b/pkg/processtree/process_tree_manager_mock.go index e0e569832..4726f171f 100644 --- a/pkg/processtree/process_tree_manager_mock.go +++ b/pkg/processtree/process_tree_manager_mock.go @@ -1,7 +1,7 @@ package processtree import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/kubescape/node-agent/pkg/utils" ) @@ -35,8 +35,8 @@ func (m *ProcessTreeManagerMock) Stop() { } // GetContainerProcessTree returns an empty process for testing -func (m *ProcessTreeManagerMock) GetContainerProcessTree(containerID string, pid uint32, useCache bool) (apitypes.Process, error) { - return apitypes.Process{}, nil +func (m *ProcessTreeManagerMock) GetContainerProcessTree(containerID string, pid uint32, useCache bool) (armotypes.Process, error) { + return armotypes.Process{}, nil } // ReportEvent is a no-op for testing diff --git a/pkg/processtree/reparenting/reparenting_strategies.go b/pkg/processtree/reparenting/reparenting_strategies.go index 0c7d8a984..3f4dabf1d 100644 --- a/pkg/processtree/reparenting/reparenting_strategies.go +++ b/pkg/processtree/reparenting/reparenting_strategies.go @@ -4,7 +4,7 @@ import ( "fmt" "sync" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/goradd/maps" containerprocesstree "github.com/kubescape/node-agent/pkg/processtree/container" "github.com/kubescape/node-agent/pkg/processtree/reparenting/strategies" @@ -32,7 +32,7 @@ func (rl *reparentingLogicImpl) addDefaultStrategies() { rl.AddStrategy(&strategies.FallBackStrategy{}) } -func (rl *reparentingLogicImpl) Reparent(exitingPID uint32, children []*apitypes.Process, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *apitypes.Process]) (uint32, error) { +func (rl *reparentingLogicImpl) Reparent(exitingPID uint32, children []*armotypes.Process, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *armotypes.Process]) (uint32, error) { rl.mutex.Lock() defer rl.mutex.Unlock() @@ -66,7 +66,7 @@ func (rl *reparentingLogicImpl) GetStrategies() []ReparentingStrategy { return reparentingStrategies } -func (rl *reparentingLogicImpl) getSelectedStrategy(exitingPID uint32, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *apitypes.Process]) ReparentingStrategy { +func (rl *reparentingLogicImpl) getSelectedStrategy(exitingPID uint32, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *armotypes.Process]) ReparentingStrategy { if rl.firstStrategy.IsApplicable(exitingPID, containerTree, processMap) { return rl.firstStrategy } diff --git a/pkg/processtree/reparenting/reparenting_strategies_interface.go b/pkg/processtree/reparenting/reparenting_strategies_interface.go index 774c5c90c..a51e6ed45 100644 --- a/pkg/processtree/reparenting/reparenting_strategies_interface.go +++ b/pkg/processtree/reparenting/reparenting_strategies_interface.go @@ -1,22 +1,22 @@ package reparenting import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/goradd/maps" containerprocesstree "github.com/kubescape/node-agent/pkg/processtree/container" ) type ReparentingStrategy interface { - GetNewParentPID(exitingPID uint32, children []*apitypes.Process, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *apitypes.Process]) uint32 + GetNewParentPID(exitingPID uint32, children []*armotypes.Process, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *armotypes.Process]) uint32 Name() string - IsApplicable(exitingPID uint32, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *apitypes.Process]) bool + IsApplicable(exitingPID uint32, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *armotypes.Process]) bool } // ReparentingStrategies defines the interface for the reparenting logic component type ReparentingStrategies interface { - Reparent(exitingPID uint32, children []*apitypes.Process, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *apitypes.Process]) (uint32, error) + Reparent(exitingPID uint32, children []*armotypes.Process, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *armotypes.Process]) (uint32, error) AddStrategy(strategy ReparentingStrategy) diff --git a/pkg/processtree/reparenting/strategies/containerized_env.go b/pkg/processtree/reparenting/strategies/containerized_env.go index 640a72bdd..1d7d23b96 100644 --- a/pkg/processtree/reparenting/strategies/containerized_env.go +++ b/pkg/processtree/reparenting/strategies/containerized_env.go @@ -1,7 +1,7 @@ package strategies import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/goradd/maps" containerprocesstree "github.com/kubescape/node-agent/pkg/processtree/container" ) @@ -13,11 +13,11 @@ func (cs *ContainerStrategy) Name() string { return "containerized_env" } -func (cs *ContainerStrategy) IsApplicable(exitingPID uint32, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *apitypes.Process]) bool { +func (cs *ContainerStrategy) IsApplicable(exitingPID uint32, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *armotypes.Process]) bool { return containerTree != nil && containerTree.IsProcessUnderAnyContainerSubtree(exitingPID, processMap) } -func (cs *ContainerStrategy) GetNewParentPID(exitingPID uint32, children []*apitypes.Process, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *apitypes.Process]) uint32 { +func (cs *ContainerStrategy) GetNewParentPID(exitingPID uint32, children []*armotypes.Process, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *armotypes.Process]) uint32 { if containerTree != nil { shimPID, found := containerTree.GetShimPIDForProcess(exitingPID, processMap) if found { diff --git a/pkg/processtree/reparenting/strategies/containerized_env_test.go b/pkg/processtree/reparenting/strategies/containerized_env_test.go index 5114d46e6..b68d2a00f 100644 --- a/pkg/processtree/reparenting/strategies/containerized_env_test.go +++ b/pkg/processtree/reparenting/strategies/containerized_env_test.go @@ -3,7 +3,7 @@ package strategies import ( "testing" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/goradd/maps" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" "github.com/stretchr/testify/assert" @@ -15,11 +15,11 @@ type MockContainerProcessTree struct { func (m *MockContainerProcessTree) ContainerCallback(notif containercollection.PubSubEvent) {} -func (m *MockContainerProcessTree) GetPidBranch(containerID string, targetPID uint32, fullTree *maps.SafeMap[uint32, *apitypes.Process]) (apitypes.Process, error) { - return apitypes.Process{}, nil +func (m *MockContainerProcessTree) GetPidBranch(containerID string, targetPID uint32, fullTree *maps.SafeMap[uint32, *armotypes.Process]) (armotypes.Process, error) { + return armotypes.Process{}, nil } -func (m *MockContainerProcessTree) GetShimPIDForProcess(pid uint32, fullTree *maps.SafeMap[uint32, *apitypes.Process]) (uint32, bool) { +func (m *MockContainerProcessTree) GetShimPIDForProcess(pid uint32, fullTree *maps.SafeMap[uint32, *armotypes.Process]) (uint32, bool) { if _, ok := fullTree.Load(pid); ok { return m.shimPID, true } @@ -30,18 +30,18 @@ func (m *MockContainerProcessTree) GetPidByContainerID(containerID string) (uint return m.shimPID, nil } -func (m *MockContainerProcessTree) IsProcessUnderAnyContainerSubtree(pid uint32, fullTree *maps.SafeMap[uint32, *apitypes.Process]) bool { +func (m *MockContainerProcessTree) IsProcessUnderAnyContainerSubtree(pid uint32, fullTree *maps.SafeMap[uint32, *armotypes.Process]) bool { return true } -func (m *MockContainerProcessTree) IsProcessUnderContainer(pid uint32, containerID string, fullTree *maps.SafeMap[uint32, *apitypes.Process]) bool { +func (m *MockContainerProcessTree) IsProcessUnderContainer(pid uint32, containerID string, fullTree *maps.SafeMap[uint32, *armotypes.Process]) bool { return true } func TestContainerStrategy_GetNewParentPID(t *testing.T) { // Setup strategy := &ContainerStrategy{} - processMap := &maps.SafeMap[uint32, *apitypes.Process]{} + processMap := &maps.SafeMap[uint32, *armotypes.Process]{} shimPID := uint32(100) containerInitPID := uint32(101) @@ -49,14 +49,14 @@ func TestContainerStrategy_GetNewParentPID(t *testing.T) { childPID := uint32(103) // Build tree: Shim -> Init -> Parent -> Child - processMap.Set(shimPID, &apitypes.Process{PID: shimPID, PPID: 1, Comm: "shim"}) - processMap.Set(containerInitPID, &apitypes.Process{PID: containerInitPID, PPID: shimPID, Comm: "init"}) - processMap.Set(parentPID, &apitypes.Process{PID: parentPID, PPID: containerInitPID, Comm: "parent"}) - processMap.Set(childPID, &apitypes.Process{PID: childPID, PPID: parentPID, Comm: "child"}) + processMap.Set(shimPID, &armotypes.Process{PID: shimPID, PPID: 1, Comm: "shim"}) + processMap.Set(containerInitPID, &armotypes.Process{PID: containerInitPID, PPID: shimPID, Comm: "init"}) + processMap.Set(parentPID, &armotypes.Process{PID: parentPID, PPID: containerInitPID, Comm: "parent"}) + processMap.Set(childPID, &armotypes.Process{PID: childPID, PPID: parentPID, Comm: "child"}) mockContainerTree := &MockContainerProcessTree{shimPID: shimPID} - children := []*apitypes.Process{ + children := []*armotypes.Process{ {PID: childPID, PPID: parentPID}, } @@ -71,20 +71,20 @@ func TestContainerStrategy_GetNewParentPID(t *testing.T) { func TestContainerStrategy_GetNewParentPID_InitExits(t *testing.T) { // Setup strategy := &ContainerStrategy{} - processMap := &maps.SafeMap[uint32, *apitypes.Process]{} + processMap := &maps.SafeMap[uint32, *armotypes.Process]{} shimPID := uint32(100) containerInitPID := uint32(101) childPID := uint32(102) // Build tree: Shim -> Init -> Child - processMap.Set(shimPID, &apitypes.Process{PID: shimPID, PPID: 1, Comm: "shim"}) - processMap.Set(containerInitPID, &apitypes.Process{PID: containerInitPID, PPID: shimPID, Comm: "init"}) - processMap.Set(childPID, &apitypes.Process{PID: childPID, PPID: containerInitPID, Comm: "child"}) + processMap.Set(shimPID, &armotypes.Process{PID: shimPID, PPID: 1, Comm: "shim"}) + processMap.Set(containerInitPID, &armotypes.Process{PID: containerInitPID, PPID: shimPID, Comm: "init"}) + processMap.Set(childPID, &armotypes.Process{PID: childPID, PPID: containerInitPID, Comm: "child"}) mockContainerTree := &MockContainerProcessTree{shimPID: shimPID} - children := []*apitypes.Process{ + children := []*armotypes.Process{ {PID: childPID, PPID: containerInitPID}, } diff --git a/pkg/processtree/reparenting/strategies/default.go b/pkg/processtree/reparenting/strategies/default.go index e53773f80..a44c82733 100644 --- a/pkg/processtree/reparenting/strategies/default.go +++ b/pkg/processtree/reparenting/strategies/default.go @@ -1,7 +1,7 @@ package strategies import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/goradd/maps" containerprocesstree "github.com/kubescape/node-agent/pkg/processtree/container" ) @@ -12,7 +12,7 @@ func (defs *DefaultStrategy) Name() string { return "fallback" } -func (defs *DefaultStrategy) IsApplicable(exitingPID uint32, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *apitypes.Process]) bool { +func (defs *DefaultStrategy) IsApplicable(exitingPID uint32, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *armotypes.Process]) bool { if exitingProcess, ok := processMap.Load(exitingPID); ok { ppid := exitingProcess.PPID if ppid > 0 { @@ -25,7 +25,7 @@ func (defs *DefaultStrategy) IsApplicable(exitingPID uint32, containerTree conta return false } -func (defs *DefaultStrategy) GetNewParentPID(exitingPID uint32, children []*apitypes.Process, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *apitypes.Process]) uint32 { +func (defs *DefaultStrategy) GetNewParentPID(exitingPID uint32, children []*armotypes.Process, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *armotypes.Process]) uint32 { if exitingProcess, ok := processMap.Load(exitingPID); ok { ppid := exitingProcess.PPID if ppid > 0 { diff --git a/pkg/processtree/reparenting/strategies/fallback.go b/pkg/processtree/reparenting/strategies/fallback.go index 8a558a224..7b730d75d 100644 --- a/pkg/processtree/reparenting/strategies/fallback.go +++ b/pkg/processtree/reparenting/strategies/fallback.go @@ -1,7 +1,7 @@ package strategies import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/goradd/maps" containerprocesstree "github.com/kubescape/node-agent/pkg/processtree/container" ) @@ -12,10 +12,10 @@ func (fbs *FallBackStrategy) Name() string { return "fallback" } -func (fbs *FallBackStrategy) IsApplicable(exitingPID uint32, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *apitypes.Process]) bool { +func (fbs *FallBackStrategy) IsApplicable(exitingPID uint32, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *armotypes.Process]) bool { return true } -func (fbs *FallBackStrategy) GetNewParentPID(exitingPID uint32, children []*apitypes.Process, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *apitypes.Process]) uint32 { +func (fbs *FallBackStrategy) GetNewParentPID(exitingPID uint32, children []*armotypes.Process, containerTree containerprocesstree.ContainerProcessTree, processMap *maps.SafeMap[uint32, *armotypes.Process]) uint32 { return 1 } diff --git a/pkg/rulemanager/rule_manager.go b/pkg/rulemanager/rule_manager.go index b5c6e50c5..75241fcc2 100644 --- a/pkg/rulemanager/rule_manager.go +++ b/pkg/rulemanager/rule_manager.go @@ -7,7 +7,6 @@ import ( "time" "github.com/armosec/armoapi-go/armotypes" - apitypes "github.com/armosec/armoapi-go/armotypes" mapset "github.com/deckarep/golang-set/v2" "github.com/goradd/maps" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" @@ -25,6 +24,7 @@ import ( "github.com/kubescape/node-agent/pkg/objectcache" "github.com/kubescape/node-agent/pkg/processtree" bindingcache "github.com/kubescape/node-agent/pkg/rulebindingmanager" + "github.com/kubescape/node-agent/pkg/rulemanager/cel" "github.com/kubescape/node-agent/pkg/rulemanager/profilehelper" "github.com/kubescape/node-agent/pkg/rulemanager/ruleadapters" "github.com/kubescape/node-agent/pkg/rulemanager/rulecooldown" @@ -32,7 +32,6 @@ import ( typesv1 "github.com/kubescape/node-agent/pkg/rulemanager/types/v1" "github.com/kubescape/node-agent/pkg/utils" - "github.com/kubescape/node-agent/pkg/rulemanager/cel" corev1 "k8s.io/api/core/v1" ) @@ -81,7 +80,7 @@ func CreateRuleManager( celEvaluator cel.RuleEvaluator, mntnsRegistry contextdetection.Registry, ) (*RuleManager, error) { - ruleFailureCreator := ruleadapters.NewRuleFailureCreator(enricher, dnsManager, adapterFactory, apitypes.AlertSourcePlatformK8sAgent) + ruleFailureCreator := ruleadapters.NewRuleFailureCreator(enricher, dnsManager, adapterFactory, armotypes.AlertSourcePlatformK8sAgent) rulePolicyValidator := NewRulePolicyValidator(objectCache) detectorManager := detectors.NewDetectorManager(mntnsRegistry) @@ -109,6 +108,19 @@ func CreateRuleManager( } func (rm *RuleManager) startRuleManager(container *containercollection.Container, k8sContainerID string) { + if utils.IsHostContainer(container) { + logger.L().Debug("RuleManager - skipping shared data wait for host container", + helpers.String("container ID", container.Runtime.ContainerID)) + // Skip podToWlid and shim PID setup for host containers as they don't have K8s metadata + if err := rm.monitorContainer(container, k8sContainerID); err != nil { + logger.L().Debug("RuleManager - stop monitor on host container", + helpers.String("reason", err.Error()), + helpers.String("container ID", container.Runtime.ContainerID), + helpers.String("k8s container id", k8sContainerID)) + } + return + } + sharedData, err := rm.waitForSharedContainerData(container.Runtime.ContainerID) if err != nil { logger.L().Error("RuleManager - failed to get shared container data", helpers.Error(err)) diff --git a/pkg/rulemanager/ruleadapters/adapters/bpf.go b/pkg/rulemanager/ruleadapters/adapters/bpf.go index 04d26f30f..f64cc5216 100644 --- a/pkg/rulemanager/ruleadapters/adapters/bpf.go +++ b/pkg/rulemanager/ruleadapters/adapters/bpf.go @@ -1,7 +1,7 @@ package adapters import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" "github.com/kubescape/node-agent/pkg/ebpf/events" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -44,8 +44,8 @@ func (c *BpfAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedEvent } failure.SetBaseRuntimeAlert(baseRuntimeAlert) - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ Comm: comm, Pcomm: bpfEvent.GetPcomm(), PPID: bpfEvent.GetPpid(), @@ -62,10 +62,9 @@ func (c *BpfAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedEvent failure.SetTriggerEvent(bpfEvent) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: bpfEvent.GetPod(), PodLabels: bpfEvent.GetPodLabels(), } failure.SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails) } - diff --git a/pkg/rulemanager/ruleadapters/adapters/capabilities.go b/pkg/rulemanager/ruleadapters/adapters/capabilities.go index cd17223ea..536a48ddd 100644 --- a/pkg/rulemanager/ruleadapters/adapters/capabilities.go +++ b/pkg/rulemanager/ruleadapters/adapters/capabilities.go @@ -1,7 +1,7 @@ package adapters import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" "github.com/kubescape/node-agent/pkg/ebpf/events" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -37,8 +37,8 @@ func (c *CapabilitiesAdapter) SetFailureMetadata(failure types.RuleFailure, enri } failure.SetBaseRuntimeAlert(baseRuntimeAlert) - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ Comm: comm, Gid: capEvent.GetGid(), PID: pid, @@ -50,9 +50,8 @@ func (c *CapabilitiesAdapter) SetFailureMetadata(failure types.RuleFailure, enri failure.SetTriggerEvent(capEvent) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: capEvent.GetPod(), } failure.SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails) } - diff --git a/pkg/rulemanager/ruleadapters/adapters/dns.go b/pkg/rulemanager/ruleadapters/adapters/dns.go index 8442f791f..9841725a3 100644 --- a/pkg/rulemanager/ruleadapters/adapters/dns.go +++ b/pkg/rulemanager/ruleadapters/adapters/dns.go @@ -1,7 +1,7 @@ package adapters import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" "github.com/kubescape/node-agent/pkg/ebpf/events" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -53,8 +53,8 @@ func (c *DnsAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedEvent } failure.SetBaseRuntimeAlert(baseRuntimeAlert) - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ Comm: comm, Gid: dnsEvent.GetGid(), PID: pid, @@ -70,10 +70,9 @@ func (c *DnsAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedEvent failure.SetTriggerEvent(dnsEvent) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: dnsEvent.GetPod(), PodLabels: dnsEvent.GetPodLabels(), } failure.SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails) } - diff --git a/pkg/rulemanager/ruleadapters/adapters/exec.go b/pkg/rulemanager/ruleadapters/adapters/exec.go index 0db13488d..f4f70c747 100644 --- a/pkg/rulemanager/ruleadapters/adapters/exec.go +++ b/pkg/rulemanager/ruleadapters/adapters/exec.go @@ -5,7 +5,7 @@ import ( "path/filepath" "strings" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" "github.com/kubescape/node-agent/pkg/ebpf/events" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -52,8 +52,8 @@ func (c *ExecAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedEven } failure.SetBaseRuntimeAlert(baseRuntimeAlert) - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ Comm: comm, Gid: execEvent.GetGid(), PID: pid, @@ -72,7 +72,7 @@ func (c *ExecAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedEven failure.SetTriggerEvent(execEvent) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: execEvent.GetPod(), PodLabels: execEvent.GetPodLabels(), } @@ -85,4 +85,3 @@ func GetExecFullPathFromEvent(execEvent utils.ExecEvent) string { } return utils.GetExecPathFromEvent(execEvent) } - diff --git a/pkg/rulemanager/ruleadapters/adapters/hardlink.go b/pkg/rulemanager/ruleadapters/adapters/hardlink.go index 2c51c9722..5ee5e2f33 100644 --- a/pkg/rulemanager/ruleadapters/adapters/hardlink.go +++ b/pkg/rulemanager/ruleadapters/adapters/hardlink.go @@ -3,7 +3,7 @@ package adapters import ( "path/filepath" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" "github.com/kubescape/node-agent/pkg/ebpf/events" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -48,8 +48,8 @@ func (c *HardlinkAdapter) SetFailureMetadata(failure types.RuleFailure, enriched failure.SetBaseRuntimeAlert(baseRuntimeAlert) upperLayer := hardlinkEvent.GetUpperLayer() - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ Comm: comm, PPID: hardlinkEvent.GetPpid(), PID: pid, @@ -65,10 +65,9 @@ func (c *HardlinkAdapter) SetFailureMetadata(failure types.RuleFailure, enriched failure.SetTriggerEvent(hardlinkEvent) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: hardlinkEvent.GetPod(), PodLabels: hardlinkEvent.GetPodLabels(), } failure.SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails) } - diff --git a/pkg/rulemanager/ruleadapters/adapters/http.go b/pkg/rulemanager/ruleadapters/adapters/http.go index 5aed6d107..8d1038bbb 100644 --- a/pkg/rulemanager/ruleadapters/adapters/http.go +++ b/pkg/rulemanager/ruleadapters/adapters/http.go @@ -1,7 +1,7 @@ package adapters import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" "github.com/kubescape/node-agent/pkg/ebpf/events" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -42,8 +42,8 @@ func (c *HTTPAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedEven } failure.SetBaseRuntimeAlert(baseRuntimeAlert) - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ PID: httpEvent.GetPID(), Uid: httpEvent.GetUid(), Gid: httpEvent.GetGid(), @@ -54,7 +54,7 @@ func (c *HTTPAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedEven failure.SetTriggerEvent(httpEvent) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: httpEvent.GetPod(), PodLabels: httpEvent.GetPodLabels(), } diff --git a/pkg/rulemanager/ruleadapters/adapters/iouring.go b/pkg/rulemanager/ruleadapters/adapters/iouring.go index af8ad2a9a..36ab7563c 100644 --- a/pkg/rulemanager/ruleadapters/adapters/iouring.go +++ b/pkg/rulemanager/ruleadapters/adapters/iouring.go @@ -1,7 +1,7 @@ package adapters import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" iouringsyscall "github.com/iceber/iouring-go/syscall" "github.com/kubescape/node-agent/pkg/ebpf/events" @@ -45,8 +45,8 @@ func (c *IoUringAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedE } failure.SetBaseRuntimeAlert(baseRuntimeAlert) - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ Comm: comm, PID: pid, Uid: iouringEvent.GetUid(), @@ -58,7 +58,7 @@ func (c *IoUringAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedE failure.SetTriggerEvent(iouringEvent) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: iouringEvent.GetPod(), PodLabels: iouringEvent.GetPodLabels(), } diff --git a/pkg/rulemanager/ruleadapters/adapters/kmod.go b/pkg/rulemanager/ruleadapters/adapters/kmod.go index ace37b6cf..583b39c82 100644 --- a/pkg/rulemanager/ruleadapters/adapters/kmod.go +++ b/pkg/rulemanager/ruleadapters/adapters/kmod.go @@ -1,7 +1,7 @@ package adapters import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" "github.com/kubescape/node-agent/pkg/ebpf/events" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -43,8 +43,8 @@ func (c *KmodAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedEven failure.SetBaseRuntimeAlert(baseRuntimeAlert) upperLayer := kmodEvent.GetUpperLayer() - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ Comm: comm, Pcomm: kmodEvent.GetPcomm(), PPID: kmodEvent.GetPpid(), @@ -61,7 +61,7 @@ func (c *KmodAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedEven failure.SetTriggerEvent(kmodEvent) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: kmodEvent.GetPod(), PodLabels: kmodEvent.GetPodLabels(), } diff --git a/pkg/rulemanager/ruleadapters/adapters/network.go b/pkg/rulemanager/ruleadapters/adapters/network.go index 5bd850e57..6c37a49ad 100644 --- a/pkg/rulemanager/ruleadapters/adapters/network.go +++ b/pkg/rulemanager/ruleadapters/adapters/network.go @@ -1,7 +1,7 @@ package adapters import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" "github.com/kubescape/node-agent/pkg/ebpf/events" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -46,8 +46,8 @@ func (c *NetworkAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedE } failure.SetBaseRuntimeAlert(baseRuntimeAlert) - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ Comm: comm, Gid: networkEvent.GetGid(), PID: pid, @@ -59,7 +59,7 @@ func (c *NetworkAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedE failure.SetTriggerEvent(networkEvent) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: networkEvent.GetPod(), PodLabels: networkEvent.GetPodLabels(), } diff --git a/pkg/rulemanager/ruleadapters/adapters/open.go b/pkg/rulemanager/ruleadapters/adapters/open.go index 7b894d376..4dada10cd 100644 --- a/pkg/rulemanager/ruleadapters/adapters/open.go +++ b/pkg/rulemanager/ruleadapters/adapters/open.go @@ -3,7 +3,7 @@ package adapters import ( "path/filepath" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" "github.com/kubescape/node-agent/pkg/ebpf/events" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -46,8 +46,8 @@ func (c *OpenAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedEven } failure.SetBaseRuntimeAlert(baseRuntimeAlert) - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ Comm: comm, Gid: openEvent.GetGid(), PID: pid, @@ -59,9 +59,8 @@ func (c *OpenAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedEven failure.SetTriggerEvent(openEvent) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: openEvent.GetPod(), } failure.SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails) } - diff --git a/pkg/rulemanager/ruleadapters/adapters/procfs.go b/pkg/rulemanager/ruleadapters/adapters/procfs.go index d79f70a9e..26941ab83 100644 --- a/pkg/rulemanager/ruleadapters/adapters/procfs.go +++ b/pkg/rulemanager/ruleadapters/adapters/procfs.go @@ -3,7 +3,7 @@ package adapters import ( "fmt" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" "github.com/kubescape/node-agent/pkg/ebpf/events" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -36,8 +36,8 @@ func (c *ProcfsFailureSetter) SetFailureMetadata(failure types.RuleFailure, enri } failure.SetBaseRuntimeAlert(baseRuntimeAlert) - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ Comm: procfsEvent.Comm, PID: procfsEvent.PID, PPID: procfsEvent.PPID, @@ -49,12 +49,12 @@ func (c *ProcfsFailureSetter) SetFailureMetadata(failure types.RuleFailure, enri } failure.SetRuntimeProcessDetails(runtimeProcessDetails) - ruleAlert := apitypes.RuleAlert{ + ruleAlert := armotypes.RuleAlert{ RuleDescription: fmt.Sprintf("Procfs event detected for process %s (PID: %d)", procfsEvent.Comm, procfsEvent.PID), } failure.SetRuleAlert(ruleAlert) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: procfsEvent.GetPod(), } failure.SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails) diff --git a/pkg/rulemanager/ruleadapters/adapters/ptrace.go b/pkg/rulemanager/ruleadapters/adapters/ptrace.go index e20fa09af..06ab6a2ce 100644 --- a/pkg/rulemanager/ruleadapters/adapters/ptrace.go +++ b/pkg/rulemanager/ruleadapters/adapters/ptrace.go @@ -3,7 +3,7 @@ package adapters import ( "path/filepath" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" "github.com/kubescape/node-agent/pkg/ebpf/events" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -39,8 +39,8 @@ func (c *PtraceAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedEv } failure.SetBaseRuntimeAlert(baseRuntimeAlert) - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ Comm: comm, PPID: ptraceEvent.GetPpid(), PID: pid, @@ -54,10 +54,9 @@ func (c *PtraceAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedEv failure.SetTriggerEvent(ptraceEvent) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: ptraceEvent.GetPod(), PodLabels: ptraceEvent.GetPodLabels(), } failure.SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails) } - diff --git a/pkg/rulemanager/ruleadapters/adapters/randomx.go b/pkg/rulemanager/ruleadapters/adapters/randomx.go index aeb29076a..3ea7b8f2d 100644 --- a/pkg/rulemanager/ruleadapters/adapters/randomx.go +++ b/pkg/rulemanager/ruleadapters/adapters/randomx.go @@ -1,7 +1,7 @@ package adapters import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" "github.com/kubescape/node-agent/pkg/ebpf/events" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -36,8 +36,8 @@ func (c *RandomXAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedE } failure.SetBaseRuntimeAlert(baseRuntimeAlert) - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ Comm: comm, PID: pid, Uid: randomXEvent.GetUid(), @@ -49,10 +49,9 @@ func (c *RandomXAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedE failure.SetTriggerEvent(randomXEvent) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: randomXEvent.GetPod(), PodLabels: randomXEvent.GetPodLabels(), } failure.SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails) } - diff --git a/pkg/rulemanager/ruleadapters/adapters/ssh.go b/pkg/rulemanager/ruleadapters/adapters/ssh.go index c7c5e32d5..2202ecfa5 100644 --- a/pkg/rulemanager/ruleadapters/adapters/ssh.go +++ b/pkg/rulemanager/ruleadapters/adapters/ssh.go @@ -1,7 +1,7 @@ package adapters import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" "github.com/kubescape/node-agent/pkg/ebpf/events" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -46,8 +46,8 @@ func (c *SSHAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedEvent } failure.SetBaseRuntimeAlert(baseRuntimeAlert) - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ Comm: comm, PID: pid, Uid: sshEvent.GetUid(), @@ -59,10 +59,9 @@ func (c *SSHAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedEvent failure.SetTriggerEvent(sshEvent) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: sshEvent.GetPod(), PodLabels: sshEvent.GetPodLabels(), } failure.SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails) } - diff --git a/pkg/rulemanager/ruleadapters/adapters/symlink.go b/pkg/rulemanager/ruleadapters/adapters/symlink.go index 977aac350..2be645457 100644 --- a/pkg/rulemanager/ruleadapters/adapters/symlink.go +++ b/pkg/rulemanager/ruleadapters/adapters/symlink.go @@ -3,7 +3,7 @@ package adapters import ( "path/filepath" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" "github.com/kubescape/node-agent/pkg/ebpf/events" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -48,8 +48,8 @@ func (c *SymlinkAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedE failure.SetBaseRuntimeAlert(baseRuntimeAlert) upperLayer := symlinkEvent.GetUpperLayer() - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ Comm: comm, PPID: symlinkEvent.GetPpid(), PID: pid, @@ -65,10 +65,9 @@ func (c *SymlinkAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedE failure.SetTriggerEvent(symlinkEvent) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: symlinkEvent.GetPod(), PodLabels: symlinkEvent.GetPodLabels(), } failure.SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails) } - diff --git a/pkg/rulemanager/ruleadapters/adapters/syscall.go b/pkg/rulemanager/ruleadapters/adapters/syscall.go index 9da32cbec..4c868b3b7 100644 --- a/pkg/rulemanager/ruleadapters/adapters/syscall.go +++ b/pkg/rulemanager/ruleadapters/adapters/syscall.go @@ -1,7 +1,7 @@ package adapters import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" "github.com/kubescape/node-agent/pkg/ebpf/events" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -36,8 +36,8 @@ func (c *SyscallAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedE failure.SetBaseRuntimeAlert(baseRuntimeAlert) // FIXME: find a tracer that provides these required details - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ Comm: comm, //Gid: syscallEvent.GetGid(), PID: syscallEvent.GetPID(), @@ -49,10 +49,9 @@ func (c *SyscallAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedE failure.SetTriggerEvent(syscallEvent) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: syscallEvent.GetPod(), PodLabels: syscallEvent.GetPodLabels(), } failure.SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails) } - diff --git a/pkg/rulemanager/ruleadapters/adapters/unshare.go b/pkg/rulemanager/ruleadapters/adapters/unshare.go index 1ca3bd884..5d3b1af03 100644 --- a/pkg/rulemanager/ruleadapters/adapters/unshare.go +++ b/pkg/rulemanager/ruleadapters/adapters/unshare.go @@ -1,7 +1,7 @@ package adapters import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/armoapi-go/armotypes/common" "github.com/kubescape/node-agent/pkg/ebpf/events" "github.com/kubescape/node-agent/pkg/rulemanager/types" @@ -40,8 +40,8 @@ func (c *UnshareAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedE } failure.SetBaseRuntimeAlert(baseRuntimeAlert) - runtimeProcessDetails := apitypes.ProcessTree{ - ProcessTree: apitypes.Process{ + runtimeProcessDetails := armotypes.ProcessTree{ + ProcessTree: armotypes.Process{ Comm: comm, Pcomm: unshareEvent.GetPcomm(), PPID: unshareEvent.GetPpid(), @@ -58,10 +58,9 @@ func (c *UnshareAdapter) SetFailureMetadata(failure types.RuleFailure, enrichedE failure.SetTriggerEvent(unshareEvent) - runtimeAlertK8sDetails := apitypes.RuntimeAlertK8sDetails{ + runtimeAlertK8sDetails := armotypes.RuntimeAlertK8sDetails{ PodName: unshareEvent.GetPod(), PodLabels: unshareEvent.GetPodLabels(), } failure.SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails) } - diff --git a/pkg/rulemanager/ruleadapters/creator.go b/pkg/rulemanager/ruleadapters/creator.go index 26f6c7e67..6682d9f62 100644 --- a/pkg/rulemanager/ruleadapters/creator.go +++ b/pkg/rulemanager/ruleadapters/creator.go @@ -9,7 +9,6 @@ import ( "time" "github.com/armosec/armoapi-go/armotypes" - apitypes "github.com/armosec/armoapi-go/armotypes" "github.com/dustin/go-humanize" "github.com/goradd/maps" "github.com/hashicorp/golang-lru/v2/expirable" @@ -44,10 +43,10 @@ type RuleFailureCreator struct { dnsManager dnsmanager.DNSResolver enricher types.Enricher hashCache *expirable.LRU[string, *FileHashCache] - alertPlatform apitypes.AlertSourcePlatform + alertPlatform armotypes.AlertSourcePlatform } -func NewRuleFailureCreator(enricher types.Enricher, dnsManager dnsmanager.DNSResolver, adapterFactory *EventRuleAdapterFactory, alertPlatform apitypes.AlertSourcePlatform) *RuleFailureCreator { +func NewRuleFailureCreator(enricher types.Enricher, dnsManager dnsmanager.DNSResolver, adapterFactory *EventRuleAdapterFactory, alertPlatform armotypes.AlertSourcePlatform) *RuleFailureCreator { hashCache := expirable.NewLRU[string, *FileHashCache](hashCacheMaxSize, nil, hashCacheTTL) return &RuleFailureCreator{ adapterFactory: adapterFactory, @@ -66,7 +65,7 @@ func (r *RuleFailureCreator) CreateRuleFailure(rule typesv1.Rule, enrichedEvent } ruleFailure := &types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ UniqueID: uniqueID, AlertName: rule.Name, Severity: rule.Severity, @@ -77,7 +76,7 @@ func (r *RuleFailureCreator) CreateRuleFailure(rule typesv1.Rule, enrichedEvent Timestamp: enrichedEvent.Timestamp, InfectedPID: enrichedEvent.ProcessTree.PID, }, - RuleAlert: apitypes.RuleAlert{ + RuleAlert: armotypes.RuleAlert{ RuleDescription: message, }, RuleID: rule.ID, @@ -95,7 +94,7 @@ func (r *RuleFailureCreator) CreateRuleFailure(rule typesv1.Rule, enrichedEvent r.enrichRuleFailure(ruleFailure) if enrichedEvent.ProcessTree.PID != 0 { - ruleFailure.SetRuntimeProcessDetails(apitypes.ProcessTree{ + ruleFailure.SetRuntimeProcessDetails(armotypes.ProcessTree{ ProcessTree: enrichedEvent.ProcessTree, ContainerID: enrichedEvent.ContainerID, }) @@ -120,6 +119,11 @@ func (r *RuleFailureCreator) setProfileMetadata(rule typesv1.Rule, ruleFailure * return } + // Skip profile metadata for host containers - they don't have profiles + if triggerEvent.GetContainerID() == armotypes.HostContainerID { + return + } + var profileType armotypes.ProfileType baseRuntimeAlert := ruleFailure.GetBaseRuntimeAlert() profileRequirment := rule.ProfileDependency @@ -339,7 +343,9 @@ func (r *RuleFailureCreator) setContextSpecificFields(ruleFailure *types.Generic case contextdetection.Host: ruleFailure.SetSourceContext(contextdetection.Host) - // For Host context, use NodeName to store the hostname + if k8sDetails.ContainerID == "" { + k8sDetails.ContainerID = enrichedEvent.ContainerID + } hostname, err := os.Hostname() if err == nil { k8sDetails.NodeName = hostname diff --git a/pkg/rulemanager/rulecooldown/rulecooldown_test.go b/pkg/rulemanager/rulecooldown/rulecooldown_test.go index ded2dd121..3782f45e9 100644 --- a/pkg/rulemanager/rulecooldown/rulecooldown_test.go +++ b/pkg/rulemanager/rulecooldown/rulecooldown_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/kubescape/node-agent/pkg/rulemanager/types" "github.com/stretchr/testify/assert" ) @@ -30,10 +30,10 @@ func TestShouldCooldown(t *testing.T) { MaxSize: 1000, }, ruleFailure: &types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ UniqueID: "test-alert-1", }, - RuntimeProcessDetails: apitypes.ProcessTree{ + RuntimeProcessDetails: armotypes.ProcessTree{ ContainerID: "test-container-1", }, }, @@ -51,10 +51,10 @@ func TestShouldCooldown(t *testing.T) { MaxSize: 1000, }, ruleFailure: &types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ UniqueID: "test-alert-2", }, - RuntimeProcessDetails: apitypes.ProcessTree{ + RuntimeProcessDetails: armotypes.ProcessTree{ ContainerID: "test-container-2", }, }, @@ -72,13 +72,13 @@ func TestShouldCooldown(t *testing.T) { MaxSize: 1000, }, ruleFailure: &types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ UniqueID: "test-alert-3", - ProfileMetadata: &apitypes.ProfileMetadata{ + ProfileMetadata: &armotypes.ProfileMetadata{ FailOnProfile: true, }, }, - RuntimeProcessDetails: apitypes.ProcessTree{ + RuntimeProcessDetails: armotypes.ProcessTree{ ContainerID: "test-container-3", }, }, @@ -96,10 +96,10 @@ func TestShouldCooldown(t *testing.T) { MaxSize: 1000, }, ruleFailure: &types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ UniqueID: "test-alert-4", }, - RuntimeProcessDetails: apitypes.ProcessTree{ + RuntimeProcessDetails: armotypes.ProcessTree{ ContainerID: "test-container-4", }, }, @@ -118,13 +118,13 @@ func TestShouldCooldown(t *testing.T) { MaxSize: 1000, }, ruleFailure: &types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ UniqueID: "test-alert-3", - ProfileMetadata: &apitypes.ProfileMetadata{ + ProfileMetadata: &armotypes.ProfileMetadata{ FailOnProfile: true, }, }, - RuntimeProcessDetails: apitypes.ProcessTree{ + RuntimeProcessDetails: armotypes.ProcessTree{ ContainerID: "test-container-3", }, }, @@ -168,10 +168,10 @@ func TestShouldCooldownImmediate(t *testing.T) { }) ruleFailure := &types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ UniqueID: "test-alert-immediate", }, - RuntimeProcessDetails: apitypes.ProcessTree{ + RuntimeProcessDetails: armotypes.ProcessTree{ ContainerID: "test-container-immediate", }, } @@ -196,13 +196,13 @@ func TestShouldCooldownOnProfileFailure(t *testing.T) { }) ruleFailure := &types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ UniqueID: "test-alert-profile", - ProfileMetadata: &apitypes.ProfileMetadata{ + ProfileMetadata: &armotypes.ProfileMetadata{ FailOnProfile: true, }, }, - RuntimeProcessDetails: apitypes.ProcessTree{ + RuntimeProcessDetails: armotypes.ProcessTree{ ContainerID: "test-container-profile", }, } @@ -233,20 +233,20 @@ func TestShouldCooldownDifferentKeys(t *testing.T) { // First rule failure ruleFailure1 := &types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ UniqueID: "test-alert-1", }, - RuntimeProcessDetails: apitypes.ProcessTree{ + RuntimeProcessDetails: armotypes.ProcessTree{ ContainerID: "test-container-1", }, } // Second rule failure with different key ruleFailure2 := &types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ UniqueID: "test-alert-2", }, - RuntimeProcessDetails: apitypes.ProcessTree{ + RuntimeProcessDetails: armotypes.ProcessTree{ ContainerID: "test-container-1", // Same container, different alert }, } @@ -284,10 +284,10 @@ func TestShouldCooldownMaxSize(t *testing.T) { // Fill up the cache for i := 0; i < maxSize; i++ { failure := &types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ UniqueID: fmt.Sprintf("test-alert-%d", i), }, - RuntimeProcessDetails: apitypes.ProcessTree{ + RuntimeProcessDetails: armotypes.ProcessTree{ ContainerID: fmt.Sprintf("test-container-%d", i), }, } @@ -296,10 +296,10 @@ func TestShouldCooldownMaxSize(t *testing.T) { // Add one more to trigger eviction newFailure := &types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ UniqueID: "test-alert-new", }, - RuntimeProcessDetails: apitypes.ProcessTree{ + RuntimeProcessDetails: armotypes.ProcessTree{ ContainerID: "test-container-new", }, } @@ -311,10 +311,10 @@ func TestShouldCooldownMaxSize(t *testing.T) { // Verify the oldest entry was evicted by trying to access it oldFailure := &types.GenericRuleFailure{ - BaseRuntimeAlert: apitypes.BaseRuntimeAlert{ + BaseRuntimeAlert: armotypes.BaseRuntimeAlert{ UniqueID: "test-alert-0", }, - RuntimeProcessDetails: apitypes.ProcessTree{ + RuntimeProcessDetails: armotypes.ProcessTree{ ContainerID: "test-container-0", }, } diff --git a/pkg/rulemanager/rulecreator/ruleengine_interface.go b/pkg/rulemanager/rulecreator/ruleengine_interface.go index fe3efeeba..75f8bc5cb 100644 --- a/pkg/rulemanager/rulecreator/ruleengine_interface.go +++ b/pkg/rulemanager/rulecreator/ruleengine_interface.go @@ -4,16 +4,16 @@ import ( typesv1 "github.com/kubescape/node-agent/pkg/rulemanager/types/v1" "github.com/kubescape/node-agent/pkg/utils" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" ) // ProfileRequirement indicates how a rule uses profiles type ProfileRequirement struct { // ProfileDependency indicates if the rule requires a profile - ProfileDependency apitypes.ProfileDependency + ProfileDependency armotypes.ProfileDependency // ProfileType indicates what type of profile is needed (Application, Network, etc) - ProfileType apitypes.ProfileType + ProfileType armotypes.ProfileType } // RuleCreator is an interface for creating rules by tags, IDs, and names diff --git a/pkg/rulemanager/types/failure.go b/pkg/rulemanager/types/failure.go index 638dabfd1..9c632ec19 100644 --- a/pkg/rulemanager/types/failure.go +++ b/pkg/rulemanager/types/failure.go @@ -1,7 +1,7 @@ package types import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/armosec/utils-k8s-go/wlid" "github.com/kubescape/node-agent/pkg/contextdetection" "github.com/kubescape/node-agent/pkg/utils" @@ -13,17 +13,17 @@ const ( ) type GenericRuleFailure struct { - BaseRuntimeAlert apitypes.BaseRuntimeAlert - AlertType apitypes.AlertType - AlertPlatform apitypes.AlertSourcePlatform - RuntimeProcessDetails apitypes.ProcessTree + BaseRuntimeAlert armotypes.BaseRuntimeAlert + AlertType armotypes.AlertType + AlertPlatform armotypes.AlertSourcePlatform + RuntimeProcessDetails armotypes.ProcessTree TriggerEvent utils.EnrichEvent - RuleAlert apitypes.RuleAlert - RuntimeAlertK8sDetails apitypes.RuntimeAlertK8sDetails - RuntimeAlertECSDetails apitypes.RuntimeAlertECSDetails + RuleAlert armotypes.RuleAlert + RuntimeAlertK8sDetails armotypes.RuntimeAlertK8sDetails + RuntimeAlertECSDetails armotypes.RuntimeAlertECSDetails RuleID string CloudServices []string - HttpRuleAlert apitypes.HttpRuleAlert + HttpRuleAlert armotypes.HttpRuleAlert Extra interface{} IsTriggerAlert bool SourceContext contextdetection.EventSourceContext @@ -31,27 +31,27 @@ type GenericRuleFailure struct { type RuleFailure interface { // Get Base Runtime Alert - GetBaseRuntimeAlert() apitypes.BaseRuntimeAlert + GetBaseRuntimeAlert() armotypes.BaseRuntimeAlert // Get Alert Type - GetAlertType() apitypes.AlertType + GetAlertType() armotypes.AlertType // Get Runtime Process Details - GetRuntimeProcessDetails() apitypes.ProcessTree + GetRuntimeProcessDetails() armotypes.ProcessTree // Get Trigger Event GetTriggerEvent() utils.EnrichEvent // Get Rule Description - GetRuleAlert() apitypes.RuleAlert + GetRuleAlert() armotypes.RuleAlert // Get K8s Runtime Details - GetRuntimeAlertK8sDetails() apitypes.RuntimeAlertK8sDetails + GetRuntimeAlertK8sDetails() armotypes.RuntimeAlertK8sDetails // Get ECS Runtime Details - GetRuntimeAlertEcsDetails() apitypes.RuntimeAlertECSDetails + GetRuntimeAlertEcsDetails() armotypes.RuntimeAlertECSDetails // Get Rule ID GetRuleId() string // Get Cloud Services GetCloudServices() []string // Get Http Details - GetHttpRuleAlert() apitypes.HttpRuleAlert + GetHttpRuleAlert() armotypes.HttpRuleAlert // Get Alert Platform - GetAlertPlatform() apitypes.AlertSourcePlatform + GetAlertPlatform() armotypes.AlertSourcePlatform // Get Extra GetExtra() interface{} // Get Source Context @@ -60,23 +60,23 @@ type RuleFailure interface { // Set Workload Details SetWorkloadDetails(workloadDetails string) // Set Base Runtime Alert - SetBaseRuntimeAlert(baseRuntimeAlert apitypes.BaseRuntimeAlert) + SetBaseRuntimeAlert(baseRuntimeAlert armotypes.BaseRuntimeAlert) // Set Runtime Process Details - SetRuntimeProcessDetails(runtimeProcessDetails apitypes.ProcessTree) + SetRuntimeProcessDetails(runtimeProcessDetails armotypes.ProcessTree) // Set Trigger Event SetTriggerEvent(triggerEvent utils.EnrichEvent) // Set Rule Description - SetRuleAlert(ruleAlert apitypes.RuleAlert) + SetRuleAlert(ruleAlert armotypes.RuleAlert) // Set K8s Runtime Details - SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails apitypes.RuntimeAlertK8sDetails) + SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails armotypes.RuntimeAlertK8sDetails) // Set ECS Runtime Details - SetRuntimeAlertEcsDetails(runtimeAlertEcsDetails apitypes.RuntimeAlertECSDetails) + SetRuntimeAlertEcsDetails(runtimeAlertEcsDetails armotypes.RuntimeAlertECSDetails) // Set Cloud Services SetCloudServices(cloudServices []string) // Set Alert Platform - SetAlertPlatform(alertPlatform apitypes.AlertSourcePlatform) + SetAlertPlatform(alertPlatform armotypes.AlertSourcePlatform) // Set Http Rule Alert - SetHttpRuleAlert(httpRuleAlert apitypes.HttpRuleAlert) + SetHttpRuleAlert(httpRuleAlert armotypes.HttpRuleAlert) // Set Extra SetExtra(extra interface{}) // Get IsTriggerAlert @@ -87,11 +87,11 @@ type RuleFailure interface { SetSourceContext(sourceContext contextdetection.EventSourceContext) } -func (rule *GenericRuleFailure) GetBaseRuntimeAlert() apitypes.BaseRuntimeAlert { +func (rule *GenericRuleFailure) GetBaseRuntimeAlert() armotypes.BaseRuntimeAlert { return rule.BaseRuntimeAlert } -func (rule *GenericRuleFailure) GetRuntimeProcessDetails() apitypes.ProcessTree { +func (rule *GenericRuleFailure) GetRuntimeProcessDetails() armotypes.ProcessTree { return rule.RuntimeProcessDetails } @@ -99,15 +99,15 @@ func (rule *GenericRuleFailure) GetTriggerEvent() utils.EnrichEvent { return rule.TriggerEvent } -func (rule *GenericRuleFailure) GetRuleAlert() apitypes.RuleAlert { +func (rule *GenericRuleFailure) GetRuleAlert() armotypes.RuleAlert { return rule.RuleAlert } -func (rule *GenericRuleFailure) GetRuntimeAlertK8sDetails() apitypes.RuntimeAlertK8sDetails { +func (rule *GenericRuleFailure) GetRuntimeAlertK8sDetails() armotypes.RuntimeAlertK8sDetails { return rule.RuntimeAlertK8sDetails } -func (rule *GenericRuleFailure) GetRuntimeAlertEcsDetails() apitypes.RuntimeAlertECSDetails { +func (rule *GenericRuleFailure) GetRuntimeAlertEcsDetails() armotypes.RuntimeAlertECSDetails { return rule.RuntimeAlertECSDetails } @@ -123,15 +123,15 @@ func (rule *GenericRuleFailure) GetCloudServices() []string { return rule.CloudServices } -func (rule *GenericRuleFailure) GetHttpRuleAlert() apitypes.HttpRuleAlert { +func (rule *GenericRuleFailure) GetHttpRuleAlert() armotypes.HttpRuleAlert { return rule.HttpRuleAlert } -func (rule *GenericRuleFailure) GetAlertType() apitypes.AlertType { +func (rule *GenericRuleFailure) GetAlertType() armotypes.AlertType { return rule.AlertType } -func (rule *GenericRuleFailure) GetAlertPlatform() apitypes.AlertSourcePlatform { +func (rule *GenericRuleFailure) GetAlertPlatform() armotypes.AlertSourcePlatform { return rule.AlertPlatform } @@ -139,11 +139,11 @@ func (rule *GenericRuleFailure) SetCloudServices(cloudServices []string) { rule.CloudServices = cloudServices } -func (rule *GenericRuleFailure) SetBaseRuntimeAlert(baseRuntimeAlert apitypes.BaseRuntimeAlert) { +func (rule *GenericRuleFailure) SetBaseRuntimeAlert(baseRuntimeAlert armotypes.BaseRuntimeAlert) { rule.BaseRuntimeAlert = baseRuntimeAlert } -func (rule *GenericRuleFailure) SetRuntimeProcessDetails(runtimeProcessDetails apitypes.ProcessTree) { +func (rule *GenericRuleFailure) SetRuntimeProcessDetails(runtimeProcessDetails armotypes.ProcessTree) { rule.RuntimeProcessDetails = runtimeProcessDetails } @@ -151,15 +151,15 @@ func (rule *GenericRuleFailure) SetTriggerEvent(triggerEvent utils.EnrichEvent) rule.TriggerEvent = triggerEvent } -func (rule *GenericRuleFailure) SetRuleAlert(ruleAlert apitypes.RuleAlert) { +func (rule *GenericRuleFailure) SetRuleAlert(ruleAlert armotypes.RuleAlert) { rule.RuleAlert = ruleAlert } -func (rule *GenericRuleFailure) SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails apitypes.RuntimeAlertK8sDetails) { +func (rule *GenericRuleFailure) SetRuntimeAlertK8sDetails(runtimeAlertK8sDetails armotypes.RuntimeAlertK8sDetails) { rule.RuntimeAlertK8sDetails = runtimeAlertK8sDetails } -func (rule *GenericRuleFailure) SetRuntimeAlertEcsDetails(runtimeAlertEcsDetails apitypes.RuntimeAlertECSDetails) { +func (rule *GenericRuleFailure) SetRuntimeAlertEcsDetails(runtimeAlertEcsDetails armotypes.RuntimeAlertECSDetails) { rule.RuntimeAlertECSDetails = runtimeAlertEcsDetails } @@ -174,12 +174,12 @@ func (rule *GenericRuleFailure) SetWorkloadDetails(workloadDetails string) { rule.RuntimeAlertK8sDetails.WorkloadName = wlid.GetNameFromWlid(workloadDetails) } -func (rule *GenericRuleFailure) SetAlertPlatform(alertPlatform apitypes.AlertSourcePlatform) { +func (rule *GenericRuleFailure) SetAlertPlatform(alertPlatform armotypes.AlertSourcePlatform) { rule.AlertPlatform = alertPlatform } -func (rule *GenericRuleFailure) SetHttpRuleAlert(httpRuleAlert apitypes.HttpRuleAlert) { - rule.AlertType = apitypes.AlertTypeHttpRule +func (rule *GenericRuleFailure) SetHttpRuleAlert(httpRuleAlert armotypes.HttpRuleAlert) { + rule.AlertType = armotypes.AlertTypeHttpRule rule.HttpRuleAlert = httpRuleAlert } diff --git a/pkg/rulemanager/types/v1/types.go b/pkg/rulemanager/types/v1/types.go index 120a162a0..e91f28238 100644 --- a/pkg/rulemanager/types/v1/types.go +++ b/pkg/rulemanager/types/v1/types.go @@ -1,7 +1,7 @@ package types import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/kubescape/node-agent/pkg/utils" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -18,20 +18,20 @@ type RulesSpec struct { } type Rule struct { - Enabled bool `json:"enabled" yaml:"enabled"` - ID string `json:"id" yaml:"id"` - Name string `json:"name" yaml:"name"` - Description string `json:"description" yaml:"description"` - Expressions RuleExpressions `json:"expressions" yaml:"expressions"` - ProfileDependency apitypes.ProfileDependency `json:"profileDependency" yaml:"profileDependency"` - Severity int `json:"severity" yaml:"severity"` - SupportPolicy bool `json:"supportPolicy" yaml:"supportPolicy"` - Tags []string `json:"tags" yaml:"tags"` - State map[string]any `json:"state,omitempty" yaml:"state,omitempty"` - AgentVersionRequirement string `json:"agentVersionRequirement" yaml:"agentVersionRequirement"` - IsTriggerAlert bool `json:"isTriggerAlert" yaml:"isTriggerAlert"` - MitreTactic string `json:"mitreTactic" yaml:"mitreTactic"` - MitreTechnique string `json:"mitreTechnique" yaml:"mitreTechnique"` + Enabled bool `json:"enabled" yaml:"enabled"` + ID string `json:"id" yaml:"id"` + Name string `json:"name" yaml:"name"` + Description string `json:"description" yaml:"description"` + Expressions RuleExpressions `json:"expressions" yaml:"expressions"` + ProfileDependency armotypes.ProfileDependency `json:"profileDependency" yaml:"profileDependency"` + Severity int `json:"severity" yaml:"severity"` + SupportPolicy bool `json:"supportPolicy" yaml:"supportPolicy"` + Tags []string `json:"tags" yaml:"tags"` + State map[string]any `json:"state,omitempty" yaml:"state,omitempty"` + AgentVersionRequirement string `json:"agentVersionRequirement" yaml:"agentVersionRequirement"` + IsTriggerAlert bool `json:"isTriggerAlert" yaml:"isTriggerAlert"` + MitreTactic string `json:"mitreTactic" yaml:"mitreTactic"` + MitreTechnique string `json:"mitreTechnique" yaml:"mitreTechnique"` } type RuleExpressions struct { diff --git a/pkg/sbommanager/v1/sbom_manager.go b/pkg/sbommanager/v1/sbom_manager.go index 78c12cbe8..26f266cc5 100644 --- a/pkg/sbommanager/v1/sbom_manager.go +++ b/pkg/sbommanager/v1/sbom_manager.go @@ -154,6 +154,17 @@ func (s *SbomManager) ContainerCallback(notif containercollection.PubSubEvent) { if notif.Type != containercollection.EventTypeAddContainer { return } + if utils.IsHostContainer(notif.Container) { + return + } + if notif.Container.Runtime.ContainerImageName == "" { + logger.L().Ctx(s.ctx).Debug("SbomManager - skipping container with empty image name", + helpers.String("namespace", notif.Container.K8s.Namespace), + helpers.String("pod", notif.Container.K8s.PodName), + helpers.String("container", notif.Container.K8s.ContainerName), + helpers.String("container ID", notif.Container.Runtime.ContainerID)) + return + } // check if the container should be ignored if s.cfg.IgnoreContainer(notif.Container.K8s.Namespace, notif.Container.K8s.PodName, notif.Container.K8s.PodLabels) { return diff --git a/pkg/utils/container.go b/pkg/utils/container.go new file mode 100644 index 000000000..03c967f1c --- /dev/null +++ b/pkg/utils/container.go @@ -0,0 +1,13 @@ +package utils + +import ( + "github.com/armosec/armoapi-go/armotypes" + containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" +) + +func IsHostContainer(container *containercollection.Container) bool { + if container == nil { + return false + } + return container.Runtime.ContainerPID == 1 || container.Runtime.ContainerID == armotypes.HostContainerID +} diff --git a/pkg/utils/process.go b/pkg/utils/process.go index e96b34cff..0de7bfd87 100644 --- a/pkg/utils/process.go +++ b/pkg/utils/process.go @@ -3,7 +3,7 @@ package utils import ( "strings" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" "github.com/kubescape/go-logger" "github.com/kubescape/go-logger/helpers" "github.com/prometheus/procfs" @@ -78,29 +78,29 @@ func GetProcessEnv(pid int) (map[string]string, error) { // Creates a process tree from a process. // The process tree will be built from scanning the /proc filesystem. -func CreateProcessTree(process *apitypes.Process, shimPid uint32) (apitypes.Process, error) { +func CreateProcessTree(process *armotypes.Process, shimPid uint32) (armotypes.Process, error) { pfs, err := procfs.NewFS("/proc") if err != nil { - return apitypes.Process{}, err + return armotypes.Process{}, err } proc, err := pfs.Proc(int(process.PID)) if err != nil { logger.L().Debug("Failed to get process", helpers.String("error", err.Error())) - return apitypes.Process{}, err + return armotypes.Process{}, err } // build the process tree treeRoot, err := buildProcessTree(proc, &pfs, shimPid, nil) if err != nil { - return apitypes.Process{}, err + return armotypes.Process{}, err } return treeRoot, nil } // Recursively build the process tree. -func buildProcessTree(proc procfs.Proc, procfs *procfs.FS, shimPid uint32, processTree *apitypes.Process) (apitypes.Process, error) { +func buildProcessTree(proc procfs.Proc, procfs *procfs.FS, shimPid uint32, processTree *armotypes.Process) (armotypes.Process, error) { // If the current process is the shim, return the process tree. if proc.PID == int(shimPid) { return *processTree.DeepCopy(), nil @@ -108,25 +108,25 @@ func buildProcessTree(proc procfs.Proc, procfs *procfs.FS, shimPid uint32, proce stat, err := proc.Stat() if err != nil { - return apitypes.Process{}, err + return armotypes.Process{}, err } parent, err := procfs.Proc(stat.PPID) if err != nil { - return apitypes.Process{}, err + return armotypes.Process{}, err } var uid, gid uint32 status, err := proc.NewStatus() if err != nil { - return apitypes.Process{}, err + return armotypes.Process{}, err } else { uid = uint32(status.UIDs[1]) gid = uint32(status.GIDs[1]) } // Make the parent process the parent of the current process (move the current process to the parent's children). - currentProcess := apitypes.Process{ + currentProcess := armotypes.Process{ Comm: stat.Comm, Path: func() string { path, err := proc.Executable() @@ -166,9 +166,9 @@ func buildProcessTree(proc procfs.Proc, procfs *procfs.FS, shimPid uint32, proce if processTree != nil { if currentProcess.ChildrenMap == nil { - currentProcess.ChildrenMap = make(map[apitypes.CommPID]*apitypes.Process) + currentProcess.ChildrenMap = make(map[armotypes.CommPID]*armotypes.Process) } - currentProcess.ChildrenMap[apitypes.CommPID{PID: processTree.PID}] = processTree + currentProcess.ChildrenMap[armotypes.CommPID{PID: processTree.PID}] = processTree } return buildProcessTree(parent, procfs, shimPid, ¤tProcess) @@ -212,7 +212,7 @@ func GetCommFromPid(pid uint32) (string, error) { return comm, nil } -func GetProcessFromProcessTree(process *apitypes.Process, pid uint32) *apitypes.Process { +func GetProcessFromProcessTree(process *armotypes.Process, pid uint32) *armotypes.Process { if process.PID == pid { return process } @@ -229,7 +229,7 @@ func GetProcessFromProcessTree(process *apitypes.Process, pid uint32) *apitypes. // CalculateProcessTreeDepth calculates the maximum depth of a process tree. // The depth is the maximum number of levels from the root process to any leaf process. // A single process (no children) has a depth of 1. -func CalculateProcessTreeDepth(process *apitypes.Process) int { +func CalculateProcessTreeDepth(process *armotypes.Process) int { if process == nil { return 0 } diff --git a/pkg/utils/process_test.go b/pkg/utils/process_test.go index d8c6a0f16..2c1586d08 100644 --- a/pkg/utils/process_test.go +++ b/pkg/utils/process_test.go @@ -3,13 +3,13 @@ package utils import ( "testing" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" ) func TestCalculateProcessTreeDepth(t *testing.T) { tests := []struct { name string - process *apitypes.Process + process *armotypes.Process expected int }{ { @@ -19,30 +19,30 @@ func TestCalculateProcessTreeDepth(t *testing.T) { }, { name: "single process with no children", - process: &apitypes.Process{ + process: &armotypes.Process{ PID: 1, Comm: "init", - ChildrenMap: make(map[apitypes.CommPID]*apitypes.Process), + ChildrenMap: make(map[armotypes.CommPID]*armotypes.Process), }, expected: 1, }, { name: "process with one level of children", - process: &apitypes.Process{ + process: &armotypes.Process{ PID: 1, Comm: "init", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "child1", PID: 2}: { PID: 2, Comm: "child1", PPID: 1, - ChildrenMap: make(map[apitypes.CommPID]*apitypes.Process), + ChildrenMap: make(map[armotypes.CommPID]*armotypes.Process), }, {Comm: "child2", PID: 3}: { PID: 3, Comm: "child2", PPID: 1, - ChildrenMap: make(map[apitypes.CommPID]*apitypes.Process), + ChildrenMap: make(map[armotypes.CommPID]*armotypes.Process), }, }, }, @@ -50,20 +50,20 @@ func TestCalculateProcessTreeDepth(t *testing.T) { }, { name: "process with multiple levels", - process: &apitypes.Process{ + process: &armotypes.Process{ PID: 1, Comm: "init", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "child1", PID: 2}: { PID: 2, Comm: "child1", PPID: 1, - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "grandchild1", PID: 4}: { PID: 4, Comm: "grandchild1", PPID: 2, - ChildrenMap: make(map[apitypes.CommPID]*apitypes.Process), + ChildrenMap: make(map[armotypes.CommPID]*armotypes.Process), }, }, }, @@ -71,7 +71,7 @@ func TestCalculateProcessTreeDepth(t *testing.T) { PID: 3, Comm: "child2", PPID: 1, - ChildrenMap: make(map[apitypes.CommPID]*apitypes.Process), + ChildrenMap: make(map[armotypes.CommPID]*armotypes.Process), }, }, }, @@ -79,30 +79,30 @@ func TestCalculateProcessTreeDepth(t *testing.T) { }, { name: "process with deep nesting", - process: &apitypes.Process{ + process: &armotypes.Process{ PID: 1, Comm: "root", - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "level1", PID: 2}: { PID: 2, Comm: "level1", PPID: 1, - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "level2", PID: 3}: { PID: 3, Comm: "level2", PPID: 2, - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "level3", PID: 4}: { PID: 4, Comm: "level3", PPID: 3, - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {Comm: "level4", PID: 5}: { PID: 5, Comm: "level4", PPID: 4, - ChildrenMap: make(map[apitypes.CommPID]*apitypes.Process), + ChildrenMap: make(map[armotypes.CommPID]*armotypes.Process), }, }, }, diff --git a/pkg/utils/processtree_merge.go b/pkg/utils/processtree_merge.go index 4871aff6a..1418a2517 100644 --- a/pkg/utils/processtree_merge.go +++ b/pkg/utils/processtree_merge.go @@ -1,18 +1,18 @@ package utils import ( - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" ) // FlattenChainToList converts a chain-structured process tree into an ordered list (root-first) // A chain is a single path from container init to the offending process // This is optimized for the common case where each alert provides one linear path -func FlattenChainToList(root *apitypes.Process) []*apitypes.Process { +func FlattenChainToList(root *armotypes.Process) []*armotypes.Process { if root == nil { return nil } - result := make([]*apitypes.Process, 0, 10) // Typical chain length: container init -> parent -> ... -> offender + result := make([]*armotypes.Process, 0, 10) // Typical chain length: container init -> parent -> ... -> offender current := root for current != nil { @@ -25,7 +25,7 @@ func FlattenChainToList(root *apitypes.Process) []*apitypes.Process { } // Get the single child in the chain - var child *apitypes.Process + var child *armotypes.Process for _, c := range current.ChildrenMap { child = c break // Only one child in a chain @@ -38,12 +38,12 @@ func FlattenChainToList(root *apitypes.Process) []*apitypes.Process { // CopyProcess creates a deep copy of a process node (without children) // Children map is initialized empty so the caller can rebuild the tree structure -func CopyProcess(src *apitypes.Process) *apitypes.Process { +func CopyProcess(src *armotypes.Process) *armotypes.Process { if src == nil { return nil } - return &apitypes.Process{ + return &armotypes.Process{ PID: src.PID, PPID: src.PPID, Comm: src.Comm, @@ -53,14 +53,14 @@ func CopyProcess(src *apitypes.Process) *apitypes.Process { Cwd: src.Cwd, Gid: copyUint32Ptr(src.Gid), Uid: copyUint32Ptr(src.Uid), - ChildrenMap: make(map[apitypes.CommPID]*apitypes.Process), + ChildrenMap: make(map[armotypes.CommPID]*armotypes.Process), } } // EnrichProcess updates target with non-empty fields from source // This is used when merging process information from multiple alerts // Only overwrites fields that are empty in target but present in source -func EnrichProcess(target *apitypes.Process, source *apitypes.Process) { +func EnrichProcess(target *armotypes.Process, source *armotypes.Process) { if target == nil || source == nil { return } diff --git a/pkg/utils/utils_test.go b/pkg/utils/utils_test.go index 77e64fef7..18e4abf63 100644 --- a/pkg/utils/utils_test.go +++ b/pkg/utils/utils_test.go @@ -4,7 +4,7 @@ import ( "reflect" "testing" - apitypes "github.com/armosec/armoapi-go/armotypes" + "github.com/armosec/armoapi-go/armotypes" ) func TestCalculateSHA256FileExecHash(t *testing.T) { @@ -105,20 +105,20 @@ func TestCreateK8sContainerID(t *testing.T) { func TestGetProcessFromProcessTree(t *testing.T) { type args struct { - process *apitypes.Process + process *armotypes.Process pid uint32 } tests := []struct { name string args args - want *apitypes.Process + want *armotypes.Process }{ { name: "Test Case 1: Process found in tree", args: args{ - process: &apitypes.Process{ + process: &armotypes.Process{ PID: 1, - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {PID: 2}: { PID: 2, }, @@ -129,16 +129,16 @@ func TestGetProcessFromProcessTree(t *testing.T) { }, pid: 2, }, - want: &apitypes.Process{ + want: &armotypes.Process{ PID: 2, }, }, { name: "Test Case 2: Process not found in tree", args: args{ - process: &apitypes.Process{ + process: &armotypes.Process{ PID: 1, - ChildrenMap: map[apitypes.CommPID]*apitypes.Process{ + ChildrenMap: map[armotypes.CommPID]*armotypes.Process{ {PID: 2}: { PID: 2, },