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 }