github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/controllerutil/util.go (about) 1 /* 2 Copyright (C) 2022-2023 ApeCloud Co., Ltd 3 4 This file is part of KubeBlocks project 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU Affero General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU Affero General Public License for more details. 15 16 You should have received a copy of the GNU Affero General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 package controllerutil 21 22 import ( 23 "context" 24 "reflect" 25 26 corev1 "k8s.io/api/core/v1" 27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 28 "k8s.io/apimachinery/pkg/runtime" 29 "sigs.k8s.io/controller-runtime/pkg/client" 30 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" 31 32 appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1" 33 "github.com/1aal/kubeblocks/pkg/constant" 34 viper "github.com/1aal/kubeblocks/pkg/viperx" 35 ) 36 37 // GetUncachedObjects returns a list of K8s objects, for these object types, 38 // and their list types, client.Reader will read directly from the API server instead 39 // of the cache, which may not be up-to-date. 40 // see sigs.k8s.io/controller-runtime/pkg/client/split.go to understand how client 41 // works with this UncachedObjects filter. 42 func GetUncachedObjects() []client.Object { 43 // client-side read cache reduces the number of requests processed in the API server, 44 // which is good for performance. However, it can sometimes lead to obscure issues, 45 // most notably lacking read-after-write consistency, i.e. reading a value immediately 46 // after updating it may miss to see the changes. 47 // while in most cases this problem can be mitigated by retrying later in an idempotent 48 // manner, there are some cases where it cannot, for example if a decision is to be made 49 // that has side-effect operations such as returning an error message to the user 50 // (in webhook) or deleting certain resources (in controllerutil.HandleCRDeletion). 51 // additionally, retry loops cause unnecessary delays when reconciliations are processed. 52 // for the sake of performance, now only the objects created by the end-user is listed here, 53 // to solve the two problems mentioned above. 54 // consider carefully before adding new objects to this list. 55 return []client.Object{ 56 // avoid to cache potential large data objects 57 &corev1.ConfigMap{}, 58 &corev1.Secret{}, 59 &appsv1alpha1.Cluster{}, 60 &appsv1alpha1.Configuration{}, 61 } 62 } 63 64 // Event is wrapper for Recorder.Event, if Recorder is nil, then it's no-op. 65 func (r *RequestCtx) Event(object runtime.Object, eventtype, reason, message string) { 66 if r == nil || r.Recorder == nil { 67 return 68 } 69 r.Recorder.Event(object, eventtype, reason, message) 70 } 71 72 // Eventf is wrapper for Recorder.Eventf, if Recorder is nil, then it's no-op. 73 func (r *RequestCtx) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) { 74 if r == nil || r.Recorder == nil { 75 return 76 } 77 r.Recorder.Eventf(object, eventtype, reason, messageFmt, args...) 78 } 79 80 // UpdateCtxValue updates Context value, returns parent Context. 81 func (r *RequestCtx) UpdateCtxValue(key, val any) context.Context { 82 p := r.Ctx 83 r.Ctx = context.WithValue(r.Ctx, key, val) 84 return p 85 } 86 87 // WithValue returns a copy of parent in which the value associated with key is 88 // val. 89 func (r *RequestCtx) WithValue(key, val any) context.Context { 90 return context.WithValue(r.Ctx, key, val) 91 } 92 93 // IsRSMEnabled enables rsm by default. 94 // respect the feature gate if set, keep the ability to disable it. 95 func IsRSMEnabled() bool { 96 if viper.IsSet(constant.FeatureGateReplicatedStateMachine) { 97 return viper.GetBool(constant.FeatureGateReplicatedStateMachine) 98 } 99 return true 100 } 101 102 func IsNil(i interface{}) bool { 103 if i == nil { 104 return true 105 } 106 switch reflect.TypeOf(i).Kind() { 107 case reflect.Ptr, reflect.Map, reflect.Array, reflect.Chan, reflect.Slice: 108 return reflect.ValueOf(i).IsNil() 109 } 110 return false 111 } 112 113 var innerScheme, _ = appsv1alpha1.SchemeBuilder.Build() 114 115 func SetOwnerReference(owner, object metav1.Object) error { 116 return controllerutil.SetOwnerReference(owner, object, innerScheme) 117 } 118 119 func SetControllerReference(owner, object metav1.Object) error { 120 return controllerutil.SetControllerReference(owner, object, innerScheme) 121 }