github.com/cilium/cilium@v1.16.2/operator/cmd/cnp_event.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package cmd
     5  
     6  import (
     7  	"context"
     8  	"sync"
     9  	"time"
    10  
    11  	"k8s.io/apimachinery/pkg/util/runtime"
    12  	"k8s.io/client-go/tools/cache"
    13  
    14  	"github.com/cilium/cilium/pkg/controller"
    15  	"github.com/cilium/cilium/pkg/k8s"
    16  	cilium_v2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2"
    17  	k8sClient "github.com/cilium/cilium/pkg/k8s/client"
    18  	"github.com/cilium/cilium/pkg/k8s/informer"
    19  	"github.com/cilium/cilium/pkg/k8s/types"
    20  	"github.com/cilium/cilium/pkg/k8s/utils"
    21  	"github.com/cilium/cilium/pkg/k8s/watchers/resources"
    22  	"github.com/cilium/cilium/pkg/policy/groups"
    23  )
    24  
    25  var (
    26  	cnpToGroupsControllerGroup = controller.NewGroup("cilium-network-policy-to-groups")
    27  )
    28  
    29  func init() {
    30  	runtime.ErrorHandlers = []func(error){
    31  		k8s.K8sErrorHandler,
    32  	}
    33  }
    34  
    35  // enableCNPWatcher waits for the CiliumNetworkPolicy CRD availability and then
    36  // garbage collects stale CiliumNetworkPolicy status field entries.
    37  func enableCNPWatcher(ctx context.Context, wg *sync.WaitGroup, clientset k8sClient.Clientset) error {
    38  	log.Info("Starting CNP derivative handler")
    39  	cnpStore := cache.NewStore(cache.DeletionHandlingMetaNamespaceKeyFunc)
    40  
    41  	ciliumV2Controller := informer.NewInformerWithStore(
    42  		utils.ListerWatcherFromTyped[*cilium_v2.CiliumNetworkPolicyList](clientset.CiliumV2().CiliumNetworkPolicies("")),
    43  		&cilium_v2.CiliumNetworkPolicy{},
    44  		0,
    45  		cache.ResourceEventHandlerFuncs{
    46  			AddFunc: func(obj interface{}) {
    47  				k8sEventMetric(resources.MetricCNP, resources.MetricCreate)
    48  				if cnp := informer.CastInformerEvent[types.SlimCNP](obj); cnp != nil {
    49  					// We need to deepcopy this structure because we are writing
    50  					// fields.
    51  					// See https://github.com/cilium/cilium/blob/27fee207f5422c95479422162e9ea0d2f2b6c770/pkg/policy/api/ingress.go#L112-L134
    52  					cnpCpy := cnp.DeepCopy()
    53  
    54  					groups.AddDerivativeCNPIfNeeded(clientset, cnpCpy.CiliumNetworkPolicy)
    55  				}
    56  			},
    57  			UpdateFunc: func(oldObj, newObj interface{}) {
    58  				k8sEventMetric(resources.MetricCNP, resources.MetricUpdate)
    59  				if oldCNP := informer.CastInformerEvent[types.SlimCNP](oldObj); oldCNP != nil {
    60  					if newCNP := informer.CastInformerEvent[types.SlimCNP](newObj); newCNP != nil {
    61  						if oldCNP.DeepEqual(newCNP) {
    62  							return
    63  						}
    64  
    65  						// We need to deepcopy this structure because we are writing
    66  						// fields.
    67  						// See https://github.com/cilium/cilium/blob/27fee207f5422c95479422162e9ea0d2f2b6c770/pkg/policy/api/ingress.go#L112-L134
    68  						newCNPCpy := newCNP.DeepCopy()
    69  						oldCNPCpy := oldCNP.DeepCopy()
    70  
    71  						groups.UpdateDerivativeCNPIfNeeded(clientset, newCNPCpy.CiliumNetworkPolicy, oldCNPCpy.CiliumNetworkPolicy)
    72  					}
    73  				}
    74  			},
    75  			DeleteFunc: func(obj interface{}) {
    76  				k8sEventMetric(resources.MetricCNP, resources.MetricDelete)
    77  				cnp := informer.CastInformerEvent[types.SlimCNP](obj)
    78  				if cnp == nil {
    79  					return
    80  				}
    81  				// The derivative policy will be deleted by the parent but need
    82  				// to delete the cnp from the pooling.
    83  				groups.DeleteDerivativeFromCache(cnp.CiliumNetworkPolicy)
    84  			},
    85  		},
    86  		k8s.TransformToCNP,
    87  		cnpStore,
    88  	)
    89  
    90  	mgr := controller.NewManager()
    91  
    92  	wg.Add(1)
    93  	go func() {
    94  		defer wg.Done()
    95  		ciliumV2Controller.Run(ctx.Done())
    96  		mgr.RemoveAllAndWait()
    97  	}()
    98  
    99  	mgr.UpdateController("cnp-to-groups",
   100  		controller.ControllerParams{
   101  			Group: cnpToGroupsControllerGroup,
   102  			DoFunc: func(ctx context.Context) error {
   103  				groups.UpdateCNPInformation(clientset)
   104  				return nil
   105  			},
   106  			RunInterval: 5 * time.Minute,
   107  		})
   108  
   109  	return nil
   110  }