github.com/cilium/cilium@v1.16.2/pkg/policy/k8s/watcher.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package k8s
     5  
     6  import (
     7  	"context"
     8  	"sync/atomic"
     9  
    10  	"github.com/sirupsen/logrus"
    11  
    12  	ipcacheTypes "github.com/cilium/cilium/pkg/ipcache/types"
    13  	"github.com/cilium/cilium/pkg/k8s"
    14  	cilium_v2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2"
    15  	cilium_api_v2alpha1 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2alpha1"
    16  	"github.com/cilium/cilium/pkg/k8s/resource"
    17  	slim_networking_v1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/api/networking/v1"
    18  	k8sSynced "github.com/cilium/cilium/pkg/k8s/synced"
    19  	"github.com/cilium/cilium/pkg/k8s/types"
    20  	"github.com/cilium/cilium/pkg/option"
    21  )
    22  
    23  type policyWatcher struct {
    24  	log    logrus.FieldLogger
    25  	config *option.DaemonConfig
    26  
    27  	k8sResourceSynced *k8sSynced.Resources
    28  	k8sAPIGroups      *k8sSynced.APIGroups
    29  
    30  	policyManager         PolicyManager
    31  	svcCache              serviceCache
    32  	svcCacheNotifications <-chan k8s.ServiceNotification
    33  
    34  	knpSynced, cnpSynced, ccnpSynced, cidrGroupSynced atomic.Bool
    35  
    36  	ciliumNetworkPolicies            resource.Resource[*cilium_v2.CiliumNetworkPolicy]
    37  	ciliumClusterwideNetworkPolicies resource.Resource[*cilium_v2.CiliumClusterwideNetworkPolicy]
    38  	ciliumCIDRGroups                 resource.Resource[*cilium_api_v2alpha1.CiliumCIDRGroup]
    39  	networkPolicies                  resource.Resource[*slim_networking_v1.NetworkPolicy]
    40  
    41  	// cnpCache contains both CNPs and CCNPs, stored using a common intermediate
    42  	// representation (*types.SlimCNP). The cache is indexed on resource.Key,
    43  	// that contains both the name and namespace of the resource, in order to
    44  	// avoid key clashing between CNPs and CCNPs.
    45  	// The cache contains CNPs and CCNPs in their "original form"
    46  	// (i.e: pre-translation of each CIDRGroupRef to a CIDRSet).
    47  	cnpCache       map[resource.Key]*types.SlimCNP
    48  	cidrGroupCache map[string]*cilium_api_v2alpha1.CiliumCIDRGroup
    49  	// cidrGroupPolicies is the set of policies that are referencing CiliumCIDRGroup objects.
    50  	cidrGroupPolicies map[resource.Key]struct{}
    51  	// cidrGroupPolicies is the set of policies that contain ToServices references
    52  	toServicesPolicies map[resource.Key]struct{}
    53  	cnpByServiceID     map[k8s.ServiceID]map[resource.Key]struct{}
    54  }
    55  
    56  func (p *policyWatcher) watchResources(ctx context.Context) {
    57  	go func() {
    58  		var knpEvents <-chan resource.Event[*slim_networking_v1.NetworkPolicy]
    59  		if p.config.EnableK8sNetworkPolicy {
    60  			knpEvents = p.networkPolicies.Events(ctx)
    61  		}
    62  		cnpEvents := p.ciliumNetworkPolicies.Events(ctx)
    63  		ccnpEvents := p.ciliumClusterwideNetworkPolicies.Events(ctx)
    64  		cidrGroupEvents := p.ciliumCIDRGroups.Events(ctx)
    65  		serviceEvents := p.svcCacheNotifications
    66  
    67  		for {
    68  			select {
    69  			case event, ok := <-knpEvents:
    70  				if !ok {
    71  					knpEvents = nil
    72  					break
    73  				}
    74  
    75  				if event.Kind == resource.Sync {
    76  					p.knpSynced.Store(true)
    77  					event.Done(nil)
    78  					continue
    79  				}
    80  
    81  				var err error
    82  				switch event.Kind {
    83  				case resource.Upsert:
    84  					err = p.addK8sNetworkPolicyV1(event.Object, k8sAPIGroupNetworkingV1Core)
    85  				case resource.Delete:
    86  					err = p.deleteK8sNetworkPolicyV1(event.Object, k8sAPIGroupNetworkingV1Core)
    87  				}
    88  				event.Done(err)
    89  			case event, ok := <-cnpEvents:
    90  				if !ok {
    91  					cnpEvents = nil
    92  					break
    93  				}
    94  
    95  				if event.Kind == resource.Sync {
    96  					p.cnpSynced.Store(true)
    97  					event.Done(nil)
    98  					continue
    99  				}
   100  
   101  				slimCNP := &types.SlimCNP{
   102  					CiliumNetworkPolicy: &cilium_v2.CiliumNetworkPolicy{
   103  						TypeMeta:   event.Object.TypeMeta,
   104  						ObjectMeta: event.Object.ObjectMeta,
   105  						Spec:       event.Object.Spec,
   106  						Specs:      event.Object.Specs,
   107  					},
   108  				}
   109  
   110  				resourceID := ipcacheTypes.NewResourceID(
   111  					ipcacheTypes.ResourceKindCNP,
   112  					slimCNP.ObjectMeta.Namespace,
   113  					slimCNP.ObjectMeta.Name,
   114  				)
   115  				var err error
   116  				switch event.Kind {
   117  				case resource.Upsert:
   118  					err = p.onUpsert(slimCNP, event.Key, k8sAPIGroupCiliumNetworkPolicyV2, resourceID)
   119  				case resource.Delete:
   120  					err = p.onDelete(slimCNP, event.Key, k8sAPIGroupCiliumNetworkPolicyV2, resourceID)
   121  				}
   122  				reportCNPChangeMetrics(err)
   123  				event.Done(err)
   124  			case event, ok := <-ccnpEvents:
   125  				if !ok {
   126  					ccnpEvents = nil
   127  					break
   128  				}
   129  
   130  				if event.Kind == resource.Sync {
   131  					p.ccnpSynced.Store(true)
   132  					event.Done(nil)
   133  					continue
   134  				}
   135  
   136  				slimCNP := &types.SlimCNP{
   137  					CiliumNetworkPolicy: &cilium_v2.CiliumNetworkPolicy{
   138  						TypeMeta:   event.Object.TypeMeta,
   139  						ObjectMeta: event.Object.ObjectMeta,
   140  						Spec:       event.Object.Spec,
   141  						Specs:      event.Object.Specs,
   142  					},
   143  				}
   144  
   145  				resourceID := ipcacheTypes.NewResourceID(
   146  					ipcacheTypes.ResourceKindCCNP,
   147  					slimCNP.ObjectMeta.Namespace,
   148  					slimCNP.ObjectMeta.Name,
   149  				)
   150  				var err error
   151  				switch event.Kind {
   152  				case resource.Upsert:
   153  					err = p.onUpsert(slimCNP, event.Key, k8sAPIGroupCiliumClusterwideNetworkPolicyV2, resourceID)
   154  				case resource.Delete:
   155  					err = p.onDelete(slimCNP, event.Key, k8sAPIGroupCiliumClusterwideNetworkPolicyV2, resourceID)
   156  				}
   157  				reportCNPChangeMetrics(err)
   158  				event.Done(err)
   159  			case event, ok := <-cidrGroupEvents:
   160  				if !ok {
   161  					cidrGroupEvents = nil
   162  					break
   163  				}
   164  
   165  				if event.Kind == resource.Sync {
   166  					p.cidrGroupSynced.Store(true)
   167  					event.Done(nil)
   168  					continue
   169  				}
   170  
   171  				var err error
   172  				switch event.Kind {
   173  				case resource.Upsert:
   174  					err = p.onUpsertCIDRGroup(event.Object, k8sAPIGroupCiliumCIDRGroupV2Alpha1)
   175  				case resource.Delete:
   176  					err = p.onDeleteCIDRGroup(event.Object.Name, k8sAPIGroupCiliumCIDRGroupV2Alpha1)
   177  				}
   178  				event.Done(err)
   179  			case event, ok := <-serviceEvents:
   180  				if !ok {
   181  					serviceEvents = nil
   182  					break
   183  				}
   184  
   185  				switch event.Action {
   186  				case k8s.UpdateService, k8s.DeleteService:
   187  					p.onServiceEvent(event)
   188  				}
   189  			}
   190  			if knpEvents == nil && cnpEvents == nil && ccnpEvents == nil && cidrGroupEvents == nil && serviceEvents == nil {
   191  				return
   192  			}
   193  		}
   194  	}()
   195  }