diff --git a/pkg/containerprofilemanager/v1/containerprofile_manager_test.go b/pkg/containerprofilemanager/v1/containerprofile_manager_test.go index 876919492..f537c5384 100644 --- a/pkg/containerprofilemanager/v1/containerprofile_manager_test.go +++ b/pkg/containerprofilemanager/v1/containerprofile_manager_test.go @@ -185,6 +185,17 @@ func TestFilterLabels(t *testing.T) { }, expected: map[string]string{}, }, + { + name: "filter StatefulSet pod-identity labels", + input: map[string]string{ + "app.kubernetes.io/name": "db", + "apps.kubernetes.io/pod-index": "2", + "statefulset.kubernetes.io/pod-name": "db-2", + }, + expected: map[string]string{ + "app.kubernetes.io/name": "db", + }, + }, } for _, tt := range tests { @@ -613,9 +624,11 @@ func TestTrafficTypeConstants(t *testing.T) { func TestDefaultLabelsToIgnore(t *testing.T) { expectedLabels := map[string]struct{}{ - "controller-revision-hash": {}, - "pod-template-generation": {}, - "pod-template-hash": {}, + "controller-revision-hash": {}, + "pod-template-generation": {}, + "pod-template-hash": {}, + "apps.kubernetes.io/pod-index": {}, + "statefulset.kubernetes.io/pod-name": {}, } assert.Equal(t, expectedLabels, DefaultLabelsToIgnore) diff --git a/pkg/containerprofilemanager/v1/event_reporting_test.go b/pkg/containerprofilemanager/v1/event_reporting_test.go index d948cc980..a654d3daf 100644 --- a/pkg/containerprofilemanager/v1/event_reporting_test.go +++ b/pkg/containerprofilemanager/v1/event_reporting_test.go @@ -252,3 +252,50 @@ func TestCreateNetworkNeighbor_EmptyContainerIDWithWatchedContainerData(t *testi assert.Equal(t, "93.184.216.34", resolver.lastIPAddress) assert.Equal(t, "resolved.domain", neighbor.DNS) } + +// TestCreateNetworkNeighbor_StatefulSetPeerStripsPodIdentityLabels ensures per-replica +// StatefulSet labels are stripped from PodSelector so GeneratedNetworkPolicy peers +// select the workload, not the replicas observed during learning (#942). +func TestCreateNetworkNeighbor_StatefulSetPeerStripsPodIdentityLabels(t *testing.T) { + tests := []struct { + name string + index string + podName string + }{ + {name: "replica-0", index: "0", podName: "db-0"}, + {name: "replica-1", index: "1", podName: "db-1"}, + {name: "replica-2", index: "2", podName: "db-2"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + networkEvent := NetworkEvent{ + Port: 5432, + Protocol: "TCP", + PktType: utils.OutgoingPktType, + Destination: Destination{ + Kind: EndpointKindPod, + Namespace: "default", + Name: tt.podName, + }, + } + networkEvent.SetDestinationPodLabels(map[string]string{ + "app.kubernetes.io/name": "db", + "apps.kubernetes.io/pod-index": tt.index, + "statefulset.kubernetes.io/pod-name": tt.podName, + }) + + cd := &containerData{} + neighbor := cd.createNetworkNeighbor("", networkEvent, "default", nil, nil) + if !assert.NotNil(t, neighbor) { + return + } + if !assert.NotNil(t, neighbor.PodSelector) { + return + } + assert.Equal(t, map[string]string{"app.kubernetes.io/name": "db"}, neighbor.PodSelector.MatchLabels) + assert.NotContains(t, neighbor.PodSelector.MatchLabels, "apps.kubernetes.io/pod-index") + assert.NotContains(t, neighbor.PodSelector.MatchLabels, "statefulset.kubernetes.io/pod-name") + }) + } +} diff --git a/pkg/containerprofilemanager/v1/network_helpers.go b/pkg/containerprofilemanager/v1/network_helpers.go index aab94141e..b516a0579 100644 --- a/pkg/containerprofilemanager/v1/network_helpers.go +++ b/pkg/containerprofilemanager/v1/network_helpers.go @@ -12,9 +12,11 @@ import ( type EndpointKind string var DefaultLabelsToIgnore = map[string]struct{}{ - "controller-revision-hash": {}, - "pod-template-generation": {}, - "pod-template-hash": {}, + "controller-revision-hash": {}, + "pod-template-generation": {}, + "pod-template-hash": {}, + "apps.kubernetes.io/pod-index": {}, + "statefulset.kubernetes.io/pod-name": {}, } const (