func (c *Controller) Run(stopCh <-chan struct{}) {
	defer utilruntime.HandleCrash()
	klog.InfoS("starting azurekeyvaultsecret controller")
	c.akvsInformerFactory.Start(stopCh)
	c.kubeInformerFactory.Start(stopCh)
	for _, v := range c.akvsInformerFactory.WaitForCacheSync(stopCh) {
		if !v {
			runtime.HandleError(errors.Errorf("timed out waiting for caches to sync"))
			return
		}
	}
	for _, v := range c.kubeInformerFactory.WaitForCacheSync(stopCh) {
		if !v {
			runtime.HandleError(errors.Errorf("timed out waiting for caches to sync"))
			return
		}
	}
	klog.InfoS("starting azure key vault secret queue")
	c.akvsCrdQueue.Run(stopCh)
	klog.InfoS("starting azure key vault deleted secret queue")
	c.akvsCrdDeletionQueue.Run(stopCh)
	klog.InfoS("starting azure key vault queue")
	c.azureKeyVaultQueue.Run(stopCh)
	klog.InfoS("started workers")
	<-stopCh
	klog.InfoS("Shutting down workers")
}
Run will start the controller
package controller
import (
	"time"
	"github.com/appscode/go/runtime"
	"github.com/pkg/errors"
	"k8s.io/klog/v2"
	corev1 "k8s.io/api/core/v1"
	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
	"k8s.io/client-go/informers"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/kubernetes/scheme"
	corelisters "k8s.io/client-go/listers/core/v1"
	"k8s.io/client-go/tools/record"
	"kmodules.xyz/client-go/tools/queue"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promauto"
	vault "github.com/SparebankenVest/azure-key-vault-to-kubernetes/pkg/azure/keyvault/client"
	akvcs "github.com/SparebankenVest/azure-key-vault-to-kubernetes/pkg/k8s/client/clientset/versioned"
	keyvaultScheme "github.com/SparebankenVest/azure-key-vault-to-kubernetes/pkg/k8s/client/clientset/versioned/scheme"
	akvInformers "github.com/SparebankenVest/azure-key-vault-to-kubernetes/pkg/k8s/client/informers/externalversions"
	listers "github.com/SparebankenVest/azure-key-vault-to-kubernetes/pkg/k8s/client/listers/azurekeyvault/v2beta1"
)
const (
	SuccessSynced = "Synced"
	ErrResourceExists = "ErrResourceExists"
	ErrAzureVault = "ErrAzureVault"
	ErrConfigMap = "ErrConfigMap"
	FailedAzureKeyVault = "Failed to get secret for '%s' from Azure Key Vault '%s'"
	MessageResourceExists = "Resource '%s' already exists and is not managed by AzureKeyVaultSecret"
	MessageAzureKeyVaultSecretSynced = "AzureKeyVaultSecret synced to Kubernetes Secret successfully"
	MessageAzureKeyVaultSecretSyncedWithAzureKeyVault = "AzureKeyVaultSecret synced to Kubernetes Secret successfully with change from Azure Key Vault"
	ControllerName = "Akv2k8s controller"
)
var (
	syncCounter = promauto.NewCounterVec(prometheus.CounterOpts{
		Name: "akv2k8s_syncs_total",
		Help: "The total number of syncs",
	}, []string{"operation", "object"})
	syncFailures = promauto.NewCounterVec(prometheus.CounterOpts{
		Name: "akv2k8s_syncs_failed_total",
		Help: "The total number of sync failures",
	}, []string{"operation", "object"})
)
type NamespaceSelectorLabel struct {
	Name  string
	Value string
}
type CABundle struct {
	ConfigMapName   string
	SecretNamespace string
	SecretName      string
}
type Controller struct {
	kubeclientset       kubernetes.Interface
	akvsClient          akvcs.Interface
	vaultService        vault.Service
	recorder            record.EventRecorder
	kubeInformerFactory informers.SharedInformerFactory
	namespaceAkvsLabel  string
	secretsLister corelisters.SecretLister
	configMapsLister corelisters.ConfigMapLister
	azureKeyVaultSecretLister listers.AzureKeyVaultSecretLister
	akvsInformerFactory       akvInformers.SharedInformerFactory
	akvsCrdQueue              *queue.Worker
	akvsCrdDeletionQueue      *queue.Worker
	azureKeyVaultQueue        *queue.Worker
	options *Options
	clock   Timer
}
type Options struct {
	NumThreads     int
	MaxNumRequeues int
	ResyncPeriod   time.Duration
	AkvsRef        corev1.ObjectReference
}
func NewController(client kubernetes.Interface, akvsClient akvcs.Interface, akvInformerFactory akvInformers.SharedInformerFactory, kubeInformerFactory informers.SharedInformerFactory, recorder record.EventRecorder, vaultService vault.Service, options *Options) *Controller {
	utilruntime.Must(keyvaultScheme.AddToScheme(scheme.Scheme))
	controller := &Controller{
		kubeclientset: client,
		akvsClient:    akvsClient,
		recorder:      recorder,
		vaultService:  vaultService,
		akvsInformerFactory: akvInformerFactory,
		kubeInformerFactory: kubeInformerFactory,
		secretsLister:             kubeInformerFactory.Core().V1().Secrets().Lister(),
		configMapsLister:          kubeInformerFactory.Core().V1().ConfigMaps().Lister(),
		azureKeyVaultSecretLister: akvInformerFactory.AzureKeyVault().V2beta1().AzureKeyVaultSecrets().Lister(),
		options: options,
		clock:   &Clock{},
	}
	controller.akvsCrdQueue = queue.New("AzureKeyVaultSecrets", options.MaxNumRequeues, options.NumThreads, controller.syncAzureKeyVaultSecret)
	controller.akvsCrdDeletionQueue = queue.New("DeletedAzureKeyVaultSecrets", options.MaxNumRequeues, options.NumThreads, controller.syncDeletedAzureKeyVaultSecret)
	controller.azureKeyVaultQueue = queue.New("AzureKeyVault", options.MaxNumRequeues, options.NumThreads, controller.syncAzureKeyVault)
	klog.InfoS("setting up event handlers")
	controller.initAzureKeyVaultSecret()
	return controller
}