Skip to content

Commit

Permalink
Refactor flag parsing and logging (#187)
Browse files Browse the repository at this point in the history
* Refactor flag parsing and logging

Use idiomatic golang flag parsing. Use propper logging setup instead of
custom logger with custom flags.

* Initialize kubernetes client only if a kubernetes-requiring plugin is enabled

* Use sets when checking if kubernetes client should be initialized

---------

Co-authored-by: Damyan Yordanov <[email protected]>
  • Loading branch information
afritzler and damyan committed Sep 25, 2024
1 parent 1183ade commit 39628e6
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 121 deletions.
26 changes: 12 additions & 14 deletions internal/kubernetes/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,26 @@ package kubernetes
import (
"fmt"

ipamv1alpha1 "github.com/ironcore-dev/ipam/api/ipam/v1alpha1"
metalv1alpha1 "github.com/ironcore-dev/metal-operator/api/v1alpha1"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/config"
)

var kubeClient client.Client
var (
scheme = runtime.NewScheme()
kubeClient client.Client
)

func InitClient() error {
if kubeClient != nil {
return nil
}
func init() {
utilruntime.Must(ipamv1alpha1.AddToScheme(scheme))
utilruntime.Must(metalv1alpha1.AddToScheme(scheme))
}

func InitClient() error {
cfg := config.GetConfigOrDie()

scheme := runtime.NewScheme()
if err := metalv1alpha1.AddToScheme(scheme); err != nil {
return fmt.Errorf("unable to add metalv1alpha1 to scheme: %w", err)
}

var err error
kubeClient, err = client.New(cfg, client.Options{Scheme: scheme})
if err != nil {
Expand All @@ -39,6 +39,4 @@ func SetClient(client *client.Client) {
kubeClient = *client
}

func GetClient() client.Client {
return kubeClient
}
func GetClient() client.Client { return kubeClient }
204 changes: 99 additions & 105 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,147 +4,141 @@
package main

import (
"flag"
"fmt"
"io"
"k8s.io/apimachinery/pkg/util/sets"
"os"
"time"

"github.com/ironcore-dev/fedhcp/internal/kubernetes"

"github.com/coredhcp/coredhcp/config"
"github.com/coredhcp/coredhcp/logger"
"github.com/coredhcp/coredhcp/server"

"github.com/coredhcp/coredhcp/plugins"
pl_autoconfigure "github.com/coredhcp/coredhcp/plugins/autoconfigure"
pl_dns "github.com/coredhcp/coredhcp/plugins/dns"
pl_example "github.com/coredhcp/coredhcp/plugins/example"
pl_file "github.com/coredhcp/coredhcp/plugins/file"
pl_leasetime "github.com/coredhcp/coredhcp/plugins/leasetime"
pl_mtu "github.com/coredhcp/coredhcp/plugins/mtu"
pl_nbp "github.com/coredhcp/coredhcp/plugins/nbp"
pl_netmask "github.com/coredhcp/coredhcp/plugins/netmask"
pl_prefix "github.com/coredhcp/coredhcp/plugins/prefix"
pl_range "github.com/coredhcp/coredhcp/plugins/range"
pl_router "github.com/coredhcp/coredhcp/plugins/router"
pl_searchdomains "github.com/coredhcp/coredhcp/plugins/searchdomains"
pl_serverid "github.com/coredhcp/coredhcp/plugins/serverid"
pl_sleep "github.com/coredhcp/coredhcp/plugins/sleep"
pl_staticroute "github.com/coredhcp/coredhcp/plugins/staticroute"
pl_bluefield "github.com/ironcore-dev/fedhcp/plugins/bluefield"
pl_httpboot "github.com/ironcore-dev/fedhcp/plugins/httpboot"
pl_ipam "github.com/ironcore-dev/fedhcp/plugins/ipam"
pl_metal "github.com/ironcore-dev/fedhcp/plugins/metal"
pl_onmetal "github.com/ironcore-dev/fedhcp/plugins/onmetal"
pl_oob "github.com/ironcore-dev/fedhcp/plugins/oob"
pl_pxeboot "github.com/ironcore-dev/fedhcp/plugins/pxeboot"

"github.com/sirupsen/logrus"
flag "github.com/spf13/pflag"
"github.com/coredhcp/coredhcp/plugins/autoconfigure"
"github.com/coredhcp/coredhcp/plugins/dns"
"github.com/coredhcp/coredhcp/plugins/example"
"github.com/coredhcp/coredhcp/plugins/file"
"github.com/coredhcp/coredhcp/plugins/leasetime"
"github.com/coredhcp/coredhcp/plugins/mtu"
"github.com/coredhcp/coredhcp/plugins/nbp"
"github.com/coredhcp/coredhcp/plugins/netmask"
"github.com/coredhcp/coredhcp/plugins/prefix"
rangeplugin "github.com/coredhcp/coredhcp/plugins/range"
"github.com/coredhcp/coredhcp/plugins/router"
"github.com/coredhcp/coredhcp/plugins/searchdomains"
"github.com/coredhcp/coredhcp/plugins/serverid"
"github.com/coredhcp/coredhcp/plugins/sleep"
"github.com/coredhcp/coredhcp/plugins/staticroute"
"github.com/coredhcp/coredhcp/server"
"github.com/ironcore-dev/fedhcp/internal/kubernetes"
"github.com/ironcore-dev/fedhcp/plugins/bluefield"
"github.com/ironcore-dev/fedhcp/plugins/httpboot"
"github.com/ironcore-dev/fedhcp/plugins/ipam"
"github.com/ironcore-dev/fedhcp/plugins/metal"
"github.com/ironcore-dev/fedhcp/plugins/onmetal"
"github.com/ironcore-dev/fedhcp/plugins/oob"
"github.com/ironcore-dev/fedhcp/plugins/pxeboot"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
)

var desiredPlugins = []*plugins.Plugin{
&autoconfigure.Plugin,
&dns.Plugin,
&example.Plugin,
&file.Plugin,
&leasetime.Plugin,
&mtu.Plugin,
&nbp.Plugin,
&netmask.Plugin,
&prefix.Plugin,
&rangeplugin.Plugin,
&router.Plugin,
&searchdomains.Plugin,
&serverid.Plugin,
&sleep.Plugin,
&staticroute.Plugin,
&bluefield.Plugin,
&ipam.Plugin,
&onmetal.Plugin,
&oob.Plugin,
&pxeboot.Plugin,
&httpboot.Plugin,
&metal.Plugin,
}

var (
flagLogFile = flag.StringP("logfile", "l", "", "Name of the log file to append to. Default: stdout/stderr only")
flagLogNoStdout = flag.BoolP("nostdout", "N", false, "Disable logging to stdout/stderr")
flagLogLevel = flag.StringP("loglevel", "L", "info", fmt.Sprintf("Log level. One of %v", getLogLevels()))
flagConfig = flag.StringP("conf", "c", "", "Use this configuration file instead of the default location")
flagPlugins = flag.BoolP("plugins", "P", false, "list plugins")
flagInitKubernetesClient = flag.BoolP("init-kubernetes", "i", true, "init kubernetes client")
setupLog = ctrl.Log.WithName("setup")
pluginsRequiringKubernetes = sets.New[string]("oob", "ipam", "metal")
)

var logLevels = map[string]func(*logrus.Logger){
"none": func(l *logrus.Logger) { l.SetOutput(io.Discard) },
"debug": func(l *logrus.Logger) { l.SetLevel(logrus.DebugLevel) },
"info": func(l *logrus.Logger) { l.SetLevel(logrus.InfoLevel) },
"warning": func(l *logrus.Logger) { l.SetLevel(logrus.WarnLevel) },
"error": func(l *logrus.Logger) { l.SetLevel(logrus.ErrorLevel) },
"fatal": func(l *logrus.Logger) { l.SetLevel(logrus.FatalLevel) },
"trace": func(l *logrus.Logger) { l.SetLevel(logrus.TraceLevel) },
}
func main() {
var configFile string
var listPlugins bool

func getLogLevels() []string {
var levels []string
for k := range logLevels {
levels = append(levels, k)
flag.StringVar(&configFile, "config", "", "config file")
flag.BoolVar(&listPlugins, "list-plugins", false, "list plugins")
opts := zap.Options{
Development: true,
}
return levels
}

var desiredPlugins = []*plugins.Plugin{
&pl_autoconfigure.Plugin,
&pl_dns.Plugin,
&pl_example.Plugin,
&pl_file.Plugin,
&pl_leasetime.Plugin,
&pl_mtu.Plugin,
&pl_nbp.Plugin,
&pl_netmask.Plugin,
&pl_prefix.Plugin,
&pl_range.Plugin,
&pl_router.Plugin,
&pl_searchdomains.Plugin,
&pl_serverid.Plugin,
&pl_sleep.Plugin,
&pl_staticroute.Plugin,
&pl_bluefield.Plugin,
&pl_ipam.Plugin,
&pl_onmetal.Plugin,
&pl_oob.Plugin,
&pl_pxeboot.Plugin,
&pl_httpboot.Plugin,
&pl_metal.Plugin,
}

func main() {
opts.BindFlags(flag.CommandLine)
flag.Parse()

if *flagPlugins {
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))

if listPlugins {
for _, p := range desiredPlugins {
fmt.Println(p.Name)
}
os.Exit(0)
}

log := logger.GetLogger("main")
fn, ok := logLevels[*flagLogLevel]
if !ok {
log.Fatalf("Invalid log level '%s'. Valid log levels are %v", *flagLogLevel, getLogLevels())
}
fn(log.Logger)
log.Infof("Setting log level to '%s'", *flagLogLevel)
if *flagLogFile != "" {
log.Infof("Logging to file %s", *flagLogFile)
logger.WithFile(log, *flagLogFile)
}
if *flagLogNoStdout {
log.Infof("Disabling logging to stdout/stderr")
logger.WithNoStdOutErr(log)
}
config, err := config.Load(*flagConfig)
cfg, err := config.Load(configFile)
if err != nil {
log.Fatalf("Failed to load configuration: %v", err)
setupLog.Error(err, "Failed to load configuration", "ConfigFile", configFile)
os.Exit(1)
}

// register plugins
for _, plugin := range desiredPlugins {
if err := plugins.RegisterPlugin(plugin); err != nil {
log.Fatalf("Failed to register plugin '%s': %v", plugin.Name, err)
setupLog.Error(err, "Failed to register plugin", "Plugin", plugin.Name)
os.Exit(1)
}
}

// initialize kubernetes client, if needed
if *flagInitKubernetesClient {
if shouldSetupKubeClient(cfg) {
if err := kubernetes.InitClient(); err != nil {
log.Fatalf("Failed to initialize kubernetes client: %v", err)
setupLog.Error(err, "Failed to initialize kubernetes client")
os.Exit(1)
}
}

// start server
srv, err := server.Start(config)
srv, err := server.Start(cfg)
if err != nil {
log.Fatal(err)
setupLog.Error(err, "Failed to start server")
os.Exit(1)
}
if err := srv.Wait(); err != nil {
log.Print(err)
setupLog.Error(err, "Failed to wait server")
}
time.Sleep(time.Second)
}

func shouldSetupKubeClient(cfg *config.Config) bool {
configuredPlugins := sets.Set[string]{}
if cfg.Server4 != nil {
for _, plugin := range cfg.Server4.Plugins {
configuredPlugins.Insert(plugin.Name)
}
}
if cfg.Server6 != nil {
for _, plugin := range cfg.Server6.Plugins {
configuredPlugins.Insert(plugin.Name)
}
}

if configuredPlugins.HasAny(pluginsRequiringKubernetes.UnsortedList()...) {
return true
}

return false
}
3 changes: 1 addition & 2 deletions plugins/metal/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import (
"os"
"strings"

"gopkg.in/yaml.v2"

"github.com/coredhcp/coredhcp/handler"
"github.com/coredhcp/coredhcp/logger"
"github.com/coredhcp/coredhcp/plugins"
Expand All @@ -23,6 +21,7 @@ import (
ipamv1alpha1 "github.com/ironcore-dev/ipam/api/ipam/v1alpha1"
metalv1alpha1 "github.com/ironcore-dev/metal-operator/api/v1alpha1"
"github.com/mdlayher/netx/eui64"
"gopkg.in/yaml.v3"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
controllerruntime "sigs.k8s.io/controller-runtime"
)
Expand Down

0 comments on commit 39628e6

Please sign in to comment.