github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/controllers/apps/transformer_validate_and_load_ref_resources.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 apps 21 22 import ( 23 "errors" 24 "fmt" 25 26 "k8s.io/apimachinery/pkg/types" 27 "sigs.k8s.io/controller-runtime/pkg/client" 28 29 appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1" 30 "github.com/1aal/kubeblocks/pkg/controller/graph" 31 ) 32 33 // ValidateAndLoadRefResourcesTransformer handles referenced resources'(cd & cv) validation and load them into context 34 type ValidateAndLoadRefResourcesTransformer struct{} 35 36 func (t *ValidateAndLoadRefResourcesTransformer) Transform(ctx graph.TransformContext, dag *graph.DAG) error { 37 transCtx, _ := ctx.(*clusterTransformContext) 38 cluster := transCtx.Cluster 39 40 var err error 41 defer func() { 42 setProvisioningStartedCondition(&cluster.Status.Conditions, cluster.Name, cluster.Generation, err) 43 }() 44 45 validateExistence := func(key client.ObjectKey, object client.Object) error { 46 err = transCtx.Client.Get(transCtx.Context, key, object) 47 if err != nil { 48 return newRequeueError(requeueDuration, err.Error()) 49 } 50 return nil 51 } 52 53 // validate cd & cv's existence 54 // if we can't get the referenced cd & cv, set provisioning condition failed, and jump to plan.Execute() 55 cd := &appsv1alpha1.ClusterDefinition{} 56 if err = validateExistence(types.NamespacedName{Name: cluster.Spec.ClusterDefRef}, cd); err != nil { 57 return err 58 } 59 var cv *appsv1alpha1.ClusterVersion 60 if len(cluster.Spec.ClusterVersionRef) > 0 { 61 cv = &appsv1alpha1.ClusterVersion{} 62 if err = validateExistence(types.NamespacedName{Name: cluster.Spec.ClusterVersionRef}, cv); err != nil { 63 return err 64 } 65 } 66 67 // validate cd & cv's availability 68 // if wrong phase, set provisioning condition failed, and jump to plan.Execute() 69 if cd.Status.Phase != appsv1alpha1.AvailablePhase || (cv != nil && cv.Status.Phase != appsv1alpha1.AvailablePhase) { 70 message := fmt.Sprintf("ref resource is unavailable, this problem needs to be solved first. cd: %s", cd.Name) 71 if cv != nil { 72 message = fmt.Sprintf("%s, cv: %s", message, cv.Name) 73 } 74 err = errors.New(message) 75 return newRequeueError(requeueDuration, message) 76 } 77 78 // inject cd & cv into the shared ctx 79 transCtx.ClusterDef = cd 80 transCtx.ClusterVer = cv 81 if cv == nil { 82 transCtx.ClusterVer = &appsv1alpha1.ClusterVersion{} 83 } 84 85 return nil 86 } 87 88 var _ graph.Transformer = &ValidateAndLoadRefResourcesTransformer{}