Skip to content

✨ Select Metal3DataTemplate per failure domain from BMH placement - #3589

Open
shibaPuppy wants to merge 1 commit into
metal3-io:mainfrom
shibaPuppy:feat/placement-driven-fd
Open

✨ Select Metal3DataTemplate per failure domain from BMH placement#3589
shibaPuppy wants to merge 1 commit into
metal3-io:mainfrom
shibaPuppy:feat/placement-driven-fd

Conversation

@shibaPuppy

Copy link
Copy Markdown
Contributor

What this PR does / why we need it:

Metal3MachineTemplate references a single dataTemplate, so every control-plane node gets the same network configuration even when failure domains map to different network segments (bonding, VLANs, subnets, IP pools).
Running one KCP per network layout is not possible, and workers need per-rack network configuration as well.

This PR adds an optional failureDomainDataTemplates list to Metal3MachineTemplateSpec mapping failure domain names to Metal3DataTemplate references.
When a Metal3Machine cloned from the template is associated with a BareMetalHost whose infrastructure.cluster.x-k8s.io/failure-domain label matches an entry, the machine's dataTemplate is overridden with the mapped reference before its metadata is rendered (guarded by status.renderedData and Metal3DataClaim existence, so an already rendered or claimed machine is never rewritten).

Design notes, refining the proposal in the issue:

  • The mapping is keyed by the failure domain the machine is actually placed in (the BMH label), not by the assigned Machine.spec.failureDomain.
    pickHost() treats the assigned failure domain as a soft preference and can fall back to a host in a different domain; keying the network configuration off the assignment would then inject the wrong subnet/VLAN into the node.
    Keying off the placement makes the rendered network data correct regardless of fallback, and works for MachineDeployment workers with no assigned failure domain at all.
  • To keep the failure domain fields truthful, the Metal3Machine now reports the placement failure domain in spec.failureDomain (surfaced to Machine.spec.failureDomain by the Machine controller) and in the new status.failureDomain, following the v1beta2 contract.
    The assigned value keeps being mirrored Machine→Metal3Machine until a host is associated; afterwards placement wins.
    CAPM3 never writes the core Machine object.
  • BareMetalHosts without the failure-domain label are outside the failure domain scheme entirely: no reporting, no mapping, default dataTemplate.

Behavioral note for users not using the new field: once a consumed BMH carries the failure-domain label, the Metal3Machine starts reporting the placement failure domain (and the Machine converges to it).
This only makes the existing fields reflect actual placement; dataTemplate and network data are unchanged unless failureDomainDataTemplates is set.

Validation: duplicate failure domains are rejected via listType=map, an empty dataTemplate.name via CRD CEL, and cross-namespace references via the Metal3MachineTemplate webhook.
failureDomain keys are capped at 63 characters to match the label value limit.
Both new fields round-trip through v1beta1 conversion.

Fixes #2716

Checklist:

  • Documentation has been updated, if necessary.
  • Unit tests have been added, if necessary.
  • E2E tests have been added, if necessary.
  • Integration tests have been added, if necessary.

@metal3-io-bot

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign sunnatillo for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@metal3-io-bot metal3-io-bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Jul 31, 2026
@metal3-io-bot

Copy link
Copy Markdown
Contributor

Hi @shibaPuppy. Thanks for your PR.

I'm waiting for a metal3-io member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Tip

We noticed you've done this a few times! Consider joining the org to skip this step and gain /lgtm and other bot rights. We recommend asking approvers on your previous PRs to sponsor you.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@Rozzii

Rozzii commented Aug 4, 2026

Copy link
Copy Markdown
Member

/cc @Rozzii
@shibaPuppy asked me to take a look.

This is quite a large PR, I don't recommend forcing this through the review pocess for 1.14 as the feature freeze will happen this week.

I will mark this as a 1.15 target and review when I have some time.

@metal3-io-bot
metal3-io-bot requested a review from Rozzii August 4, 2026 20:19
@Rozzii Rozzii moved this to CAPM3 WIP in Metal3 - Roadmap Aug 4, 2026
@Rozzii Rozzii added this to the CAPM3 - v1.15 milestone Aug 4, 2026
@Rozzii
Rozzii requested a balanced review from Copilot August 4, 2026 20:20
@Rozzii

