func (c *Controller) deleteHandler(obj interface{}) {
	var err error
	var key string
	if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil {
		runtime.HandleError(err)
		return
	}
	hr := obj.(*v1alpha1.HelmRequest)
	klog.Infof("receive delete event: %+v", hr)
	outdated, err := c.isOldEvent("", hr)
	if err != nil {
		c.sendFailedDeleteEvent(hr, err)
		runtime.HandleError(err)
		c.workQueue.AddRateLimited(key)
		return
	}
	if outdated {
		return
	}
	err = c.deleteHelmRequest(hr)
	if err != nil {
		c.sendFailedDeleteEvent(hr, err)
		runtime.HandleError(err)
		c.workQueue.AddRateLimited(key)
	} else {
		c.getEventRecorder(hr).Event(hr, v1.EventTypeNormal, SuccessfulDelete,
			fmt.Sprintf("Deleted HelmRequest: %s", hr.GetName()))
	}
}
deleteHandler is delete handler for HelmRequest in global cluster
package controller
import (
	"fmt"
	"strings"
	"github.com/alauda/captain/pkg/cluster"
	"github.com/alauda/captain/pkg/helm"
	"github.com/alauda/captain/pkg/util"
	"github.com/alauda/helm-crds/pkg/apis/app/v1alpha1"
	"github.com/thoas/go-funk"
	"k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
	utilerrors "k8s.io/apimachinery/pkg/util/errors"
	"k8s.io/apimachinery/pkg/util/runtime"
	"k8s.io/client-go/tools/cache"
	"k8s.io/klog"
)
func (c *Controller) syncHandler(key string) error {
	klog.Infof("Start sync helmrequest: %s", key)
	clusterName, key := splitClusterKey(key)
	namespace, name, err := cache.SplitMetaNamespaceKey(key)
	if err != nil {
		runtime.HandleError(fmt.Errorf("invalid resource key: %s", key))
		return nil
	}
	helmRequest, err := c.getClusterAppClient(clusterName).AppV1alpha1().HelmRequests(namespace).Get(name, metav1.GetOptions{})
	if err != nil {
		if errors.IsNotFound(err) {
			runtime.HandleError(fmt.Errorf("helmRequest '%s' in work queue no longer exists", key))
			return nil
		}
		return err
	}
	if helmRequest.Annotations != nil {
		if helmRequest.Annotations[util.NoSyncAnotation] == "true" {
			klog.Info("found helmrequest want to be ignored by captain: ", helmRequest.Name)
			return nil
		}
	}
	helmRequest.ClusterName = clusterName
	if !helmRequest.DeletionTimestamp.IsZero() {
		klog.Infof("HelmRequest has not nil DeletionTimestamp, starting to delete it: %s", helmRequest.Name)
		if err := c.deleteHelmRequest(helmRequest); err != nil {
			c.sendFailedDeleteEvent(helmRequest, err)
			return err
		}
		return nil
	}
	if err := c.addFinalizer(helmRequest); err != nil {
		klog.Errorf("add finalizer for helmrequest %s error, err is: %+v", helmRequest.Name, err)
		c.sendFailedSyncEvent(helmRequest, err)
		return err
	}
	if err := c.checkDependenciesForHelmRequest(helmRequest); err != nil {
		klog.Infof("check dependencies for %s not pass, err is : %+v", helmRequest.Name, err)
		c.sendFailedSyncEvent(helmRequest, err)
		return err
	}
	klog.Infof("dependency check pass for HelmRequest %s", helmRequest.GetName())
	if !helmRequest.Spec.InstallToAllClusters {
		if helm.IsHelmRequestSynced(helmRequest) {
			klog.Infof("HelmRequest %s synced", helmRequest.Name)
			if helmRequest.Status.Phase != v1alpha1.HelmRequestSynced {
				klog.Infof("helm request phase not synced, trying to set it")
				helmRequest.Status.Reason = ""
				return c.updateHelmRequestPhase(helmRequest, v1alpha1.HelmRequestSynced)
			}
			return nil
		}
		c.setPendingStatus(helmRequest)
		klog.Infof("sync HelmRequest %s to cluster %s", key, helmRequest.Spec.ClusterName)
		if err := c.syncToCluster(helmRequest); err != nil {
			c.setSyncFailedStatus(helmRequest, err)
			return err
		}
	} else if err := c.syncToAllClusters(key, helmRequest); err != nil {
		c.setSyncFailedStatus(helmRequest, err)
		return err
	}
	c.getEventRecorder(helmRequest).Event(helmRequest, v1.EventTypeNormal, SuccessSynced, MessageResourceSynced)
	return nil
}
func (c *Controller) syncToCluster(helmRequest *v1alpha1.HelmRequest) error {
	clusterName := c.getDeployCluster(helmRequest)
	info, err := c.getClusterInfo(clusterName)
	if err != nil {
		klog.Errorf("get cluster info error: %s", err.Error())
		return err
	}
	klog.Infof("get cluster %s  endpoint: %s", info.Name, info.Endpoint)
	if err := c.sync(info, helmRequest); err != nil {
		return err
	}
	err = c.updateHelmRequestStatus(helmRequest)
	return err
}
func (c *Controller) enqueueHelmRequest(obj interface{}) {
	var key string
	var err error
	if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil {
		runtime.HandleError(err)
		return
	}
	c.workQueue.Add(key)
}
func (c *Controller) isOldEvent(cluster string, hr *v1alpha1.HelmRequest) (bool, error) {
	current, err := c.getAppClient(hr).AppV1alpha1().HelmRequests(hr.Namespace).Get(hr.Name, metav1.GetOptions{})
	if err != nil {
		if errors.IsNotFound(err) {
			klog.Info("helmrequest not found when check version for delete, ignore")
			return false, nil
		}
		return false, err
	}
	if current.UID != hr.UID {
		klog.Warningf("received old delete event for helmrequest: %s %s %s", hr.Name, hr.UID, current.UID)
		return true, nil
	}
	return false, nil
}