cloud-provider-pve/cmd/pve-csr-approver-manager/main.go
2021-12-08 22:12:44 +01:00

151 lines
3.7 KiB
Go

package main
import (
"encoding/json"
"errors"
"flag"
"io/ioutil"
"math/rand"
"os"
"time"
"k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
typedcertificatesv1 "k8s.io/client-go/kubernetes/typed/certificates/v1"
"k8s.io/klog/v2"
"k8s.io/klog/v2/klogr"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"git.giftfish.de/ston1th/cloud-controller-manager-pve/pkg/approver"
pve "git.giftfish.de/ston1th/pve-go"
)
type config struct {
PVE pve.Config `json:"pve"`
}
var (
scheme = runtime.NewScheme()
setupLog = ctrl.Log.WithName("setup")
leaderElect bool
healthAddr string
cloudConfig string
csrConcurrency int
syncPeriod time.Duration
)
const name = "pve-csr-approver-manager"
func init() {
_ = clientgoscheme.AddToScheme(scheme)
}
func main() {
rand.Seed(time.Now().UnixNano())
klog.InitFlags(nil)
ctrl.SetLogger(klogr.New())
initFlags()
flag.Parse()
rcfg := ctrl.GetConfigOrDie()
rcfg.UserAgent = name
mgr, err := ctrl.NewManager(rcfg, ctrl.Options{
Scheme: scheme,
LeaderElection: leaderElect,
LeaderElectionID: name,
LeaderElectionResourceLock: "leases",
HealthProbeBindAddress: healthAddr,
MetricsBindAddress: "0",
SyncPeriod: &syncPeriod,
})
if err != nil {
setupLog.Error(err, "unable to start manager")
os.Exit(1)
}
var opts []pve.ClientOption
cr, err := os.Open(cloudConfig)
if err == nil {
buf, _ := ioutil.ReadAll(cr)
if len(buf) != 0 {
var cfg config
err = json.Unmarshal(buf, &cfg)
if err != nil {
setupLog.Error(err, "failed to read config file")
os.Exit(1)
}
opts, err = pve.ClientOptionsFromConfig(cfg.PVE)
if err != nil {
setupLog.Error(err, "failed to create client options from file")
os.Exit(1)
}
}
} else {
opts, err = pve.ClientOptionsFromEnv()
if err != nil {
setupLog.Error(err, "failed to create client options from env")
os.Exit(1)
}
}
if len(opts) == 0 {
setupLog.Error(errors.New("missing pve config"), "")
os.Exit(1)
}
pveClient := pve.NewClient(opts...)
if err = (&approver.CSRReconciler{
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controllers").WithName("approver"),
Scheme: mgr.GetScheme(),
PVEClient: pveClient,
CSRClient: typedcertificatesv1.NewForConfigOrDie(rcfg),
}).SetupWithManager(mgr, controller.Options{MaxConcurrentReconciles: csrConcurrency}); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "approver")
os.Exit(1)
}
if err := mgr.AddReadyzCheck("ping", healthz.Ping); err != nil {
setupLog.Error(err, "unable to create ready check")
os.Exit(1)
}
if err := mgr.AddHealthzCheck("ping", healthz.Ping); err != nil {
setupLog.Error(err, "unable to create health check")
os.Exit(1)
}
setupLog.Info("starting manager")
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
setupLog.Error(err, "problem running manager")
os.Exit(1)
}
}
func initFlags() {
flag.BoolVar(&leaderElect, "leader-elect", true,
"Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
flag.StringVar(&cloudConfig,
"cloud-config",
"",
"The path to the cloud provider configuration file. Empty string for no configuration file.",
)
flag.StringVar(&healthAddr,
"health-addr",
":9449",
"The address the health endpoint binds to.",
)
flag.IntVar(&csrConcurrency,
"csr-concurrency",
1,
"Number of CSRs to process simultaneously",
)
flag.DurationVar(&syncPeriod,
"sync-period",
10*time.Minute,
"The minimum interval at which watched resources are reconciled (e.g. 15m)",
)
}