@@ -240,7 +240,7 @@ func (m *DataManager) createSecrets(ctx context.Context) error {
240240
241241 // Fetch all the Metal3IPPools and create Metal3IPClaims as needed. Check if the
242242 // IP address has been allocated, if so, fetch the address, gateway and prefix.
243- poolAddresses , err := m .getAddressesFromPool (ctx , * m3dt )
243+ poolAddresses , err := m .getAddressesFromPool (ctx , * m3dt , m3m , capiMachine , bmh )
244244 if err != nil {
245245 return err
246246 }
@@ -334,15 +334,18 @@ type reconciledClaim struct {
334334// return a Transient type ReconcileError, indicating that some addresses were not fully allocated yet.
335335func (m * DataManager ) getAddressesFromPool (ctx context.Context ,
336336 m3dt infrav1.Metal3DataTemplate ,
337+ m3m * infrav1.Metal3Machine ,
338+ machine * clusterv1.Machine ,
339+ bmh * bmov1alpha1.BareMetalHost ,
337340) (map [string ]addressFromPool , error ) {
338341 var err error
342+ addresses := map [string ]addressFromPool {}
339343
340- poolRefs , err := getReferencedPools (m3dt )
344+ poolRefs , err := getReferencedPools (m3dt , m3m , machine , bmh )
341345 if err != nil {
342- return nil , err
346+ return addresses , err
343347 }
344348 claims := map [string ]reconciledClaim {}
345- addresses := map [string ]addressFromPool {}
346349
347350 for pool , ref := range poolRefs {
348351 var rc reconciledClaim
@@ -401,7 +404,7 @@ func isMetal3IPPoolRef(ref corev1.TypedLocalObjectReference) bool {
401404
402405// releaseAddressesFromPool releases all addresses allocated by a [Metal3DataTemplate] by deleting the IP claims.
403406func (m * DataManager ) releaseAddressesFromPool (ctx context.Context , m3dt infrav1.Metal3DataTemplate ) error {
404- poolRefs , err := getReferencedPools (m3dt )
407+ poolRefs , err := getReferencedPools (m3dt , nil , nil , nil )
405408 if err != nil {
406409 return err
407410 }
@@ -461,8 +464,48 @@ func (p poolRefs) addName(name string) error {
461464 return p .addRef (corev1.TypedLocalObjectReference {Name : name })
462465}
463466
467+ // addFromAnnotation resolves a pool reference from an annotation and adds it to the pool refs.
468+ // The annotation value should be a string containing the pool name.
469+ // If the annotation pointer is nil or objects are nil (e.g., during release), this function returns nil without error.
470+ func (p poolRefs ) addFromAnnotation (
471+ fromPoolAnnotation * infrav1.FromPoolAnnotation ,
472+ m3m * infrav1.Metal3Machine ,
473+ machine * clusterv1.Machine ,
474+ bmh * bmov1alpha1.BareMetalHost ,
475+ ) error {
476+ if fromPoolAnnotation == nil {
477+ return nil
478+ }
479+
480+ if m3m == nil && machine == nil && bmh == nil {
481+ return nil
482+ }
483+
484+ annotationValue , err := getValueFromAnnotation (fromPoolAnnotation .Object , fromPoolAnnotation .Annotation , m3m , machine , bmh )
485+ if err != nil {
486+ return err
487+ }
488+
489+ if annotationValue == "" {
490+ return fmt .Errorf ("annotation %s not found or empty on %s" , fromPoolAnnotation .Annotation , fromPoolAnnotation .Object )
491+ }
492+
493+ ref := corev1.TypedLocalObjectReference {
494+ Name : annotationValue ,
495+ APIGroup : ptr .To ("ipam.metal3.io" ),
496+ Kind : IPPoolKind ,
497+ }
498+
499+ return p .addRef (ref )
500+ }
501+
464502// getReferencedPools returns a map containing references to all pools mentioned by a [Metal3DataTemplate].
465- func getReferencedPools (m3dt infrav1.Metal3DataTemplate ) (map [string ]corev1.TypedLocalObjectReference , error ) {
503+ // It resolves both direct pool references and annotation-based references.
504+ func getReferencedPools (m3dt infrav1.Metal3DataTemplate ,
505+ m3m * infrav1.Metal3Machine ,
506+ machine * clusterv1.Machine ,
507+ bmh * bmov1alpha1.BareMetalHost ,
508+ ) (map [string ]corev1.TypedLocalObjectReference , error ) {
466509 pools := poolRefs {}
467510 if m3dt .Spec .MetaData != nil {
468511 for _ , pool := range m3dt .Spec .MetaData .IPAddressesFromPool {
@@ -488,7 +531,9 @@ func getReferencedPools(m3dt infrav1.Metal3DataTemplate) (map[string]corev1.Type
488531 }
489532 if m3dt .Spec .NetworkData != nil {
490533 for _ , network := range m3dt .Spec .NetworkData .Networks .IPv4 { //nolint:dupl
491- if network .FromPoolRef != nil && network .FromPoolRef .Name != "" {
534+ if err := pools .addFromAnnotation (network .FromPoolAnnotation , m3m , machine , bmh ); err != nil {
535+ return pools , err
536+ } else if network .FromPoolRef != nil && network .FromPoolRef .Name != "" {
492537 if err := pools .addRef (* network .FromPoolRef ); err != nil {
493538 return pools , err
494539 }
@@ -499,7 +544,9 @@ func getReferencedPools(m3dt infrav1.Metal3DataTemplate) (map[string]corev1.Type
499544 }
500545
501546 for _ , route := range network .Routes {
502- if route .Gateway .FromPoolRef != nil && route .Gateway .FromPoolRef .Name != "" {
547+ if err := pools .addFromAnnotation (route .Gateway .FromPoolAnnotation , m3m , machine , bmh ); err != nil {
548+ return pools , err
549+ } else if route .Gateway .FromPoolRef != nil && route .Gateway .FromPoolRef .Name != "" {
503550 if err := pools .addRef (* route .Gateway .FromPoolRef ); err != nil {
504551 return pools , err
505552 }
@@ -517,7 +564,9 @@ func getReferencedPools(m3dt infrav1.Metal3DataTemplate) (map[string]corev1.Type
517564 }
518565
519566 for _ , network := range m3dt .Spec .NetworkData .Networks .IPv6 { //nolint:dupl
520- if network .FromPoolRef != nil && network .FromPoolRef .Name != "" {
567+ if err := pools .addFromAnnotation (network .FromPoolAnnotation , m3m , machine , bmh ); err != nil {
568+ return pools , err
569+ } else if network .FromPoolRef != nil && network .FromPoolRef .Name != "" {
521570 if err := pools .addRef (* network .FromPoolRef ); err != nil {
522571 return pools , err
523572 }
@@ -527,7 +576,9 @@ func getReferencedPools(m3dt infrav1.Metal3DataTemplate) (map[string]corev1.Type
527576 }
528577 }
529578 for _ , route := range network .Routes {
530- if route .Gateway .FromPoolRef != nil && route .Gateway .FromPoolRef .Name != "" {
579+ if err := pools .addFromAnnotation (route .Gateway .FromPoolAnnotation , m3m , machine , bmh ); err != nil {
580+ return pools , err
581+ } else if route .Gateway .FromPoolRef != nil && route .Gateway .FromPoolRef .Name != "" {
531582 if err := pools .addRef (* route .Gateway .FromPoolRef ); err != nil {
532583 return pools , err
533584 }
0 commit comments