func (r *NifiParameterContextReconciler) SetupWithManager(mgr ctrl.Manager) error {
	return ctrl.NewControllerManagedBy(mgr).
		For(&v1alpha1.NifiParameterContext{}).
		Complete(r)
}
SetupWithManager sets up the controller with the Manager.
package controllers
import (
	"context"
	"emperror.dev/errors"
	"encoding/json"
	"fmt"
	"github.com/Orange-OpenSource/nifikop/pkg/clientwrappers/parametercontext"
	errorfactory "github.com/Orange-OpenSource/nifikop/pkg/errorfactory"
	"github.com/Orange-OpenSource/nifikop/pkg/k8sutil"
	"github.com/Orange-OpenSource/nifikop/pkg/nificlient/config"
	"github.com/Orange-OpenSource/nifikop/pkg/util"
	"github.com/Orange-OpenSource/nifikop/pkg/util/clientconfig"
	"github.com/banzaicloud/k8s-objectmatcher/patch"
	corev1 "k8s.io/api/core/v1"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/client-go/tools/record"
	"reflect"
	"sigs.k8s.io/controller-runtime/pkg/reconcile"
	"time"
	"github.com/go-logr/logr"
	"k8s.io/apimachinery/pkg/runtime"
	ctrl "sigs.k8s.io/controller-runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"github.com/Orange-OpenSource/nifikop/api/v1alpha1"
)
var parameterContextFinalizer = "nifiparametercontexts.nifi.orange.com/finalizer"
type NifiParameterContextReconciler struct {
	client.Client
	Log      logr.Logger
	Scheme   *runtime.Scheme
	Recorder record.EventRecorder
}
func (r *NifiParameterContextReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	_ = r.Log.WithValues("nifiparametercontext", req.NamespacedName)
	var err error
	instance := &v1alpha1.NifiParameterContext{}
	if err = r.Client.Get(ctx, req.NamespacedName, instance); err != nil {
		if apierrors.IsNotFound(err) {
			return Reconciled()
		}
		return RequeueWithError(r.Log, err.Error(), err)
	}
	o, err := patch.DefaultAnnotator.GetOriginalConfiguration(instance)
	if o == nil {
		if err := patch.DefaultAnnotator.SetLastAppliedAnnotation(instance); err != nil {
			return RequeueWithError(r.Log, "could not apply last state to annotation", err)
		}
		if err := r.Client.Update(ctx, instance); err != nil {
			return RequeueWithError(r.Log, "failed to update NifiParameterContext", err)
		}
		o, err = patch.DefaultAnnotator.GetOriginalConfiguration(instance)
	}
	original := &v1alpha1.NifiParameterContext{}
	current := instance.DeepCopy()
	json.Unmarshal(o, original)
	if !v1alpha1.ClusterRefsEquals([]v1alpha1.ClusterReference{original.Spec.ClusterRef, instance.Spec.ClusterRef}) {
		instance.Spec.ClusterRef = original.Spec.ClusterRef
	}
	var parameterSecrets []*corev1.Secret
	for _, parameterSecret := range instance.Spec.SecretRefs {
		secretNamespace := GetSecretRefNamespace(instance.Namespace, parameterSecret)
		var secret *corev1.Secret
		if secret, err = k8sutil.LookupSecret(r.Client, parameterSecret.Name, secretNamespace); err != nil {
			if k8sutil.IsMarkedForDeletion(instance.ObjectMeta) {
				r.Log.Info("Secret is already gone, there is nothing we can do")
				if err = r.removeFinalizer(ctx, instance); err != nil {
					return RequeueWithError(r.Log, "failed to remove finalizer", err)
				}
				return Reconciled()
			}
			return RequeueWithError(r.Log, "failed to lookup referenced secret", err)
		}
		parameterSecrets = append(parameterSecrets, secret)
	}
	var clientConfig *clientconfig.NifiConfig
	var clusterConnect clientconfig.ClusterConnect
	clusterRef := instance.Spec.ClusterRef
	clusterRef.Namespace = GetClusterRefNamespace(instance.Namespace, instance.Spec.ClusterRef)
	configManager := config.GetClientConfigManager(r.Client, clusterRef)
	if clusterConnect, err = configManager.BuildConnect(); err != nil {
		if k8sutil.IsMarkedForDeletion(instance.ObjectMeta) {
			r.Log.Info("Cluster is already gone, there is nothing we can do")
			if err = r.removeFinalizer(ctx, instance); err != nil {
				return RequeueWithError(r.Log, "failed to remove finalizer", err)
			}
			return Reconciled()
		}
		if !v1alpha1.ClusterRefsEquals([]v1alpha1.ClusterReference{instance.Spec.ClusterRef, current.Spec.ClusterRef}) {
			if err := patch.DefaultAnnotator.SetLastAppliedAnnotation(current); err != nil {
				return RequeueWithError(r.Log, "could not apply last state to annotation", err)
			}
			if err := r.Client.Update(ctx, current); err != nil {
				return RequeueWithError(r.Log, "failed to update NifiParameterContext", err)
			}
			return RequeueAfter(time.Duration(15) * time.Second)
		}
		r.Recorder.Event(instance, corev1.EventTypeWarning, "ReferenceClusterError",
			fmt.Sprintf("Failed to lookup reference cluster : %s in %s",
				instance.Spec.ClusterRef.Name, clusterRef.Namespace))
		return RequeueWithError(r.Log, "failed to lookup referenced cluster", err)
	}
	clientConfig, err = configManager.BuildConfig()
	if err != nil {
		r.Recorder.Event(instance, corev1.EventTypeWarning, "ReferenceClusterError",
			fmt.Sprintf("Failed to create HTTP client for the referenced cluster : %s in %s",
				instance.Spec.ClusterRef.Name, clusterRef.Namespace))
		return RequeueWithError(r.Log, "failed to create HTTP client the for referenced cluster", err)
	}
	if k8sutil.IsMarkedForDeletion(instance.ObjectMeta) {
		return r.checkFinalizers(ctx, instance, parameterSecrets, clientConfig)
	}
	if !clusterConnect.IsReady(r.Log) {
		r.Log.Info("Cluster is not ready yet, will wait until it is.")
		r.Recorder.Event(instance, corev1.EventTypeNormal, "ReferenceClusterNotReady",
			fmt.Sprintf("The referenced cluster is not ready yet : %s in %s",
				instance.Spec.ClusterRef.Name, clusterConnect.Id()))
		return RequeueAfter(time.Duration(15) * time.Second)
	}
	if !v1alpha1.ClusterRefsEquals([]v1alpha1.ClusterReference{instance.Spec.ClusterRef, current.Spec.ClusterRef}) {
		if err := parametercontext.RemoveParameterContext(instance, parameterSecrets, clientConfig); err != nil {
			r.Recorder.Event(instance, corev1.EventTypeWarning, "RemoveError",
				fmt.Sprintf("Failed to delete NifiParameterContext %s from cluster %s before moving in %s",
					instance.Name, original.Spec.ClusterRef.Name, original.Spec.ClusterRef.Name))
			return RequeueWithError(r.Log, "Failed to delete NifiParameterContext before moving", err)
		}
		if err := patch.DefaultAnnotator.SetLastAppliedAnnotation(current); err != nil {
			return RequeueWithError(r.Log, "could not apply last state to annotation", err)
		}
		if err := r.Client.Update(ctx, current); err != nil {
			return RequeueWithError(r.Log, "failed to update NifiParameterContext", err)
		}
		return RequeueAfter(time.Duration(15) * time.Second)
	}
	r.Recorder.Event(instance, corev1.EventTypeNormal, "Reconciling",
		fmt.Sprintf("Reconciling parameter context %s", instance.Name))
	exist, err := parametercontext.ExistParameterContext(instance, clientConfig)
	if err != nil {
		return RequeueWithError(r.Log, "failure checking for existing parameter context", err)
	}
	if !exist {
		r.Recorder.Event(instance, corev1.EventTypeNormal, "Creating",
			fmt.Sprintf("Creating parameter context %s", instance.Name))
		status, err := parametercontext.CreateParameterContext(instance, parameterSecrets, clientConfig)
		if err != nil {
			return RequeueWithError(r.Log, "failure creating parameter context", err)
		}
		instance.Status = *status
		if err := r.Client.Status().Update(ctx, instance); err != nil {
			return RequeueWithError(r.Log, "failed to update NifiParameterContext status", err)
		}
		r.Recorder.Event(instance, corev1.EventTypeNormal, "Created",
			fmt.Sprintf("Created parameter context %s", instance.Name))
	}
	r.Recorder.Event(instance, corev1.EventTypeNormal, "Synchronizing",
		fmt.Sprintf("Synchronizing parameter context %s", instance.Name))
	status, err := parametercontext.SyncParameterContext(instance, parameterSecrets, clientConfig)
	if status != nil {
		instance.Status = *status
		if err := r.Client.Status().Update(ctx, instance); err != nil {
			return RequeueWithError(r.Log, "failed to update NifiParameterContext status", err)
		}
	}
	if err != nil {
		switch errors.Cause(err).(type) {
		case errorfactory.NifiParameterContextUpdateRequestRunning:
			return RequeueAfter(time.Duration(5) * time.Second)
		default:
			r.Recorder.Event(instance, corev1.EventTypeNormal, "SynchronizingFailed",
				fmt.Sprintf("Synchronizing parameter context %s failed", instance.Name))
			return RequeueWithError(r.Log, "failed to sync NifiParameterContext", err)
		}
	}
	r.Recorder.Event(instance, corev1.EventTypeNormal, "Synchronized",
		fmt.Sprintf("Synchronized parameter context %s", instance.Name))
	if instance, err = r.ensureClusterLabel(ctx, clusterConnect, instance); err != nil {
		return RequeueWithError(r.Log, "failed to ensure NifiCluster label on parameter context", err)
	}
	if !util.StringSliceContains(instance.GetFinalizers(), parameterContextFinalizer) {
		r.Log.Info("Adding Finalizer for NifiParameterContext")
		instance.SetFinalizers(append(instance.GetFinalizers(), parameterContextFinalizer))
	}
	if instance, err = r.updateAndFetchLatest(ctx, instance); err != nil {
		return RequeueWithError(r.Log, "failed to update NifiParameterContext", err)
	}
	r.Recorder.Event(instance, corev1.EventTypeNormal, "Reconciled",
		fmt.Sprintf("Reconciling parameter context %s", instance.Name))
	r.Log.Info("Ensured Parameter Context")
	return RequeueAfter(time.Duration(15) * time.Second)
}