github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/verify-install/validators/mysql_podspec_validator_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 package validators 4 5 import ( 6 . "github.com/onsi/gomega" 7 "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1alpha1" 8 "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1beta1" 9 "github.com/verrazzano/verrazzano/tests/e2e/pkg/update" 10 apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" 11 "k8s.io/client-go/rest" 12 "sigs.k8s.io/controller-runtime/pkg/client" 13 ) 14 15 const ( 16 // Used by this test to make an illegal edit, to ensure that the apply is rejected but still generate the 17 // warnings we're looking for 18 illegalEnvironmentName = "asfsdafsdafadsfdsafdsafdsafadsfadsfadsfadsfdsafadsfsdafdsafasdfasdfsadfasdfasdfdasfasdfasdfasadsfasdfdasfasdfdsafdsafasd" 19 20 podSpecJSON = ` 21 { 22 "podSpec": { 23 "affinity": { 24 "podAffinity": { 25 "preferredDuringSchedulingIgnoredDuringExecution": [ 26 { 27 "weight": 200, 28 "podAffinityTerm": { 29 "labelSelector": { 30 "matchLabels": { 31 "app.kubernetes.io/instance": "mysql-innodbcluster-mysql-mysql-server", 32 "app.kubernetes.io/name": "mysql-innodbcluster-mysql-server" 33 } 34 }, 35 "topologyKey": "kubernetes.io/hostname" 36 } 37 } 38 ] 39 } 40 } 41 } 42 }` 43 44 warningSubstring = "Modifications to MySQL server pod specs do not trigger an automatic restart of the stateful set" 45 ) 46 47 type warningInfo struct { 48 code int 49 agent string 50 text string 51 } 52 53 type mysqlPodSpecUpdater struct { 54 warnings []warningInfo 55 } 56 57 func (j *mysqlPodSpecUpdater) ModifyCRV1beta1(cr *v1beta1.Verrazzano) { 58 // Attempt to make an illegal edit to the Jaeger configuration to ensure its component validation is working properly 59 trueValue := true 60 if cr.Spec.Components.JaegerOperator == nil { 61 cr.Spec.Components.JaegerOperator = &v1beta1.JaegerOperatorComponent{} 62 } 63 // Include an illegal edit to prevent the edit from succeeding 64 cr.Spec.EnvironmentName = illegalEnvironmentName 65 if cr.Spec.Components.Keycloak == nil { 66 cr.Spec.Components.Keycloak = &v1beta1.KeycloakComponent{} 67 } 68 cr.Spec.Components.Keycloak.Enabled = &trueValue 69 illegalValuesObj := generateJSONValuesObj() 70 cr.Spec.Components.Keycloak.MySQL.InstallOverrides.ValueOverrides = append( 71 cr.Spec.Components.Keycloak.MySQL.InstallOverrides.ValueOverrides, 72 v1beta1.Overrides{Values: illegalValuesObj}) 73 } 74 75 func (j *mysqlPodSpecUpdater) ModifyCR(cr *v1alpha1.Verrazzano) { 76 // Attempt to make an illegal edit to the Jaeger configuration to ensure its component validation is working properly 77 trueValue := true 78 if cr.Spec.Components.JaegerOperator == nil { 79 cr.Spec.Components.JaegerOperator = &v1alpha1.JaegerOperatorComponent{} 80 } 81 // Include an illegal edit to prevent the edit from succeeding 82 cr.Spec.EnvironmentName = illegalEnvironmentName 83 if cr.Spec.Components.Keycloak == nil { 84 cr.Spec.Components.Keycloak = &v1alpha1.KeycloakComponent{} 85 } 86 cr.Spec.Components.Keycloak.Enabled = &trueValue 87 illegalValuesObj := generateJSONValuesObj() 88 cr.Spec.Components.Keycloak.MySQL.InstallOverrides.ValueOverrides = append( 89 cr.Spec.Components.Keycloak.MySQL.InstallOverrides.ValueOverrides, 90 v1alpha1.Overrides{Values: illegalValuesObj}) 91 } 92 93 func (j *mysqlPodSpecUpdater) HandleWarningHeader(code int, agent string, text string) { 94 j.warnings = append(j.warnings, warningInfo{code: code, agent: agent, text: text}) 95 } 96 97 var _ update.CRModifier = &mysqlPodSpecUpdater{} 98 var _ update.CRModifierV1beta1 = &mysqlPodSpecUpdater{} 99 var _ rest.WarningHandler = &mysqlPodSpecUpdater{} 100 101 func generateJSONValuesObj() *apiextensionsv1.JSON { 102 illegalOverride := podSpecJSON 103 illegalValuesObj := &apiextensionsv1.JSON{ 104 Raw: []byte(illegalOverride), 105 } 106 return illegalValuesObj 107 } 108 109 // runValidatorTestV1Beta1 Attempt to generate the MySQL values webhook warning, with an illegal edit so the overall edit is rejected 110 func runMySQLPodspecEditWarningTestV1Beta1() { 111 updater := &mysqlPodSpecUpdater{} 112 checkExpectations(update.UpdateCRV1beta1(updater, client.DryRunAll), updater) 113 } 114 115 // runValidatorTestV1Alpha1 Attempt to use an illegal overrides value on the Jaeger operator configuration using the v1alpha1 API 116 func runMySQLPodspecEditWarningTestV1Alpha1() { 117 updater := &mysqlPodSpecUpdater{} 118 checkExpectations(update.UpdateCR(updater, client.DryRunAll), updater) 119 } 120 121 func checkExpectations(err error, updater *mysqlPodSpecUpdater) { 122 Eventually(func() []string { 123 t.Logs.Infof("Verifies that an update to the MySQL overrides containing a podSpec value issues a warning to " + 124 "the user; also makes an illegal edit to avoid mutating the system but also generate the warning") 125 if err == nil { 126 t.Logs.Info("Did not get an error on illegal update") 127 return []string{} 128 } 129 if err != nil { 130 t.Logs.Infof("Update error: %s", err.Error()) 131 } 132 var warningText []string 133 for _, warning := range updater.warnings { 134 warningText = append(warningText, warning.text) 135 t.Logs.Infof("Warning: %v", warning) 136 } 137 return warningText 138 }, waitTimeout, pollingInterval).Should(ContainElements(ContainSubstring(warningSubstring))) 139 }