github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/update/certmc/certmc_test.go (about) 1 // Copyright (c) 2022, 2023, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package certmc 5 6 import ( 7 "fmt" 8 "reflect" 9 "time" 10 11 . "github.com/onsi/ginkgo/v2" 12 "github.com/onsi/gomega" 13 "github.com/verrazzano/verrazzano/pkg/constants" 14 "github.com/verrazzano/verrazzano/pkg/mcconstants" 15 vzapi "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1alpha1" 16 pocnst "github.com/verrazzano/verrazzano/platform-operator/constants" 17 "github.com/verrazzano/verrazzano/tests/e2e/multicluster" 18 "github.com/verrazzano/verrazzano/tests/e2e/pkg" 19 "github.com/verrazzano/verrazzano/tests/e2e/pkg/test/framework" 20 "github.com/verrazzano/verrazzano/tests/e2e/pkg/update" 21 ) 22 23 var ( 24 t = framework.NewTestFramework("update fluentd external opensearch") 25 adminCluster *multicluster.Cluster 26 managedClusters []*multicluster.Cluster 27 waitTimeout = 10 * time.Minute 28 pollingInterval = 5 * time.Second 29 ) 30 31 type CertModifier struct { 32 CertManager *vzapi.CertManagerComponent 33 } 34 35 func (u *CertModifier) ModifyCR(cr *vzapi.Verrazzano) { 36 cr.Spec.Components.CertManager = u.CertManager 37 } 38 39 var beforeSuite = t.BeforeSuiteFunc(func() { 40 adminCluster = multicluster.AdminCluster() 41 managedClusters = multicluster.ManagedClusters() 42 verifyRegistration() 43 verifyThanosStore() 44 }) 45 46 var _ = BeforeSuite(beforeSuite) 47 48 var afterSuite = t.AfterSuiteFunc(func() { 49 verifyThanosStore() 50 }) 51 52 var _ = AfterSuite(afterSuite) 53 54 var _ = t.Describe("Update managed-cluster cert-manager", Label("f:platform-lcm.update"), func() { 55 t.Describe("multicluster cert-manager verify", Label("f:platform-lcm.multicluster-verify"), func() { 56 t.It("managed-cluster cert-manager custom CA", func() { 57 updateCustomCA() 58 verifyCaSync() 59 verifyThanosStore() 60 }) 61 }) 62 t.Describe("multicluster cert-manager verify", Label("f:platform-lcm.multicluster-verify"), func() { 63 t.It("managed-cluster cert-manager default self-signed CA", func() { 64 revertToDefaultCertManager() 65 verifyCaSync() 66 }) 67 }) 68 }) 69 70 var originalCMs = map[string]*vzapi.CertManagerComponent{} 71 var oldCaCrts = map[string]string{} 72 73 func updateCustomCA() { 74 for _, managedCluster := range managedClusters { 75 managedVZ := managedCluster.GetCR(true) 76 oldCaCrt := managedCluster. 77 GetSecretDataAsString(constants.VerrazzanoSystemNamespace, pocnst.VerrazzanoIngressSecret, mcconstants.CaCrtKey) 78 oldCaCrts[managedCluster.Name] = oldCaCrt 79 oldCM := managedVZ.Spec.Components.CertManager 80 var newCM *vzapi.CertManagerComponent 81 if isDefaultConfig(oldCM) { 82 caname := managedCluster.GenerateCA() 83 newCM = &vzapi.CertManagerComponent{ 84 Certificate: vzapi.Certificate{CA: vzapi.CA{SecretName: caname, ClusterResourceNamespace: constants.CertManagerNamespace}}, 85 } 86 } 87 originalCMs[managedCluster.Name] = oldCM 88 m := &CertModifier{CertManager: newCM} 89 update.RetryUpdate(m, managedCluster.KubeConfigPath, true, pollingInterval, waitTimeout) 90 } 91 } 92 93 func isDefaultConfig(cm *vzapi.CertManagerComponent) bool { 94 return cm == nil || reflect.DeepEqual(*cm, vzapi.CertManagerComponent{}) 95 } 96 97 func revertToDefaultCertManager() { 98 for _, managedCluster := range managedClusters { 99 oldCaCrt := managedCluster. 100 GetSecretDataAsString(constants.VerrazzanoSystemNamespace, pocnst.VerrazzanoIngressSecret, mcconstants.CaCrtKey) 101 oldCaCrts[managedCluster.Name] = oldCaCrt 102 oldCm := originalCMs[managedCluster.Name] 103 m := &CertModifier{CertManager: oldCm} 104 update.RetryUpdate(m, managedCluster.KubeConfigPath, true, pollingInterval, waitTimeout) 105 } 106 } 107 108 func verifyCaSync() { 109 for _, managedCluster := range managedClusters { 110 oldCaCrt := oldCaCrts[managedCluster.Name] 111 newCaCrt := "" 112 admCaCrt := "" 113 start := time.Now() 114 gomega.Eventually(func() bool { 115 newCaCrt = managedCluster. 116 GetSecretDataAsString(constants.VerrazzanoSystemNamespace, pocnst.VerrazzanoIngressSecret, mcconstants.CaCrtKey) 117 if oldCaCrt == newCaCrt { 118 pkg.Log(pkg.Error, fmt.Sprintf("%v of %v is not updated", pocnst.VerrazzanoIngressSecret, managedCluster.Name)) 119 } else { 120 pkg.Log(pkg.Error, fmt.Sprintf("%v of %v took %v updated", pocnst.VerrazzanoIngressSecret, managedCluster.Name, time.Since(start))) 121 } 122 return newCaCrt != oldCaCrt 123 }, waitTimeout, pollingInterval).Should(gomega.BeTrue(), fmt.Sprintf("Sync CA %v", managedCluster.Name)) 124 newCaCrt = managedCluster. 125 GetSecretDataAsString(constants.VerrazzanoSystemNamespace, pocnst.VerrazzanoIngressSecret, mcconstants.CaCrtKey) 126 casecName := fmt.Sprintf("ca-secret-%s", managedCluster.Name) 127 start = time.Now() 128 gomega.Eventually(func() bool { 129 admCaCrt = adminCluster.GetSecretDataAsString(constants.VerrazzanoMultiClusterNamespace, casecName, "cacrt") 130 if admCaCrt == newCaCrt { 131 pkg.Log(pkg.Error, fmt.Sprintf("%v of %v took %v updated", casecName, managedCluster.Name, time.Since(start))) 132 } else { 133 pkg.Log(pkg.Error, fmt.Sprintf("%v of %v is not updated", casecName, managedCluster.Name)) 134 } 135 return admCaCrt == newCaCrt 136 }, waitTimeout, pollingInterval).Should(gomega.BeTrue(), fmt.Sprintf("Sync CA %v", managedCluster.Name)) 137 } 138 } 139 140 func verifyThanosStore() { 141 for _, managedCluster := range managedClusters { 142 gomega.Eventually(func() (bool, error) { 143 metricsTest, err := pkg.NewMetricsTest(adminCluster.KubeConfigPath, map[string]string{}, managedCluster.KubeConfigPath) 144 if err != nil { 145 t.Logs.Errorf("Failed to create metrics test object for cluster: %v", err) 146 return false, err 147 } 148 149 queryStores, err := metricsTest.Source.GetTargets() 150 if err != nil { 151 t.Logs.Errorf("Failed to create get metrics target source: %v", err) 152 return false, err 153 } 154 155 expectedName := fmt.Sprintf("%s:443", managedCluster.GetQueryIngress()) 156 for _, store := range queryStores { 157 storeMap, ok := store.(map[string]interface{}) 158 if !ok { 159 t.Logs.Infof("Thanos store empty, skipping entry") 160 continue 161 } 162 name, ok := storeMap["name"] 163 if !ok { 164 t.Logs.Infof("Name not found for store, skipping entry") 165 continue 166 } 167 nameString, nameOk := name.(string) 168 if !nameOk { 169 t.Logs.Infof("Name not valid format, skipping entry") 170 continue 171 } 172 if ok { 173 t.Logs.Infof("Found store in Thanos %s, want is equal to %s", nameString, expectedName) 174 } 175 if ok && nameString == expectedName { 176 return true, nil 177 } 178 } 179 return false, nil 180 }, waitTimeout, pollingInterval).Should(gomega.BeTrue(), fmt.Sprintf("store of %s is not ready", managedCluster.Name)) 181 } 182 } 183 184 func verifyRegistration() { 185 for _, managedCluster := range managedClusters { 186 reg, _ := adminCluster.GetRegistration(managedCluster.Name) 187 if reg == nil { 188 adminCluster.Register(managedCluster) 189 gomega.Eventually(func() bool { 190 reg, err := adminCluster.GetRegistration(managedCluster.Name) 191 return reg != nil && err == nil 192 }, waitTimeout, pollingInterval).Should(gomega.BeTrue(), fmt.Sprintf("%s is not registered", managedCluster.Name)) 193 } 194 } 195 }