Rozzii commented Aug 4, 2026

Copy link
Copy Markdown
Member

/ok-to-test

@metal3-io-bot metal3-io-bot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Aug 4, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds failure-domain-specific data templates based on actual BareMetalHost placement and reports the resulting failure domain.

Changes:

  • Adds API fields, CRD validation, conversion, and deepcopy support.
  • Selects data templates from BareMetalHost failure-domain labels.
  • Adds controller and webhook tests.

Reviewed changes

Copilot reviewed 9 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
internal/webhooks/v1beta2/metal3machinetemplate_webhook.go Validates template namespaces.
internal/webhooks/v1beta2/metal3machinetemplate_webhook_test.go Tests namespace validation.
controllers/metal3machine_controller.go Implements placement reporting and template selection.
controllers/metal3machine_controller_test.go Tests placement and selection behavior.
config/crd/bases/infrastructure.cluster.x-k8s.io_metal3machinetemplates.yaml Exposes mapping schema.
config/crd/bases/infrastructure.cluster.x-k8s.io_metal3machines.yaml Exposes failure-domain status.
api/v1beta2/zz_generated.deepcopy.go Adds generated deepcopy support.
api/v1beta2/metal3machinetemplate_types.go Defines failure-domain mappings.
api/v1beta2/metal3machine_types.go Defines placement status.
api/v1beta1/zz_generated.conversion.go Records manual conversion requirements.
api/v1beta1/conversion.go Preserves new fields across conversion.
Files not reviewed (2)
  • api/v1beta1/zz_generated.conversion.go: Generated file
  • api/v1beta2/zz_generated.deepcopy.go: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread controllers/metal3machine_controller.go
Comment thread controllers/metal3machine_controller.go
Comment on lines +451 to +455
if err := r.Client.Get(ctx, key, m3mt); err != nil {
if apierrors.IsNotFound(err) {
log.V(baremetal.VerbosityLevelDebug).Info("Source Metal3MachineTemplate not found, keeping dataTemplate",
baremetal.LogFieldMetal3MachineTemplate, templateName)
return nil

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scenario is real, but I think the lookup is the right trade-off here — happy to change it if you disagree.
In CAPI an infrastructure template is a live clone source: KCP and MachineSet hold an infrastructureRef to it, so deleting one that is still in use already breaks scale-up and rollout independently of this feature. CAPM3 also already relies on this lookup — the Metal3MachineTemplate controller resolves its clones through the same cloned-from annotations to propagate automatedCleaningMode.

The exposure is also narrow: with the claim-existence guard above, the default template can only be used if the source template is deleted in the window between the Metal3Machine being cloned and its Metal3DataClaim being created. The missing template is logged rather than silently ignored.

If you would rather fail closed, the alternative is to requeue instead of proceeding when the source template is missing. I avoided it because it would also block machines whose template was intentionally removed after a rollout, but I am fine either way.

…ement

- failureDomainDataTemplates on Metal3MachineTemplate selects the
  Metal3DataTemplate matching the failure-domain label of the BMH the
  machine is actually placed on, before metadata rendering.
- Metal3Machine reports the placement failure domain in
  spec.failureDomain and the new status.failureDomain; CAPI surfaces
  them to the Machine. Hosts without the label stay outside the FD
  scheme.

Signed-off-by: shibaPuppy <sub951@naver.com>
@shibaPuppy
shibaPuppy force-pushed the feat/placement-driven-fd branch from b3df74f to 5af9a5c Compare August 5, 2026 10:01
@shibaPuppy

Copy link
Copy Markdown
Contributor Author

@Rozzii
just wanted to check if there's a rough timeframe I should plan around for the 1.15 review cycle, so I can keep the branch rebased and ready. Let me know if there's anything I can do to make review easier in the meantime.

@Rozzii

Rozzii commented Aug 31, 2026

Copy link
Copy Markdown
Member

@Rozzii just wanted to check if there's a rough timeframe I should plan around for the 1.15 review cycle, so I can keep the branch rebased and ready. Let me know if there's anything I can do to make review easier in the meantime.

1.15 review cycle just started so this PR is on my review list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

Status: CAPM3 WIP

Development

Successfully merging this pull request may close these issues.

Feature: Select Metal3DataTemplate per Failure Domain for KCP

4 participants