github.com/cilium/cilium@v1.16.2/pkg/k8s/watchers/cilium_endpoint_slice.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package watchers 5 6 import ( 7 "context" 8 "sync" 9 "sync/atomic" 10 11 cilium_api_v2a1 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2alpha1" 12 "github.com/cilium/cilium/pkg/k8s/resource" 13 "github.com/cilium/cilium/pkg/k8s/watchers/subscriber" 14 "github.com/cilium/cilium/pkg/kvstore" 15 ) 16 17 var cesNotify = subscriber.NewCES() 18 19 func (k *K8sCiliumEndpointsWatcher) ciliumEndpointSliceInit(ctx context.Context, asyncControllers *sync.WaitGroup) { 20 log.Info("Initializing CES controller") 21 22 var once sync.Once 23 apiGroup := k8sAPIGroupCiliumEndpointSliceV2Alpha1 24 25 // Register for all ces updates. 26 cesNotify.Register(newCESSubscriber(k)) 27 28 for { 29 var synced atomic.Bool 30 stop := make(chan struct{}) 31 32 k.k8sResourceSynced.BlockWaitGroupToSyncResources( 33 stop, 34 nil, 35 func() bool { return synced.Load() }, 36 apiGroup, 37 ) 38 k.k8sAPIGroups.AddAPI(apiGroup) 39 40 // Signalize that we have put node controller in the wait group to sync resources. 41 once.Do(asyncControllers.Done) 42 43 // derive another context to signal Events() in case of kvstore connection 44 eventsCtx, cancel := context.WithCancel(ctx) 45 46 go func() { 47 defer close(stop) 48 49 events := k.resources.CiliumEndpointSlice.Events(eventsCtx) 50 cache := make(map[resource.Key]*cilium_api_v2a1.CiliumEndpointSlice) 51 for event := range events { 52 var err error 53 switch event.Kind { 54 case resource.Sync: 55 synced.Store(true) 56 case resource.Upsert: 57 var needUpdate bool 58 oldObj, ok := cache[event.Key] 59 if !ok { 60 cesNotify.NotifyAdd(event.Object) 61 needUpdate = true 62 } else if !oldObj.DeepEqual(event.Object) { 63 cesNotify.NotifyUpdate(oldObj, event.Object) 64 needUpdate = true 65 } 66 if needUpdate { 67 cache[event.Key] = event.Object 68 } 69 case resource.Delete: 70 cesNotify.NotifyDelete(event.Object) 71 delete(cache, event.Key) 72 } 73 event.Done(err) 74 } 75 }() 76 77 select { 78 case <-kvstore.Connected(): 79 log.Info("Connected to key-value store, stopping CiliumEndpointSlice watcher") 80 cancel() 81 k.k8sResourceSynced.CancelWaitGroupToSyncResources(apiGroup) 82 k.k8sAPIGroups.RemoveAPI(apiGroup) 83 <-stop 84 case <-ctx.Done(): 85 cancel() 86 <-stop 87 return 88 } 89 90 select { 91 case <-ctx.Done(): 92 return 93 case <-kvstore.Client().Disconnected(): 94 log.Info("Disconnected from key-value store, restarting CiliumEndpointSlice watcher") 95 } 96 } 97 }