sigs.k8s.io/cluster-api@v1.7.1/util/log/log.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // Package log provides log utils. 18 package log 19 20 import ( 21 "context" 22 23 "github.com/go-logr/logr" 24 "github.com/pkg/errors" 25 apierrors "k8s.io/apimachinery/pkg/api/errors" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/apimachinery/pkg/util/sets" 28 "k8s.io/klog/v2" 29 ctrl "sigs.k8s.io/controller-runtime" 30 "sigs.k8s.io/controller-runtime/pkg/client" 31 32 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" 33 ) 34 35 // AddOwners adds the owners of an Object based on OwnerReferences as k/v pairs to the logger in ctx. 36 // Note: If an owner is a MachineSet we also add the owners from the MachineSet OwnerReferences. 37 func AddOwners(ctx context.Context, c client.Client, obj metav1.Object) (context.Context, logr.Logger, error) { 38 log := ctrl.LoggerFrom(ctx) 39 40 owners, err := getOwners(ctx, c, obj) 41 if err != nil { 42 return nil, logr.Logger{}, errors.Wrapf(err, "failed to add object hierarchy to logger") 43 } 44 45 // Add owners as k/v pairs. 46 keysAndValues := []interface{}{} 47 addedKinds := sets.Set[string]{} 48 for _, owner := range owners { 49 // Don't add duplicate kinds. 50 if addedKinds.Has(owner.Kind) { 51 continue 52 } 53 54 keysAndValues = append(keysAndValues, owner.Kind, klog.KRef(owner.Namespace, owner.Name)) 55 addedKinds.Insert(owner.Kind) 56 } 57 log = log.WithValues(keysAndValues...) 58 59 ctx = ctrl.LoggerInto(ctx, log) 60 return ctx, log, nil 61 } 62 63 // owner represents an owner of an object. 64 type owner struct { 65 Kind string 66 Name string 67 Namespace string 68 } 69 70 // getOwners returns owners of an Object based on OwnerReferences. 71 // Note: If an owner is a MachineSet we also return the owners from the MachineSet OwnerReferences. 72 func getOwners(ctx context.Context, c client.Client, obj metav1.Object) ([]owner, error) { 73 owners := []owner{} 74 for _, ownerRef := range obj.GetOwnerReferences() { 75 owners = append(owners, owner{ 76 Kind: ownerRef.Kind, 77 Namespace: obj.GetNamespace(), 78 Name: ownerRef.Name, 79 }) 80 81 // continue if the ownerRef does not point to a MachineSet. 82 if ownerRef.Kind != "MachineSet" { 83 continue 84 } 85 86 // get owners of the MachineSet. 87 var ms clusterv1.MachineSet 88 if err := c.Get(ctx, client.ObjectKey{Namespace: obj.GetNamespace(), Name: ownerRef.Name}, &ms); err != nil { 89 // continue if the MachineSet doesn't exist. 90 if apierrors.IsNotFound(err) { 91 continue 92 } 93 return nil, errors.Wrapf(err, "failed to get owners: failed to get MachineSet %s", klog.KRef(obj.GetNamespace(), ownerRef.Name)) 94 } 95 96 for _, ref := range ms.GetOwnerReferences() { 97 owners = append(owners, owner{ 98 Kind: ref.Kind, 99 Namespace: obj.GetNamespace(), 100 Name: ref.Name, 101 }) 102 } 103 } 104 105 return owners, nil 106 }