From 44779518c4e1a924f7711406746061a0146b5acd Mon Sep 17 00:00:00 2001 From: Richard Case Date: Fri, 26 Jan 2024 15:52:00 +0000 Subject: [PATCH] feat: Fix handling of registries config to work as rke2 This is a cherrypick of #251. Signed-off-by: Richard Case --- bootstrap/api/v1alpha1/rke2config_webhook.go | 20 +++ pkg/rke2/registries.go | 140 +++++++++++-------- 2 files changed, 98 insertions(+), 62 deletions(-) diff --git a/bootstrap/api/v1alpha1/rke2config_webhook.go b/bootstrap/api/v1alpha1/rke2config_webhook.go index 7b5b2a35..d9d4dd2f 100644 --- a/bootstrap/api/v1alpha1/rke2config_webhook.go +++ b/bootstrap/api/v1alpha1/rke2config_webhook.go @@ -21,6 +21,7 @@ import ( "github.com/coreos/butane/config/common" fcos "github.com/coreos/butane/config/fcos/v1_4" + v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/validation/field" @@ -113,6 +114,25 @@ func (s *RKE2ConfigSpec) validate(pathPrefix *field.Path) field.ErrorList { var allErrs field.ErrorList allErrs = append(allErrs, s.validateIgnition(pathPrefix)...) + allErrs = append(allErrs, s.validateRegistries(pathPrefix)...) + + return allErrs +} + +func (s *RKE2ConfigSpec) validateRegistries(pathPrefix *field.Path) field.ErrorList { + var allErrs field.ErrorList + + for regName, regConfig := range s.PrivateRegistriesConfig.Configs { + if regConfig.AuthSecret == (v1.ObjectReference{}) && regConfig.TLS == (TLSConfig{}) { + allErrs = append( + allErrs, + field.Invalid( + pathPrefix.Child(fmt.Sprintf("privateRegistriesConfig.configs.%s", regName)), + regConfig, + fmt.Sprintf("need either credentials, tls settings or both for registry: %s", regName)), + ) + } + } return allErrs } diff --git a/pkg/rke2/registries.go b/pkg/rke2/registries.go index 8f54b832..da22573c 100644 --- a/pkg/rke2/registries.go +++ b/pkg/rke2/registries.go @@ -17,6 +17,7 @@ package rke2 import ( corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" bootstrapv1 "github.com/rancher-sandbox/cluster-api-provider-rke2/bootstrap/api/v1alpha1" @@ -45,85 +46,100 @@ func GenerateRegistries(rke2ConfigRegistry RegistryScope) (*Registry, []bootstra } for configName, regConfig := range rke2ConfigRegistry.Registry.Configs { - tlsSecret := corev1.Secret{} - authSecret := corev1.Secret{} - - err := rke2ConfigRegistry.Client.Get( - rke2ConfigRegistry.Ctx, - types.NamespacedName{ - Name: regConfig.TLS.TLSConfigSecret.Name, - Namespace: regConfig.TLS.TLSConfigSecret.Namespace, - }, - &tlsSecret, - ) - if err != nil { - rke2ConfigRegistry.Logger.Error(err, "TLS Config Secret for the registry was not found!") - - return &Registry{}, []bootstrapv1.File{}, err - } - - for _, secretEntry := range []string{"tls.crt", "tls.key", "ca.crt"} { - if tlsSecret.Data[secretEntry] == nil { - rke2ConfigRegistry.Logger.Error(err, "TLS Config Secret for the registry is missing entries!", "secret-missing-entry", secretEntry) + registryConfig := RegistryConfig{} + + if regConfig.TLS != (bootstrapv1.TLSConfig{}) { + tlsSecret := corev1.Secret{} + + err := rke2ConfigRegistry.Client.Get( + rke2ConfigRegistry.Ctx, + types.NamespacedName{ + Name: regConfig.TLS.TLSConfigSecret.Name, + Namespace: regConfig.TLS.TLSConfigSecret.Namespace, + }, + &tlsSecret, + ) + if err != nil { + if apierrors.IsNotFound(err) { + rke2ConfigRegistry.Logger.Error(err, "TLS Secret for the registry was not found!") + } else { + rke2ConfigRegistry.Logger.Error(err, "Error fetching TLS Secret") + } return &Registry{}, []bootstrapv1.File{}, err } - files = append(files, bootstrapv1.File{ - Path: registryCertsPath + "/" + secretEntry, - Content: string(tlsSecret.Data[secretEntry]), - }) - } + for _, secretEntry := range []string{"tls.crt", "tls.key", "ca.crt"} { + if tlsSecret.Data[secretEntry] == nil { + rke2ConfigRegistry.Logger.Error(err, "TLS Secret for the registry is missing entries!", "secret-missing-entry", secretEntry) - err = rke2ConfigRegistry.Client.Get( - rke2ConfigRegistry.Ctx, - types.NamespacedName{ - Name: regConfig.AuthSecret.Name, - Namespace: regConfig.AuthSecret.Namespace, - }, - &authSecret, - ) + return &Registry{}, []bootstrapv1.File{}, err + } - if err != nil { - rke2ConfigRegistry.Logger.Error(err, "Auth Config Secret for the registry was not found!") + files = append(files, bootstrapv1.File{ + Path: registryCertsPath + "/" + secretEntry, + Content: string(tlsSecret.Data[secretEntry]), + }) + } - return &Registry{}, []bootstrapv1.File{}, err + registryConfig.TLS = &TLSConfig{ + InsecureSkipVerify: regConfig.TLS.InsecureSkipVerify, + CAFile: registryCertsPath + "/" + "ca.crt", + CertFile: registryCertsPath + "/" + "tls.crt", + KeyFile: registryCertsPath + "/" + "tls.key", + } } - isBasicAuth := authSecret.Data["username"] != nil && authSecret.Data["password"] != nil - isTokenAuth := authSecret.Data["identity-token"] != nil + if regConfig.AuthSecret != (corev1.ObjectReference{}) { + authSecret := corev1.Secret{} + + err := rke2ConfigRegistry.Client.Get( + rke2ConfigRegistry.Ctx, + types.NamespacedName{ + Name: regConfig.AuthSecret.Name, + Namespace: regConfig.AuthSecret.Namespace, + }, + &authSecret, + ) + if err != nil { + if apierrors.IsNotFound(err) { + rke2ConfigRegistry.Logger.Error(err, "AuthSecret for the registry was not found!") + } else { + rke2ConfigRegistry.Logger.Error(err, "Error fetching AuthSecret") + } - ok := isBasicAuth || isTokenAuth + return &Registry{}, []bootstrapv1.File{}, err + } - if !ok { - rke2ConfigRegistry.Logger.Error( - err, - "Auth Secret for the registry is missing entries! Possible entries are: (\"username\" AND \"password\") OR \"identity-token\" ", - "secret-entries", bsutil.GetMapKeysAsString(authSecret.Data)) + isBasicAuth := authSecret.Data["username"] != nil && authSecret.Data["password"] != nil + isTokenAuth := authSecret.Data["identity-token"] != nil - return &Registry{}, []bootstrapv1.File{}, err - } + ok := isBasicAuth || isTokenAuth - authData := &AuthConfig{} - if isBasicAuth { - authData.Username = string(authSecret.Data["username"]) - authData.Password = string(authSecret.Data["password"]) - } + if !ok { + rke2ConfigRegistry.Logger.Error( + err, + "Auth Secret for the registry is missing entries! Possible entries are: (\"username\" AND \"password\") OR \"identity-token\" ", + "secret-entries", bsutil.GetMapKeysAsString(authSecret.Data)) - if isTokenAuth { - authData.IdentityToken = string(authSecret.Data["identity-token"]) + return &Registry{}, []bootstrapv1.File{}, err + } + + authData := &AuthConfig{} + if isBasicAuth { + authData.Username = string(authSecret.Data["username"]) + authData.Password = string(authSecret.Data["password"]) + } + + if isTokenAuth { + authData.IdentityToken = string(authSecret.Data["identity-token"]) + } + + registryConfig.Auth = authData } registry.Configs = make(map[string]RegistryConfig) - registry.Configs[configName] = RegistryConfig{ - TLS: &TLSConfig{ - InsecureSkipVerify: regConfig.TLS.InsecureSkipVerify, - CAFile: registryCertsPath + "/" + "ca.crt", - CertFile: registryCertsPath + "/" + "tls.crt", - KeyFile: registryCertsPath + "/" + "tls.key", - }, - Auth: authData, - } + registry.Configs[configName] = registryConfig } return registry, files, nil