diff --git a/.golangci.yml b/.golangci.yml index 12770943..ec50a982 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,21 +1,7 @@ run: - deadline: 5m allow-parallel-runners: true + timeout: 5m -issues: - # don't skip warning about doc comments - # don't exclude the default set of lint - exclude-use-default: false - # restore some of the defaults - # (fill in the rest as needed) - exclude-rules: - - path: "api/*" - linters: - - lll - - path: "internal/*" - linters: - - dupl - - lll linters: disable-all: true enable: @@ -29,7 +15,6 @@ linters: - gosimple - govet - ineffassign - - lll - misspell - nakedret - prealloc diff --git a/cmd/main.go b/cmd/main.go index 1c78d9da..b3a726f8 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -4,132 +4,231 @@ package main import ( + "context" "crypto/tls" - "flag" + "fmt" "os" + "os/signal" + "path/filepath" + "strings" + "syscall" + "github.com/go-logr/logr" + "github.com/spf13/pflag" + "github.com/spf13/viper" "k8s.io/apimachinery/pkg/runtime" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - clientgoscheme "k8s.io/client-go/kubernetes/scheme" + kscheme "k8s.io/client-go/kubernetes/scheme" _ "k8s.io/client-go/plugin/pkg/client/auth" + "k8s.io/client-go/rest" + "k8s.io/klog/v2" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/webhook" metalv1alpha1 "github.com/ironcore-dev/metal/api/v1alpha1" "github.com/ironcore-dev/metal/internal/controller" + "github.com/ironcore-dev/metal/internal/log" //+kubebuilder:scaffold:imports ) -var ( - scheme = runtime.NewScheme() - setupLog = ctrl.Log.WithName("setup") -) +type params struct { + dev bool + leaderElection bool + healthProbeBindAddress string + metricsBindAddress string + secureMetrics bool + enableHTTP2 bool + kubeconfig string + enableMachineController bool + enableMachineClaimController bool + enableOOBController bool + enableOOBSecretController bool +} -func init() { - utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - utilruntime.Must(metalv1alpha1.AddToScheme(scheme)) - //+kubebuilder:scaffold:scheme +func parseCmdLine() params { + pflag.Usage = usage + pflag.ErrHelp = nil + pflag.CommandLine = pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError) + + pflag.Bool("dev", false, "Log human-readable messages at debug level.") + pflag.Bool("leader-elect", false, "Enable leader election to ensure there is only one active controller manager.") + pflag.String("health-probe-bind-address", "", "The address that the health probe server binds to.") + pflag.String("metrics-bind-address", "0", "The address that the metrics server binds to.") + pflag.Bool("metrics-secure", false, "Serve metrics securely.") + pflag.Bool("enable-http2", false, "Enable HTTP2 for the metrics and webhook servers.") + pflag.String("kubeconfig", "", "Use a kubeconfig to run out of cluster.") + pflag.Bool("enable-machine-controller", true, "Enable the Machine controller.") + pflag.Bool("enable-machineclaim-controller", true, "Enable the MachineClaim controller.") + pflag.Bool("enable-oob-controller", true, "Enable the OOB controller.") + pflag.Bool("enable-oobsecret-controller", true, "Enable the OOBSecret controller.") + + var help bool + pflag.BoolVarP(&help, "help", "h", false, "Show this help message.") + err := viper.BindPFlags(pflag.CommandLine) + if err != nil { + exitUsage(err) + } + viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_")) + viper.AutomaticEnv() + err = pflag.CommandLine.Parse(os.Args[1:]) + if err != nil { + exitUsage(err) + } + if help { + exitUsage(nil) + } + + return params{ + dev: viper.GetBool("dev"), + leaderElection: viper.GetBool("leader-elect"), + healthProbeBindAddress: viper.GetString("health-probe-bind-address"), + metricsBindAddress: viper.GetString("metrics-bind-address"), + secureMetrics: viper.GetBool("metrics-secure"), + enableHTTP2: viper.GetBool("enable-http2"), + kubeconfig: viper.GetString("kubeconfig"), + enableMachineController: viper.GetBool("enable-machine-controller"), + enableMachineClaimController: viper.GetBool("enable-machineclaim-controller"), + enableOOBController: viper.GetBool("enable-oob-controller"), + enableOOBSecretController: viper.GetBool("enable-oobsecret-controller"), + } +} + +func usage() { + name := filepath.Base(os.Args[0]) + _, _ = fmt.Fprintf(os.Stderr, "Usage: %s [--option]...\n", name) + _, _ = fmt.Fprintf(os.Stderr, "Options:\n") + pflag.PrintDefaults() +} + +func exitUsage(err error) { + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "%s: %s\n", filepath.Base(os.Args[0]), err) + } + pflag.Usage() + os.Exit(2) } func main() { - var metricsAddr string - var enableLeaderElection bool - var probeAddr string - var secureMetrics bool - var enableHTTP2 bool - flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") - flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") - flag.BoolVar(&enableLeaderElection, "leader-elect", false, - "Enable leader election for controller manager. "+ - "Enabling this will ensure there is only one active controller manager.") - flag.BoolVar(&secureMetrics, "metrics-secure", false, - "If set the metrics endpoint is served securely") - flag.BoolVar(&enableHTTP2, "enable-http2", false, - "If set, HTTP/2 will be enabled for the metrics and webhook servers") - opts := zap.Options{ - Development: true, - } - opts.BindFlags(flag.CommandLine) - flag.Parse() - - ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) - - disableHTTP2 := func(c *tls.Config) { - setupLog.Info("disabling http/2") - c.NextProtos = []string{"http/1.1"} + p := parseCmdLine() + + var exitCode int + defer func() { + os.Exit(exitCode) + }() + + ctx, stop := signal.NotifyContext(log.Setup(context.Background(), p.dev, false, os.Stderr), syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGHUP) + defer stop() + log.Info(ctx, "Starting OOB operator") + + defer func() { + log.Info(ctx, "Exiting", "exitCode", exitCode) + }() + + l := logr.FromContextOrDiscard(ctx) + klog.SetLogger(l) + ctrl.SetLogger(l) + + scheme := runtime.NewScheme() + err := kscheme.AddToScheme(scheme) + if err != nil { + log.Error(ctx, fmt.Errorf("cannot create type scheme: %w", err)) + exitCode = 1 + return + } + err = metalv1alpha1.AddToScheme(scheme) + if err != nil { + log.Error(ctx, fmt.Errorf("cannot create type scheme: %w", err)) + exitCode = 1 + return } + //+kubebuilder:scaffold:scheme - var tlsOpts []func(*tls.Config) - if !enableHTTP2 { - tlsOpts = append(tlsOpts, disableHTTP2) + var kcfg *rest.Config + kcfg, err = ctrl.GetConfig() + if err != nil { + log.Error(ctx, fmt.Errorf("cannot get kubeconfig: %w", err)) + exitCode = 1 + return } - webhookServer := webhook.NewServer(webhook.Options{ - TLSOpts: tlsOpts, - }) + var tlsOpts []func(*tls.Config) + if !p.enableHTTP2 { + tlsOpts = append(tlsOpts, func(c *tls.Config) { + c.NextProtos = []string{"http/1.1"} + }) + } - mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ - Scheme: scheme, - Metrics: metricsserver.Options{ - BindAddress: metricsAddr, - SecureServing: secureMetrics, + var mgr manager.Manager + mgr, err = ctrl.NewManager(kcfg, ctrl.Options{ + Scheme: scheme, + LeaderElection: p.leaderElection, + LeaderElectionID: "metal.ironcore.dev", + Metrics: server.Options{ + BindAddress: p.metricsBindAddress, + SecureServing: p.secureMetrics, TLSOpts: tlsOpts, }, - WebhookServer: webhookServer, - HealthProbeBindAddress: probeAddr, - LeaderElection: enableLeaderElection, - LeaderElectionID: "metal.ironcore.dev", + HealthProbeBindAddress: p.healthProbeBindAddress, + WebhookServer: webhook.NewServer(webhook.Options{ + TLSOpts: tlsOpts, + }), + BaseContext: func() context.Context { + return ctx + }, }) if err != nil { - setupLog.Error(err, "unable to start manager") - os.Exit(1) - } - - if err = (&controller.MachineReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Machine") - os.Exit(1) - } - if err = (&controller.MachineClaimReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "MachineClaim") - os.Exit(1) - } - if err = (&controller.OOBReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "OOB") - os.Exit(1) - } - if err = (&controller.OOBSecretReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "OOBSecret") - os.Exit(1) + log.Error(ctx, fmt.Errorf("cannot create manager: %w", err)) + exitCode = 1 + return + } + + err = controller.NewMachineReconciler().SetupWithManager(mgr) + if err != nil { + log.Error(ctx, fmt.Errorf("cannot create controller: %w", err), "controller", "Machine") + exitCode = 1 + return + } + err = controller.NewMachineClaimReconciler().SetupWithManager(mgr) + if err != nil { + log.Error(ctx, fmt.Errorf("cannot create controller: %w", err), "controller", "MachineClaim") + exitCode = 1 + return + } + err = controller.NewOOBReconciler().SetupWithManager(mgr) + if err != nil { + log.Error(ctx, fmt.Errorf("cannot create controller: %w", err), "controller", "OOB") + exitCode = 1 + return + } + err = controller.NewOOBSecretReconciler().SetupWithManager(mgr) + if err != nil { + log.Error(ctx, fmt.Errorf("cannot create controller: %w", err), "controller", "OOBSecret") + exitCode = 1 + return } //+kubebuilder:scaffold:builder - if err = mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up health check") - os.Exit(1) + err = mgr.AddHealthzCheck("health", healthz.Ping) + if err != nil { + log.Error(ctx, fmt.Errorf("cannot set up health check: %w", err)) + exitCode = 1 + return } - if err = mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up ready check") - os.Exit(1) + + err = mgr.AddReadyzCheck("check", healthz.Ping) + if err != nil { + log.Error(ctx, fmt.Errorf("cannot set up ready check: %w", err)) + exitCode = 1 + return } - setupLog.Info("starting manager") - if err = mgr.Start(ctrl.SetupSignalHandler()); err != nil { - setupLog.Error(err, "problem running manager") - os.Exit(1) + log.Info(ctx, "Starting manager") + err = mgr.Start(ctx) + if err != nil { + log.Error(ctx, err) + exitCode = 1 + return } } diff --git a/go.mod b/go.mod index fb792c0f..972feca0 100644 --- a/go.mod +++ b/go.mod @@ -1,24 +1,32 @@ module github.com/ironcore-dev/metal -go 1.22 +go 1.22.0 + +toolchain go1.22.1 require ( github.com/go-logr/logr v1.4.1 + github.com/go-logr/zerologr v1.2.3 + github.com/google/addlicense v1.1.1 github.com/google/uuid v1.6.0 - github.com/ironcore-dev/controller-utils v0.9.3 github.com/onsi/ginkgo/v2 v2.17.1 github.com/onsi/gomega v1.32.0 + github.com/rs/zerolog v1.32.0 + github.com/spf13/pflag v1.0.5 + github.com/spf13/viper v1.18.2 k8s.io/api v0.29.3 k8s.io/apimachinery v0.29.3 k8s.io/client-go v0.29.3 + k8s.io/klog/v2 v2.120.1 sigs.k8s.io/controller-runtime v0.17.2 + sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20240325154454-1762a686fa75 ) require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bmatcuk/doublestar/v4 v4.0.2 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch/v5 v5.8.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect @@ -30,47 +38,57 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/google/addlicense v1.1.1 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect - github.com/imdario/mergo v0.3.13 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/imdario/mergo v0.3.6 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.18.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect + github.com/subosito/gotenv v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/net v0.20.0 // indirect - golang.org/x/oauth2 v0.12.0 // indirect + golang.org/x/oauth2 v0.15.0 // indirect golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.16.0 // indirect golang.org/x/term v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.3.0 // indirect + golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.17.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.29.2 // indirect - k8s.io/component-base v0.29.2 // indirect - k8s.io/klog/v2 v2.110.1 // indirect + k8s.io/apiextensions-apiserver v0.29.0 // indirect + k8s.io/component-base v0.29.0 // indirect k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect - k8s.io/utils v0.0.0-20231127182322-b307cd553661 // indirect + k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/go.sum b/go.sum index 2255c64b..b1357efa 100644 --- a/go.sum +++ b/go.sum @@ -7,23 +7,28 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= +github.com/go-logr/zerologr v1.2.3 h1:up5N9vcH9Xck3jJkXzgyOxozT14R47IyDODz8LM1KSs= +github.com/go-logr/zerologr v1.2.3/go.mod h1:BxwGo7y5zgSHYR1BjbnHPyF/5ZjVKfKxAZANVu6E8Ho= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= @@ -32,6 +37,7 @@ github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/ github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -53,11 +59,11 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJY github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= -github.com/ironcore-dev/controller-utils v0.9.3 h1:sTrnxSzX5RrLf4B8KrAH2axSC+gxfJXphkV6df2GSsw= -github.com/ironcore-dev/controller-utils v0.9.3/go.mod h1:djKnxDs0Hwxhhc0VmVY8tZnrOrElvrRV2jov/LiCZ2Y= +github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -71,10 +77,19 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -86,10 +101,13 @@ github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8 github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= @@ -100,26 +118,39 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= +github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= @@ -127,8 +158,8 @@ go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -138,8 +169,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= -golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= +golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= +golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -149,6 +180,9 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= @@ -158,8 +192,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -181,31 +215,34 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/api v0.29.3 h1:2ORfZ7+bGC3YJqGpV0KSDDEVf8hdGQ6A03/50vj8pmw= k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80= -k8s.io/apiextensions-apiserver v0.29.2 h1:UK3xB5lOWSnhaCk0RFZ0LUacPZz9RY4wi/yt2Iu+btg= -k8s.io/apiextensions-apiserver v0.29.2/go.mod h1:aLfYjpA5p3OwtqNXQFkhJ56TB+spV8Gc4wfMhUA3/b8= +k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= +k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU= k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU= k8s.io/client-go v0.29.3 h1:R/zaZbEAxqComZ9FHeQwOh3Y1ZUs7FaHKZdQtIc2WZg= k8s.io/client-go v0.29.3/go.mod h1:tkDisCvgPfiRpxGnOORfkljmS+UrW+WtXAy2fTvXJB0= -k8s.io/component-base v0.29.2 h1:lpiLyuvPA9yV1aQwGLENYyK7n/8t6l3nn3zAtFTJYe8= -k8s.io/component-base v0.29.2/go.mod h1:BfB3SLrefbZXiBfbM+2H1dlat21Uewg/5qtKOl8degM= -k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= +k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s= +k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI= -k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/controller-runtime v0.17.2 h1:FwHwD1CTUemg0pW2otk7/U5/i5m2ymzvOXdbeGOUvw0= sigs.k8s.io/controller-runtime v0.17.2/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= +sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20240325154454-1762a686fa75 h1:x1atg5QpRY5lptXwMieGWCHkdlUd8Y5CWk6bn7o6FUQ= +sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20240325154454-1762a686fa75/go.mod h1:B2xTzIWVko5xZLWDkXFS7Zo9hxX+ecdMzZ8oiTPJoRI= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/internal/controller/machine_controller.go b/internal/controller/machine_controller.go index d9034613..ff8da4a2 100644 --- a/internal/controller/machine_controller.go +++ b/internal/controller/machine_controller.go @@ -6,7 +6,6 @@ package controller import ( "context" - "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" @@ -14,16 +13,19 @@ import ( metalv1alpha1 "github.com/ironcore-dev/metal/api/v1alpha1" ) +//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=machines,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=machines/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=machines/finalizers,verbs=update + +func NewMachineReconciler() *MachineReconciler { + return &MachineReconciler{} +} + // MachineReconciler reconciles a Machine object type MachineReconciler struct { client.Client - Scheme *runtime.Scheme } -//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=machines,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=machines/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=machines/finalizers,verbs=update - // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. func (r *MachineReconciler) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result, error) { diff --git a/internal/controller/machineclaim_controller.go b/internal/controller/machineclaim_controller.go index 6b46ee14..7a2b14c1 100644 --- a/internal/controller/machineclaim_controller.go +++ b/internal/controller/machineclaim_controller.go @@ -7,11 +7,9 @@ import ( "context" "fmt" - "github.com/go-logr/logr" - "github.com/ironcore-dev/controller-utils/clientutils" + "github.com/ironcore-dev/metal/internal/log" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -26,12 +24,6 @@ const ( MachineClaimFinalizer string = "metal.ironcore.dev/machineclaim" ) -// MachineClaimReconciler reconciles a MachineClaim object -type MachineClaimReconciler struct { - client.Client - Scheme *runtime.Scheme -} - //+kubebuilder:rbac:groups=metal.ironcore.dev,resources=machineclaims,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=metal.ironcore.dev,resources=machineclaims/status,verbs=get;update;patch //+kubebuilder:rbac:groups=metal.ironcore.dev,resources=machineclaims/finalizers,verbs=update @@ -39,35 +31,45 @@ type MachineClaimReconciler struct { //+kubebuilder:rbac:groups=metal.ironcore.dev,resources=machines/status,verbs=get //+kubebuilder:rbac:groups=metal.ironcore.dev,resources=machines/finalizers,verbs=update +func NewMachineClaimReconciler() *MachineClaimReconciler { + return &MachineClaimReconciler{} +} + +// MachineClaimReconciler reconciles a MachineClaim object +type MachineClaimReconciler struct { + client.Client +} + // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. -// TODO Add logs // TODO Server-side apply func (r *MachineClaimReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - log := ctrl.LoggerFrom(ctx) - claim := &metalv1alpha1.MachineClaim{} - if err := r.Get(ctx, req.NamespacedName, claim); err != nil { + err := r.Get(ctx, req.NamespacedName, claim) + if err != nil { return ctrl.Result{}, client.IgnoreNotFound(fmt.Errorf("cannot get MachineClaim: %w", err)) } if !claim.DeletionTimestamp.IsZero() { - return ctrl.Result{}, r.delete(ctx, log, claim) + return ctrl.Result{}, r.finalize(ctx, claim) } - return r.reconcile(ctx, log, claim) + return r.reconcile(ctx, claim) } -func (r *MachineClaimReconciler) delete(ctx context.Context, _ logr.Logger, claim *metalv1alpha1.MachineClaim) error { +func (r *MachineClaimReconciler) finalize(ctx context.Context, claim *metalv1alpha1.MachineClaim) error { if !controllerutil.ContainsFinalizer(claim, MachineClaimFinalizer) { return nil } + log.Debug(ctx, "Finalizing") switch { default: if claim.Spec.MachineRef == nil { break } + ctx = log.WithValues(ctx, "machine", claim.Spec.MachineRef.Name) + log.Debug(ctx, "Getting Machine") machine := &metalv1alpha1.Machine{} err := r.Get(ctx, client.ObjectKey{Name: claim.Spec.MachineRef.Name}, machine) if err != nil { @@ -85,59 +87,75 @@ func (r *MachineClaimReconciler) delete(ctx context.Context, _ logr.Logger, clai return fmt.Errorf("MachineClaimRef in Machine does not match MachineClaim UID") } - machineBase := machine.DeepCopy() + log.Debug(ctx, "Removing finalizer from Machine") + base := machine.DeepCopy() machine.Spec.MachineClaimRef = nil _ = controllerutil.RemoveFinalizer(machine, MachineClaimFinalizer) - err = r.Patch(ctx, machine, client.MergeFrom(machineBase)) + err = r.Patch(ctx, machine, client.MergeFrom(base)) if err != nil { return fmt.Errorf("cannot patch Machine: %w", err) } } - _, err := clientutils.PatchEnsureNoFinalizer(ctx, r.Client, claim, MachineClaimFinalizer) + log.Debug(ctx, "Removing finalizer") + base := claim.DeepCopy() + controllerutil.RemoveFinalizer(claim, MachineClaimFinalizer) + err := r.Patch(ctx, claim, client.MergeFrom(base)) if err != nil { - return fmt.Errorf("cannot remove finalizer from MachineClaim: %w", err) + return fmt.Errorf("cannot remove finalizer: %w", err) } + log.Debug(ctx, "Finalized successfully") return nil } -func (r *MachineClaimReconciler) reconcile(ctx context.Context, _ logr.Logger, claim *metalv1alpha1.MachineClaim) (ctrl.Result, error) { - modified, err := clientutils.PatchEnsureFinalizer(ctx, r.Client, claim, MachineClaimFinalizer) - if err != nil || modified { - return ctrl.Result{}, err +func (r *MachineClaimReconciler) reconcile(ctx context.Context, claim *metalv1alpha1.MachineClaim) (ctrl.Result, error) { + log.Debug(ctx, "Reconciling") + + if !controllerutil.ContainsFinalizer(claim, MachineClaimFinalizer) { + log.Debug(ctx, "Adding finalizer") + base := claim.DeepCopy() + controllerutil.AddFinalizer(claim, MachineClaimFinalizer) + err := r.Patch(ctx, claim, client.MergeFrom(base)) + if err != nil { + return ctrl.Result{}, fmt.Errorf("cannot add finalizer: %w", err) + } + + log.Debug(ctx, "Finalizer added, reconciled successfully") + return ctrl.Result{}, nil } if claim.Status.Phase == "" { - claimBase := claim.DeepCopy() + log.Debug(ctx, "Updating status") + base := claim.DeepCopy() claim.Status.Phase = metalv1alpha1.MachineClaimPhaseUnbound - err = r.Status().Patch(ctx, claim, client.MergeFrom(claimBase)) + err := r.Status().Patch(ctx, claim, client.MergeFrom(base)) if err != nil { return ctrl.Result{}, fmt.Errorf("cannot patch MachineClaim status: %w", err) } + log.Debug(ctx, "Status set, reconciled successfully") return ctrl.Result{}, nil } var machines []metalv1alpha1.Machine if claim.Spec.MachineRef == nil { + log.Debug(ctx, "Listing Machines with matching labels") machineList := &metalv1alpha1.MachineList{} - err = r.List(ctx, machineList, client.MatchingLabels(claim.Spec.MachineSelector.MatchLabels)) + err := r.List(ctx, machineList, client.MatchingLabels(claim.Spec.MachineSelector.MatchLabels)) if err != nil { return ctrl.Result{}, fmt.Errorf("cannot list Machines from MachineClaim selector: %w", err) } machines = machineList.Items } else { + log.Debug(ctx, "Getting referenced Machine") machine := &metalv1alpha1.Machine{} - err = r.Get(ctx, client.ObjectKey{Name: claim.Spec.MachineRef.Name}, machine) + err := r.Get(ctx, client.ObjectKey{Name: claim.Spec.MachineRef.Name}, machine) if err != nil { return ctrl.Result{}, fmt.Errorf("cannot get Machine from MachineClaim ref: %w", err) } machines = append(machines, *machine) } - if len(machines) == 0 { - return ctrl.Result{}, nil - } var machine *metalv1alpha1.Machine for _, m := range machines { @@ -152,11 +170,13 @@ func (r *MachineClaimReconciler) reconcile(ctx context.Context, _ logr.Logger, c break } if machine == nil { + log.Debug(ctx, "No suitable Machines, reconciled successfully") return ctrl.Result{}, nil } + ctx = log.WithValues(ctx, "machine", machine.Name) machineBase := machine.DeepCopy() - modified = controllerutil.AddFinalizer(machine, MachineClaimFinalizer) + modified := controllerutil.AddFinalizer(machine, MachineClaimFinalizer) if machine.Spec.MachineClaimRef == nil { machine.Spec.MachineClaimRef = &v1.ObjectReference{ Namespace: claim.Namespace, @@ -170,29 +190,40 @@ func (r *MachineClaimReconciler) reconcile(ctx context.Context, _ logr.Logger, c modified = true } if modified { - err = r.Patch(ctx, machine, client.MergeFrom(machineBase)) + log.Debug(ctx, "Updating Machine") + err := r.Patch(ctx, machine, client.MergeFrom(machineBase)) if err != nil { return ctrl.Result{}, fmt.Errorf("cannot patch MachineClaim: %w", err) } } if claim.Spec.MachineRef == nil || claim.Spec.MachineRef.Name != machine.Name { - claimBase := claim.DeepCopy() + log.Debug(ctx, "Updating") + base := claim.DeepCopy() claim.Spec.MachineRef = &v1.LocalObjectReference{Name: machine.Name} - err = r.Patch(ctx, claim, client.MergeFrom(claimBase)) + err := r.Patch(ctx, claim, client.MergeFrom(base)) if err != nil { return ctrl.Result{}, fmt.Errorf("cannot patch MachineClaim: %w", err) } + + log.Debug(ctx, "Reconciled successfully") + return ctrl.Result{}, nil } if claim.Status.Phase != metalv1alpha1.MachineClaimPhaseBound { - claimBase := claim.DeepCopy() + log.Debug(ctx, "Updating status") + base := claim.DeepCopy() claim.Status.Phase = metalv1alpha1.MachineClaimPhaseBound - err = r.Status().Patch(ctx, claim, client.MergeFrom(claimBase)) + err := r.Status().Patch(ctx, claim, client.MergeFrom(base)) if err != nil { return ctrl.Result{}, fmt.Errorf("cannot patch MachineClaim status: %w", err) } + + log.Debug(ctx, "Reconciled successfully") + return ctrl.Result{}, nil } + + log.Debug(ctx, "Reconciled successfully") return ctrl.Result{}, nil } @@ -207,13 +238,12 @@ func (r *MachineClaimReconciler) SetupWithManager(mgr ctrl.Manager) error { func (r *MachineClaimReconciler) enqueueMachineClaimsByRef() handler.EventHandler { return handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request { - log := ctrl.LoggerFrom(ctx) machine := obj.(*metalv1alpha1.Machine) // TODO: Filter this list with a field selector. claimList := &metalv1alpha1.MachineClaimList{} if err := r.List(ctx, claimList); err != nil { - log.Error(fmt.Errorf("cannot list MachineClaims: %w", err), "") + log.Error(ctx, fmt.Errorf("cannot list MachineClaims: %w", err)) return nil } diff --git a/internal/controller/oob_controller.go b/internal/controller/oob_controller.go index 41572cad..a9afc6de 100644 --- a/internal/controller/oob_controller.go +++ b/internal/controller/oob_controller.go @@ -6,7 +6,6 @@ package controller import ( "context" - "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" @@ -14,16 +13,19 @@ import ( metalv1alpha1 "github.com/ironcore-dev/metal/api/v1alpha1" ) +//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=oobs,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=oobs/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=oobs/finalizers,verbs=update + +func NewOOBReconciler() *OOBReconciler { + return &OOBReconciler{} +} + // OOBReconciler reconciles a OOB object type OOBReconciler struct { client.Client - Scheme *runtime.Scheme } -//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=oobs,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=oobs/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=oobs/finalizers,verbs=update - // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. func (r *OOBReconciler) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result, error) { diff --git a/internal/controller/oobsecret_controller.go b/internal/controller/oobsecret_controller.go index 2bdbcbe9..af2880ba 100644 --- a/internal/controller/oobsecret_controller.go +++ b/internal/controller/oobsecret_controller.go @@ -6,7 +6,6 @@ package controller import ( "context" - "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" @@ -14,16 +13,19 @@ import ( metalv1alpha1 "github.com/ironcore-dev/metal/api/v1alpha1" ) +//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=oobsecrets,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=oobsecrets/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=oobsecrets/finalizers,verbs=update + +func NewOOBSecretReconciler() *OOBSecretReconciler { + return &OOBSecretReconciler{} +} + // OOBSecretReconciler reconciles a OOBSecret object type OOBSecretReconciler struct { client.Client - Scheme *runtime.Scheme } -//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=oobsecrets,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=oobsecrets/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=oobsecrets/finalizers,verbs=update - // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. func (r *OOBSecretReconciler) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result, error) { diff --git a/internal/controller/suite_test.go b/internal/controller/suite_test.go index 665eb30d..f184d385 100644 --- a/internal/controller/suite_test.go +++ b/internal/controller/suite_test.go @@ -71,7 +71,6 @@ var _ = BeforeSuite(func() { Expect((&MachineClaimReconciler{ Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), }).SetupWithManager(mgr)).To(Succeed()) ctx, cancel := context.WithCancel(context.Background()) diff --git a/internal/log/log.go b/internal/log/log.go new file mode 100644 index 00000000..f3c9997a --- /dev/null +++ b/internal/log/log.go @@ -0,0 +1,47 @@ +package log + +import ( + "context" + "io" + + "github.com/go-logr/logr" + "github.com/go-logr/zerologr" + "github.com/rs/zerolog" +) + +func Setup(ctx context.Context, dev, silent bool, writer io.Writer) context.Context { + var zeroLog zerolog.Logger + + if silent { + return logr.NewContext(ctx, logr.Discard()) + } + + if dev { + cw := zerolog.ConsoleWriter{ + Out: writer, + TimeFormat: "2006-01-02 15:04:05 MST", + FieldsExclude: []string{"v"}, + } + zeroLog = zerolog.New(cw).Level(zerolog.DebugLevel).With().Timestamp().Logger() + } else { + zeroLog = zerolog.New(writer).Level(zerolog.DebugLevel).With().Timestamp().Logger() + } + + return logr.NewContext(ctx, zerologr.New(&zeroLog)) +} + +func Info(ctx context.Context, msg string, keysAndValues ...interface{}) { + logr.FromContextOrDiscard(ctx).Info(msg, keysAndValues...) +} + +func Debug(ctx context.Context, msg string, keysAndValues ...interface{}) { + logr.FromContextOrDiscard(ctx).V(1).Info(msg, keysAndValues...) +} + +func Error(ctx context.Context, err error, keysAndValues ...interface{}) { + logr.FromContextOrDiscard(ctx).Error(err, "", keysAndValues...) +} + +func WithValues(ctx context.Context, keysAndValues ...interface{}) context.Context { + return logr.NewContext(ctx, logr.FromContextOrDiscard(ctx).WithValues(keysAndValues...)) +}