@@ -17,12 +17,15 @@ limitations under the License.
1717package controllers
1818
1919import (
20+ "bytes"
2021 "context"
2122 "fmt"
23+ "net/url"
2224 "os"
2325 "strings"
2426 "time"
2527
28+ "github.com/docker/cli/cli/config"
2629 "github.com/fluxcd/pkg/apis/meta"
2730 "github.com/fluxcd/pkg/runtime/conditions"
2831 helper "github.com/fluxcd/pkg/runtime/controller"
@@ -273,7 +276,7 @@ func (r *HelmRepositoryOCIReconciler) reconcileSource(ctx context.Context, obj *
273276 }
274277
275278 // Construct actual options
276- logOpt , err := loginOptionFromSecret (secret )
279+ logOpt , err := loginOptionFromSecret (obj . Spec . URL , secret )
277280 if err != nil {
278281 e := & serror.Event {
279282 Err : fmt .Errorf ("failed to configure Helm client with secret data: %w" , err ),
@@ -352,8 +355,30 @@ func (r *HelmRepositoryOCIReconciler) validateSource(ctx context.Context, obj *s
352355 return sreconcile .ResultSuccess , nil
353356}
354357
355- func loginOptionFromSecret (secret corev1.Secret ) (registry.LoginOption , error ) {
356- username , password := string (secret .Data ["username" ]), string (secret .Data ["password" ])
358+ // loginOptionFromSecret derives authentication data from a Secret to login to an OCI registry. This Secret
359+ // may either hold "username" and "password" fields or be of the corev1.SecretTypeDockerConfigJson type and hold
360+ // a corev1.DockerConfigJsonKey field with a complete Docker configuration. If both, "username" and "password" are
361+ // empty, a nil LoginOption and a nil error will be returned.
362+ func loginOptionFromSecret (registryURL string , secret corev1.Secret ) (registry.LoginOption , error ) {
363+ var username , password string
364+ if secret .Type == corev1 .SecretTypeDockerConfigJson {
365+ dockerCfg , err := config .LoadFromReader (bytes .NewReader (secret .Data [corev1 .DockerConfigJsonKey ]))
366+ if err != nil {
367+ return nil , fmt .Errorf ("unable to load Docker config: %w" , err )
368+ }
369+ parsedURL , err := url .Parse (registryURL )
370+ if err != nil {
371+ return nil , fmt .Errorf ("unable to parse registry URL: %w" , err )
372+ }
373+ authConfig , err := dockerCfg .GetAuthConfig (parsedURL .Host )
374+ if err != nil {
375+ return nil , fmt .Errorf ("unable to get authentication data from Secret: %w" , err )
376+ }
377+ username = authConfig .Username
378+ password = authConfig .Password
379+ } else {
380+ username , password = string (secret .Data ["username" ]), string (secret .Data ["password" ])
381+ }
357382 switch {
358383 case username == "" && password == "" :
359384 return nil , nil
0 commit comments