github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/controllers/apps/transformer_rbac_test.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 "context" 24 25 . "github.com/onsi/ginkgo/v2" 26 . "github.com/onsi/gomega" 27 28 "github.com/go-logr/logr" 29 appsv1 "k8s.io/api/apps/v1" 30 corev1 "k8s.io/api/core/v1" 31 "k8s.io/apimachinery/pkg/types" 32 logf "sigs.k8s.io/controller-runtime/pkg/log" 33 34 appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1" 35 "github.com/1aal/kubeblocks/pkg/constant" 36 "github.com/1aal/kubeblocks/pkg/controller/factory" 37 "github.com/1aal/kubeblocks/pkg/controller/graph" 38 "github.com/1aal/kubeblocks/pkg/controller/model" 39 testapps "github.com/1aal/kubeblocks/pkg/testutil/apps" 40 viper "github.com/1aal/kubeblocks/pkg/viperx" 41 ) 42 43 var _ = Describe("object rbac transformer test.", func() { 44 const ( 45 clusterName = "test-cluster" 46 clusterDefName = "test-clusterdef" 47 clusterVersionName = "test-clusterversion" 48 compName = "compName" 49 compDefName = "compDefName" 50 serviceAccountName = "kb-" + clusterName 51 ) 52 53 var transCtx graph.TransformContext 54 var ctx context.Context 55 var logger logr.Logger 56 var dag *graph.DAG 57 var graphCli model.GraphClient 58 var transformer graph.Transformer 59 var cluster *appsv1alpha1.Cluster 60 var clusterDefObj *appsv1alpha1.ClusterDefinition 61 var saKey types.NamespacedName 62 var allSettings map[string]interface{} 63 64 BeforeEach(func() { 65 ctx = context.Background() 66 logger = logf.FromContext(ctx).WithValues("transformer-rbac-test", "testnamespace") 67 By("Creating a cluster") 68 cluster = testapps.NewClusterFactory(testCtx.DefaultNamespace, clusterName, 69 clusterDefName, clusterVersionName).WithRandomName(). 70 AddComponent(compName, compDefName). 71 SetServiceAccountName(serviceAccountName).GetObject() 72 r := int32(1) 73 cluster.Spec.Replicas = &r 74 clusterDefObj = testapps.NewClusterDefFactory(clusterDefName). 75 AddComponentDef(testapps.StatefulMySQLComponent, "sts"). 76 GetObject() 77 clusterDefObj.Spec.ComponentDefs[0].Probes = &appsv1alpha1.ClusterDefinitionProbes{} 78 saKey = types.NamespacedName{ 79 Namespace: testCtx.DefaultNamespace, 80 Name: serviceAccountName, 81 } 82 83 graphCli = model.NewGraphClient(k8sClient) 84 85 transCtx = &clusterTransformContext{ 86 Context: ctx, 87 Client: graphCli, 88 EventRecorder: nil, 89 Logger: logger, 90 Cluster: cluster, 91 ClusterDef: clusterDefObj, 92 } 93 94 dag = mockDAG(graphCli, cluster) 95 transformer = &RBACTransformer{} 96 allSettings = viper.AllSettings() 97 viper.SetDefault(constant.EnableRBACManager, true) 98 }) 99 100 AfterEach(func() { 101 viper.SetDefault(constant.EnableRBACManager, false) 102 if allSettings != nil { 103 Expect(viper.MergeConfigMap(allSettings)).ShouldNot(HaveOccurred()) 104 allSettings = nil 105 } 106 }) 107 108 Context("transformer rbac manager", func() { 109 It("create serviceaccount, rolebinding if not exist", func() { 110 clusterDefObj.Spec.ComponentDefs[0].VolumeProtectionSpec = nil 111 Eventually(testapps.CheckObjExists(&testCtx, saKey, 112 &corev1.ServiceAccount{}, false)).Should(Succeed()) 113 Expect(transformer.Transform(transCtx, dag)).Should(BeNil()) 114 115 serviceAccount := factory.BuildServiceAccount(cluster) 116 roleBinding := factory.BuildRoleBinding(cluster) 117 118 dagExpected := mockDAG(graphCli, cluster) 119 graphCli.Create(dagExpected, serviceAccount) 120 graphCli.Create(dagExpected, roleBinding) 121 graphCli.DependOn(dagExpected, roleBinding, serviceAccount) 122 stsList := graphCli.FindAll(dagExpected, &appsv1.StatefulSet{}) 123 for i := range stsList { 124 graphCli.DependOn(dagExpected, stsList[i], serviceAccount) 125 } 126 deployList := graphCli.FindAll(dagExpected, &appsv1.Deployment{}) 127 for i := range deployList { 128 graphCli.DependOn(dagExpected, deployList[i], serviceAccount) 129 } 130 Expect(dag.Equals(dagExpected, model.DefaultLess)).Should(BeTrue()) 131 }) 132 133 It("create clusterrolebinding if volumeprotection enabled", func() { 134 clusterDefObj.Spec.ComponentDefs[0].VolumeProtectionSpec = &appsv1alpha1.VolumeProtectionSpec{} 135 Eventually(testapps.CheckObjExists(&testCtx, saKey, 136 &corev1.ServiceAccount{}, false)).Should(Succeed()) 137 Expect(transformer.Transform(transCtx, dag)).Should(BeNil()) 138 139 serviceAccount := factory.BuildServiceAccount(cluster) 140 roleBinding := factory.BuildRoleBinding(cluster) 141 clusterRoleBinding := factory.BuildClusterRoleBinding(cluster) 142 143 dagExpected := mockDAG(graphCli, cluster) 144 graphCli.Create(dagExpected, serviceAccount) 145 graphCli.Create(dagExpected, roleBinding) 146 graphCli.Create(dagExpected, clusterRoleBinding) 147 graphCli.DependOn(dagExpected, roleBinding, clusterRoleBinding) 148 graphCli.DependOn(dagExpected, clusterRoleBinding, serviceAccount) 149 stsList := graphCli.FindAll(dagExpected, &appsv1.StatefulSet{}) 150 for i := range stsList { 151 graphCli.DependOn(dagExpected, stsList[i], serviceAccount) 152 } 153 deployList := graphCli.FindAll(dagExpected, &appsv1.Deployment{}) 154 for i := range deployList { 155 graphCli.DependOn(dagExpected, deployList[i], serviceAccount) 156 } 157 Expect(dag.Equals(dagExpected, model.DefaultLess)).Should(BeTrue()) 158 }) 159 }) 160 }) 161 162 func mockDAG(graphCli model.GraphClient, cluster *appsv1alpha1.Cluster) *graph.DAG { 163 d := graph.NewDAG() 164 graphCli.Root(d, cluster, cluster, model.ActionStatusPtr()) 165 sts := &appsv1.StatefulSet{} 166 graphCli.Create(d, sts) 167 deploy := &appsv1.Deployment{} 168 graphCli.Create(d, deploy) 169 return d 170 }