package config import ( "flag" "fmt" "time" "github.com/spf13/afero" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/cache" ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" "edge-infra.dev/pkg/edge/info" kuberetryclient "edge-infra.dev/pkg/sds/lib/k8s/retryclient" kubeclienttypes "edge-infra.dev/pkg/sds/lib/k8s/retryclient/types" ) type Config struct { KubeRetryClient kubeclienttypes.Retrier Cache cache.Cache Fs afero.Fs } func (cf *Config) BindFlags(flags *flag.FlagSet) { flags.StringVar( &info.EdgeConfigMapNS, "edge-configmap-namespace", info.DefaultEdgeConfigMapNS, "Optionally override edge info config map namespace. This is mainly useful for integration tests which run in a shared cluster.", ) } func New(fs afero.Fs) (*Config, error) { client, err := newKubeClient() if err != nil { return nil, err } reader, err := newKubeReader() if err != nil { return nil, err } cfg := &Config{ KubeRetryClient: kuberetryclient.New(client, reader, kuberetryclient.Config{}), Cache: reader, Fs: fs, } return cfg, nil } // newKubeClient creates a new Kubernetes client without read cache. func newKubeClient() (ctrlclient.Client, error) { config, err := rest.InClusterConfig() if err != nil { return nil, fmt.Errorf("unable to load in-cluster config: %v", err) } opts := ctrlclient.Options{ Scheme: createScheme(), } return ctrlclient.New(config, opts) } // newKubeReader creates a new Kubernetes client with read cache. func newKubeReader() (cache.Cache, error) { config, err := rest.InClusterConfig() if err != nil { return nil, fmt.Errorf("unable to load in-cluster config: %v", err) } resync := 1 * time.Hour opts := cache.Options{ Scheme: createScheme(), SyncPeriod: &resync, ByObject: map[ctrlclient.Object]cache.ByObject{ &corev1.ConfigMap{}: { Field: fields.SelectorFromSet(fields.Set{ "metadata.name": info.EdgeConfigMapName, "metadata.namespace": info.EdgeConfigMapNS, }), }, }, } return cache.New(config, opts) } // createScheme creates a new scheme with the EtcdMember type registered func createScheme() *runtime.Scheme { scheme := runtime.NewScheme() utilruntime.Must(clientgoscheme.AddToScheme(scheme)) return scheme }