11package controller
22
33import (
4+ "errors"
45 "fmt"
56 "reflect"
67 "slices"
@@ -28,6 +29,7 @@ import (
2829const (
2930 NetworkPolicyEnforcementStandard = "standard"
3031 NetworkPolicyEnforcementLax = "lax"
32+ policyForAnnotation = "ovn.kubernetes.io/policy-for"
3133)
3234
3335func (c * Controller ) enqueueAddNp (obj any ) {
@@ -121,6 +123,11 @@ func (c *Controller) handleUpdateNp(key string) error {
121123 }
122124 logRate := parseACLLogRate (np .Annotations )
123125
126+ providers , includeSvc , err := parsePolicyFor (np )
127+ if err != nil {
128+ return err
129+ }
130+
124131 npName := np .Name
125132 nameArray := []rune (np .Name )
126133 if ! unicode .IsLetter (nameArray [0 ]) {
@@ -142,7 +149,7 @@ func (c *Controller) handleUpdateNp(key string) error {
142149 }
143150
144151 namedPortMap := c .namedPort .GetNamedPortByNs (np .Namespace )
145- ports , subnetNames , err := c .fetchSelectedPorts (np .Namespace , & np .Spec .PodSelector )
152+ ports , subnetNames , err := c .fetchSelectedPorts (np .Namespace , & np .Spec .PodSelector , providers )
146153 if err != nil {
147154 klog .Errorf ("fetch ports belongs to np %s: %v" , key , err )
148155 return err
@@ -212,7 +219,7 @@ func (c *Controller) handleUpdateNp(key string) error {
212219 } else {
213220 var allow , except []string
214221 for _ , npp := range npr .From {
215- if allow , except , err = c .fetchPolicySelectedAddresses (np .Namespace , protocol , npp ); err != nil {
222+ if allow , except , err = c .fetchPolicySelectedAddresses (np .Namespace , protocol , npp , providers , includeSvc ); err != nil {
216223 klog .Errorf ("failed to fetch policy selected addresses, %v" , err )
217224 return err
218225 }
@@ -359,7 +366,7 @@ func (c *Controller) handleUpdateNp(key string) error {
359366 } else {
360367 var allow , except []string
361368 for _ , npp := range npr .To {
362- if allow , except , err = c .fetchPolicySelectedAddresses (np .Namespace , protocol , npp ); err != nil {
369+ if allow , except , err = c .fetchPolicySelectedAddresses (np .Namespace , protocol , npp , providers , includeSvc ); err != nil {
363370 klog .Errorf ("failed to fetch policy selected addresses, %v" , err )
364371 return err
365372 }
@@ -531,7 +538,50 @@ func (c *Controller) handleDeleteNp(key string) error {
531538 return nil
532539}
533540
534- func (c * Controller ) fetchSelectedPorts (namespace string , selector * metav1.LabelSelector ) ([]string , []string , error ) {
541+ func parsePolicyFor (np * netv1.NetworkPolicy ) (map [string ]struct {}, bool , error ) {
542+ raw := strings .TrimSpace (np .Annotations [policyForAnnotation ])
543+ if raw == "" {
544+ return nil , true , nil
545+ }
546+
547+ providers := map [string ]struct {}{}
548+ includeSvc := false
549+
550+ for _ , token := range strings .Split (raw , "," ) {
551+ t := strings .TrimSpace (token )
552+ if t == "" {
553+ continue
554+ }
555+
556+ switch strings .ToLower (t ) {
557+ case "primary" :
558+ providers [util .OvnProvider ] = struct {}{}
559+ includeSvc = true
560+ continue
561+ case "default" :
562+ return nil , false , fmt .Errorf ("invalid policy-for entry %q (use 'primary')" , t )
563+ case "all" :
564+ return nil , false , fmt .Errorf ("invalid policy-for entry %q (omit annotation for all)" , t )
565+ }
566+ if strings .Contains (t , "/" ) {
567+ parts := strings .SplitN (t , "/" , 2 )
568+ if len (parts ) != 2 || parts [0 ] == "" || parts [1 ] == "" {
569+ return nil , false , fmt .Errorf ("invalid policy-for entry %q" , t )
570+ }
571+ provider := fmt .Sprintf ("%s.%s.%s" , parts [1 ], parts [0 ], util .OvnProvider )
572+ providers [provider ] = struct {}{}
573+ continue
574+ }
575+ return nil , false , fmt .Errorf ("invalid policy-for entry %q" , t )
576+ }
577+
578+ if len (providers ) == 0 {
579+ return nil , false , errors .New ("policy-for annotation has no valid entries" )
580+ }
581+ return providers , includeSvc , nil
582+ }
583+
584+ func (c * Controller ) fetchSelectedPorts (namespace string , selector * metav1.LabelSelector , providers map [string ]struct {}) ([]string , []string , error ) {
535585 var subnets []string
536586 sel , err := metav1 .LabelSelectorAsSelector (selector )
537587 if err != nil {
@@ -557,6 +607,12 @@ func (c *Controller) fetchSelectedPorts(namespace string, selector *metav1.Label
557607 if ! isOvnSubnet (podNet .Subnet ) {
558608 continue
559609 }
610+ provider := podNet .ProviderName
611+ if providers != nil {
612+ if _ , ok := providers [provider ]; ! ok {
613+ continue
614+ }
615+ }
560616
561617 if pod .Annotations [fmt .Sprintf (util .AllocatedAnnotationTemplate , podNet .ProviderName )] == "true" {
562618 ports = append (ports , ovs .PodNameToPortName (podName , pod .Namespace , podNet .ProviderName ))
@@ -587,7 +643,7 @@ func hasEgressRule(np *netv1.NetworkPolicy) bool {
587643 return np .Spec .Egress != nil
588644}
589645
590- func (c * Controller ) fetchPolicySelectedAddresses (namespace , protocol string , npp netv1.NetworkPolicyPeer ) ([]string , []string , error ) {
646+ func (c * Controller ) fetchPolicySelectedAddresses (namespace , protocol string , npp netv1.NetworkPolicyPeer , providers map [ string ] struct {}, includeSvc bool ) ([]string , []string , error ) {
591647 selectedAddresses := []string {}
592648 exceptAddresses := []string {}
593649
@@ -644,14 +700,21 @@ func (c *Controller) fetchPolicySelectedAddresses(namespace, protocol string, np
644700 return nil , nil , err
645701 }
646702 for _ , podNet := range podNets {
703+ provider := podNet .ProviderName
704+ if providers != nil {
705+ if _ , ok := providers [provider ]; ! ok {
706+ continue
707+ }
708+ }
709+
647710 podIPAnnotation := pod .Annotations [fmt .Sprintf (util .IPAddressAnnotationTemplate , podNet .ProviderName )]
648711 podIPs := strings .SplitSeq (podIPAnnotation , "," )
649712 for podIP := range podIPs {
650713 if podIP != "" && util .CheckProtocol (podIP ) == protocol {
651714 selectedAddresses = append (selectedAddresses , podIP )
652715 }
653716 }
654- if len (svcs ) == 0 {
717+ if ! includeSvc || len (svcs ) == 0 {
655718 continue
656719 }
657720
0 commit comments