✨ Accept per-host pull secrets for external OCI registries#2745
✨ Accept per-host pull secrets for external OCI registries#2745mabulgu wants to merge 2 commits intometal3-io:mainfrom
Conversation
|
Hi @mabulgu. 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 Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions 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. |
898fffc to
9594af2
Compare
|
/ok-to-test |
|
It might be too much code to be squashing into one commit...what do we think? |
10 is definitely not right either. One for implementation, one for tesrts, and one for docs? There is plenty of work left though, given the conditions need work per Dmitry's review. |
|
Thanks for your comments! @MahnoorAsghar > It might be too much code to be squashing into one commit...what do we think? As soon as we itemize them and they are in the same context, I don't think so. I am going to remove everything related to conditions as they were like extra, but everything else share the same context and can be in the same squash commit IMO. @tuminoid > One for implementation, one for tesrts, and one for docs +1 for docs -1 for tests as tests are a part of the "implementation". Without tests, I would not count it as implemented. What I will do is: seperating the code commit (which will have less changes than the current changes because of the condition revert) and the commit for docs. |
This is fine as well, but its quite common to implement tests in separate commit in same PR. Makes it maybe easier to manage, but like said, I'm 100% fine with code+tests in same commit. |
|
/retest |
b18570e to
27c9860
Compare
|
@dtantsur I applied your suggestions. pls check when you have time. You will find the relevant commetns resolved but pls feel free to reopen them if you feel any of them are not implemented the way you suggested |
|
Not sure if the e2e test filure is related to my changes as it seems to be related to the BMC management credentials |
10854e7 to
ae36d3a
Compare
|
/retest |
|
/approve |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: elfosardo The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
There was a problem hiding this comment.
In general great improvement and very well tested.
I mainly paid attention to the new logic, just skimmed over the tests.
I have a few nits but in general looks very nice.
I know I have a naming related comment and naming things is hard but I think in this case the name really could be a bit more specific.
Also please rebase the PR.
I have also triggered Co-Pilote reviews too because this change is quite large 1400+ lines.
| ociRelevant := img.IsOCI() | ||
|
|
||
| // No per-host secret referenced → not required, valid for public images | ||
| if img.AuthSecretName == nil || *img.AuthSecretName == "" { |
There was a problem hiding this comment.
Similar question as above wasn't this tested in getImageAuthSecret ?
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 16 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ae36d3a to
14d69b3
Compare
14d69b3 to
cc34dc5
Compare
|
|
||
| // Warn if secret is set for non-OCI image (future-proof, do not fail) | ||
| if !ociRelevant && v.recorder != nil { | ||
| v.recorder.Eventf(bmh, corev1.EventTypeWarning, EventAuthSecretIrrelevant, |
There was a problem hiding this comment.
Side note: we already have a different pattern to publish events in the controller, we need to reconcile them eventually..
There was a problem hiding this comment.
Agreed, that's worth a follow-up to unify the event publishing patterns across the controller.
|
@mabulgu the linter failure looks real from a quick glance + a couple of minor comments |
cc34dc5 to
0bd7da0
Compare
This feature allows users to specify per-host OCI registry credentials via spec.image.authSecretName for authenticated container image pulls. Key changes: - Add AuthSecretName field to Image struct in BareMetalHost API - Add IsOCI() method to Image for checking OCI scheme - Implement ImageAuthValidator for secret validation and credential extraction - Add dockerconfig parser using cpuguy83/dockercfg library - Pass extracted credentials to Ironic provisioner for OCI images - Support both kubernetes.io/dockerconfigjson and legacy dockercfg formats Signed-off-by: mabulgu <mabulgu@gmail.com> # Conflicts: # internal/controller/metal3.io/baremetalhost_controller.go # Conflicts: # internal/controller/metal3.io/baremetalhost_controller.go
Comprehensive test coverage for the OCI image authentication feature: pkg/secretutils/dockerconfig_test.go: - TestExtractRegistryCredentials: dockerconfigjson format tests - TestExtractRegistryCredentials_LegacyDockerCfg: legacy dockercfg format - TestExtractRegistryHost: URL parsing tests internal/controller/metal3.io/image_auth_validator_test.go: - Tests for ImageAuthValidator with various secret types and error cases internal/controller/metal3.io/baremetalhost_controller_test.go: - Integration tests for getImageAuthSecret covering: - OCI image with valid/invalid/missing auth secret - Non-OCI images with auth secret (should be ignored) - Registry mismatch scenarios Signed-off-by: mabulgu <mabulgu@gmail.com>
0bd7da0 to
645c8b1
Compare
| authSecret, err := r.getImageAuthSecret(ctx, info.host, &image) | ||
| if err != nil { | ||
| return recordActionFailure(info, metal3api.ProvisioningError, | ||
| "failed to get image auth secret: "+err.Error()) |
There was a problem hiding this comment.
nit: the error messages that getImageAuthSecret produces already contain enough context, you don't need to add more here
| res.Credentials = credentials | ||
| } | ||
|
|
||
| res.Secret = sec |
There was a problem hiding this comment.
It looks like Secret is actually unused? In this case, you can simplify this function to return (credentials, error). After all, that's what getImageAuthSecret returns anyway.
| return res, nil | ||
| } | ||
|
|
||
| func isAllowedDockerConfigType(t corev1.SecretType) bool { |
What this PR does / why we need it:
Adds per-host registry authentication for oci:// provisioning images.
New optional field on BareMetalHost:
When set, the controller validates the Kubernetes Docker-config secret (kubernetes.io/dockerconfigjson or kubernetes.io/dockercfg), selects the correct registry entry (supports exact host and host:port), and uses those credentials during provisioning so private OCI artefacts can be fetched on a per-host basis. Public images continue to work without credentials.
This removes a blocker for users who need different registries/accounts per machine.
Assisted-By: Claude-4.5-sonnet