github.com/cilium/cilium@v1.16.2/operator/cmd/ccnp_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/client-go/tools/cache"
    12  
    13  	"github.com/cilium/cilium/pkg/controller"
    14  	"github.com/cilium/cilium/pkg/k8s"
    15  	cilium_v2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2"
    16  	k8sClient "github.com/cilium/cilium/pkg/k8s/client"
    17  	"github.com/cilium/cilium/pkg/k8s/informer"
    18  	"github.com/cilium/cilium/pkg/k8s/types"
    19  	"github.com/cilium/cilium/pkg/k8s/utils"
    20  	"github.com/cilium/cilium/pkg/k8s/watchers/resources"
    21  	"github.com/cilium/cilium/pkg/metrics"
    22  	"github.com/cilium/cilium/pkg/policy/groups"
    23  )
    24  
    25  var ccnpToGroupsControllerGroup = controller.NewGroup("cilium-clusterwide-network-policy-to-groups")
    26  
    27  func k8sEventMetric(scope, action string) {
    28  	metrics.EventTS.WithLabelValues(metrics.LabelEventSourceK8s, scope, action).SetToCurrentTime()
    29  }
    30  
    31  // enableCCNPWatcher is similar to enableCNPWatcher but handles the watch events for
    32  // clusterwide policies. Since, internally Clusterwide policies are implemented
    33  // using CiliumNetworkPolicy itself, the entire implementation uses the methods
    34  // associcated with CiliumNetworkPolicy.
    35  func enableCCNPWatcher(ctx context.Context, wg *sync.WaitGroup, clientset k8sClient.Clientset) error {
    36  	log.Info("Starting CCNP derivative handler")
    37  
    38  	ccnpStore := cache.NewStore(cache.DeletionHandlingMetaNamespaceKeyFunc)
    39  
    40  	ciliumV2Controller := informer.NewInformerWithStore(
    41  		utils.ListerWatcherFromTyped[*cilium_v2.CiliumClusterwideNetworkPolicyList](clientset.CiliumV2().CiliumClusterwideNetworkPolicies()),
    42  		&cilium_v2.CiliumClusterwideNetworkPolicy{},
    43  		0,
    44  		cache.ResourceEventHandlerFuncs{
    45  			AddFunc: func(obj interface{}) {
    46  				k8sEventMetric(resources.MetricCCNP, resources.MetricCreate)
    47  				if cnp := informer.CastInformerEvent[types.SlimCNP](obj); cnp != nil {
    48  					// We need to deepcopy this structure because we are writing
    49  					// fields.
    50  					// See https://github.com/cilium/cilium/blob/27fee207f5422c95479422162e9ea0d2f2b6c770/pkg/policy/api/ingress.go#L112-L134
    51  					cnpCpy := cnp.DeepCopy()
    52  
    53  					groups.AddDerivativeCCNPIfNeeded(clientset, cnpCpy.CiliumNetworkPolicy)
    54  				}
    55  			},
    56  			UpdateFunc: func(oldObj, newObj interface{}) {
    57  				k8sEventMetric(resources.MetricCCNP, resources.MetricUpdate)
    58  				if oldCNP := informer.CastInformerEvent[types.SlimCNP](oldObj); oldCNP != nil {
    59  					if newCNP := informer.CastInformerEvent[types.SlimCNP](newObj); newCNP != nil {
    60  						if oldCNP.DeepEqual(newCNP) {
    61  							return
    62  						}
    63  
    64  						// We need to deepcopy this structure because we are writing
    65  						// fields.
    66  						// See https://github.com/cilium/cilium/blob/27fee207f5422c95479422162e9ea0d2f2b6c770/pkg/policy/api/ingress.go#L112-L134
    67  						newCNPCpy := newCNP.DeepCopy()
    68  						oldCNPCpy := oldCNP.DeepCopy()
    69  
    70  						groups.UpdateDerivativeCCNPIfNeeded(clientset, newCNPCpy.CiliumNetworkPolicy, oldCNPCpy.CiliumNetworkPolicy)
    71  					}
    72  				}
    73  			},
    74  			DeleteFunc: func(obj interface{}) {
    75  				k8sEventMetric(resources.MetricCCNP, resources.MetricDelete)
    76  				cnp := informer.CastInformerEvent[types.SlimCNP](obj)
    77  				if cnp == nil {
    78  					return
    79  				}
    80  				// The derivative policy will be deleted by the parent but need
    81  				// to delete the cnp from the pooling.
    82  				groups.DeleteDerivativeFromCache(cnp.CiliumNetworkPolicy)
    83  			},
    84  		},
    85  		k8s.TransformToCCNP,
    86  		ccnpStore,
    87  	)
    88  	mgr := controller.NewManager()
    89  
    90  	wg.Add(1)
    91  	go func() {
    92  		defer wg.Done()
    93  		ciliumV2Controller.Run(ctx.Done())
    94  		mgr.RemoveAllAndWait()
    95  	}()
    96  
    97  	mgr.UpdateController(
    98  		"ccnp-to-groups",
    99  		controller.ControllerParams{
   100  			Group: ccnpToGroupsControllerGroup,
   101  			DoFunc: func(ctx context.Context) error {
   102  				groups.UpdateCNPInformation(clientset)
   103  				return nil
   104  			},
   105  			RunInterval: 5 * time.Minute,
   106  		})
   107  
   108  	return nil
   109  }