github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/controllers/apps/configuration/config_related_helper.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 configuration 21 22 import ( 23 "context" 24 "reflect" 25 26 appv1 "k8s.io/api/apps/v1" 27 corev1 "k8s.io/api/core/v1" 28 "sigs.k8s.io/controller-runtime/pkg/client" 29 30 workloads "github.com/1aal/kubeblocks/apis/workloads/v1alpha1" 31 "github.com/1aal/kubeblocks/pkg/configuration/core" 32 cfgutil "github.com/1aal/kubeblocks/pkg/configuration/util" 33 "github.com/1aal/kubeblocks/pkg/constant" 34 intctrlutil "github.com/1aal/kubeblocks/pkg/controllerutil" 35 "github.com/1aal/kubeblocks/pkg/generics" 36 ) 37 38 func retrieveRelatedComponentsByConfigmap[T generics.Object, PT generics.PObject[T], L generics.ObjList[T], PL generics.PObjList[T, L]](cli client.Client, ctx context.Context, configSpecName string, _ func(T, PT, L, PL), cfg client.ObjectKey, opts ...client.ListOption) ([]T, []string, error) { 39 var objList L 40 if err := cli.List(ctx, PL(&objList), opts...); err != nil { 41 return nil, nil, err 42 } 43 44 objs := make([]T, 0) 45 containers := cfgutil.NewSet() 46 configSpecKey := core.GenerateTPLUniqLabelKeyWithConfig(configSpecName) 47 items := toObjects[T, L, PL](&objList) 48 for i := range items { 49 obj := toResourceObject(&items[i]) 50 if objs == nil { 51 return nil, nil, core.MakeError("failed to convert to resource object") 52 } 53 if !foundComponentConfigSpec(obj.GetAnnotations(), configSpecKey, cfg.Name) { 54 continue 55 } 56 podTemplate := transformPodTemplate(obj) 57 if podTemplate == nil { 58 continue 59 } 60 volumeMounted := intctrlutil.GetVolumeMountName(podTemplate.Spec.Volumes, cfg.Name) 61 if volumeMounted == nil { 62 continue 63 } 64 // filter config manager sidecar container 65 contains := intctrlutil.GetContainersByConfigmap(podTemplate.Spec.Containers, 66 volumeMounted.Name, core.GenerateEnvFromName(cfg.Name), 67 func(containerName string) bool { 68 return constant.ConfigSidecarName == containerName 69 }) 70 if len(contains) > 0 { 71 objs = append(objs, items[i]) 72 containers.Add(contains...) 73 } 74 } 75 return objs, containers.AsSlice(), nil 76 } 77 78 func transformPodTemplate(obj client.Object) *corev1.PodTemplateSpec { 79 switch v := obj.(type) { 80 default: 81 return nil 82 case *appv1.StatefulSet: 83 return &v.Spec.Template 84 case *appv1.Deployment: 85 return &v.Spec.Template 86 case *workloads.ReplicatedStateMachine: 87 return &v.Spec.Template 88 } 89 } 90 91 func toObjects[T generics.Object, L generics.ObjList[T], PL generics.PObjList[T, L]](compList PL) []T { 92 return reflect.ValueOf(compList).Elem().FieldByName("Items").Interface().([]T) 93 } 94 95 func toResourceObject(obj any) client.Object { 96 return obj.(client.Object) 97 } 98 99 func foundComponentConfigSpec(annotations map[string]string, key, value string) bool { 100 return len(annotations) != 0 && annotations[key] == value 101 }