Skip to content

Commit 6a56bce

Browse files
committed
Implement FromPoolAnnotation
Signed-off-by: s3rj1k <[email protected]>
1 parent e4974ef commit 6a56bce

File tree

5 files changed

+668
-11
lines changed

5 files changed

+668
-11
lines changed

api/v1beta1/metal3datatemplate_types.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,17 @@ type FromPool struct {
141141
Kind string `json:"kind"`
142142
}
143143

144+
// FromPoolAnnotation contains the information to fetch pool reference details from an annotation.
145+
type FromPoolAnnotation struct {
146+
// +kubebuilder:validation:Enum=machine;metal3machine;baremetalhost
147+
// Object is the type of the object from which we retrieve the annotation
148+
Object string `json:"object"`
149+
150+
// Annotation is the key of the annotation that contains the pool name.
151+
// The annotation value should be a string containing the pool name.
152+
Annotation string `json:"annotation"`
153+
}
154+
144155
// MetaData represents a keyand value of the metadata.
145156
type MetaData struct {
146157
// Strings is the list of metadata items to be rendered from strings
@@ -363,6 +374,12 @@ type NetworkGatewayv4 struct {
363374

364375
// FromPoolRef is a reference to a IP pool to fetch the gateway from
365376
FromPoolRef *corev1.TypedLocalObjectReference `json:"fromPoolRef,omitempty"`
377+
378+
// FromPoolAnnotation allows specifying the pool name via an annotation on
379+
// a Machine, Metal3Machine, or BareMetalHost object.
380+
// When set, FromIPPool and FromPoolRef are ignored.
381+
// +optional
382+
FromPoolAnnotation *FromPoolAnnotation `json:"fromPoolAnnotation,omitempty"`
366383
}
367384

368385
// NetworkGatewayv6 represents a gateway, given as a string or as a reference to
@@ -379,6 +396,12 @@ type NetworkGatewayv6 struct {
379396

380397
// FromPoolRef is a reference to a IP pool to fetch the gateway from
381398
FromPoolRef *corev1.TypedLocalObjectReference `json:"fromPoolRef,omitempty"`
399+
400+
// FromPoolAnnotation allows specifying the pool name via an annotation on
401+
// a Machine, Metal3Machine, or BareMetalHost object.
402+
// When set, FromIPPool and FromPoolRef are ignored.
403+
// +optional
404+
FromPoolAnnotation *FromPoolAnnotation `json:"fromPoolAnnotation,omitempty"`
382405
}
383406

384407
// NetworkDataRoutev4 represents an ipv4 route object.
@@ -432,6 +455,12 @@ type NetworkDataIPv4 struct {
432455
// FromPoolRef is a reference to a IP pool to allocate an address from.
433456
FromPoolRef *corev1.TypedLocalObjectReference `json:"fromPoolRef,omitempty"`
434457

458+
// FromPoolAnnotation allows specifying the pool reference via an annotation on
459+
// a Machine, Metal3Machine, or BareMetalHost object.
460+
// When set, IPAddressFromIPPool and FromPoolRef are ignored.
461+
// +optional
462+
FromPoolAnnotation *FromPoolAnnotation `json:"fromPoolAnnotation,omitempty"`
463+
435464
// Routes contains a list of IPv4 routes
436465
// +optional
437466
Routes []NetworkDataRoutev4 `json:"routes,omitempty"`
@@ -452,6 +481,12 @@ type NetworkDataIPv6 struct {
452481
// FromPoolRef is a reference to a IP pool to allocate an address from.
453482
FromPoolRef *corev1.TypedLocalObjectReference `json:"fromPoolRef,omitempty"`
454483

484+
// FromPoolAnnotation allows specifying the pool reference via an annotation on
485+
// a Machine, Metal3Machine, or BareMetalHost object.
486+
// When set, IPAddressFromIPPool and FromPoolRef are ignored.
487+
// +optional
488+
FromPoolAnnotation *FromPoolAnnotation `json:"fromPoolAnnotation,omitempty"`
489+
455490
// Routes contains a list of IPv6 routes
456491
// +optional
457492
Routes []NetworkDataRoutev6 `json:"routes,omitempty"`

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

baremetal/metal3data_manager.go

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
335335
func (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.
403406
func (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

Comments
 (0)