diff --git a/npm/metrics/ai-utils.go b/npm/metrics/ai-utils.go index 068fdb8f6a..9329d05329 100644 --- a/npm/metrics/ai-utils.go +++ b/npm/metrics/ai-utils.go @@ -111,13 +111,16 @@ func SendLog(operationID int, msg string, printLog bool) { } func SendHeartbeatWithNumPolicies() { - var message string numPolicies, err := GetNumPolicies() - if err == nil { - message = fmt.Sprintf("info: NPM heartbeat. Current num policies: %d", numPolicies) + numPoliciesString := "unknown" + if err != nil { + klog.Warningf("warn: NPM heartbeat. Couldn't get number of policies for telemetry log: %s", err.Error()) } else { - message = fmt.Sprintf("warn: NPM hearbeat. Couldn't get number of policies for telemetry log: %v", err) - klog.Warning(message) + numPoliciesString = strconv.Itoa(numPolicies) } + + cidrNetPols := GetCidrNetPols() + endPortNetPols := GetEndPortNetPols() + message := fmt.Sprintf("info: NPM heartbeat. Total policies: %s, CIDR policies: %d, EndPort policies: %d", numPoliciesString, cidrNetPols, endPortNetPols) SendLog(util.NpmID, message, DonotPrint) } diff --git a/npm/metrics/counts.go b/npm/metrics/counts.go new file mode 100644 index 0000000000..f4e3e5b25d --- /dev/null +++ b/npm/metrics/counts.go @@ -0,0 +1,66 @@ +package metrics + +import "sync" + +var nonPrometheusCounts *counts + +// counts is a struct holding non-Prometheus counts. +type counts struct { + sync.Mutex + cidrNetPols int + endPortNetPols int +} + +func IncCidrNetPols() { + if nonPrometheusCounts == nil { + return + } + nonPrometheusCounts.Lock() + defer nonPrometheusCounts.Unlock() + nonPrometheusCounts.cidrNetPols++ +} + +func DecCidrNetPols() { + if nonPrometheusCounts == nil { + return + } + nonPrometheusCounts.Lock() + defer nonPrometheusCounts.Unlock() + nonPrometheusCounts.cidrNetPols-- +} + +func GetCidrNetPols() int { + if nonPrometheusCounts == nil { + return 0 + } + nonPrometheusCounts.Lock() + defer nonPrometheusCounts.Unlock() + return nonPrometheusCounts.cidrNetPols +} + +func IncEndPortNetPols() { + if nonPrometheusCounts == nil { + return + } + nonPrometheusCounts.Lock() + defer nonPrometheusCounts.Unlock() + nonPrometheusCounts.endPortNetPols++ +} + +func DecEndPortNetPols() { + if nonPrometheusCounts == nil { + return + } + nonPrometheusCounts.Lock() + defer nonPrometheusCounts.Unlock() + nonPrometheusCounts.endPortNetPols-- +} + +func GetEndPortNetPols() int { + if nonPrometheusCounts == nil { + return 0 + } + nonPrometheusCounts.Lock() + defer nonPrometheusCounts.Unlock() + return nonPrometheusCounts.endPortNetPols +} diff --git a/npm/metrics/prometheus-metrics.go b/npm/metrics/prometheus-metrics.go index 4dcc07653f..dadf2c9f17 100644 --- a/npm/metrics/prometheus-metrics.go +++ b/npm/metrics/prometheus-metrics.go @@ -162,6 +162,9 @@ func InitializeAll() { return } + // initialize global variable (see counts.go) + nonPrometheusCounts = &counts{} + initializeDaemonMetrics() initializeControllerMetrics() diff --git a/npm/pkg/controlplane/controllers/v2/networkPolicyController.go b/npm/pkg/controlplane/controllers/v2/networkPolicyController.go index cb14840c67..fe1d85b977 100644 --- a/npm/pkg/controlplane/controllers/v2/networkPolicyController.go +++ b/npm/pkg/controlplane/controllers/v2/networkPolicyController.go @@ -301,7 +301,7 @@ func (c *NetworkPolicyController) syncAddAndUpdateNetPol(netPolObj *networkingv1 return metrics.NoOp, nil } - _, policyExisted := c.rawNpSpecMap[netpolKey] + oldNetPolSpec, policyExisted := c.rawNpSpecMap[netpolKey] var operationKind metrics.OperationKind if policyExisted { operationKind = metrics.UpdateOp @@ -320,18 +320,34 @@ func (c *NetworkPolicyController) syncAddAndUpdateNetPol(netPolObj *networkingv1 return operationKind, fmt.Errorf("[syncAddAndUpdateNetPol] Error: failed to update translated NPMNetworkPolicy into Dataplane due to %w", err) } - if !policyExisted { + if policyExisted { + if translation.HasCIDRBlock(oldNetPolSpec) { + metrics.DecCidrNetPols() + } + + if translation.HasEndPort(oldNetPolSpec) { + metrics.DecEndPortNetPols() + } + } else { // inc metric for NumPolicies only if it a new network policy metrics.IncNumPolicies() } + if translation.HasCIDRBlock(&netPolObj.Spec) { + metrics.IncCidrNetPols() + } + + if translation.HasEndPort(&netPolObj.Spec) { + metrics.IncEndPortNetPols() + } + c.rawNpSpecMap[netpolKey] = &netPolObj.Spec return operationKind, nil } // DeleteNetworkPolicy handles deleting network policy based on netPolKey. func (c *NetworkPolicyController) cleanUpNetworkPolicy(netPolKey string) error { - _, cachedNetPolObjExists := c.rawNpSpecMap[netPolKey] + cachedNetPolSpec, cachedNetPolObjExists := c.rawNpSpecMap[netPolKey] // if there is no applied network policy with the netPolKey, do not need to clean up process. if !cachedNetPolObjExists { return nil @@ -342,6 +358,14 @@ func (c *NetworkPolicyController) cleanUpNetworkPolicy(netPolKey string) error { return fmt.Errorf("[cleanUpNetworkPolicy] Error: failed to remove policy due to %w", err) } + if translation.HasCIDRBlock(cachedNetPolSpec) { + metrics.DecCidrNetPols() + } + + if translation.HasEndPort(cachedNetPolSpec) { + metrics.DecEndPortNetPols() + } + // Success to clean up ipset and iptables operations in kernel and delete the cached network policy from RawNpMap delete(c.rawNpSpecMap, netPolKey) metrics.DecNumPolicies() diff --git a/npm/pkg/controlplane/controllers/v2/networkPolicyController_test.go b/npm/pkg/controlplane/controllers/v2/networkPolicyController_test.go index d14f6f67f1..60115632fc 100644 --- a/npm/pkg/controlplane/controllers/v2/networkPolicyController_test.go +++ b/npm/pkg/controlplane/controllers/v2/networkPolicyController_test.go @@ -24,6 +24,13 @@ import ( "k8s.io/client-go/tools/cache" ) +var ( + eightyFive int32 = 85 + eightyFivePointer = &eightyFive + eightySix int32 = 86 + eightySixPointer = &eightySix +) + type netPolFixture struct { t *testing.T @@ -177,10 +184,13 @@ func addNetPol(f *netPolFixture, netPolObj *networkingv1.NetworkPolicy) { f.netPolController.processNextWorkItem() } -func deleteNetPol(t *testing.T, f *netPolFixture, netPolObj *networkingv1.NetworkPolicy, isDeletedFinalStateUnknownObject IsDeletedFinalStateUnknownObject) { +func addAndDeleteNetPol(t *testing.T, f *netPolFixture, netPolObj *networkingv1.NetworkPolicy, isDeletedFinalStateUnknownObject IsDeletedFinalStateUnknownObject) { addNetPol(f, netPolObj) t.Logf("Complete adding network policy event") + deleteNetPol(t, f, netPolObj, isDeletedFinalStateUnknownObject) +} +func deleteNetPol(t *testing.T, f *netPolFixture, netPolObj *networkingv1.NetworkPolicy, isDeletedFinalStateUnknownObject IsDeletedFinalStateUnknownObject) { // simulate network policy deletion event and delete network policy object from sharedInformer cache err := f.kubeInformer.Networking().V1().NetworkPolicies().Informer().GetIndexer().Delete(netPolObj) if err != nil { @@ -198,28 +208,35 @@ func deleteNetPol(t *testing.T, f *netPolFixture, netPolObj *networkingv1.Networ } if f.netPolController.workqueue.Len() == 0 { + t.Logf("Complete deleting network policy event. workqueue is empty") return } f.netPolController.processNextWorkItem() + t.Logf("Complete deleting network policy event") } -func updateNetPol(t *testing.T, f *netPolFixture, oldNetPolObj, netNetPolObj *networkingv1.NetworkPolicy) { +func addAndUpdateNetPol(t *testing.T, f *netPolFixture, oldNetPolObj, newNetPolObj *networkingv1.NetworkPolicy) { addNetPol(f, oldNetPolObj) t.Logf("Complete adding network policy event") + updateNetPol(t, f, oldNetPolObj, newNetPolObj) +} +func updateNetPol(t *testing.T, f *netPolFixture, oldNetPolObj, newNetPolObj *networkingv1.NetworkPolicy) { // simulate network policy update event and update the network policy to shared informer's cache - err := f.kubeInformer.Networking().V1().NetworkPolicies().Informer().GetIndexer().Update(netNetPolObj) + err := f.kubeInformer.Networking().V1().NetworkPolicies().Informer().GetIndexer().Update(newNetPolObj) if err != nil { - f.t.Errorf("Failed to update network policy %s to shared informer cache: %v", netNetPolObj.Name, err) + f.t.Errorf("Failed to update network policy %s to shared informer cache: %v", newNetPolObj.Name, err) } - f.netPolController.updateNetworkPolicy(oldNetPolObj, netNetPolObj) + f.netPolController.updateNetworkPolicy(oldNetPolObj, newNetPolObj) if f.netPolController.workqueue.Len() == 0 { return } f.netPolController.processNextWorkItem() + + t.Logf("Complete updating network policy event") } type expectedNetPolValues struct { @@ -466,7 +483,7 @@ func TestDeleteNetworkPolicy(t *testing.T) { {0, 0, netPolPromVals{0, 1, 0, 1}}, } } - deleteNetPol(t, f, netPolObj, DeletedFinalStateknownObject) + addAndDeleteNetPol(t, f, netPolObj, DeletedFinalStateknownObject) checkNetPolTestResult("TestDelNetPol", f, testCases) } @@ -528,7 +545,7 @@ func TestDeleteNetworkPolicyWithTombstoneAfterAddingNetworkPolicy(t *testing.T) {0, 0, netPolPromVals{0, 1, 0, 1}}, } } - deleteNetPol(t, f, netPolObj, DeletedFinalStateUnknownObject) + addAndDeleteNetPol(t, f, netPolObj, DeletedFinalStateUnknownObject) checkNetPolTestResult("TestDeleteNetworkPolicyWithTombstoneAfterAddingNetworkPolicy", f, testCases) } @@ -552,7 +569,7 @@ func TestUpdateNetworkPolicy(t *testing.T) { newNetPolObj := oldNetPolObj.DeepCopy() // oldNetPolObj.ResourceVersion value is "0" newRV, _ := strconv.Atoi(oldNetPolObj.ResourceVersion) - newNetPolObj.ResourceVersion = fmt.Sprintf("%d", newRV+1) + newNetPolObj.ResourceVersion = strconv.Itoa(newRV + 1) var testCases []expectedNetPolValues if util.IsWindowsDP() { @@ -568,7 +585,7 @@ func TestUpdateNetworkPolicy(t *testing.T) { {1, 0, netPolPromVals{1, 1, 0, 0}}, } } - updateNetPol(t, f, oldNetPolObj, newNetPolObj) + addAndUpdateNetPol(t, f, oldNetPolObj, newNetPolObj) checkNetPolTestResult("TestUpdateNetPol", f, testCases) } @@ -597,7 +614,7 @@ func TestLabelUpdateNetworkPolicy(t *testing.T) { } // oldNetPolObj.ResourceVersion value is "0" newRV, _ := strconv.Atoi(oldNetPolObj.ResourceVersion) - newNetPolObj.ResourceVersion = fmt.Sprintf("%d", newRV+1) + newNetPolObj.ResourceVersion = strconv.Itoa(newRV + 1) var testCases []expectedNetPolValues @@ -614,7 +631,468 @@ func TestLabelUpdateNetworkPolicy(t *testing.T) { {1, 0, netPolPromVals{1, 1, 1, 0}}, } } - updateNetPol(t, f, oldNetPolObj, newNetPolObj) + addAndUpdateNetPol(t, f, oldNetPolObj, newNetPolObj) checkNetPolTestResult("TestUpdateNetPol", f, testCases) } + +func TestCountsAddAndDeleteNetPol(t *testing.T) { + tests := []struct { + name string + // network policy to add + netPolSpec *networkingv1.NetworkPolicySpec + cidrCount int + endPortCount int + }{ + { + name: "no-cidr-endPort", + netPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + networkingv1.PolicyTypeEgress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + From: []networkingv1.NetworkPolicyPeer{ + { + PodSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "test"}, + }, + }, + }, + Ports: []networkingv1.NetworkPolicyPort{ + { + Port: &intstr.IntOrString{IntVal: 8000}, + }, + }, + }, + }, + Egress: []networkingv1.NetworkPolicyEgressRule{ + { + To: []networkingv1.NetworkPolicyPeer{ + { + PodSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "test"}, + }, + }, + }, + Ports: []networkingv1.NetworkPolicyPort{ + { + Port: &intstr.IntOrString{IntVal: 8000}, + }, + }, + }, + }, + }, + }, + { + name: "cidr-ingress", + netPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + From: []networkingv1.NetworkPolicyPeer{ + { + IPBlock: &networkingv1.IPBlock{ + CIDR: "0.0.0.0/0", + }, + }, + }, + }, + }, + }, + cidrCount: 1, + }, + { + name: "cidr-egress", + netPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeEgress, + }, + Egress: []networkingv1.NetworkPolicyEgressRule{ + { + To: []networkingv1.NetworkPolicyPeer{ + { + IPBlock: &networkingv1.IPBlock{ + CIDR: "0.0.0.0/0", + }, + }, + }, + }, + }, + }, + cidrCount: 1, + }, + { + name: "endPort-ingress", + netPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + Ports: []networkingv1.NetworkPolicyPort{ + { + Port: &intstr.IntOrString{IntVal: 80}, + EndPort: eightyFivePointer, + }, + }, + }, + }, + }, + endPortCount: 1, + }, + { + name: "endPort-egress", + netPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeEgress, + }, + Egress: []networkingv1.NetworkPolicyEgressRule{ + { + Ports: []networkingv1.NetworkPolicyPort{ + { + Port: &intstr.IntOrString{IntVal: 80}, + EndPort: eightyFivePointer, + }, + }, + }, + }, + }, + endPortCount: 1, + }, + { + name: "cidr-and-endPort", + netPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + From: []networkingv1.NetworkPolicyPeer{ + { + IPBlock: &networkingv1.IPBlock{ + CIDR: "0.0.0.0/0", + }, + }, + }, + Ports: []networkingv1.NetworkPolicyPort{ + { + Port: &intstr.IntOrString{IntVal: 80}, + EndPort: eightyFivePointer, + }, + }, + }, + }, + }, + cidrCount: 1, + endPortCount: 1, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + f := newNetPolFixture(t) + netPolObj := createNetPol() + netPolObj.Spec = *tt.netPolSpec + f.netPolLister = append(f.netPolLister, netPolObj) + f.kubeobjects = append(f.kubeobjects, netPolObj) + stopCh := make(chan struct{}) + defer close(stopCh) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + dp := dpmocks.NewMockGenericDataplane(ctrl) + f.newNetPolController(stopCh, dp, false) + + dp.EXPECT().UpdatePolicy(gomock.Any()).Times(1) + dp.EXPECT().RemovePolicy(gomock.Any()).Times(1) + + addNetPol(f, netPolObj) + testCases := []expectedNetPolValues{ + {1, 0, netPolPromVals{1, 1, 0, 0}}, + } + checkNetPolTestResult("TestCountsCreateNetPol", f, testCases) + require.Equal(t, tt.cidrCount, metrics.GetCidrNetPols()) + require.Equal(t, tt.endPortCount, metrics.GetEndPortNetPols()) + + deleteNetPol(t, f, netPolObj, DeletedFinalStateknownObject) + testCases = []expectedNetPolValues{ + {0, 0, netPolPromVals{0, 1, 0, 1}}, + } + checkNetPolTestResult("TestCountsDelNetPol", f, testCases) + require.Equal(t, 0, metrics.GetCidrNetPols()) + require.Equal(t, 0, metrics.GetEndPortNetPols()) + }) + } +} + +func TestCountsUpdateNetPol(t *testing.T) { + tests := []struct { + name string + netPolSpec *networkingv1.NetworkPolicySpec + updatedNetPolSpec *networkingv1.NetworkPolicySpec + cidrCount int + endPortCount int + updatedCidrCount int + updatedEndPortCount int + }{ + { + name: "cidr-to-no-cidr", + netPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + From: []networkingv1.NetworkPolicyPeer{ + { + IPBlock: &networkingv1.IPBlock{ + CIDR: "0.0.0.0/0", + }, + }, + }, + }, + }, + }, + updatedNetPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + From: []networkingv1.NetworkPolicyPeer{ + { + PodSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "test"}, + }, + }, + }, + }, + }, + }, + cidrCount: 1, + updatedCidrCount: 0, + }, + { + name: "no-cidr-to-cidr", + netPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + From: []networkingv1.NetworkPolicyPeer{ + { + PodSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "test"}, + }, + }, + }, + }, + }, + }, + updatedNetPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + From: []networkingv1.NetworkPolicyPeer{ + { + IPBlock: &networkingv1.IPBlock{ + CIDR: "0.0.0.0/0", + }, + }, + }, + }, + }, + }, + cidrCount: 0, + updatedCidrCount: 1, + }, + { + name: "cidr-to-cidr", + netPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + From: []networkingv1.NetworkPolicyPeer{ + { + IPBlock: &networkingv1.IPBlock{ + CIDR: "0.0.0.0/0", + }, + }, + }, + }, + }, + }, + updatedNetPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + From: []networkingv1.NetworkPolicyPeer{ + { + IPBlock: &networkingv1.IPBlock{ + CIDR: "1.0.0.0/32", + }, + }, + }, + }, + }, + }, + cidrCount: 1, + updatedCidrCount: 1, + }, + { + name: "endPort-to-no-endPort", + netPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + Ports: []networkingv1.NetworkPolicyPort{ + { + Port: &intstr.IntOrString{IntVal: 80}, + EndPort: eightyFivePointer, + }, + }, + }, + }, + }, + updatedNetPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + Ports: []networkingv1.NetworkPolicyPort{ + { + Port: &intstr.IntOrString{IntVal: 8000}, + }, + }, + }, + }, + }, + endPortCount: 1, + updatedEndPortCount: 0, + }, + { + name: "no-endPort-to-endPort", + netPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + Ports: []networkingv1.NetworkPolicyPort{ + { + Port: &intstr.IntOrString{IntVal: 8000}, + }, + }, + }, + }, + }, + updatedNetPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + Ports: []networkingv1.NetworkPolicyPort{ + { + Port: &intstr.IntOrString{IntVal: 80}, + EndPort: eightyFivePointer, + }, + }, + }, + }, + }, + endPortCount: 0, + updatedEndPortCount: 1, + }, + { + name: "endPort-to-endPort", + netPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + Ports: []networkingv1.NetworkPolicyPort{ + { + Port: &intstr.IntOrString{IntVal: 80}, + EndPort: eightyFivePointer, + }, + }, + }, + }, + }, + updatedNetPolSpec: &networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + Ports: []networkingv1.NetworkPolicyPort{ + { + Port: &intstr.IntOrString{IntVal: 80}, + EndPort: eightySixPointer, + }, + }, + }, + }, + }, + endPortCount: 1, + updatedEndPortCount: 1, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + f := newNetPolFixture(t) + netPolObj := createNetPol() + netPolObj.Spec = *tt.netPolSpec + f.netPolLister = append(f.netPolLister, netPolObj) + f.kubeobjects = append(f.kubeobjects, netPolObj) + stopCh := make(chan struct{}) + defer close(stopCh) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + dp := dpmocks.NewMockGenericDataplane(ctrl) + f.newNetPolController(stopCh, dp, false) + + dp.EXPECT().UpdatePolicy(gomock.Any()).Times(2) + + addNetPol(f, netPolObj) + testCases := []expectedNetPolValues{ + {1, 0, netPolPromVals{1, 1, 0, 0}}, + } + checkNetPolTestResult("TestCountsAddNetPol", f, testCases) + require.Equal(t, tt.cidrCount, metrics.GetCidrNetPols()) + require.Equal(t, tt.endPortCount, metrics.GetEndPortNetPols()) + + newNetPolObj := createNetPol() + newNetPolObj.Spec = *tt.updatedNetPolSpec + newRV, _ := strconv.Atoi(netPolObj.ResourceVersion) + newNetPolObj.ResourceVersion = strconv.Itoa(newRV + 1) + updateNetPol(t, f, netPolObj, newNetPolObj) + testCases = []expectedNetPolValues{ + {1, 0, netPolPromVals{1, 1, 1, 0}}, + } + checkNetPolTestResult("TestCountsUpdateNetPol", f, testCases) + require.Equal(t, tt.updatedCidrCount, metrics.GetCidrNetPols()) + require.Equal(t, tt.updatedEndPortCount, metrics.GetEndPortNetPols()) + }) + } +} diff --git a/npm/pkg/controlplane/translation/translatePolicy.go b/npm/pkg/controlplane/translation/translatePolicy.go index 9b029b4616..bd415d3138 100644 --- a/npm/pkg/controlplane/translation/translatePolicy.go +++ b/npm/pkg/controlplane/translation/translatePolicy.go @@ -684,3 +684,51 @@ func checkOnlyPortRuleExists( } return nil } + +func HasCIDRBlock(netPolSpec *networkingv1.NetworkPolicySpec) bool { + for _, ingress := range netPolSpec.Ingress { + for _, from := range ingress.From { + if from.IPBlock != nil && from.IPBlock.CIDR != "" { + return true + } + } + } + + for _, egress := range netPolSpec.Egress { + for _, to := range egress.To { + if to.IPBlock != nil && to.IPBlock.CIDR != "" { + return true + } + } + } + + return false +} + +func HasEndPort(netPolObj *networkingv1.NetworkPolicySpec) bool { + for _, ingress := range netPolObj.Ingress { + for _, port := range ingress.Ports { + if port.EndPort == nil { + continue + } + + if t, err := portType(port); err == nil && t == numericPortType { + return true + } + } + } + + for _, egress := range netPolObj.Egress { + for _, port := range egress.Ports { + if port.EndPort == nil { + continue + } + + if t, err := portType(port); err == nil && t == numericPortType { + return true + } + } + } + + return false +}