pkg/config/runtime_config.go (111 lines of code) (raw):
package config
import (
"time"
"github.com/aws/amazon-network-policy-controller-k8s/api/v1alpha1"
"github.com/aws/amazon-network-policy-controller-k8s/pkg/k8s"
networkingv1 "k8s.io/api/networking/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
"github.com/spf13/pflag"
)
const (
flagKubeconfig = "kubeconfig"
flagMetricsBindAddr = "metrics-bind-addr"
flagHealthProbeBindAddr = "health-probe-bind-addr"
flagEnableLeaderElection = "enable-leader-election"
flagLeaderElectionID = "leader-election-id"
flagLeaderElectionNamespace = "leader-election-namespace"
flagWatchNamespace = "watch-namespace"
defaultKubeconfig = ""
defaultLeaderElectionID = "amazon-network-policy-controller-k8s"
defaultLeaderElectionNamespace = ""
defaultWatchNamespace = corev1.NamespaceAll
defaultMetricsAddr = ":8080"
defaultHealthProbeBindAddress = ":8081"
defaultQPS = 20
defaultBurst = 100
)
// RuntimeConfig stores the configuration for the controller-runtime
type RuntimeConfig struct {
APIServer string
KubeConfig string
MetricsBindAddress string
HealthProbeBindAddress string
EnableLeaderElection bool
LeaderElectionID string
LeaderElectionNamespace string
WatchNamespace string
SyncPeriod time.Duration
}
func (c *RuntimeConfig) BindFlags(fs *pflag.FlagSet) {
fs.StringVar(&c.KubeConfig, flagKubeconfig, defaultKubeconfig,
"Path to the kubeconfig file containing authorization and API server information.")
fs.StringVar(&c.MetricsBindAddress, flagMetricsBindAddr, defaultMetricsAddr,
"The address the metric endpoint binds to.")
fs.StringVar(&c.HealthProbeBindAddress, flagHealthProbeBindAddr, defaultHealthProbeBindAddress,
"The address the health probes binds to.")
fs.BoolVar(&c.EnableLeaderElection, flagEnableLeaderElection, true,
"Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
fs.StringVar(&c.LeaderElectionID, flagLeaderElectionID, defaultLeaderElectionID,
"Name of the leader election ID to use for this controller")
fs.StringVar(&c.LeaderElectionNamespace, flagLeaderElectionNamespace, defaultLeaderElectionNamespace,
"Name of the leader election ID to use for this controller")
fs.StringVar(&c.WatchNamespace, flagWatchNamespace, defaultWatchNamespace,
"Namespace the controller watches for updates to Kubernetes objects, If empty, all namespaces are watched.")
}
// BuildRestConfig builds the REST config for the controller runtime
// Note: the ByObject opts should include all the objects that the controller watches for
func BuildRestConfig(rtCfg RuntimeConfig) (*rest.Config, error) {
var restCFG *rest.Config
var err error
if rtCfg.KubeConfig == "" {
restCFG, err = rest.InClusterConfig()
} else {
restCFG, err = clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
&clientcmd.ClientConfigLoadingRules{ExplicitPath: rtCfg.KubeConfig}, &clientcmd.ConfigOverrides{}).ClientConfig()
}
if err != nil {
return nil, err
}
restCFG.QPS = defaultQPS
restCFG.Burst = defaultBurst
return restCFG, nil
}
// BuildCacheOptions returns a cache.Options struct for this controller.
func BuildCacheOptions() cache.Options {
cacheOptions := cache.Options{
ReaderFailOnMissingInformer: true,
ByObject: map[client.Object]cache.ByObject{
&corev1.Pod{}: {
Transform: k8s.StripDownPodTransformFunc,
},
&corev1.Service{}: {
Transform: k8s.StripDownServiceTransformFunc,
},
&corev1.Namespace{}: {},
&networkingv1.NetworkPolicy{}: {},
&v1alpha1.PolicyEndpoint{}: {},
},
}
return cacheOptions
}
// BuildRuntimeOptions builds the options for the controller runtime based on config
func BuildRuntimeOptions(rtCfg RuntimeConfig, scheme *runtime.Scheme) ctrl.Options {
cacheOptions := BuildCacheOptions()
// if WatchNamespace in Options is not set, cache will watch for all namespaces
if rtCfg.WatchNamespace != corev1.NamespaceAll {
cacheOptions.DefaultNamespaces = map[string]cache.Config{
rtCfg.WatchNamespace: {},
}
}
return ctrl.Options{
Scheme: scheme,
Metrics: metricsserver.Options{BindAddress: rtCfg.MetricsBindAddress},
HealthProbeBindAddress: rtCfg.HealthProbeBindAddress,
LeaderElection: rtCfg.EnableLeaderElection,
LeaderElectionID: rtCfg.LeaderElectionID,
LeaderElectionNamespace: rtCfg.LeaderElectionNamespace,
Cache: cacheOptions,
}
}