From 459a2dcc203c605b3b611b4812d81932b0d130b6 Mon Sep 17 00:00:00 2001 From: Xieql Date: Mon, 30 Oct 2023 15:51:33 +0800 Subject: [PATCH 1/2] bugfix: make sure ns exsit when create velero secret Signed-off-by: Xieql --- pkg/fleet-manager/fleet_plugin_backup.go | 27 +++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/pkg/fleet-manager/fleet_plugin_backup.go b/pkg/fleet-manager/fleet_plugin_backup.go index e7ea5c111..f7ec6c829 100644 --- a/pkg/fleet-manager/fleet_plugin_backup.go +++ b/pkg/fleet-manager/fleet_plugin_backup.go @@ -71,7 +71,7 @@ func (f *FleetManager) reconcileBackupPlugin(ctx context.Context, fleet *v1alpha // newSecret is a variable used to store the newly created secret object which contains the necessary credentials for the object storage provider. The specific structure and content of the secret vary depending on the provider. newSecret, err := f.buildNewSecret(ctx, veleroCfg.Storage.SecretName, objStoreProvider, fleetNN) if err != nil { - log.Error(err, "failed to builder new object store secret") + err = fmt.Errorf("error building new secret for objStoreProvider %s: %w", objStoreProvider, err) return nil, ctrl.Result{}, err } @@ -87,11 +87,13 @@ func (f *FleetManager) reconcileBackupPlugin(ctx context.Context, fleet *v1alpha SecretKey: cluster.SecretKey, }, veleroCfg, newSecret.Name) if err != nil { + err = fmt.Errorf("error rendering Velero for fleet cluster %s: %w", key.Name, err) return nil, ctrl.Result{}, err } // create a new secret in the current fleet cluster before initializing the backup plugin. if err := createNewSecretInFleetCluster(cluster, newSecret); err != nil { + err = fmt.Errorf("error creating new secret in fleet cluster %s: %w", key.Name, err) return nil, ctrl.Result{}, err } @@ -117,7 +119,7 @@ func (f *FleetManager) reconcileBackupPlugin(ctx context.Context, fleet *v1alpha // preventing orphaned resources and maintaining the cleanliness of the cluster. for key, cluster := range fleetClusters { if err := f.updateNewSecretOwnerReference(ctx, key.Name, cluster, newSecret); err != nil { - log.Error(err, "failed to update object store owner reference", "cluster", key.Name) + err = fmt.Errorf("error updating owner reference for secret in cluster %s: %w", key.Name, err) return nil, ctrl.Result{}, err } } @@ -210,9 +212,28 @@ func createNewSecretInFleetCluster(cluster *fleetCluster, newSecret *corev1.Secr // Get the namespace of the secret namespace := newSecret.Namespace + // Check if namespace exists + _, err := kubeClient.CoreV1().Namespaces().Get(context.TODO(), namespace, metav1.GetOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { + // Namespace does not exist, create it + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + }, + } + _, err := kubeClient.CoreV1().Namespaces().Create(context.TODO(), ns, metav1.CreateOptions{}) + if err != nil { + return fmt.Errorf("failed to create namespace %s: %w", namespace, err) + } + } else { + return fmt.Errorf("failed to check for namespace %s: %w", namespace, err) + } + } + // Create the new secret if _, err := kubeClient.CoreV1().Secrets(namespace).Create(context.TODO(), newSecret, metav1.CreateOptions{}); err != nil && !apierrors.IsAlreadyExists(err) { - return err + return fmt.Errorf("failed to create secret in namespace %s: %w", namespace, err) } return nil From f671023590a9b8aaeeaac5c0719a365d371e9310 Mon Sep 17 00:00:00 2001 From: Xieql Date: Mon, 30 Oct 2023 19:22:59 +0800 Subject: [PATCH 2/2] fix Signed-off-by: Xieql --- pkg/fleet-manager/fleet_plugin_backup.go | 43 +++++++++++------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/pkg/fleet-manager/fleet_plugin_backup.go b/pkg/fleet-manager/fleet_plugin_backup.go index f7ec6c829..1ee00b396 100644 --- a/pkg/fleet-manager/fleet_plugin_backup.go +++ b/pkg/fleet-manager/fleet_plugin_backup.go @@ -21,11 +21,11 @@ import ( "github.com/pkg/errors" "helm.sh/helm/v3/pkg/kube" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "kurator.dev/kurator/pkg/apis/fleet/v1alpha1" "kurator.dev/kurator/pkg/fleet-manager/plugin" @@ -92,7 +92,7 @@ func (f *FleetManager) reconcileBackupPlugin(ctx context.Context, fleet *v1alpha } // create a new secret in the current fleet cluster before initializing the backup plugin. - if err := createNewSecretInFleetCluster(cluster, newSecret); err != nil { + if err := createNewSecretInFleetCluster(ctx, cluster, newSecret); err != nil { err = fmt.Errorf("error creating new secret in fleet cluster %s: %w", key.Name, err) return nil, ctrl.Result{}, err } @@ -205,35 +205,30 @@ func getObjStoreCredentials(ctx context.Context, client client.Client, namespace // createNewSecretInFleetCluster creates a new secret in the specified fleet cluster. // It takes a fleetCluster instance and a pre-built corev1.Secret instance as parameters. // It uses the kube client from the fleetCluster instance to create the new secret in the respective cluster. -func createNewSecretInFleetCluster(cluster *fleetCluster, newSecret *corev1.Secret) error { +func createNewSecretInFleetCluster(ctx context.Context, cluster *fleetCluster, newSecret *corev1.Secret) error { // Get the kubeclient.Interface instance - kubeClient := cluster.client.KubeClient() + kubeClient := cluster.client.CtrlRuntimeClient() // Get the namespace of the secret namespace := newSecret.Namespace + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + }, + } - // Check if namespace exists - _, err := kubeClient.CoreV1().Namespaces().Get(context.TODO(), namespace, metav1.GetOptions{}) - if err != nil { - if apierrors.IsNotFound(err) { - // Namespace does not exist, create it - ns := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: namespace, - }, - } - _, err := kubeClient.CoreV1().Namespaces().Create(context.TODO(), ns, metav1.CreateOptions{}) - if err != nil { - return fmt.Errorf("failed to create namespace %s: %w", namespace, err) - } - } else { - return fmt.Errorf("failed to check for namespace %s: %w", namespace, err) - } + // Create or update namespace + if _, syncErr := controllerutil.CreateOrUpdate(ctx, kubeClient, ns, func() error { + return nil + }); syncErr != nil { + return fmt.Errorf("failed to sync namespace %s: %w", namespace, syncErr) } - // Create the new secret - if _, err := kubeClient.CoreV1().Secrets(namespace).Create(context.TODO(), newSecret, metav1.CreateOptions{}); err != nil && !apierrors.IsAlreadyExists(err) { - return fmt.Errorf("failed to create secret in namespace %s: %w", namespace, err) + // Create or update new secret + if _, syncErr := controllerutil.CreateOrUpdate(ctx, kubeClient, newSecret, func() error { + return nil + }); syncErr != nil { + return fmt.Errorf("failed to sync new secret in namespace %s: %w", namespace, syncErr) } return nil