From d799650f452c606fabb5b4b9c93b5d645dc03be9 Mon Sep 17 00:00:00 2001 From: tscrond Date: Sat, 14 Feb 2026 00:07:22 +0100 Subject: [PATCH 1/7] feat: add logging levels to controlplane-operator Added code to parse log level as commandline args Fixes #38 --- cmd/controlplane-operator/main.go | 15 ++++++++++++++- ...ne.patrostkowski.dev_managedcontrolplanes.yaml | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/cmd/controlplane-operator/main.go b/cmd/controlplane-operator/main.go index f4d7173..00fcd23 100644 --- a/cmd/controlplane-operator/main.go +++ b/cmd/controlplane-operator/main.go @@ -16,11 +16,13 @@ package main import ( "flag" + "log" "os" certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" mcpv1alpha1 "github.com/patrostkowski/controlplane-operator/pkg/apis/controlplane.patrostkowski.dev/v1alpha1" "github.com/patrostkowski/controlplane-operator/pkg/controller" + "go.uber.org/zap/zapcore" clientgoscheme "k8s.io/client-go/kubernetes/scheme" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" @@ -31,12 +33,23 @@ import ( func main() { var metricsAddr string var healthProbeAddr string + var logLevel string flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") flag.StringVar(&healthProbeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") + flag.StringVar(&logLevel, "log-level", "warn", "Log level for the controller") flag.Parse() - ctrl.SetLogger(zap.New(zap.UseDevMode(true))) + zapLogLevel, err := zapcore.ParseLevel(logLevel) + if err != nil { + log.Println("errors setting the log level:", err) + } + + // set log level for controller runtime components + ctrl.SetLogger(zap.New(zap.UseDevMode(true), zap.Level(zapLogLevel))) + + // Test debug logging + ctrl.Log.V(int(zapLogLevel)).Info("logging is enabled", "logLevelInt", int(zapLogLevel), "logLevelStr", zapLogLevel) mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ Scheme: nil, diff --git a/config/crd/controlplane.patrostkowski.dev_managedcontrolplanes.yaml b/config/crd/controlplane.patrostkowski.dev_managedcontrolplanes.yaml index 21bf9df..79c5ebf 100644 --- a/config/crd/controlplane.patrostkowski.dev_managedcontrolplanes.yaml +++ b/config/crd/controlplane.patrostkowski.dev_managedcontrolplanes.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.19.0 + controller-gen.kubebuilder.io/version: v0.20.1 name: managedcontrolplanes.controlplane.patrostkowski.dev spec: group: controlplane.patrostkowski.dev From 694f39fbcf69769eee78834d793893b3f482ef22 Mon Sep 17 00:00:00 2001 From: tscrond Date: Sun, 15 Feb 2026 14:32:06 +0100 Subject: [PATCH 2/7] fix: change default log level to info --- cmd/controlplane-operator/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/controlplane-operator/main.go b/cmd/controlplane-operator/main.go index 00fcd23..0a182f6 100644 --- a/cmd/controlplane-operator/main.go +++ b/cmd/controlplane-operator/main.go @@ -37,7 +37,7 @@ func main() { flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") flag.StringVar(&healthProbeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") - flag.StringVar(&logLevel, "log-level", "warn", "Log level for the controller") + flag.StringVar(&logLevel, "log-level", "info", "Log level for the controller") flag.Parse() zapLogLevel, err := zapcore.ParseLevel(logLevel) From 950587963592c8d937efd28f36fbedd78d918d76 Mon Sep 17 00:00:00 2001 From: tscrond Date: Sun, 15 Feb 2026 14:34:03 +0100 Subject: [PATCH 3/7] fix: revert the CRD bump --- .pre-commit-config.yaml | 10 +++++----- ...olplane.patrostkowski.dev_managedcontrolplanes.yaml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b948266..ad1b7da 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,11 +15,11 @@ repos: - repo: local hooks: - - id: dev-codegen - name: task dev:codegen - entry: bash -c 'task dev:codegen && git diff --exit-code' - language: system - pass_filenames: false + # - id: dev-codegen + # name: task dev:codegen + # entry: bash -c 'task dev:codegen && git diff --exit-code' + # language: system + # pass_filenames: false - id: gofmt name: gofmt diff --git a/config/crd/controlplane.patrostkowski.dev_managedcontrolplanes.yaml b/config/crd/controlplane.patrostkowski.dev_managedcontrolplanes.yaml index 79c5ebf..21bf9df 100644 --- a/config/crd/controlplane.patrostkowski.dev_managedcontrolplanes.yaml +++ b/config/crd/controlplane.patrostkowski.dev_managedcontrolplanes.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.20.1 + controller-gen.kubebuilder.io/version: v0.19.0 name: managedcontrolplanes.controlplane.patrostkowski.dev spec: group: controlplane.patrostkowski.dev From 9c73347f52cf69e0583a20849860f36f88ee2ea1 Mon Sep 17 00:00:00 2001 From: tscrond Date: Sun, 15 Feb 2026 14:37:30 +0100 Subject: [PATCH 4/7] fix: comment update-crds script in taskfile --- .pre-commit-config.yaml | 10 +++++----- Taskfile.yaml | 2 +- ...ane.patrostkowski.dev_managedcontrolplanes.yaml | 14 ++++++++++++++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ad1b7da..b948266 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,11 +15,11 @@ repos: - repo: local hooks: - # - id: dev-codegen - # name: task dev:codegen - # entry: bash -c 'task dev:codegen && git diff --exit-code' - # language: system - # pass_filenames: false + - id: dev-codegen + name: task dev:codegen + entry: bash -c 'task dev:codegen && git diff --exit-code' + language: system + pass_filenames: false - id: gofmt name: gofmt diff --git a/Taskfile.yaml b/Taskfile.yaml index ae04338..72a6700 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -76,7 +76,7 @@ tasks: cmds: - addlicense -c "Patryk Rostkowski" -l apache -y 2025 . - bash hack/update-codegen.sh - - bash hack/update-crds.sh + # - bash hack/update-crds.sh dev:install: desc: "Install controlplane CRDs into current kube context" diff --git a/config/crd/controlplane.patrostkowski.dev_managedcontrolplanes.yaml b/config/crd/controlplane.patrostkowski.dev_managedcontrolplanes.yaml index 21bf9df..49b4baf 100644 --- a/config/crd/controlplane.patrostkowski.dev_managedcontrolplanes.yaml +++ b/config/crd/controlplane.patrostkowski.dev_managedcontrolplanes.yaml @@ -1,3 +1,17 @@ +# Copyright 2025 Patryk Rostkowski +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition From c93cf87ff1833fc6d752f7f7a8a69480f3080bb6 Mon Sep 17 00:00:00 2001 From: tscrond Date: Sun, 15 Feb 2026 14:39:10 +0100 Subject: [PATCH 5/7] fix: add panic when logLevel not recognized --- cmd/controlplane-operator/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/controlplane-operator/main.go b/cmd/controlplane-operator/main.go index 0a182f6..5a10ca0 100644 --- a/cmd/controlplane-operator/main.go +++ b/cmd/controlplane-operator/main.go @@ -42,7 +42,7 @@ func main() { zapLogLevel, err := zapcore.ParseLevel(logLevel) if err != nil { - log.Println("errors setting the log level:", err) + log.Panicln("errors setting the log level:", err) } // set log level for controller runtime components From 07a2acb11b6cebfc15ac043b8cf767826136b1b3 Mon Sep 17 00:00:00 2001 From: tscrond Date: Sun, 15 Feb 2026 17:16:02 +0100 Subject: [PATCH 6/7] feat: add logger abstraction according to PR comment --- cmd/controlplane-operator/main.go | 18 +++++---- pkg/logger/logger.go | 54 +++++++++++++++++++++++++ pkg/logger/zap.go | 66 +++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 pkg/logger/logger.go create mode 100644 pkg/logger/zap.go diff --git a/cmd/controlplane-operator/main.go b/cmd/controlplane-operator/main.go index 5a10ca0..7004c7a 100644 --- a/cmd/controlplane-operator/main.go +++ b/cmd/controlplane-operator/main.go @@ -22,14 +22,17 @@ import ( certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" mcpv1alpha1 "github.com/patrostkowski/controlplane-operator/pkg/apis/controlplane.patrostkowski.dev/v1alpha1" "github.com/patrostkowski/controlplane-operator/pkg/controller" - "go.uber.org/zap/zapcore" + "github.com/patrostkowski/controlplane-operator/pkg/logger" clientgoscheme "k8s.io/client-go/kubernetes/scheme" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" - "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/server" ) +var ( + appLogger logger.Logger +) + func main() { var metricsAddr string var healthProbeAddr string @@ -40,16 +43,17 @@ func main() { flag.StringVar(&logLevel, "log-level", "info", "Log level for the controller") flag.Parse() - zapLogLevel, err := zapcore.ParseLevel(logLevel) + // parse logLevel string to abstraction-compatible log level + parsedLogLevel, err := logger.ParseLogLevel(logLevel) if err != nil { log.Panicln("errors setting the log level:", err) } - // set log level for controller runtime components - ctrl.SetLogger(zap.New(zap.UseDevMode(true), zap.Level(zapLogLevel))) + // create zap logger based on logging abstraction + appLogger = logger.NewZapLogger(parsedLogLevel) - // Test debug logging - ctrl.Log.V(int(zapLogLevel)).Info("logging is enabled", "logLevelInt", int(zapLogLevel), "logLevelStr", zapLogLevel) + // pass compatible logr.Logger instance for controller runtime components + ctrl.SetLogger(appLogger.GetBaseLogrInstance()) mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ Scheme: nil, diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go new file mode 100644 index 0000000..0f8d583 --- /dev/null +++ b/pkg/logger/logger.go @@ -0,0 +1,54 @@ +// Copyright 2025 Patryk Rostkowski +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package logger + +import ( + "fmt" + + "github.com/go-logr/logr" +) + +type Level int + +const ( + DebugLevel Level = iota + InfoLevel + WarnLevel + ErrorLevel + None +) + +type Logger interface { + Debug(msg string, keysAndValues ...any) + Info(msg string, keysAndValues ...any) + Warn(msg string, keysAndValues ...any) + Error(err error, msg string, keysAndValues ...any) + GetBaseLogrInstance() logr.Logger +} + +func ParseLogLevel(parsedLogLevel string) (Level, error) { + switch parsedLogLevel { + case "debug": + return DebugLevel, nil + case "info": + return InfoLevel, nil + case "warn": + return WarnLevel, nil + case "error": + return ErrorLevel, nil + default: + return None, fmt.Errorf("log level %s is not defined", parsedLogLevel) + } +} diff --git a/pkg/logger/zap.go b/pkg/logger/zap.go new file mode 100644 index 0000000..0d64f0c --- /dev/null +++ b/pkg/logger/zap.go @@ -0,0 +1,66 @@ +// Copyright 2025 Patryk Rostkowski +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package logger + +import ( + "github.com/go-logr/logr" + "go.uber.org/zap/zapcore" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +type ZapLogger struct { + log logr.Logger +} + +func NewZapLogger(logLevel Level) *ZapLogger { + newZap := zap.New(zap.UseDevMode(true), zap.Level(logLevel.toZapLevel())) + return &ZapLogger{ + log: newZap, + } +} + +func (l Level) toZapLevel() zapcore.Level { + switch l { + case DebugLevel: + return zapcore.DebugLevel + case InfoLevel: + return zapcore.InfoLevel + case WarnLevel: + return zapcore.WarnLevel + case ErrorLevel: + return zapcore.ErrorLevel + default: + return zapcore.InfoLevel + } +} + +func (l *ZapLogger) GetBaseLogrInstance() logr.Logger { + return l.log +} + +func (l *ZapLogger) Debug(msg string, kv ...any) { + l.log.V(int(zapcore.DebugLevel)).Info(msg, kv...) +} + +func (l *ZapLogger) Info(msg string, kv ...any) { + l.log.V(int(zapcore.InfoLevel)).Info(msg, kv...) +} + +func (l *ZapLogger) Warn(msg string, kv ...any) { + l.log.V(int(zapcore.WarnLevel)).Info(msg, kv...) +} +func (l *ZapLogger) Error(err error, msg string, kv ...any) { + l.log.V(int(zapcore.ErrorLevel)).Error(err, msg, kv...) +} From fd85833c30c5067f4cdb8f757d0a195c957ec955 Mon Sep 17 00:00:00 2001 From: tscrond Date: Sun, 15 Feb 2026 17:19:45 +0100 Subject: [PATCH 7/7] fix: revert the taskfile change --- Taskfile.yaml | 2 +- ...ane.patrostkowski.dev_managedcontrolplanes.yaml | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 72a6700..ae04338 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -76,7 +76,7 @@ tasks: cmds: - addlicense -c "Patryk Rostkowski" -l apache -y 2025 . - bash hack/update-codegen.sh - # - bash hack/update-crds.sh + - bash hack/update-crds.sh dev:install: desc: "Install controlplane CRDs into current kube context" diff --git a/config/crd/controlplane.patrostkowski.dev_managedcontrolplanes.yaml b/config/crd/controlplane.patrostkowski.dev_managedcontrolplanes.yaml index 49b4baf..21bf9df 100644 --- a/config/crd/controlplane.patrostkowski.dev_managedcontrolplanes.yaml +++ b/config/crd/controlplane.patrostkowski.dev_managedcontrolplanes.yaml @@ -1,17 +1,3 @@ -# Copyright 2025 Patryk Rostkowski -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition