func (r *NifiUserReconciler) SetupWithManager(mgr ctrl.Manager, certManagerEnabled bool) error {
	builder := ctrl.NewControllerManagedBy(mgr).
		For(&v1alpha1.NifiUser{}).
		Owns(&corev1.Secret{})
	if certManagerEnabled {
		builder.Owns(&certv1.Certificate{})
	}
	return builder.Complete(r)
}
SetupWithManager sets up the controller with the Manager.
package controllers
import (
	"context"
	"emperror.dev/errors"
	"encoding/json"
	"fmt"
	usercli "github.com/Orange-OpenSource/nifikop/pkg/clientwrappers/user"
	"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/pki"
	"github.com/Orange-OpenSource/nifikop/pkg/util"
	"github.com/Orange-OpenSource/nifikop/pkg/util/clientconfig"
	"github.com/banzaicloud/k8s-objectmatcher/patch"
	"github.com/go-logr/logr"
	certv1 "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1alpha2"
	corev1 "k8s.io/api/core/v1"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/client-go/tools/record"
	"reflect"
	ctrl "sigs.k8s.io/controller-runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/reconcile"
	"time"
	"github.com/Orange-OpenSource/nifikop/api/v1alpha1"
)
var userFinalizer = "nifiusers.nifi.orange.com/finalizer"
type NifiUserReconciler struct {
	client.Client
	Log      logr.Logger
	Scheme   *runtime.Scheme
	Recorder record.EventRecorder
}
func (r *NifiUserReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	_ = r.Log.WithValues("nifiuser", req.NamespacedName)
	var err error
	instance := &v1alpha1.NifiUser{}
	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 NifiUser", err)
		}
		o, err = patch.DefaultAnnotator.GetOriginalConfiguration(instance)
	}
	original := &v1alpha1.NifiUser{}
	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 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 gone already, there is nothing we can do")
			if err = r.removeFinalizer(ctx, instance); err != nil {
				return RequeueWithError(r.Log, "failed to remove finalizer from NifiUser", 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 NifiUser", 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)
	}
	var cluster *v1alpha1.NifiCluster
	if cluster, err = k8sutil.LookupNifiCluster(r.Client, instance.Spec.ClusterRef.Name, clusterRef.Namespace); err != nil {
		if k8sutil.IsMarkedForDeletion(instance.ObjectMeta) {
			r.Log.Info("Cluster is gone already, there is nothing we can do")
			if err = r.removeFinalizer(ctx, instance); err != nil {
				return RequeueWithError(r.Log, "failed to remove finalizer from NifiUser", err)
			}
			return Reconciled()
		}
	}
	if v1alpha1.ClusterRefsEquals([]v1alpha1.ClusterReference{instance.Spec.ClusterRef, current.Spec.ClusterRef}) &&
		instance.Spec.GetCreateCert() && !clusterConnect.IsExternal() {
		if cluster.Spec.ListenersConfig.SSLSecrets == nil {
			return RequeueWithError(r.Log, "could not create Nifi user since cluster does not use ssl", errors.New("failed to create Nifi user"))
		}
		pkiManager := pki.GetPKIManager(r.Client, cluster)
		r.Recorder.Event(instance, corev1.EventTypeNormal, "ReconcilingCertificate",
			fmt.Sprintf("Reconciling certificate for nifi user %s", instance.Name))
		_, err := pkiManager.ReconcileUserCertificate(ctx, instance, r.Scheme)
		if err != nil {
			switch errors.Cause(err).(type) {
			case errorfactory.ResourceNotReady:
				r.Log.Info("generated secret not found, may not be ready")
				return ctrl.Result{
					Requeue:      true,
					RequeueAfter: time.Duration(5) * time.Second,
				}, nil
			case errorfactory.FatalReconcileError:
				r.Log.Error(err, "Fatal error attempting to reconcile the user certificate. If using vault perhaps a permissions issue or improperly configured PKI?")
				return ctrl.Result{
					Requeue:      true,
					RequeueAfter: time.Duration(15) * time.Second,
				}, nil
			case errorfactory.VaultAPIFailure:
				r.Log.Error(err, "Vault API error attempting to reconcile the user certificate. If using vault perhaps a permissions issue or improperly configured PKI?")
				return ctrl.Result{
					Requeue:      true,
					RequeueAfter: time.Duration(15) * time.Second,
				}, nil
			default:
				return RequeueWithError(r.Log, "failed to reconcile user secret", err)
			}
		}
		r.Recorder.Event(instance, corev1.EventTypeNormal, "ReconciledCertificate",
			fmt.Sprintf("Reconciled certificate for nifi user %s", instance.Name))
		if k8sutil.IsMarkedForDeletion(instance.ObjectMeta) {
			r.Log.Info("Nifi user is marked for deletion, revoking certificates")
			if err = pkiManager.FinalizeUserCertificate(ctx, instance); err != nil {
				return RequeueWithError(r.Log, "failed to finalize user certificate", 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, 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 := usercli.RemoveUser(instance, clientConfig); err != nil {
			r.Recorder.Event(instance, corev1.EventTypeWarning, "RemoveError",
				fmt.Sprintf("Failed to delete NifiUser %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 NifiUser 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 NifiUser", err)
		}
		return RequeueAfter(time.Duration(15) * time.Second)
	}
	r.Recorder.Event(instance, corev1.EventTypeNormal, "Reconciling",
		fmt.Sprintf("Reconciling user %s", instance.Name))
	exist, err := usercli.ExistUser(instance, clientConfig)
	if err != nil {
		return RequeueWithError(r.Log, "failure checking for existing registry client", err)
	}
	if !exist {
		r.Recorder.Event(instance, corev1.EventTypeNormal, "Creating",
			fmt.Sprintf("Creating user %s", instance.Name))
		var status *v1alpha1.NifiUserStatus
		status, err = usercli.FindUserByIdentity(instance, clientConfig)
		if err != nil {
			return RequeueWithError(r.Log, "failure finding user", err)
		}
		if status == nil {
			status, err = usercli.CreateUser(instance, clientConfig)
			if err != nil {
				return RequeueWithError(r.Log, "failure creating user", err)
			}
		}
		instance.Status = *status
		if err := r.Client.Status().Update(ctx, instance); err != nil {
			return RequeueWithError(r.Log, "failed to update NifiUser status", err)
		}
		r.Recorder.Event(instance, corev1.EventTypeNormal, "Created",
			fmt.Sprintf("Created user %s", instance.Name))
	}
	r.Recorder.Event(instance, corev1.EventTypeNormal, "Synchronizing",
		fmt.Sprintf("Synchronizing user %s", instance.Name))
	status, err := usercli.SyncUser(instance, clientConfig)
	if err != nil {
		return RequeueWithError(r.Log, "failed to sync NifiUser", err)
	}
	instance.Status = *status
	if err := r.Client.Status().Update(ctx, instance); err != nil {
		return RequeueWithError(r.Log, "failed to update NifiUser status", err)
	}
	r.Recorder.Event(instance, corev1.EventTypeNormal, "Synchronized",
		fmt.Sprintf("Synchronized user %s", instance.Name))
	if instance, err = r.ensureClusterLabel(ctx, clusterConnect, instance); err != nil {
		return RequeueWithError(r.Log, "failed to ensure NifiCluster label on user", err)
	}
	if !util.StringSliceContains(instance.GetFinalizers(), userFinalizer) {
		r.addFinalizer(instance)
		if instance, err = r.updateAndFetchLatest(ctx, instance); err != nil {
			return RequeueWithError(r.Log, "failed to update NifiUser with finalizer", err)
		}
	}
	if instance, err = r.updateAndFetchLatest(ctx, instance); err != nil {
		return RequeueWithError(r.Log, "failed to update NifiUser", err)
	}
	r.Recorder.Event(instance, corev1.EventTypeNormal, "Reconciled",
		fmt.Sprintf("Reconciling user %s", instance.Name))
	r.Log.Info("Ensured user")
	return RequeueAfter(time.Duration(15) * time.Second)
}