Skip to content

Commit 1f02e01

Browse files
authored
Do not store loggers in controller stucts (#462)
Leverages the context to grab the correct logger for each method that uses a logger in ResourceGraphDefinition controller.
1 parent 0e2f0d1 commit 1f02e01

File tree

8 files changed

+80
-86
lines changed

8 files changed

+80
-86
lines changed

Diff for: cmd/controller/main.go

+4-18
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,9 @@ import (
2424
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
2525
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
2626
ctrl "sigs.k8s.io/controller-runtime"
27-
ctrlrtcontroller "sigs.k8s.io/controller-runtime/pkg/controller"
2827
"sigs.k8s.io/controller-runtime/pkg/healthz"
2928
"sigs.k8s.io/controller-runtime/pkg/log/zap"
3029
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
31-
"sigs.k8s.io/controller-runtime/pkg/predicate"
32-
"sigs.k8s.io/controller-runtime/pkg/reconcile"
3330

3431
xv1alpha1 "github.com/kro-run/kro/api/v1alpha1"
3532
kroclient "github.com/kro-run/kro/pkg/client"
@@ -161,6 +158,7 @@ func main() {
161158
// if you are doing or is intended to do any operation such as perform cleanups
162159
// after the manager stops then its usage might be unsafe.
163160
// LeaderElectionReleaseOnCancel: true,
161+
Logger: rootLogger,
164162
})
165163
if err != nil {
166164
setupLog.Error(err, "unable to start manager")
@@ -187,26 +185,14 @@ func main() {
187185
os.Exit(1)
188186
}
189187

190-
reconciler := resourcegraphdefinitionctrl.NewResourceGraphDefinitionReconciler(
191-
rootLogger,
192-
mgr.GetClient(),
188+
rgd := resourcegraphdefinitionctrl.NewResourceGraphDefinitionReconciler(
193189
set,
194190
allowCRDDeletion,
195191
dc,
196192
resourceGraphDefinitionGraphBuilder,
193+
resourceGraphDefinitionConcurrentReconciles,
197194
)
198-
err = ctrl.NewControllerManagedBy(
199-
mgr,
200-
).For(
201-
&xv1alpha1.ResourceGraphDefinition{},
202-
).WithEventFilter(
203-
predicate.GenerationChangedPredicate{},
204-
).WithOptions(
205-
ctrlrtcontroller.Options{
206-
MaxConcurrentReconciles: resourceGraphDefinitionConcurrentReconciles,
207-
},
208-
).Complete(reconcile.AsReconciler[*xv1alpha1.ResourceGraphDefinition](mgr.GetClient(), reconciler))
209-
if err != nil {
195+
if err := rgd.SetupWithManager(mgr); err != nil {
210196
setupLog.Error(err, "unable to create controller", "controller", "ResourceGraphDefinition")
211197
os.Exit(1)
212198
}

Diff for: pkg/client/crd.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ import (
1818
"fmt"
1919
"time"
2020

21-
"github.com/go-logr/logr"
2221
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2322
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
2423
apierrors "k8s.io/apimachinery/pkg/api/errors"
2524
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2625
"k8s.io/apimachinery/pkg/types"
2726
"k8s.io/apimachinery/pkg/util/wait"
27+
logr "sigs.k8s.io/controller-runtime/pkg/log"
2828
)
2929

3030
const (
@@ -51,15 +51,13 @@ type CRDClient interface {
5151
// CRDWrapper provides a simplified interface for CRD operations
5252
type CRDWrapper struct {
5353
client apiextensionsv1.CustomResourceDefinitionInterface
54-
log logr.Logger
5554
pollInterval time.Duration
5655
timeout time.Duration
5756
}
5857

5958
// CRDWrapperConfig contains configuration for the CRD wrapper
6059
type CRDWrapperConfig struct {
6160
Client *apiextensionsv1.ApiextensionsV1Client
62-
Log logr.Logger
6361
PollInterval time.Duration
6462
Timeout time.Duration
6563
}
@@ -83,7 +81,6 @@ func newCRDWrapper(cfg CRDWrapperConfig) *CRDWrapper {
8381

8482
return &CRDWrapper{
8583
client: cfg.Client.CustomResourceDefinitions(),
86-
log: cfg.Log.WithName("crd-wrapper"),
8784
pollInterval: cfg.PollInterval,
8885
timeout: cfg.Timeout,
8986
}
@@ -95,18 +92,19 @@ func newCRDWrapper(cfg CRDWrapperConfig) *CRDWrapper {
9592
// The caller is responsible for ensuring the CRD, isn't introducing
9693
// breaking changes.
9794
func (w *CRDWrapper) Ensure(ctx context.Context, crd v1.CustomResourceDefinition) error {
95+
log := logr.FromContext(ctx)
9896
_, err := w.Get(ctx, crd.Name)
9997
if err != nil {
10098
if !apierrors.IsNotFound(err) {
10199
return fmt.Errorf("failed to check for existing CRD: %w", err)
102100
}
103101

104-
w.log.Info("Creating CRD", "name", crd.Name)
102+
log.Info("Creating CRD", "name", crd.Name)
105103
if err := w.create(ctx, crd); err != nil {
106104
return fmt.Errorf("failed to create CRD: %w", err)
107105
}
108106
} else {
109-
w.log.Info("Updating existing CRD", "name", crd.Name)
107+
log.Info("Updating existing CRD", "name", crd.Name)
110108
if err := w.patch(ctx, crd); err != nil {
111109
return fmt.Errorf("failed to patch CRD: %w", err)
112110
}
@@ -143,7 +141,8 @@ func (w *CRDWrapper) patch(ctx context.Context, newCRD v1.CustomResourceDefiniti
143141

144142
// Delete removes a CRD if it exists
145143
func (w *CRDWrapper) Delete(ctx context.Context, name string) error {
146-
w.log.Info("Deleting CRD", "name", name)
144+
log := logr.FromContext(ctx)
145+
log.Info("Deleting CRD", "name", name)
147146

148147
err := w.client.Delete(ctx, name, metav1.DeleteOptions{})
149148
if err != nil && !apierrors.IsNotFound(err) {
@@ -154,7 +153,8 @@ func (w *CRDWrapper) Delete(ctx context.Context, name string) error {
154153

155154
// waitForReady waits for a CRD to become ready
156155
func (w *CRDWrapper) waitForReady(ctx context.Context, name string) error {
157-
w.log.Info("Waiting for CRD to become ready", "name", name)
156+
log := logr.FromContext(ctx)
157+
log.Info("Waiting for CRD to become ready", "name", name)
158158

159159
return wait.PollUntilContextTimeout(ctx, w.pollInterval, w.timeout, true,
160160
func(ctx context.Context) (bool, error) {

Diff for: pkg/client/set.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,9 @@ func (c *Set) RESTConfig() *rest.Config {
117117
}
118118

119119
// CRD returns a new CRDWrapper instance
120-
func (s *Set) CRD(cfg CRDWrapperConfig) *CRDWrapper {
120+
func (c *Set) CRD(cfg CRDWrapperConfig) *CRDWrapper {
121121
if cfg.Client == nil {
122-
cfg.Client = s.apiExtensionsV1
122+
cfg.Client = c.apiExtensionsV1
123123
}
124124

125125
return newCRDWrapper(cfg)

Diff for: pkg/controller/resourcegraphdefinition/controller.go

+48-39
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@ import (
1717
"context"
1818

1919
"github.com/go-logr/logr"
20-
"k8s.io/apimachinery/pkg/types"
2120
ctrl "sigs.k8s.io/controller-runtime"
2221
"sigs.k8s.io/controller-runtime/pkg/client"
23-
"sigs.k8s.io/controller-runtime/pkg/log"
22+
ctrlrtcontroller "sigs.k8s.io/controller-runtime/pkg/controller"
2423
"sigs.k8s.io/controller-runtime/pkg/predicate"
2524
"sigs.k8s.io/controller-runtime/pkg/reconcile"
2625

@@ -37,79 +36,89 @@ import (
3736

3837
// ResourceGraphDefinitionReconciler reconciles a ResourceGraphDefinition object
3938
type ResourceGraphDefinitionReconciler struct {
40-
log logr.Logger
41-
rootLogger logr.Logger
42-
4339
allowCRDDeletion bool
4440

41+
// Client and instanceLogger are set with SetupWithManager
42+
4543
client.Client
44+
instanceLogger logr.Logger
45+
4646
clientSet *kroclient.Set
4747
crdManager kroclient.CRDClient
4848

49-
metadataLabeler metadata.Labeler
50-
rgBuilder *graph.Builder
51-
dynamicController *dynamiccontroller.DynamicController
49+
metadataLabeler metadata.Labeler
50+
rgBuilder *graph.Builder
51+
dynamicController *dynamiccontroller.DynamicController
52+
maxConcurrentReconciles int
5253
}
5354

5455
func NewResourceGraphDefinitionReconciler(
55-
log logr.Logger,
56-
mgrClient client.Client,
5756
clientSet *kroclient.Set,
5857
allowCRDDeletion bool,
5958
dynamicController *dynamiccontroller.DynamicController,
6059
builder *graph.Builder,
60+
maxConcurrentReconciles int,
6161
) *ResourceGraphDefinitionReconciler {
62-
crdWrapper := clientSet.CRD(kroclient.CRDWrapperConfig{
63-
Log: log,
64-
})
65-
rgLogger := log.WithName("controller.resourceGraphDefinition")
62+
crdWrapper := clientSet.CRD(kroclient.CRDWrapperConfig{})
6663

6764
return &ResourceGraphDefinitionReconciler{
68-
rootLogger: log,
69-
log: rgLogger,
70-
clientSet: clientSet,
71-
Client: mgrClient,
72-
allowCRDDeletion: allowCRDDeletion,
73-
crdManager: crdWrapper,
74-
dynamicController: dynamicController,
75-
metadataLabeler: metadata.NewKROMetaLabeler(),
76-
rgBuilder: builder,
65+
clientSet: clientSet,
66+
allowCRDDeletion: allowCRDDeletion,
67+
crdManager: crdWrapper,
68+
dynamicController: dynamicController,
69+
metadataLabeler: metadata.NewKROMetaLabeler(),
70+
rgBuilder: builder,
71+
maxConcurrentReconciles: maxConcurrentReconciles,
7772
}
7873
}
7974

8075
// SetupWithManager sets up the controller with the Manager.
8176
func (r *ResourceGraphDefinitionReconciler) SetupWithManager(mgr ctrl.Manager) error {
77+
r.Client = mgr.GetClient()
78+
r.instanceLogger = mgr.GetLogger()
79+
80+
logConstructor := func(req *reconcile.Request) logr.Logger {
81+
log := mgr.GetLogger().WithName("rgd-controller").WithValues(
82+
"controller", "ResourceGraphDefinition",
83+
"controllerGroup", v1alpha1.GroupVersion.Group,
84+
"controllerKind", "ResourceGraphDefinition",
85+
)
86+
if req != nil {
87+
log = log.WithValues("name", req.Name)
88+
}
89+
return log
90+
}
91+
8292
return ctrl.NewControllerManagedBy(mgr).
93+
Named("ResourceGraphDefinition").
8394
For(&v1alpha1.ResourceGraphDefinition{}).
8495
WithEventFilter(predicate.GenerationChangedPredicate{}).
96+
WithOptions(
97+
ctrlrtcontroller.Options{
98+
LogConstructor: logConstructor,
99+
MaxConcurrentReconciles: r.maxConcurrentReconciles,
100+
},
101+
).
85102
Complete(reconcile.AsReconciler[*v1alpha1.ResourceGraphDefinition](mgr.GetClient(), r))
86103
}
87104

88-
func (r *ResourceGraphDefinitionReconciler) Reconcile(ctx context.Context, resourcegraphdefinition *v1alpha1.ResourceGraphDefinition) (ctrl.Result, error) {
89-
rlog := r.log.WithValues("resourcegraphdefinition", types.NamespacedName{Namespace: resourcegraphdefinition.Namespace, Name: resourcegraphdefinition.Name})
90-
ctx = log.IntoContext(ctx, rlog)
91-
92-
if !resourcegraphdefinition.DeletionTimestamp.IsZero() {
93-
if err := r.cleanupResourceGraphDefinition(ctx, resourcegraphdefinition); err != nil {
105+
func (r *ResourceGraphDefinitionReconciler) Reconcile(ctx context.Context, o *v1alpha1.ResourceGraphDefinition) (ctrl.Result, error) {
106+
if !o.DeletionTimestamp.IsZero() {
107+
if err := r.cleanupResourceGraphDefinition(ctx, o); err != nil {
94108
return ctrl.Result{}, err
95109
}
96-
97-
if err := r.setUnmanaged(ctx, resourcegraphdefinition); err != nil {
110+
if err := r.setUnmanaged(ctx, o); err != nil {
98111
return ctrl.Result{}, err
99112
}
100-
101113
return ctrl.Result{}, nil
102114
}
103115

104-
if err := r.setManaged(ctx, resourcegraphdefinition); err != nil {
116+
if err := r.setManaged(ctx, o); err != nil {
105117
return ctrl.Result{}, err
106118
}
107119

108-
topologicalOrder, resourcesInformation, reconcileErr := r.reconcileResourceGraphDefinition(ctx, resourcegraphdefinition)
109-
110-
if err := r.setResourceGraphDefinitionStatus(ctx, resourcegraphdefinition, topologicalOrder, resourcesInformation, reconcileErr); err != nil {
111-
return ctrl.Result{}, err
112-
}
120+
topologicalOrder, resourcesInformation, reconcileErr := r.reconcileResourceGraphDefinition(ctx, o)
113121

114-
return ctrl.Result{}, nil
122+
return ctrl.Result{},
123+
r.setResourceGraphDefinitionStatus(ctx, o, topologicalOrder, resourcesInformation, reconcileErr)
115124
}

Diff for: pkg/controller/resourcegraphdefinition/controller_cleanup.go

+3-5
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ import (
1818
"fmt"
1919
"strings"
2020

21-
"github.com/go-logr/logr"
2221
"github.com/gobuffalo/flect"
2322
"k8s.io/apimachinery/pkg/runtime/schema"
23+
ctrl "sigs.k8s.io/controller-runtime"
2424

2525
"github.com/kro-run/kro/api/v1alpha1"
2626
"github.com/kro-run/kro/pkg/metadata"
@@ -31,8 +31,7 @@ import (
3131
// 1. Shuts down the microcontroller
3232
// 2. Deletes the associated CRD (if CRD deletion is enabled)
3333
func (r *ResourceGraphDefinitionReconciler) cleanupResourceGraphDefinition(ctx context.Context, rgd *v1alpha1.ResourceGraphDefinition) error {
34-
log, _ := logr.FromContext(ctx)
35-
log.V(1).Info("cleaning up resource graph definition", "name", rgd.Name)
34+
ctrl.LoggerFrom(ctx).V(1).Info("cleaning up resource graph definition", "name", rgd.Name)
3635

3736
// shutdown microcontroller
3837
gvr := metadata.GetResourceGraphDefinitionInstanceGVR(rgd.Spec.Schema.Group, rgd.Spec.Schema.APIVersion, rgd.Spec.Schema.Kind)
@@ -66,8 +65,7 @@ func (r *ResourceGraphDefinitionReconciler) shutdownResourceGraphDefinitionMicro
6665
// If CRD deletion is disabled, it logs the skip and returns nil.
6766
func (r *ResourceGraphDefinitionReconciler) cleanupResourceGraphDefinitionCRD(ctx context.Context, crdName string) error {
6867
if !r.allowCRDDeletion {
69-
log, _ := logr.FromContext(ctx)
70-
log.Info("skipping CRD deletion (disabled)", "crd", crdName)
68+
ctrl.LoggerFrom(ctx).Info("skipping CRD deletion (disabled)", "crd", crdName)
7169
return nil
7270
}
7371

Diff for: pkg/controller/resourcegraphdefinition/controller_reconcile.go

+10-4
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ import (
1818
"fmt"
1919
"time"
2020

21-
"github.com/go-logr/logr"
2221
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2322
"k8s.io/apimachinery/pkg/runtime/schema"
23+
ctrl "sigs.k8s.io/controller-runtime"
2424

2525
"github.com/kro-run/kro/api/v1alpha1"
2626
instancectrl "github.com/kro-run/kro/pkg/controller/instance"
@@ -34,7 +34,7 @@ import (
3434
// 2. Ensuring CRDs are present
3535
// 3. Setting up and starting the microcontroller
3636
func (r *ResourceGraphDefinitionReconciler) reconcileResourceGraphDefinition(ctx context.Context, rgd *v1alpha1.ResourceGraphDefinition) ([]string, []v1alpha1.ResourceInformation, error) {
37-
log, _ := logr.FromContext(ctx)
37+
log := ctrl.LoggerFrom(ctx)
3838

3939
// Process resource graph definition graph first to validate structure
4040
log.V(1).Info("reconciling resource graph definition graph")
@@ -63,6 +63,9 @@ func (r *ResourceGraphDefinitionReconciler) reconcileResourceGraphDefinition(ctx
6363
controller := r.setupMicroController(gvr, processedRGD, rgd.Spec.DefaultServiceAccounts, graphExecLabeler)
6464

6565
log.V(1).Info("reconciling resource graph definition micro controller")
66+
// TODO: the context that is passed here is tied to the reconciliation of the rgd, we might need to make
67+
// a new context with our own cancel function here to allow us to cleanly term the dynamic controller
68+
// rather than have it ignore this context and use the background context.
6669
if err := r.reconcileResourceGraphDefinitionMicroController(ctx, &gvr, controller.Reconcile); err != nil {
6770
return processedRGD.TopologicalOrder, resourcesInfo, err
6871
}
@@ -83,8 +86,11 @@ func (r *ResourceGraphDefinitionReconciler) setupMicroController(
8386
defaultSVCs map[string]string,
8487
labeler metadata.Labeler,
8588
) *instancectrl.Controller {
86-
87-
instanceLogger := r.rootLogger.WithName("controller." + gvr.Resource)
89+
instanceLogger := r.instanceLogger.WithName(fmt.Sprintf("%s-controller", gvr.Resource)).WithValues(
90+
"controller", gvr.Resource,
91+
"controllerGroup", processedRGD.Instance.GetCRD().Spec.Group,
92+
"controllerKind", processedRGD.Instance.GetCRD().Spec.Names.Kind,
93+
)
8894

8995
return instancectrl.NewController(
9096
instanceLogger,

Diff for: pkg/controller/resourcegraphdefinition/controller_status.go

+3-5
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ import (
2020

2121
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2222
"k8s.io/client-go/util/retry"
23+
ctrl "sigs.k8s.io/controller-runtime"
2324
"sigs.k8s.io/controller-runtime/pkg/client"
2425

2526
"github.com/go-logr/logr"
26-
2727
"github.com/kro-run/kro/api/v1alpha1"
2828
"github.com/kro-run/kro/pkg/metadata"
2929
)
@@ -143,8 +143,7 @@ func (r *ResourceGraphDefinitionReconciler) setResourceGraphDefinitionStatus(
143143
// setManaged sets the resourcegraphdefinition as managed, by adding the
144144
// default finalizer if it doesn't exist.
145145
func (r *ResourceGraphDefinitionReconciler) setManaged(ctx context.Context, rgd *v1alpha1.ResourceGraphDefinition) error {
146-
log, _ := logr.FromContext(ctx)
147-
log.V(1).Info("setting resourcegraphdefinition as managed")
146+
ctrl.LoggerFrom(ctx).V(1).Info("setting resourcegraphdefinition as managed")
148147

149148
// Skip if finalizer already exists
150149
if metadata.HasResourceGraphDefinitionFinalizer(rgd) {
@@ -159,8 +158,7 @@ func (r *ResourceGraphDefinitionReconciler) setManaged(ctx context.Context, rgd
159158
// setUnmanaged sets the resourcegraphdefinition as unmanaged, by removing the
160159
// default finalizer if it exists.
161160
func (r *ResourceGraphDefinitionReconciler) setUnmanaged(ctx context.Context, rgd *v1alpha1.ResourceGraphDefinition) error {
162-
log, _ := logr.FromContext(ctx)
163-
log.V(1).Info("setting resourcegraphdefinition as unmanaged")
161+
ctrl.LoggerFrom(ctx).V(1).Info("setting resourcegraphdefinition as unmanaged")
164162

165163
// Skip if finalizer already removed
166164
if !metadata.HasResourceGraphDefinitionFinalizer(rgd) {

0 commit comments

Comments
 (0)