Browse Source

feat: improve code integration api (#4777)

Signed-off-by: Gustavo Carvalho <gustavo@externalsecrets.com>
Gustavo Fernandes de Carvalho 11 months ago
parent
commit
cb98cf8b62

+ 3 - 0
cmd/controller/root.go

@@ -81,6 +81,7 @@ var (
 	enableClusterPushSecretReconciler     bool
 	enablePushSecretReconciler            bool
 	enableFloodGate                       bool
+	enableGeneratorState                  bool
 	enableExtendedMetricLabels            bool
 	storeRequeueInterval                  time.Duration
 	serviceName, serviceNamespace         string
@@ -227,6 +228,7 @@ var rootCmd = &cobra.Command{
 			RequeueInterval:           time.Hour,
 			ClusterSecretStoreEnabled: enableClusterStoreReconciler,
 			EnableFloodGate:           enableFloodGate,
+			EnableGeneratorState:      enableGeneratorState,
 		}).SetupWithManager(mgr, controller.Options{
 			MaxConcurrentReconciles: concurrent,
 			RateLimiter:             ctrlcommon.BuildRateLimiter(),
@@ -325,6 +327,7 @@ func init() {
 	rootCmd.Flags().BoolVar(&enableManagedSecretsCache, "enable-managed-secrets-caching", true, "Enable secrets caching for secrets managed by an ExternalSecret")
 	rootCmd.Flags().DurationVar(&storeRequeueInterval, "store-requeue-interval", time.Minute*5, "Default Time duration between reconciling (Cluster)SecretStores")
 	rootCmd.Flags().BoolVar(&enableFloodGate, "enable-flood-gate", true, "Enable flood gate. External secret will be reconciled only if the ClusterStore or Store have an healthy or unknown state.")
+	rootCmd.Flags().BoolVar(&enableGeneratorState, "enable-generator-state", true, "Whether the Controller should manage GeneratorState")
 	rootCmd.Flags().BoolVar(&enableExtendedMetricLabels, "enable-extended-metric-labels", false, "Enable recommended kubernetes annotations as labels in metrics.")
 	fs := feature.Features()
 	for _, f := range fs {

+ 3 - 2
pkg/controllers/externalsecret/externalsecret_controller.go

@@ -136,6 +136,7 @@ type Reconciler struct {
 	RequeueInterval           time.Duration
 	ClusterSecretStoreEnabled bool
 	EnableFloodGate           bool
+	EnableGeneratorState      bool
 	recorder                  record.EventRecorder
 }
 
@@ -324,7 +325,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ct
 	}()
 
 	// retrieve the provider secret data.
-	dataMap, err := r.getProviderSecretData(ctx, externalSecret)
+	dataMap, err := r.GetProviderSecretData(ctx, externalSecret)
 	if err != nil {
 		r.markAsFailed(msgErrorGetSecretData, err, externalSecret, syncCallsError.With(resourceLabels))
 		return ctrl.Result{}, err
@@ -429,7 +430,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ct
 
 		// WARNING: this will remove any labels or annotations managed by this ExternalSecret
 		//          so any updates to labels and annotations should be done AFTER this point
-		err = r.applyTemplate(ctx, externalSecret, secret, dataMap)
+		err = r.ApplyTemplate(ctx, externalSecret, secret, dataMap)
 		if err != nil {
 			return fmt.Errorf(errApplyTemplate, err)
 		}

+ 40 - 27
pkg/controllers/externalsecret/externalsecret_controller_secret.go

@@ -37,7 +37,7 @@ import (
 )
 
 // getProviderSecretData returns the provider's secret data with the provided ExternalSecret.
-func (r *Reconciler) getProviderSecretData(ctx context.Context, externalSecret *esv1.ExternalSecret) (providerData map[string][]byte, err error) {
+func (r *Reconciler) GetProviderSecretData(ctx context.Context, externalSecret *esv1.ExternalSecret) (providerData map[string][]byte, err error) {
 	// We MUST NOT create multiple instances of a provider client (mostly due to limitations with GCP)
 	// Clientmanager keeps track of the client instances
 	// that are created during the fetching process and closes clients
@@ -50,25 +50,28 @@ func (r *Reconciler) getProviderSecretData(ctx context.Context, externalSecret *
 	// statemanager takes care of managing the state of the generators.
 	// Since ExternalSecrets can have multiple generators, we need to keep track of the state of each generator
 	// and if one fails we need to rollback all generated values from this iteration.
-	genState := statemanager.New(ctx, r.Client, r.Scheme, externalSecret.Namespace, externalSecret)
-	defer func() {
-		// NoSecretErr does not make sense for the generator state.
-		// A generator is expected to always generate a secret.
-		// If it doesn't, it should return an error.
-		// If the error is NoSecretErr, we should commit the generator state.
-		if err != nil && !errors.Is(err, esv1.NoSecretErr) {
-			if rollBackErr := genState.Rollback(); rollBackErr != nil {
-				r.Log.Error(rollBackErr, "error rolling back generator state")
+	var genState *statemanager.Manager
+	if r.EnableGeneratorState {
+		genState = statemanager.New(ctx, r.Client, r.Scheme, externalSecret.Namespace, externalSecret)
+		defer func() {
+			// NoSecretErr does not make sense for the generator state.
+			// A generator is expected to always generate a secret.
+			// If it doesn't, it should return an error.
+			// If the error is NoSecretErr, we should commit the generator state.
+			if err != nil && !errors.Is(err, esv1.NoSecretErr) {
+				if rollBackErr := genState.Rollback(); rollBackErr != nil {
+					r.Log.Error(rollBackErr, "error rolling back generator state")
+				}
+				return
 			}
-			return
-		}
-		if commitErr := genState.Commit(); commitErr != nil {
-			r.Log.Error(commitErr, "error committing generator state")
-			// At this point the original error can only be a NoSecretErr
-			// but we should return the commit error here as it's more important.
-			err = commitErr
-		}
-	}()
+			if commitErr := genState.Commit(); commitErr != nil {
+				r.Log.Error(commitErr, "error committing generator state")
+				// At this point the original error can only be a NoSecretErr
+				// but we should return the commit error here as it's more important.
+				err = commitErr
+			}
+		}()
+	}
 	providerData = make(map[string][]byte)
 	for i, remoteRef := range externalSecret.Spec.DataFrom {
 		var secretMap map[string][]byte
@@ -153,18 +156,25 @@ func (r *Reconciler) handleGenerateSecrets(ctx context.Context, namespace string
 	if err != nil {
 		return nil, err
 	}
-	latestState, err := generatorState.GetLatestState(generatorStateKey(i))
-	if err != nil {
-		return nil, fmt.Errorf("unable to get latest state: %w", err)
+	var latestState *genv1alpha1.GeneratorState
+	if generatorState != nil {
+		latestState, err = generatorState.GetLatestState(generatorStateKey(i))
+		if err != nil {
+			return nil, fmt.Errorf("unable to get latest state: %w", err)
+		}
 	}
 	secretMap, newState, err := impl.Generate(ctx, generatorResource, r.Client, namespace)
 	if err != nil {
 		return nil, fmt.Errorf(errGenerate, err)
 	}
 	if latestState != nil {
-		generatorState.EnqueueMoveStateToGC(generatorStateKey(i))
+		if generatorState != nil {
+			generatorState.EnqueueMoveStateToGC(generatorStateKey(i))
+		}
+	}
+	if generatorState != nil {
+		generatorState.EnqueueSetLatest(ctx, generatorStateKey(i), namespace, generatorResource, impl, newState)
 	}
-	generatorState.EnqueueSetLatest(ctx, generatorStateKey(i), namespace, generatorResource, impl, newState)
 	// rewrite the keys if needed
 	secretMap, err = utils.RewriteMap(remoteRef.Rewrite, secretMap)
 	if err != nil {
@@ -222,8 +232,9 @@ func (r *Reconciler) handleExtractSecrets(ctx context.Context, externalSecret *e
 	if err != nil {
 		return nil, fmt.Errorf(errDecode, remoteRef.Extract.DecodingStrategy, err)
 	}
-
-	genState.EnqueueFlagLatestStateForGC(generatorStateKey(i))
+	if genState != nil {
+		genState.EnqueueFlagLatestStateForGC(generatorStateKey(i))
+	}
 	return secretMap, nil
 }
 
@@ -262,7 +273,9 @@ func (r *Reconciler) handleFindAllSecrets(ctx context.Context, externalSecret *e
 	if err != nil {
 		return nil, fmt.Errorf(errDecode, remoteRef.Find.DecodingStrategy, err)
 	}
-	genState.EnqueueFlagLatestStateForGC(generatorStateKey(i))
+	if genState != nil {
+		genState.EnqueueFlagLatestStateForGC(generatorStateKey(i))
+	}
 	return secretMap, nil
 }
 

+ 1 - 1
pkg/controllers/externalsecret/externalsecret_controller_template.go

@@ -34,7 +34,7 @@ import (
 // * template.TemplateFrom
 // * secret via es.data or es.dataFrom (if template.MergePolicy is Merge, or there is no template)
 // * existing secret keys (if CreationPolicy is Merge).
-func (r *Reconciler) applyTemplate(ctx context.Context, es *esv1.ExternalSecret, secret *v1.Secret, dataMap map[string][]byte) error {
+func (r *Reconciler) ApplyTemplate(ctx context.Context, es *esv1.ExternalSecret, secret *v1.Secret, dataMap map[string][]byte) error {
 	// update metadata (labels, annotations) of the secret
 	if err := setMetadata(secret, es); err != nil {
 		return err