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  }