func (c *Cluster) Stop() {
	c.cancelContext()
}
Stop cancel/close the cache to terminate informers.
package cluster
import (
	"context"
	"fmt"
	"time"
	"k8s.io/apimachinery/pkg/api/meta"
	"k8s.io/apimachinery/pkg/runtime"
	clientset "k8s.io/client-go/kubernetes"
	"k8s.io/client-go/kubernetes/scheme"
	"k8s.io/client-go/rest"
	restclient "k8s.io/client-go/rest"
	clientgocache "k8s.io/client-go/tools/cache"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/klog"
	"sigs.k8s.io/controller-runtime/pkg/cache"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
	"sigs.k8s.io/cluster-api-provider-nested/virtualcluster/pkg/util/constants"
	"sigs.k8s.io/cluster-api-provider-nested/virtualcluster/pkg/util/mccontroller"
)
type Cluster struct {
	key string
	name string
	namespace string
	uid string
	RestConfig *rest.Config
	getter mccontroller.Getter
	scheme *runtime.Scheme
	mapper meta.RESTMapper
	cache            cache.Cache
	delegatingClient client.Client
	client *clientset.Clientset
	options Options
	synced bool
	cancelContext context.CancelFunc
	context context.Context
}
type Options struct {
	CacheOptions
	RequestTimeout time.Duration
}
type CacheOptions struct {
	Resync *time.Duration
	WatchNamespace string
}
var _ mccontroller.ClusterInterface = &Cluster{}
func NewCluster(key, namespace, name, uid string, getter mccontroller.Getter, configBytes []byte, o Options) (*Cluster, error) {
	clusterRestConfig, err := clientcmd.RESTConfigFromKubeConfig(configBytes)
	if err != nil {
		return nil, fmt.Errorf("failed to build rest config: %v", err)
	}
	if o.RequestTimeout == 0 {
		clusterRestConfig.Timeout = constants.DefaultRequestTimeout
	}
	if clusterRestConfig.QPS == 0 {
		clusterRestConfig.QPS = constants.DefaultSyncerClientQPS
	}
	if clusterRestConfig.Burst == 0 {
		clusterRestConfig.Burst = constants.DefaultSyncerClientBurst
	}
	return &Cluster{
		key:        key,
		name:       name,
		namespace:  namespace,
		uid:        uid,
		getter:     getter,
		RestConfig: clusterRestConfig,
		options:    o,
		synced:     false,
		context:    context.Background(),
	}, nil
}
func (c *Cluster) GetClusterName() string {
	return c.key
}
func (c *Cluster) GetOwnerInfo() (string, string, string) {
	return c.name, c.namespace, c.uid
}
func (c *Cluster) GetObject() (client.Object, error) {
	obj, err := c.getter.GetObject(c.namespace, c.name)
	if err != nil {
		return nil, err
	}
	return obj, nil
}
func (c *Cluster) getScheme() *runtime.Scheme {
	return scheme.Scheme
}
func (c *Cluster) GetClientSet() (clientset.Interface, error) {
	if c.client != nil {
		return c.client, nil
	}
	var err error
	c.client, err = clientset.NewForConfig(restclient.AddUserAgent(c.RestConfig, constants.ResourceSyncerUserAgent))
	if err != nil {
		return nil, err
	}
	return c.client, nil
}
func (c *Cluster) getMapper() (meta.RESTMapper, error) {
	if c.mapper != nil {
		return c.mapper, nil
	}
	mapper, err := apiutil.NewDynamicRESTMapper(c.RestConfig)
	if err != nil {
		return nil, err
	}
	c.mapper = mapper
	return mapper, nil
}
func (c *Cluster) getCache() (cache.Cache, error) {
	if c.cache != nil {
		return c.cache, nil
	}
	m, err := c.getMapper()
	if err != nil {
		return nil, err
	}
	ca, err := cache.New(c.RestConfig, cache.Options{
		Scheme:    c.getScheme(),
		Mapper:    m,
		Resync:    c.options.Resync,
		Namespace: c.options.WatchNamespace,
	})
	if err != nil {
		return nil, err
	}
	c.cache = ca
	return ca, nil
}
func (c *Cluster) GetDelegatingClient() (client.Client, error) {
	if !c.synced {
		return nil, fmt.Errorf("The client cache has not been synced yet.")
	}
	if c.delegatingClient != nil {
		return c.delegatingClient, nil
	}
	ca, err := c.getCache()
	if err != nil {
		return nil, err
	}
	m, err := c.getMapper()
	if err != nil {
		return nil, err
	}
	cl, err := client.New(c.RestConfig, client.Options{
		Scheme: c.getScheme(),
		Mapper: m,
	})
	if err != nil {
		return nil, err
	}
	dc, err := client.NewDelegatingClient(client.NewDelegatingClientInput{
		Client:      cl,
		CacheReader: ca,
	})
	if err != nil {
		return nil, err
	}
	c.delegatingClient = dc
	return dc, nil
}
func (c *Cluster) GetRestConfig() *rest.Config {
	return c.RestConfig
}
func (c *Cluster) AddEventHandler(objectType client.Object, handler clientgocache.ResourceEventHandler) error {
	ca, err := c.getCache()
	if err != nil {
		return err
	}
	i, err := ca.GetInformer(context.TODO(), objectType)
	if err != nil {
		return err
	}
	i.AddEventHandler(handler)
	return nil
}
func (c *Cluster) GetInformer(objectType client.Object) (cache.Informer, error) {
	ca, err := c.getCache()
	if err != nil {
		return nil, err
	}
	i, err := ca.GetInformer(context.TODO(), objectType)
	if err != nil {
		return nil, err
	}
	return i, nil
}
func (c *Cluster) Start() error {
	ca, err := c.getCache()
	if err != nil {
		return err
	}
	ctx, cancel := context.WithCancel(c.context)
	c.cancelContext = cancel
	return ca.Start(ctx)
}
func (c *Cluster) WaitForCacheSync() bool {
	ca, err := c.getCache()
	if err != nil {
		klog.Errorf("Fail to get cache: %v", err)
		return false
	}
	return ca.WaitForCacheSync(c.context)
}
func (c *Cluster) SetSynced() {
	c.synced = true
}
func (c *Cluster) SetKey(k string) {
	c.key = k
}