github.com/cilium/cilium@v1.16.2/pkg/bgpv1/manager/reconciler/pod_cidr.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package reconciler 5 6 import ( 7 "context" 8 "fmt" 9 "net/netip" 10 11 "github.com/cilium/hive/cell" 12 13 "github.com/cilium/cilium/pkg/bgpv1/manager/instance" 14 "github.com/cilium/cilium/pkg/bgpv1/types" 15 "github.com/cilium/cilium/pkg/option" 16 ) 17 18 type ExportPodCIDRReconcilerOut struct { 19 cell.Out 20 21 Reconciler ConfigReconciler `group:"bgp-config-reconciler"` 22 } 23 24 // exportPodCIDRReconciler is a ConfigReconciler which reconciles the 25 // advertisement of the private Kubernetes PodCIDR block. 26 type ExportPodCIDRReconciler struct{} 27 28 // ExportPodCIDRReconcilerMetadata keeps a list of all advertised Paths 29 type ExportPodCIDRReconcilerMetadata []*types.Path 30 31 func NewExportPodCIDRReconciler(dc *option.DaemonConfig) ExportPodCIDRReconcilerOut { 32 // Don't provide the reconciler if the IPAM mode is not supported 33 if !types.CanAdvertisePodCIDR(dc.IPAMMode()) { 34 log.Info("Unsupported IPAM mode, disabling PodCIDR advertisements. exportPodCIDR doesn't take effect.") 35 return ExportPodCIDRReconcilerOut{} 36 } 37 38 return ExportPodCIDRReconcilerOut{ 39 Reconciler: &ExportPodCIDRReconciler{}, 40 } 41 } 42 43 func (r *ExportPodCIDRReconciler) Name() string { 44 return "ExportPodCIDR" 45 } 46 47 func (r *ExportPodCIDRReconciler) Priority() int { 48 return 30 49 } 50 51 func (r *ExportPodCIDRReconciler) Init(_ *instance.ServerWithConfig) error { 52 return nil 53 } 54 55 func (r *ExportPodCIDRReconciler) Cleanup(_ *instance.ServerWithConfig) {} 56 57 func (r *ExportPodCIDRReconciler) Reconcile(ctx context.Context, p ReconcileParams) error { 58 if p.DesiredConfig == nil { 59 return fmt.Errorf("attempted pod CIDR advertisements reconciliation with nil CiliumBGPPeeringPolicy") 60 } 61 if p.CurrentServer == nil { 62 return fmt.Errorf("attempted pod CIDR advertisements reconciliation with nil ServerWithConfig") 63 } 64 if p.CiliumNode == nil { 65 return fmt.Errorf("attempted pod CIDR advertisements reconciliation with nil local CiliumNode") 66 } 67 68 var toAdvertise []*types.Path 69 for _, cidr := range p.CiliumNode.Spec.IPAM.PodCIDRs { 70 prefix, err := netip.ParsePrefix(cidr) 71 if err != nil { 72 return fmt.Errorf("failed to parse prefix %s: %w", cidr, err) 73 } 74 toAdvertise = append(toAdvertise, types.NewPathForPrefix(prefix)) 75 } 76 77 advertisements, err := exportAdvertisementsReconciler(&advertisementsReconcilerParams{ 78 ctx: ctx, 79 name: "pod CIDR", 80 component: "exportPodCIDRReconciler", 81 enabled: *p.DesiredConfig.ExportPodCIDR, 82 83 sc: p.CurrentServer, 84 newc: p.DesiredConfig, 85 86 currentAdvertisements: r.getMetadata(p.CurrentServer), 87 toAdvertise: toAdvertise, 88 }) 89 90 if err != nil { 91 return err 92 } 93 94 // Update the server config's list of current advertisements only if the 95 // reconciliation logic didn't return any error 96 r.storeMetadata(p.CurrentServer, advertisements) 97 return nil 98 } 99 100 func (r *ExportPodCIDRReconciler) getMetadata(sc *instance.ServerWithConfig) ExportPodCIDRReconcilerMetadata { 101 if _, found := sc.ReconcilerMetadata[r.Name()]; !found { 102 sc.ReconcilerMetadata[r.Name()] = make(ExportPodCIDRReconcilerMetadata, 0) 103 } 104 return sc.ReconcilerMetadata[r.Name()].(ExportPodCIDRReconcilerMetadata) 105 } 106 107 func (r *ExportPodCIDRReconciler) storeMetadata(sc *instance.ServerWithConfig, meta ExportPodCIDRReconcilerMetadata) { 108 sc.ReconcilerMetadata[r.Name()] = meta 109 }