func newAccountCreateUpdater(ao azurestorage.AccountOperations, kube client.Client, acct *v1alpha3.Account, poll time.Duration) *accountCreateUpdater {
	return &accountCreateUpdater{
		syncbacker:        newAccountSyncBacker(ao, kube, acct, poll),
		AccountOperations: ao,
		kube:              kube,
		acct:              acct,
		poll:              poll,
	}
}
newAccountCreateUpdater new instance of accountCreateUpdater
package account
import (
	"context"
	"reflect"
	"time"
	"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-06-01/storage"
	"github.com/Azure/go-autorest/autorest/to"
	"github.com/pkg/errors"
	corev1 "k8s.io/api/core/v1"
	kerrors "k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/client-go/util/workqueue"
	ctrl "sigs.k8s.io/controller-runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/controller"
	"sigs.k8s.io/controller-runtime/pkg/reconcile"
	xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
	"github.com/crossplane/crossplane-runtime/pkg/logging"
	"github.com/crossplane/crossplane-runtime/pkg/meta"
	"github.com/crossplane/crossplane-runtime/pkg/ratelimiter"
	"github.com/crossplane/crossplane-runtime/pkg/reconciler/managed"
	"github.com/crossplane/crossplane-runtime/pkg/resource"
	"github.com/crossplane/provider-azure/apis/storage/v1alpha3"
	azure "github.com/crossplane/provider-azure/pkg/clients"
	azurestorage "github.com/crossplane/provider-azure/pkg/clients/storage"
)
const (
	controllerName = "account.storage.azure.crossplane.io"
	finalizer      = "finalizer." + controllerName
	reconcileTimeout   = 2 * time.Minute
	requeueAfterOnWait = 30 * time.Second
)
var (
	resultRequeue = reconcile.Result{Requeue: true}
	requeueOnWait = reconcile.Result{RequeueAfter: requeueAfterOnWait}
)
type Reconciler struct {
	client.Client
	syncdeleterMaker
	managed.ReferenceResolver
	managed.Initializer
	poll time.Duration
	log logging.Logger
}
func Setup(mgr ctrl.Manager, l logging.Logger, rl workqueue.RateLimiter, poll time.Duration) error {
	name := managed.ControllerName(v1alpha3.AccountGroupKind)
	r := &Reconciler{
		Client:           mgr.GetClient(),
		syncdeleterMaker: &accountSyncdeleterMaker{mgr.GetClient()},
		Initializer:      managed.NewNameAsExternalName(mgr.GetClient()),
		poll:             poll,
		log:              l.WithValues("controller", name),
	}
	return ctrl.NewControllerManagedBy(mgr).
		Named(name).
		WithOptions(controller.Options{
			RateLimiter: ratelimiter.NewDefaultManagedRateLimiter(rl),
		}).
		For(&v1alpha3.Account{}).
		Owns(&corev1.Secret{}).
		Complete(r)
}
func (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) {
	r.log.Debug("Reconciling", "request", request)
	ctx, cancel := context.WithTimeout(ctx, reconcileTimeout)
	defer cancel()
	b := &v1alpha3.Account{}
	if err := r.Get(ctx, request.NamespacedName, b); err != nil {
		if kerrors.IsNotFound(err) {
			return reconcile.Result{}, nil
		}
		return reconcile.Result{}, err
	}
	if err := r.Initialize(ctx, b); err != nil {
		return reconcile.Result{}, err
	}
	bh, err := r.newSyncdeleter(ctx, b, r.poll)
	if err != nil {
		b.Status.SetConditions(xpv1.ReconcileError(err))
		return resultRequeue, r.Status().Update(ctx, b)
	}
	if b.DeletionTimestamp != nil {
		return bh.delete(ctx)
	}
	return bh.sync(ctx)
}
type syncdeleterMaker interface {
	newSyncdeleter(context.Context, *v1alpha3.Account, time.Duration) (syncdeleter, error)
}
type accountSyncdeleterMaker struct {
	client.Client
}
func (m *accountSyncdeleterMaker) newSyncdeleter(ctx context.Context, b *v1alpha3.Account, poll time.Duration) (syncdeleter, error) {
	creds, auth, err := azure.GetAuthInfo(ctx, m.Client, b)
	if err != nil {
		return nil, errors.Wrap(err, "cannot get auth information")
	}
	cl := storage.NewAccountsClient(creds[azure.CredentialsKeySubscriptionID])
	cl.Authorizer = auth
	return newAccountSyncDeleter(
		azurestorage.NewAccountHandle(&cl, b.Spec.ResourceGroupName, meta.GetExternalName(b)),
		m.Client, b, poll), nil
}
type deleter interface {
	delete(context.Context) (reconcile.Result, error)
}
type syncer interface {
	sync(context.Context) (reconcile.Result, error)
}
type creator interface {
	create(context.Context) (reconcile.Result, error)
}
type updater interface {
	update(context.Context, *storage.Account) (reconcile.Result, error)
}
type syncbacker interface {
	syncback(context.Context, *storage.Account) (reconcile.Result, error)
}
type secretupdater interface {
	updatesecret(ctx context.Context, acct *storage.Account) error
}
type syncdeleter interface {
	deleter
	syncer
}
type accountSyncDeleter struct {
	createupdater
	azurestorage.AccountOperations
	kube client.Client
	acct *v1alpha3.Account
}
func newAccountSyncDeleter(ao azurestorage.AccountOperations, kube client.Client, b *v1alpha3.Account, poll time.Duration) *accountSyncDeleter {
	return &accountSyncDeleter{
		createupdater:     newAccountCreateUpdater(ao, kube, b, poll),
		AccountOperations: ao,
		kube:              kube,
		acct:              b,
	}
}
func (asd *accountSyncDeleter) delete(ctx context.Context) (reconcile.Result, error) {
	asd.acct.Status.SetConditions(xpv1.Deleting())
	switch asd.acct.Spec.DeletionPolicy {
	case xpv1.DeletionDelete, "":
		if err := asd.Delete(ctx); err != nil && !azure.IsNotFound(err) {
			asd.acct.Status.SetConditions(xpv1.ReconcileError(err))
			return resultRequeue, asd.kube.Status().Update(ctx, asd.acct)
		}
	case xpv1.DeletionOrphan:
	}
	meta.RemoveFinalizer(asd.acct, finalizer)
	return reconcile.Result{}, asd.kube.Update(ctx, asd.acct)
}
func (asd *accountSyncDeleter) sync(ctx context.Context) (reconcile.Result, error) {
	account, err := asd.Get(ctx)
	if err != nil && !azure.IsNotFound(err) {
		asd.acct.Status.SetConditions(xpv1.ReconcileError(err))
		return resultRequeue, asd.kube.Status().Update(ctx, asd.acct)
	}
	if account == nil {
		return asd.create(ctx)
	}
	return asd.update(ctx, account)
}
type createupdater interface {
	creator
	updater
}
type accountCreateUpdater struct {
	syncbacker
	azurestorage.AccountOperations
	kube      client.Client
	acct      *v1alpha3.Account
	poll      time.Duration
	projectID string
}