Skip to content

Commit 6df168f

Browse files
authored
Merge pull request #6832 from ykakarap/runtime-sdk_logging
🌱 runtime-sdk: add logs
2 parents b2605ab + 4843b49 commit 6df168f

File tree

5 files changed

+54
-2
lines changed

5 files changed

+54
-2
lines changed

exp/runtime/internal/controllers/extensionconfig_controller.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package controllers
1818

1919
import (
2020
"context"
21+
"fmt"
2122
"strings"
2223

2324
"github.com/pkg/errors"
@@ -151,6 +152,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
151152
}
152153

153154
// Register the ExtensionConfig if it was found and patched without error.
155+
log.Info("Registering ExtensionConfig information into registry")
154156
if err = r.RuntimeClient.Register(discoveredExtensionConfig); err != nil {
155157
return ctrl.Result{}, errors.Wrapf(err, "failed to register ExtensionConfig %s/%s", extensionConfig.Namespace, extensionConfig.Name)
156158
}
@@ -175,7 +177,9 @@ func patchExtensionConfig(ctx context.Context, client client.Client, original, m
175177

176178
// reconcileDelete will remove the ExtensionConfig from the registry on deletion of the object. Note this is a best
177179
// effort deletion that may not catch all cases.
178-
func (r *Reconciler) reconcileDelete(_ context.Context, extensionConfig *runtimev1.ExtensionConfig) (ctrl.Result, error) {
180+
func (r *Reconciler) reconcileDelete(ctx context.Context, extensionConfig *runtimev1.ExtensionConfig) (ctrl.Result, error) {
181+
log := ctrl.LoggerFrom(ctx)
182+
log.Info("Unregistering ExtensionConfig information from registry")
179183
if err := r.RuntimeClient.Unregister(extensionConfig); err != nil {
180184
return ctrl.Result{}, errors.Wrapf(err, "failed to unregister %s", tlog.KObj{Obj: extensionConfig})
181185
}
@@ -224,12 +228,16 @@ func discoverExtensionConfig(ctx context.Context, runtimeClient runtimeclient.Cl
224228
// Note: This was implemented to behave similar to the cert-manager cainjector.
225229
// We couldn't use the cert-manager cainjector because it doesn't work with CustomResources.
226230
func reconcileCABundle(ctx context.Context, client client.Client, config *runtimev1.ExtensionConfig) error {
231+
log := ctrl.LoggerFrom(ctx)
232+
227233
secretNameRaw, ok := config.Annotations[runtimev1.InjectCAFromSecretAnnotation]
228234
if !ok {
229235
return nil
230236
}
231237
secretName := splitNamespacedName(secretNameRaw)
232238

239+
log.Info(fmt.Sprintf("Injecting CA Bundle into ExtensionConfig from secret %q", secretNameRaw))
240+
233241
if secretName.Namespace == "" || secretName.Name == "" {
234242
return errors.Errorf("failed to reconcile caBundle: secret name %q must be in the form <namespace>/<name>", secretNameRaw)
235243
}

exp/runtime/internal/controllers/warmup.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/pkg/errors"
2424
kerrors "k8s.io/apimachinery/pkg/util/errors"
2525
"k8s.io/apimachinery/pkg/util/wait"
26+
"k8s.io/klog/v2"
2627
ctrl "sigs.k8s.io/controller-runtime"
2728
"sigs.k8s.io/controller-runtime/pkg/client"
2829
"sigs.k8s.io/controller-runtime/pkg/manager"
@@ -89,6 +90,8 @@ func (r *warmupRunnable) Start(ctx context.Context) error {
8990
// warmupRegistry attempts to discover all existing ExtensionConfigs and patch their status with discovered Handlers.
9091
// It warms up the registry by passing it the up-to-date list of ExtensionConfigs.
9192
func warmupRegistry(ctx context.Context, client client.Client, reader client.Reader, runtimeClient runtimeclient.Client) error {
93+
log := ctrl.LoggerFrom(ctx)
94+
9295
var errs []error
9396

9497
extensionConfigList := runtimev1.ExtensionConfigList{}
@@ -100,6 +103,9 @@ func warmupRegistry(ctx context.Context, client client.Client, reader client.Rea
100103
extensionConfig := &extensionConfigList.Items[i]
101104
original := extensionConfig.DeepCopy()
102105

106+
log := log.WithValues("extensionConfig", klog.KObj(extensionConfig), "name", extensionConfig.Name, "namespace", extensionConfig.Namespace)
107+
ctx := ctrl.LoggerInto(ctx, log)
108+
103109
// Inject CABundle from secret if annotation is set. Otherwise https calls may fail.
104110
if err := reconcileCABundle(ctx, client, extensionConfig); err != nil {
105111
errs = append(errs, err)
@@ -128,5 +134,7 @@ func warmupRegistry(ctx context.Context, client client.Client, reader client.Rea
128134
return err
129135
}
130136

137+
log.Info("The extension registry is warmed up")
138+
131139
return nil
132140
}

internal/controllers/topology/cluster/cluster_controller.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,14 @@ import (
3737
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
3838
"sigs.k8s.io/cluster-api/api/v1beta1/index"
3939
"sigs.k8s.io/cluster-api/controllers/external"
40+
runtimecatalog "sigs.k8s.io/cluster-api/exp/runtime/catalog"
4041
runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"
4142
"sigs.k8s.io/cluster-api/feature"
4243
"sigs.k8s.io/cluster-api/internal/controllers/topology/cluster/patches"
4344
"sigs.k8s.io/cluster-api/internal/controllers/topology/cluster/scope"
4445
"sigs.k8s.io/cluster-api/internal/controllers/topology/cluster/structuredmerge"
4546
"sigs.k8s.io/cluster-api/internal/hooks"
47+
tlog "sigs.k8s.io/cluster-api/internal/log"
4648
runtimeclient "sigs.k8s.io/cluster-api/internal/runtime/client"
4749
"sigs.k8s.io/cluster-api/util"
4850
"sigs.k8s.io/cluster-api/util/annotations"
@@ -273,6 +275,7 @@ func (r *Reconciler) setupDynamicWatches(ctx context.Context, s *scope.Scope) er
273275
func (r *Reconciler) callBeforeClusterCreateHook(ctx context.Context, s *scope.Scope) (reconcile.Result, error) {
274276
// If the cluster objects (InfraCluster, ControlPlane, etc) are not yet created we are in the creation phase.
275277
// Call the BeforeClusterCreate hook before proceeding.
278+
log := tlog.LoggerFrom(ctx)
276279
if s.Current.Cluster.Spec.InfrastructureRef == nil && s.Current.Cluster.Spec.ControlPlaneRef == nil {
277280
hookRequest := &runtimehooksv1.BeforeClusterCreateRequest{
278281
Cluster: *s.Current.Cluster,
@@ -283,6 +286,7 @@ func (r *Reconciler) callBeforeClusterCreateHook(ctx context.Context, s *scope.S
283286
}
284287
s.HookResponseTracker.Add(runtimehooksv1.BeforeClusterCreate, hookResponse)
285288
if hookResponse.RetryAfterSeconds != 0 {
289+
log.Infof("Creation of Cluster topology is blocked by %s hook", runtimecatalog.HookName(runtimehooksv1.BeforeClusterCreate))
286290
return ctrl.Result{RequeueAfter: time.Duration(hookResponse.RetryAfterSeconds) * time.Second}, nil
287291
}
288292
}
@@ -338,6 +342,7 @@ func (r *Reconciler) machineDeploymentToCluster(o client.Object) []ctrl.Request
338342
func (r *Reconciler) reconcileDelete(ctx context.Context, cluster *clusterv1.Cluster) (ctrl.Result, error) {
339343
// Call the BeforeClusterDelete hook if the 'ok-to-delete' annotation is not set
340344
// and add the annotation to the cluster after receiving a successful non-blocking response.
345+
log := tlog.LoggerFrom(ctx)
341346
if feature.Gates.Enabled(feature.RuntimeSDK) {
342347
if !hooks.IsOkToDelete(cluster) {
343348
hookRequest := &runtimehooksv1.BeforeClusterDeleteRequest{
@@ -348,6 +353,7 @@ func (r *Reconciler) reconcileDelete(ctx context.Context, cluster *clusterv1.Clu
348353
return ctrl.Result{}, err
349354
}
350355
if hookResponse.RetryAfterSeconds != 0 {
356+
log.Infof("Cluster deletion is blocked by %q hook", runtimecatalog.HookName(runtimehooksv1.BeforeClusterDelete))
351357
return ctrl.Result{RequeueAfter: time.Duration(hookResponse.RetryAfterSeconds) * time.Second}, nil
352358
}
353359
// The BeforeClusterDelete hook returned a non-blocking response. Now the cluster is ready to be deleted.

internal/controllers/topology/cluster/desired_state.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131

3232
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
3333
"sigs.k8s.io/cluster-api/controllers/external"
34+
runtimecatalog "sigs.k8s.io/cluster-api/exp/runtime/catalog"
3435
runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"
3536
"sigs.k8s.io/cluster-api/feature"
3637
"sigs.k8s.io/cluster-api/internal/contract"
@@ -257,6 +258,7 @@ func (r *Reconciler) computeControlPlane(ctx context.Context, s *scope.Scope, in
257258
// The version is calculated using the state of the current machine deployments, the current control plane
258259
// and the version defined in the topology.
259260
func (r *Reconciler) computeControlPlaneVersion(ctx context.Context, s *scope.Scope) (string, error) {
261+
log := tlog.LoggerFrom(ctx)
260262
desiredVersion := s.Blueprint.Topology.Version
261263
// If we are creating the control plane object (current control plane is nil), use version from topology.
262264
if s.Current.ControlPlane == nil || s.Current.ControlPlane.Object == nil {
@@ -334,6 +336,7 @@ func (r *Reconciler) computeControlPlaneVersion(ctx context.Context, s *scope.Sc
334336
// change the UpgradeTracker accordingly, otherwise the hook call is completed and we
335337
// can remove this hook from the list of pending-hooks.
336338
if hookResponse.RetryAfterSeconds != 0 {
339+
log.Infof("MachineDeployments upgrade to version %q are blocked by %q hook", desiredVersion, runtimecatalog.HookName(runtimehooksv1.AfterControlPlaneUpgrade))
337340
s.UpgradeTracker.MachineDeployments.HoldUpgrades(true)
338341
} else {
339342
if err := hooks.MarkAsDone(ctx, r.Client, s.Current.Cluster, runtimehooksv1.AfterControlPlaneUpgrade); err != nil {
@@ -383,6 +386,7 @@ func (r *Reconciler) computeControlPlaneVersion(ctx context.Context, s *scope.Sc
383386
s.HookResponseTracker.Add(runtimehooksv1.BeforeClusterUpgrade, hookResponse)
384387
if hookResponse.RetryAfterSeconds != 0 {
385388
// Cannot pickup the new version right now. Need to try again later.
389+
log.Infof("Cluster upgrade to version %q is blocked by %q hook", desiredVersion, runtimecatalog.HookName(runtimehooksv1.BeforeClusterUpgrade))
386390
return *currentVersion, nil
387391
}
388392

internal/runtime/client/client.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"bytes"
2222
"context"
2323
"encoding/json"
24+
"fmt"
2425
"io"
2526
"net"
2627
"net/http"
@@ -40,6 +41,7 @@ import (
4041
"k8s.io/apimachinery/pkg/util/validation"
4142
"k8s.io/client-go/transport"
4243
"k8s.io/utils/pointer"
44+
ctrl "sigs.k8s.io/controller-runtime"
4345
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
4446

4547
runtimev1 "sigs.k8s.io/cluster-api/exp/runtime/api/v1alpha1"
@@ -117,6 +119,9 @@ func (c *client) IsReady() bool {
117119
}
118120

119121
func (c *client) Discover(ctx context.Context, extensionConfig *runtimev1.ExtensionConfig) (*runtimev1.ExtensionConfig, error) {
122+
log := ctrl.LoggerFrom(ctx)
123+
log.Info("Performing discovery for ExtensionConfig")
124+
120125
hookGVH, err := c.catalog.GroupVersionHook(runtimehooksv1.Discovery)
121126
if err != nil {
122127
return nil, errors.Wrapf(err, "failed to discover extension %q: failed to compute GVH of hook", extensionConfig.Name)
@@ -187,9 +192,12 @@ func (c *client) Unregister(extensionConfig *runtimev1.ExtensionConfig) error {
187192
// See CallExtension for more details on when an ExtensionHandler returns an error.
188193
// The aggregated result of the ExtensionHandlers is updated into the response object passed to the function.
189194
func (c *client) CallAllExtensions(ctx context.Context, hook runtimecatalog.Hook, forObject metav1.Object, request runtime.Object, response runtimehooksv1.ResponseObject) error {
195+
hookName := runtimecatalog.HookName(hook)
196+
log := ctrl.LoggerFrom(ctx).WithValues("hook", hookName)
197+
ctx = ctrl.LoggerInto(ctx, log)
190198
gvh, err := c.catalog.GroupVersionHook(hook)
191199
if err != nil {
192-
return errors.Wrapf(err, "failed to call extension handlers for hook %q: failed to compute GroupVersionHook", runtimecatalog.HookName(hook))
200+
return errors.Wrapf(err, "failed to call extension handlers for hook %q: failed to compute GroupVersionHook", hookName)
193201
}
194202
// Make sure the request is compatible with the hook.
195203
if err := c.catalog.ValidateRequest(gvh, request); err != nil {
@@ -205,6 +213,7 @@ func (c *client) CallAllExtensions(ctx context.Context, hook runtimecatalog.Hook
205213
return errors.Wrapf(err, "failed to call extension handlers for hook %q", gvh.GroupHook())
206214
}
207215

216+
log.Info(fmt.Sprintf("Calling all extensions of hook %q", hookName))
208217
responses := []runtimehooksv1.ResponseObject{}
209218
for _, registration := range registrations {
210219
// Creates a new instance of the response parameter.
@@ -221,12 +230,14 @@ func (c *client) CallAllExtensions(ctx context.Context, hook runtimecatalog.Hook
221230
}
222231
// If the object namespace isn't matched by the registration NamespaceSelector skip the call.
223232
if !namespaceMatches {
233+
log.V(5).Info(fmt.Sprintf("skipping extension handler %q as object '%s/%s' does not match selector %q of ExtensionConfig", registration.Name, forObject.GetNamespace(), forObject.GetName(), registration.NamespaceSelector))
224234
continue
225235
}
226236

227237
err = c.CallExtension(ctx, hook, forObject, registration.Name, request, tmpResponse)
228238
// If one of the extension handlers fails lets short-circuit here and return early.
229239
if err != nil {
240+
log.Error(err, "failed to call extension handlers")
230241
return errors.Wrapf(err, "failed to call extension handlers for hook %q", gvh.GroupHook())
231242
}
232243
responses = append(responses, tmpResponse)
@@ -289,6 +300,8 @@ func lowestNonZeroRetryAfterSeconds(i, j int32) int32 {
289300
// - Internal errors. Examples: hooks is incompatible with ExtensionHandler, ExtensionHandler information is missing.
290301
// - Error when ExtensionHandler returns a response with `Status` set to `Failure`.
291302
func (c *client) CallExtension(ctx context.Context, hook runtimecatalog.Hook, forObject metav1.Object, name string, request runtime.Object, response runtimehooksv1.ResponseObject) error {
303+
log := ctrl.LoggerFrom(ctx).WithValues("extensionHandler", name, "hook", runtimecatalog.HookName(hook))
304+
ctx = ctrl.LoggerInto(ctx, log)
292305
hookGVH, err := c.catalog.GroupVersionHook(hook)
293306
if err != nil {
294307
return errors.Wrapf(err, "failed to call extension handler %q: failed to compute GroupVersionHook", name)
@@ -320,6 +333,7 @@ func (c *client) CallExtension(ctx context.Context, hook runtimecatalog.Hook, fo
320333
return errors.Errorf("failed to call extension handler %q: namespaceSelector did not match object %s", name, util.ObjectKey(forObject))
321334
}
322335

336+
log.Info(fmt.Sprintf("Calling extension handler %q", name))
323337
var timeoutDuration time.Duration
324338
if registration.TimeoutSeconds != nil {
325339
timeoutDuration = time.Duration(*registration.TimeoutSeconds) * time.Second
@@ -339,18 +353,27 @@ func (c *client) CallExtension(ctx context.Context, hook runtimecatalog.Hook, fo
339353
ignore := *registration.FailurePolicy == runtimev1.FailurePolicyIgnore
340354
if _, ok := err.(errCallingExtensionHandler); ok && ignore {
341355
// Update the response to a default success response and return.
356+
log.Info(fmt.Sprintf("ignoring error calling extension handler because of FailurePolicy %q", *registration.FailurePolicy))
342357
response.SetStatus(runtimehooksv1.ResponseStatusSuccess)
343358
response.SetMessage("")
344359
return nil
345360
}
361+
log.Error(err, "failed to call extension handler")
346362
return errors.Wrapf(err, "failed to call extension handler %q", name)
347363
}
348364

349365
// If the received response is a failure then return an error.
350366
if response.GetStatus() == runtimehooksv1.ResponseStatusFailure {
367+
log.Error(err, "extension handler returned a failure response")
351368
return errors.Errorf("failed to call extension handler %q: got failure response with message %q", name, response.GetMessage())
352369
}
353370

371+
if retryResponse, ok := response.(runtimehooksv1.RetryResponseObject); ok && retryResponse.GetRetryAfterSeconds() != 0 {
372+
log.Info(fmt.Sprintf("extension handler returned blocking response with retryAfterSeconds of %q", retryResponse.GetRetryAfterSeconds()))
373+
} else {
374+
log.Info("extension handler returned success response")
375+
}
376+
354377
// Received a successful response from the extension handler. The `response` object
355378
// has been populated with the result. Return no error.
356379
return nil
@@ -366,6 +389,7 @@ type httpCallOptions struct {
366389
}
367390

368391
func httpCall(ctx context.Context, request, response runtime.Object, opts *httpCallOptions) error {
392+
log := ctrl.LoggerFrom(ctx)
369393
if opts == nil || request == nil || response == nil {
370394
return errors.New("http call failed: opts, request and response cannot be nil")
371395
}
@@ -389,6 +413,7 @@ func httpCall(ctx context.Context, request, response runtime.Object, opts *httpC
389413
responseLocal := response
390414

391415
if requireConversion {
416+
log.V(5).Info(fmt.Sprintf("Hook version of supported request is %s. Converting request from %s", opts.registrationGVH, opts.hookGVH))
392417
// The request and response objects need to be converted to match the version supported by
393418
// the ExtensionHandler.
394419
var err error
@@ -485,6 +510,7 @@ func httpCall(ctx context.Context, request, response runtime.Object, opts *httpC
485510
}
486511

487512
if requireConversion {
513+
log.V(5).Info(fmt.Sprintf("Hook version of received response is %s. Converting response to %s", opts.registrationGVH, opts.hookGVH))
488514
// Convert the received response to the original version of the response object.
489515
if err := opts.catalog.Convert(responseLocal, response, ctx); err != nil {
490516
return errors.Wrapf(err, "http call failed: failed to convert response from %T to %T", requestLocal, response)

0 commit comments

Comments
 (0)