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  }