func (b *AdapterBase) Informers() (informers.SharedInformerFactory, error) {
	if b.informers == nil {
		clientConfig, err := b.ClientConfig()
		if err != nil {
			return nil, err
		}
		kubeClient, err := kubernetes.NewForConfig(clientConfig)
		if err != nil {
			return nil, err
		}
		b.informers = informers.NewSharedInformerFactory(kubeClient, 0)
	}
	return b.informers, nil
}
Informers returns a SharedInformerFactory for constructing new informers.
The informers will be automatically started as part of starting the adapter.
package cmd
import (
	"fmt"
	"sync"
	"time"
	"github.com/spf13/pflag"
	apimeta "k8s.io/apimachinery/pkg/api/meta"
	"k8s.io/client-go/discovery"
	"k8s.io/client-go/dynamic"
	"k8s.io/client-go/informers"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
	openapicommon "k8s.io/kube-openapi/pkg/common"
	"sigs.k8s.io/custom-metrics-apiserver/pkg/apiserver"
	"sigs.k8s.io/custom-metrics-apiserver/pkg/cmd/server"
	"sigs.k8s.io/custom-metrics-apiserver/pkg/dynamicmapper"
	"sigs.k8s.io/custom-metrics-apiserver/pkg/provider"
)
type AdapterBase struct {
	*server.CustomMetricsAdapterServerOptions
	Name string
	RemoteKubeConfigFile string
	DiscoveryInterval time.Duration
	FlagSet *pflag.FlagSet
	OpenAPIConfig *openapicommon.Config
	flagOnce sync.Once
	clientConfig    *rest.Config
	discoveryClient discovery.DiscoveryInterface
	restMapper      apimeta.RESTMapper
	dynamicClient   dynamic.Interface
	informers       informers.SharedInformerFactory
	config *apiserver.Config
	server *apiserver.CustomMetricsAdapterServer
	cmProvider provider.CustomMetricsProvider
	emProvider provider.ExternalMetricsProvider
}
func (b *AdapterBase) InstallFlags() {
	b.initFlagSet()
	b.flagOnce.Do(func() {
		if b.CustomMetricsAdapterServerOptions == nil {
			b.CustomMetricsAdapterServerOptions = server.NewCustomMetricsAdapterServerOptions()
			b.CustomMetricsAdapterServerOptions.OpenAPIConfig = b.OpenAPIConfig
		}
		b.SecureServing.AddFlags(b.FlagSet)
		b.Authentication.AddFlags(b.FlagSet)
		b.Authorization.AddFlags(b.FlagSet)
		b.Audit.AddFlags(b.FlagSet)
		b.Features.AddFlags(b.FlagSet)
		b.FlagSet.StringVar(&b.RemoteKubeConfigFile, "lister-kubeconfig", b.RemoteKubeConfigFile,
			"kubeconfig file pointing at the 'core' kubernetes server with enough rights to list "+
				"any described objects")
		b.FlagSet.DurationVar(&b.DiscoveryInterval, "discovery-interval", b.DiscoveryInterval,
			"interval at which to refresh API discovery information")
	})
}
func (b *AdapterBase) initFlagSet() {
	if b.FlagSet == nil {
		b.FlagSet = pflag.CommandLine
	}
}
func (b *AdapterBase) Flags() *pflag.FlagSet {
	b.initFlagSet()
	b.InstallFlags()
	return b.FlagSet
}
func (b *AdapterBase) ClientConfig() (*rest.Config, error) {
	if b.clientConfig == nil {
		var clientConfig *rest.Config
		var err error
		if len(b.RemoteKubeConfigFile) > 0 {
			loadingRules := &clientcmd.ClientConfigLoadingRules{ExplicitPath: b.RemoteKubeConfigFile}
			loader := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{})
			clientConfig, err = loader.ClientConfig()
		} else {
			clientConfig, err = rest.InClusterConfig()
		}
		if err != nil {
			return nil, fmt.Errorf("unable to construct lister client config to initialize provider: %v", err)
		}
		b.clientConfig = clientConfig
	}
	return b.clientConfig, nil
}
func (b *AdapterBase) DiscoveryClient() (discovery.DiscoveryInterface, error) {
	if b.discoveryClient == nil {
		clientConfig, err := b.ClientConfig()
		if err != nil {
			return nil, err
		}
		discoveryClient, err := discovery.NewDiscoveryClientForConfig(clientConfig)
		if err != nil {
			return nil, fmt.Errorf("unable to construct discovery client for dynamic client: %v", err)
		}
		b.discoveryClient = discoveryClient
	}
	return b.discoveryClient, nil
}
func (b *AdapterBase) RESTMapper() (apimeta.RESTMapper, error) {
	if b.restMapper == nil {
		discoveryClient, err := b.DiscoveryClient()
		if err != nil {
			return nil, err
		}
		dynamicMapper, err := dynamicmapper.NewRESTMapper(discoveryClient, b.DiscoveryInterval)
		if err != nil {
			return nil, fmt.Errorf("unable to construct dynamic discovery mapper: %v", err)
		}
		b.restMapper = dynamicMapper
	}
	return b.restMapper, nil
}
func (b *AdapterBase) DynamicClient() (dynamic.Interface, error) {
	if b.dynamicClient == nil {
		clientConfig, err := b.ClientConfig()
		if err != nil {
			return nil, err
		}
		dynClient, err := dynamic.NewForConfig(clientConfig)
		if err != nil {
			return nil, fmt.Errorf("unable to construct lister client to initialize provider: %v", err)
		}
		b.dynamicClient = dynClient
	}
	return b.dynamicClient, nil
}
func (b *AdapterBase) WithCustomMetrics(p provider.CustomMetricsProvider) {
	b.cmProvider = p
}
func (b *AdapterBase) WithExternalMetrics(p provider.ExternalMetricsProvider) {
	b.emProvider = p
}
func (b *AdapterBase) Config() (*apiserver.Config, error) {
	if b.config == nil {
		b.InstallFlags()  
		config, err := b.CustomMetricsAdapterServerOptions.Config()
		if err != nil {
			return nil, err
		}
		b.config = config
	}
	return b.config, nil
}
func (b *AdapterBase) Server() (*apiserver.CustomMetricsAdapterServer, error) {
	if b.server == nil {
		config, err := b.Config()
		if err != nil {
			return nil, err
		}
		if b.Name == "" {
			b.Name = "custom-metrics-adapter"
		}
		server, err := config.Complete(b.informers).New(b.Name, b.cmProvider, b.emProvider)
		if err != nil {
			return nil, err
		}
		b.server = server
	}
	return b.server, nil
}