github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/controllers/apps/operations/util/common_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 util 21 22 import ( 23 "context" 24 "encoding/json" 25 "time" 26 27 "sigs.k8s.io/controller-runtime/pkg/client" 28 29 appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1" 30 dpv1alpha1 "github.com/1aal/kubeblocks/apis/dataprotection/v1alpha1" 31 intctrlutil "github.com/1aal/kubeblocks/pkg/constant" 32 ) 33 34 func setOpsRequestToCluster(cluster *appsv1alpha1.Cluster, opsRequestSlice []appsv1alpha1.OpsRecorder) { 35 if cluster.Annotations == nil { 36 cluster.Annotations = map[string]string{} 37 } 38 if len(opsRequestSlice) > 0 { 39 result, _ := json.Marshal(opsRequestSlice) 40 cluster.Annotations[intctrlutil.OpsRequestAnnotationKey] = string(result) 41 } else { 42 delete(cluster.Annotations, intctrlutil.OpsRequestAnnotationKey) 43 } 44 } 45 46 // PatchClusterOpsAnnotations patches OpsRequest annotation in Cluster.annotations 47 func PatchClusterOpsAnnotations(ctx context.Context, 48 cli client.Client, 49 cluster *appsv1alpha1.Cluster, 50 opsRequestSlice []appsv1alpha1.OpsRecorder) error { 51 patch := client.MergeFrom(cluster.DeepCopy()) 52 setOpsRequestToCluster(cluster, opsRequestSlice) 53 return cli.Patch(ctx, cluster, patch) 54 } 55 56 // UpdateClusterOpsAnnotations updates OpsRequest annotation in Cluster.annotations 57 func UpdateClusterOpsAnnotations(ctx context.Context, 58 cli client.Client, 59 cluster *appsv1alpha1.Cluster, 60 opsRequestSlice []appsv1alpha1.OpsRecorder) error { 61 setOpsRequestToCluster(cluster, opsRequestSlice) 62 return cli.Update(ctx, cluster) 63 } 64 65 // PatchOpsRequestReconcileAnnotation patches the reconcile annotation to OpsRequest 66 func PatchOpsRequestReconcileAnnotation(ctx context.Context, cli client.Client, namespace string, opsRequestName string) error { 67 opsRequest := &appsv1alpha1.OpsRequest{} 68 if err := cli.Get(ctx, client.ObjectKey{Name: opsRequestName, Namespace: namespace}, opsRequest); err != nil { 69 return err 70 } 71 patch := client.MergeFrom(opsRequest.DeepCopy()) 72 if opsRequest.Annotations == nil { 73 opsRequest.Annotations = map[string]string{} 74 } 75 // because many changes may be triggered within one second, if the accuracy is only in seconds, the event may be lost. 76 // so use nanoseconds to record the time. 77 opsRequest.Annotations[intctrlutil.ReconcileAnnotationKey] = time.Now().Format(time.RFC3339Nano) 78 return cli.Patch(ctx, opsRequest, patch) 79 } 80 81 // GetOpsRequestSliceFromCluster gets OpsRequest slice from cluster annotations. 82 // this records what OpsRequests are running in cluster 83 func GetOpsRequestSliceFromCluster(cluster *appsv1alpha1.Cluster) ([]appsv1alpha1.OpsRecorder, error) { 84 var ( 85 opsRequestValue string 86 opsRequestSlice []appsv1alpha1.OpsRecorder 87 ok bool 88 ) 89 if cluster == nil || cluster.Annotations == nil { 90 return nil, nil 91 } 92 if opsRequestValue, ok = cluster.Annotations[intctrlutil.OpsRequestAnnotationKey]; !ok { 93 return nil, nil 94 } 95 // opsRequest annotation value in cluster to slice 96 if err := json.Unmarshal([]byte(opsRequestValue), &opsRequestSlice); err != nil { 97 return nil, err 98 } 99 return opsRequestSlice, nil 100 } 101 102 // GetOpsRequestFromBackup gets OpsRequest slice from cluster annotations. 103 func GetOpsRequestFromBackup(backup *dpv1alpha1.Backup) *appsv1alpha1.OpsRecorder { 104 var ( 105 opsRequestName string 106 opsRequestType string 107 ok bool 108 ) 109 if backup == nil || backup.Labels == nil { 110 return nil 111 } 112 if opsRequestName, ok = backup.Labels[intctrlutil.OpsRequestNameLabelKey]; !ok { 113 return nil 114 } 115 if opsRequestType, ok = backup.Labels[intctrlutil.OpsRequestTypeLabelKey]; !ok { 116 return nil 117 } 118 return &appsv1alpha1.OpsRecorder{ 119 Name: opsRequestName, 120 Type: appsv1alpha1.OpsType(opsRequestType), 121 } 122 }