From 6ca5130ab48c5a9c48e16caaa5233cf98f09e223 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Oct 2023 15:46:53 +0200 Subject: [PATCH] ROX-20073: Implement Network Policy Store Reconciliation (#8153) --- .../listener/resources/hash_reconciliation.go | 10 ++++++ .../resources/hash_reconciliation_test.go | 34 +++++++++++++++++++ .../listener/resources/networkpolicy_store.go | 18 +++++++--- .../listener/resources/store_provider.go | 1 + 4 files changed, 58 insertions(+), 5 deletions(-) diff --git a/sensor/kubernetes/listener/resources/hash_reconciliation.go b/sensor/kubernetes/listener/resources/hash_reconciliation.go index 59bc5b97a7e26..4ebcffb10638a 100644 --- a/sensor/kubernetes/listener/resources/hash_reconciliation.go +++ b/sensor/kubernetes/listener/resources/hash_reconciliation.go @@ -87,6 +87,16 @@ func resourceToMessage(resType string, resID string) (*central.MsgFromSensor, er }, } return ¢ral.MsgFromSensor{Msg: &msg}, nil + case deduper.TypeNetworkPolicy.String(): + msg := central.MsgFromSensor_Event{ + Event: ¢ral.SensorEvent{ + Id: resID, + Action: central.ResourceAction_REMOVE_RESOURCE, + Resource: ¢ral.SensorEvent_NetworkPolicy{ + NetworkPolicy: &storage.NetworkPolicy{Id: resID}}, + }, + } + return ¢ral.MsgFromSensor{Msg: &msg}, nil case deduper.TypeNode.String(): msg := central.MsgFromSensor_Event{ Event: ¢ral.SensorEvent{ diff --git a/sensor/kubernetes/listener/resources/hash_reconciliation_test.go b/sensor/kubernetes/listener/resources/hash_reconciliation_test.go index d6201c8115e70..0e2315d8b3299 100644 --- a/sensor/kubernetes/listener/resources/hash_reconciliation_test.go +++ b/sensor/kubernetes/listener/resources/hash_reconciliation_test.go @@ -57,6 +57,11 @@ func (s *HashReconciliationSuite) TestResourceToMessage() { expectedMsg: ¢ral.MsgFromSensor_Event{Event: ¢ral.SensorEvent{Id: testResID, Action: central.ResourceAction_REMOVE_RESOURCE, Resource: ¢ral.SensorEvent_Secret{Secret: &storage.Secret{Id: testResID}}}}, expectedError: nil, }, + "NetworkPolicy": { + resType: deduper.TypeNetworkPolicy.String(), + expectedMsg: ¢ral.MsgFromSensor_Event{Event: ¢ral.SensorEvent{Id: testResID, Action: central.ResourceAction_REMOVE_RESOURCE, Resource: ¢ral.SensorEvent_NetworkPolicy{NetworkPolicy: &storage.NetworkPolicy{Id: testResID}}}}, + expectedError: nil, + }, "Unknown should throw error": { resType: "Unknown", expectedMsg: nil, @@ -99,6 +104,10 @@ func resourceTypeToFn(resType string) (func(*central.SensorEvent) string, error) return func(event *central.SensorEvent) string { return event.GetNode().GetId() }, nil + case deduper.TypeNetworkPolicy.String(): + return func(event *central.SensorEvent) string { + return event.GetNetworkPolicy().GetId() + }, nil default: return nil, errors.Errorf("not implemented for resource type %v", resType) } @@ -113,6 +122,8 @@ func initStore() *InMemoryStoreProvider { s.podStore.addOrUpdatePod(&storage.Pod{Id: "4"}) s.nodeStore.addOrUpdateNode(makeNode("42")) s.nodeStore.addOrUpdateNode(makeNode("43")) + s.networkPolicyStore.Upsert(&storage.NetworkPolicy{Id: "1"}) + s.networkPolicyStore.Upsert(&storage.NetworkPolicy{Id: "2"}) s.serviceAccountStore.Add(&storage.ServiceAccount{ Id: "5", Name: "Acc1", @@ -265,6 +276,29 @@ func (s *HashReconciliationSuite) TestProcessHashes() { }, deletedIDs: []string{"99", "98", "97"}, }, + "No Network Policy": { + dstate: map[deduper.Key]uint64{ + makeKey("1", deduper.TypeNetworkPolicy): 12345, + makeKey("2", deduper.TypeNetworkPolicy): 34567, + }, + deletedIDs: []string{}, + }, + "Single Network Policy": { + dstate: map[deduper.Key]uint64{ + makeKey("99", deduper.TypeNetworkPolicy): 34567, + makeKey("1", deduper.TypeNetworkPolicy): 12345, + }, + deletedIDs: []string{"99"}, + }, + "Multiple Network Policies": { + dstate: map[deduper.Key]uint64{ + makeKey("99", deduper.TypeNetworkPolicy): 34567, + makeKey("98", deduper.TypeNetworkPolicy): 34567, + makeKey("97", deduper.TypeNetworkPolicy): 34567, + makeKey("1", deduper.TypeNetworkPolicy): 12345, + }, + deletedIDs: []string{"97", "98", "99"}, + }, } for n, c := range cases { diff --git a/sensor/kubernetes/listener/resources/networkpolicy_store.go b/sensor/kubernetes/listener/resources/networkpolicy_store.go index dc816300cca62..79b9f7907b23b 100644 --- a/sensor/kubernetes/listener/resources/networkpolicy_store.go +++ b/sensor/kubernetes/listener/resources/networkpolicy_store.go @@ -4,6 +4,7 @@ import ( "github.com/pkg/errors" "github.com/stackrox/rox/pkg/labels" "github.com/stackrox/rox/pkg/sync" + "github.com/stackrox/rox/sensor/common/deduper" "github.com/stackrox/rox/sensor/common/detector/metrics" "github.com/stackrox/rox/sensor/common/store" @@ -45,7 +46,7 @@ The Find operation returns all NetworkPolicies that would match a given set of l Example: policiesMatchingDeployment := store.Find("default"), map[string]string{"app": "nginx"}) -*) TODO: See ADR-XXX for alternative implementations that were considered +See ADR-0002 "Design In-Memory Data Store for Network Policies in Sensor" for alternative implementations that were considered ## Complexities @@ -86,10 +87,17 @@ type networkPolicyStoreImpl struct { // ReconcileDelete is called after Sensor reconnects with Central and receives its state hashes. // Reconciliacion ensures that Sensor and Central have the same state by checking whether a given resource // shall be deleted from Central. -func (n *networkPolicyStoreImpl) ReconcileDelete(resType, resID string, resHash uint64) (string, error) { - _, _, _ = resType, resID, resHash - // TODO(ROX-20073): Implement me - return "", errors.New("Not implemented") +func (n *networkPolicyStoreImpl) ReconcileDelete(resType, resID string, _ uint64) (string, error) { + if resType != deduper.TypeNetworkPolicy.String() { + return "", errors.Errorf("invalid resource type %v", resType) + } + + p := n.Get(resID) + if p != nil { + return "", nil + } + // Resource on Central but not on Sensor, send for deletion + return resID, nil } func newNetworkPoliciesStore() *networkPolicyStoreImpl { diff --git a/sensor/kubernetes/listener/resources/store_provider.go b/sensor/kubernetes/listener/resources/store_provider.go index 6f2a84cf27fda..00873056fd3b2 100644 --- a/sensor/kubernetes/listener/resources/store_provider.go +++ b/sensor/kubernetes/listener/resources/store_provider.go @@ -83,6 +83,7 @@ func InitializeStore() *InMemoryStoreProvider { deduper.TypeServiceAccount.String(): p.serviceAccountStore, deduper.TypeSecret.String(): p.registryStore, deduper.TypeNode.String(): p.nodeStore, + deduper.TypeNetworkPolicy.String(): p.networkPolicyStore, } return p