github.com/verrazzano/verrazzano@v1.7.1/platform-operator/controllers/secrets/verrazzano_tls_secret_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 secrets 5 6 import ( 7 "bytes" 8 "context" 9 "fmt" 10 "testing" 11 12 "github.com/stretchr/testify/assert" 13 vzconst "github.com/verrazzano/verrazzano/pkg/constants" 14 "github.com/verrazzano/verrazzano/pkg/log/vzlog" 15 vzapi "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1alpha1" 16 "github.com/verrazzano/verrazzano/platform-operator/constants" 17 "github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/healthcheck" 18 appsv1 "k8s.io/api/apps/v1" 19 corev1 "k8s.io/api/core/v1" 20 v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 "k8s.io/apimachinery/pkg/runtime" 22 "k8s.io/apimachinery/pkg/types" 23 controllerruntime "sigs.k8s.io/controller-runtime" 24 "sigs.k8s.io/controller-runtime/pkg/client" 25 "sigs.k8s.io/controller-runtime/pkg/client/fake" 26 ) 27 28 type testUpdater struct{} 29 30 // Update test impl for reconciler unit tests 31 func (t *testUpdater) Update(_ *healthcheck.UpdateEvent) {} 32 33 // TestReconcileVerrazzanoTLS tests the reconcileVerrazzanoTLS method keeping the VZ CA secret in sync when rotated 34 // GIVEN a call to reconcileVerrazzanoTLS to reconcile the verrazzano-tls secret update 35 // WHEN the Verrazzano ingress secret CA bundle exists and has been updated 36 // THEN the reconcileVerrazzanoTLS can extract the request and call the function to update the copies, unless a VZ reconcile is in progress 37 func TestReconcileVerrazzanoTLS(t *testing.T) { 38 39 scheme := newScheme() 40 log := vzlog.DefaultLogger() 41 updater := &testUpdater{} 42 43 vzTLSName := types.NamespacedName{Name: vzconst.VerrazzanoIngressTLSSecret, Namespace: vzconst.VerrazzanoSystemNamespace} 44 privateCABundleName := types.NamespacedName{Name: vzconst.PrivateCABundle, Namespace: vzconst.VerrazzanoSystemNamespace} 45 rancherTLSCATestSecret := types.NamespacedName{Namespace: vzconst.RancherSystemNamespace, Name: vzconst.RancherTLSCA} 46 multiclusterCASecret := types.NamespacedName{Namespace: constants.VerrazzanoMultiClusterNamespace, Name: constants.VerrazzanoLocalCABundleSecret} 47 48 defaultReq := controllerruntime.Request{ 49 NamespacedName: vzTLSName, 50 } 51 52 defaultWantErr := assert.NoError 53 54 ingressTLSSecret := &corev1.Secret{ 55 ObjectMeta: v1.ObjectMeta{Name: vzTLSSecret.Name, Namespace: vzTLSSecret.Namespace}, 56 } 57 privateCASecret := &corev1.Secret{ 58 ObjectMeta: v1.ObjectMeta{Name: privateCABundleName.Name, Namespace: privateCABundleName.Namespace}, 59 } 60 defaultObjsList := []runtime.Object{ 61 &corev1.Secret{ 62 ObjectMeta: v1.ObjectMeta{Namespace: rancherTLSCATestSecret.Namespace, Name: rancherTLSCATestSecret.Name}, 63 }, 64 &corev1.Secret{ 65 ObjectMeta: v1.ObjectMeta{Namespace: multiclusterCASecret.Namespace, Name: multiclusterCASecret.Name}, 66 }, 67 privateCASecret, 68 &corev1.Namespace{ 69 ObjectMeta: v1.ObjectMeta{Name: constants.VerrazzanoMultiClusterNamespace}, 70 }, 71 &appsv1.Deployment{ 72 ObjectMeta: v1.ObjectMeta{Name: rancherDeploymentName, Namespace: vzconst.RancherSystemNamespace}, 73 }, 74 } 75 76 vzReady := vzapi.Verrazzano{ 77 Status: vzapi.VerrazzanoStatus{ 78 State: vzapi.VzStateReady, 79 }, 80 } 81 82 type args struct { 83 req *controllerruntime.Request 84 vz *vzapi.Verrazzano 85 } 86 tests := []struct { 87 name string 88 cli client.Client 89 args args 90 requeueRequired bool 91 wantErr assert.ErrorAssertionFunc 92 }{ 93 { 94 name: "verrazzano-tls-update", 95 cli: fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects( 96 append(defaultObjsList, ingressTLSSecret)..., 97 ).Build(), 98 }, 99 { 100 name: "verrazzano-tls-does-not-exist", 101 cli: fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects( 102 defaultObjsList..., 103 ).Build(), 104 }, 105 } 106 for _, tt := range tests { 107 t.Run(tt.name, func(t *testing.T) { 108 r := &VerrazzanoSecretsReconciler{ 109 Client: tt.cli, 110 Scheme: scheme, 111 log: log, 112 StatusUpdater: updater, 113 } 114 wantErr := defaultWantErr 115 if tt.wantErr != nil { 116 wantErr = tt.wantErr 117 } 118 119 vz := &vzReady 120 if tt.args.vz != nil { 121 vz = tt.args.vz 122 } 123 124 req := defaultReq 125 if tt.args.req != nil { 126 req = *tt.args.req 127 } 128 129 ctx := context.TODO() 130 got, err := r.reconcileVerrazzanoTLS(ctx, req.NamespacedName, vzconst.CACertKey) 131 if !wantErr(t, err, fmt.Sprintf("reconcileVerrazzanoTLS(%v, %v, %v)", ctx, req, vz)) { 132 return 133 } 134 assert.Equal(t, got.Requeue, tt.requeueRequired, "Did not get expected result") 135 }) 136 } 137 } 138 139 // TestReconcileVerrazzanoCABundleCopies tests the reconcileVerrazzanoCABundleCopies method keeping upstream copies in sync 140 // GIVEN a call to reconcileVerrazzanoCABundleCopies to reconcile the verrazzano-tls secret 141 // WHEN the verrazzano-tls secret CA bundle exists and has been updated 142 // THEN the upstream copies are updated and any required actions are taken 143 func TestReconcileVerrazzanoCABundleCopies(t *testing.T) { 144 scheme := newScheme() 145 log := vzlog.DefaultLogger() 146 updater := &testUpdater{} 147 148 updatedBundleData := []byte("bundleupdate") 149 originalBundleData := []byte("original bundle data") 150 letsEncryptStagingBundleData := []byte("letsencrypt staging bundle data") 151 152 rancherTLSCATestSecret := types.NamespacedName{Namespace: vzconst.RancherSystemNamespace, Name: vzconst.RancherTLSCA} 153 multiclusterCASecret := types.NamespacedName{Namespace: constants.VerrazzanoMultiClusterNamespace, Name: constants.VerrazzanoLocalCABundleSecret} 154 rancherDeploymentNSName := types.NamespacedName{Namespace: vzconst.RancherSystemNamespace, Name: rancherDeploymentName} 155 156 defaultWantErr := assert.NoError 157 defaultBundleWantErr := assert.NoError 158 159 clusterIssuerSecretNotUpdated := &corev1.Secret{ 160 ObjectMeta: v1.ObjectMeta{Name: vzconst.DefaultVerrazzanoCASecretName, Namespace: vzconst.CertManagerNamespace}, 161 Data: map[string][]byte{ 162 "tls.crt": originalBundleData, 163 }, 164 } 165 166 clusterIssuerSecretUpdated := &corev1.Secret{ 167 ObjectMeta: v1.ObjectMeta{Name: vzconst.DefaultVerrazzanoCASecretName, Namespace: vzconst.CertManagerNamespace}, 168 Data: map[string][]byte{ 169 "tls.crt": updatedBundleData, 170 }, 171 } 172 173 ingressLeafCertOnly := &corev1.Secret{ 174 ObjectMeta: v1.ObjectMeta{Name: vzTLSSecret.Name, Namespace: vzTLSSecret.Namespace}, 175 Data: map[string][]byte{ 176 "tls.crt": []byte("leaf-cert"), 177 "tls.key": []byte("leaf-cert-key"), 178 }, 179 } 180 181 vzPrivateCASecret := &corev1.Secret{ 182 ObjectMeta: v1.ObjectMeta{Name: vzPrivateCABundleSecret.Name, Namespace: vzPrivateCABundleSecret.Namespace}, 183 Data: map[string][]byte{ 184 vzconst.CABundleKey: originalBundleData, 185 }, 186 } 187 188 rancherTLSCASecert := &corev1.Secret{ 189 ObjectMeta: v1.ObjectMeta{Namespace: rancherTLSCATestSecret.Namespace, Name: rancherTLSCATestSecret.Name}, 190 Data: map[string][]byte{ 191 vzconst.RancherTLSCAKey: originalBundleData, 192 }, 193 } 194 195 defaultObjsList := []runtime.Object{ 196 rancherTLSCASecert, 197 &corev1.Secret{ 198 ObjectMeta: v1.ObjectMeta{Namespace: multiclusterCASecret.Namespace, Name: multiclusterCASecret.Name}, 199 Data: map[string][]byte{ 200 mcCABundleKey: originalBundleData, 201 }, 202 }, 203 vzPrivateCASecret, 204 clusterIssuerSecretUpdated, 205 // verrazzano-mc namespace exists 206 &corev1.Namespace{ 207 ObjectMeta: v1.ObjectMeta{Name: constants.VerrazzanoMultiClusterNamespace}, 208 }, 209 // Rancher deployment to detect when we have/haven't issued a restart 210 &appsv1.Deployment{ 211 ObjectMeta: v1.ObjectMeta{Name: rancherDeploymentName, Namespace: vzconst.RancherSystemNamespace}, 212 }, 213 } 214 215 tests := []struct { 216 name string 217 description string 218 cli client.Client 219 requeueRequired bool 220 wantErr assert.ErrorAssertionFunc 221 sourceSecret *corev1.Secret 222 sourceSecretKey string 223 privateCAExpectedBundleData []byte 224 privateCABundleSecretWantErr assert.ErrorAssertionFunc 225 mcExpectedBundleData []byte 226 mcBundleSecretWantErr assert.ErrorAssertionFunc 227 rancherExpectedBundleData []byte 228 rancherBundleSecretWantErr assert.ErrorAssertionFunc 229 rancherRestartRequired bool 230 }{ 231 { 232 name: "self-signed-ca", 233 description: `Basic case where the ClusterIssuer secret has been updated and the MC and Rancher copies exist `, 234 cli: fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(defaultObjsList...).Build(), 235 privateCAExpectedBundleData: updatedBundleData, 236 mcExpectedBundleData: updatedBundleData, 237 rancherExpectedBundleData: updatedBundleData, 238 rancherRestartRequired: true, 239 }, 240 { 241 name: "verrazzano-tls-ca-does-not-exist", 242 description: `TLS CA bundle does not exist, the target copies should not be updated; likely a case where the secret was deleted, but should not happen`, 243 cli: fake.NewClientBuilder().WithScheme(scheme).WithObjects( 244 &corev1.Secret{ 245 ObjectMeta: v1.ObjectMeta{Namespace: multiclusterCASecret.Namespace, Name: multiclusterCASecret.Name}, 246 Data: map[string][]byte{ 247 mcCABundleKey: originalBundleData, 248 }, 249 }, 250 ingressLeafCertOnly, 251 &corev1.Namespace{ 252 ObjectMeta: v1.ObjectMeta{Name: constants.VerrazzanoMultiClusterNamespace}, 253 }, 254 // Rancher deployment to detect when we have/haven't issued a restart 255 &appsv1.Deployment{ 256 ObjectMeta: v1.ObjectMeta{Name: rancherDeploymentName, Namespace: vzconst.RancherSystemNamespace}, 257 }, 258 ).Build(), 259 sourceSecret: ingressLeafCertOnly, 260 privateCABundleSecretWantErr: assert.Error, 261 rancherBundleSecretWantErr: assert.Error, 262 mcExpectedBundleData: []byte(nil), 263 }, 264 { 265 name: "lets-encrypt-staging-update-scenario", 266 description: "ACME/Let's encrypt staging case, TLS CA bundle-key does not exist in ingress secret but the leaf cert has been rotated. " + 267 "The target copies should not be updated, preserving the staging CA root bundle", 268 sourceSecret: ingressLeafCertOnly, 269 sourceSecretKey: vzconst.CACertKey, 270 cli: fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects( 271 &corev1.Secret{ 272 ObjectMeta: v1.ObjectMeta{Namespace: rancherTLSCATestSecret.Namespace, Name: rancherTLSCATestSecret.Name}, 273 Data: map[string][]byte{ 274 vzconst.RancherTLSCAKey: letsEncryptStagingBundleData, 275 }, 276 }, 277 &corev1.Secret{ 278 ObjectMeta: v1.ObjectMeta{Namespace: multiclusterCASecret.Namespace, Name: multiclusterCASecret.Name}, 279 Data: map[string][]byte{ 280 mcCABundleKey: originalBundleData, 281 }, 282 }, 283 &corev1.Secret{ 284 ObjectMeta: v1.ObjectMeta{Name: vzPrivateCABundleSecret.Name, Namespace: vzPrivateCABundleSecret.Namespace}, 285 Data: map[string][]byte{ 286 vzconst.CABundleKey: letsEncryptStagingBundleData, 287 }, 288 }, 289 ingressLeafCertOnly, 290 &corev1.Namespace{ 291 ObjectMeta: v1.ObjectMeta{Name: constants.VerrazzanoMultiClusterNamespace}, 292 }, 293 &appsv1.Deployment{ 294 ObjectMeta: v1.ObjectMeta{Name: rancherDeploymentName, Namespace: vzconst.RancherSystemNamespace}, 295 }, 296 ).Build(), 297 privateCAExpectedBundleData: letsEncryptStagingBundleData, 298 mcExpectedBundleData: letsEncryptStagingBundleData, 299 rancherExpectedBundleData: letsEncryptStagingBundleData, 300 }, 301 { 302 name: "lets-encrypt-staging-to-production", 303 description: "ACME/Let's encrypt staging-to-production case; VZ and Rancher TLS CA bundle-key do not exist," + 304 "leaf cert has no CA bundle, but the ingress secret but the leaf cert has been rotated. Only the" + 305 "multi-cluster copy should be updated with an empty value, and the other copies should not exist", 306 sourceSecret: ingressLeafCertOnly, 307 sourceSecretKey: vzconst.CACertKey, 308 cli: fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects( 309 &corev1.Secret{ 310 ObjectMeta: v1.ObjectMeta{Namespace: multiclusterCASecret.Namespace, Name: multiclusterCASecret.Name}, 311 Data: map[string][]byte{ 312 mcCABundleKey: letsEncryptStagingBundleData, 313 }, 314 }, 315 ingressLeafCertOnly, 316 &corev1.Namespace{ 317 ObjectMeta: v1.ObjectMeta{Name: constants.VerrazzanoMultiClusterNamespace}, 318 }, 319 &appsv1.Deployment{ 320 ObjectMeta: v1.ObjectMeta{Name: rancherDeploymentName, Namespace: vzconst.RancherSystemNamespace}, 321 }, 322 ).Build(), 323 privateCABundleSecretWantErr: assert.Error, 324 rancherBundleSecretWantErr: assert.Error, 325 mcExpectedBundleData: []byte(nil), 326 }, 327 { 328 name: "lets-encrypt-staging-to-self-signed-rotated", 329 description: "System has been updated from LE staging to self-signed; verrazzano-tls-ca and tls-ca are " + 330 "using private CA with old data, verrazzano-local-ca-bundle has LE staging data. verrazzano-tls updated" + 331 "with new bundle data. All secrets should be updated with new bundle data.", 332 cli: fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects( 333 &corev1.Secret{ 334 ObjectMeta: v1.ObjectMeta{Namespace: multiclusterCASecret.Namespace, Name: multiclusterCASecret.Name}, 335 Data: map[string][]byte{ 336 mcCABundleKey: letsEncryptStagingBundleData, 337 }, 338 }, 339 &corev1.Secret{ 340 ObjectMeta: v1.ObjectMeta{Namespace: rancherTLSCATestSecret.Namespace, Name: rancherTLSCATestSecret.Name}, 341 Data: map[string][]byte{ 342 vzconst.RancherTLSCAKey: originalBundleData, 343 }, 344 }, 345 vzPrivateCASecret, 346 clusterIssuerSecretUpdated, 347 &corev1.Namespace{ 348 ObjectMeta: v1.ObjectMeta{Name: constants.VerrazzanoMultiClusterNamespace}, 349 }, 350 &appsv1.Deployment{ 351 ObjectMeta: v1.ObjectMeta{Name: rancherDeploymentName, Namespace: vzconst.RancherSystemNamespace}, 352 }, 353 ).Build(), 354 rancherRestartRequired: true, 355 privateCAExpectedBundleData: updatedBundleData, 356 rancherExpectedBundleData: updatedBundleData, 357 mcExpectedBundleData: updatedBundleData, 358 }, 359 { 360 name: "lets-encrypt-staging-to-self-signed-not-rotated", 361 description: "System has been updated from LE staging to self-signed; verrazzano-tls-ca and tls-ca are " + 362 "using up-to-date private CA data, verrazzano-local-ca-bundle has stale LE staging data. verrazzano-tls updated" + 363 "with new bundle data. All secrets should be updated with new bundle data.", 364 sourceSecret: clusterIssuerSecretNotUpdated, 365 cli: fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects( 366 &corev1.Secret{ 367 ObjectMeta: v1.ObjectMeta{Namespace: multiclusterCASecret.Namespace, Name: multiclusterCASecret.Name}, 368 Data: map[string][]byte{ 369 mcCABundleKey: letsEncryptStagingBundleData, 370 }, 371 }, 372 &corev1.Secret{ 373 ObjectMeta: v1.ObjectMeta{Namespace: rancherTLSCATestSecret.Namespace, Name: rancherTLSCATestSecret.Name}, 374 Data: map[string][]byte{ 375 vzconst.RancherTLSCAKey: originalBundleData, 376 }, 377 }, 378 vzPrivateCASecret, 379 clusterIssuerSecretNotUpdated, 380 &corev1.Namespace{ 381 ObjectMeta: v1.ObjectMeta{Name: constants.VerrazzanoMultiClusterNamespace}, 382 }, 383 &appsv1.Deployment{ 384 ObjectMeta: v1.ObjectMeta{Name: rancherDeploymentName, Namespace: vzconst.RancherSystemNamespace}, 385 }, 386 ).Build(), 387 privateCAExpectedBundleData: originalBundleData, 388 rancherExpectedBundleData: originalBundleData, 389 mcExpectedBundleData: originalBundleData, 390 }, 391 { 392 name: "mc-namespace-does-not-exist", 393 description: `TLS CA bundle updated, but MC namespace does not exist; Rancher secret should be updated but we should requeue until the verrazzano-mc namespace exists`, 394 cli: fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects( 395 &corev1.Secret{ 396 ObjectMeta: v1.ObjectMeta{Namespace: rancherTLSCATestSecret.Namespace, Name: rancherTLSCATestSecret.Name}, 397 Data: map[string][]byte{ 398 vzconst.RancherTLSCAKey: originalBundleData, 399 }, 400 }, 401 &corev1.Secret{ 402 ObjectMeta: v1.ObjectMeta{Namespace: multiclusterCASecret.Namespace, Name: multiclusterCASecret.Name}, 403 Data: map[string][]byte{ 404 mcCABundleKey: originalBundleData, 405 }, 406 }, 407 &corev1.Secret{ 408 ObjectMeta: v1.ObjectMeta{Name: vzPrivateCABundleSecret.Name, Namespace: vzPrivateCABundleSecret.Namespace}, 409 Data: map[string][]byte{ 410 vzconst.CABundleKey: updatedBundleData, 411 }, 412 }, 413 &appsv1.Deployment{ 414 ObjectMeta: v1.ObjectMeta{Name: rancherDeploymentName, Namespace: vzconst.RancherSystemNamespace}, 415 }, 416 ).Build(), 417 requeueRequired: true, 418 privateCAExpectedBundleData: updatedBundleData, 419 mcExpectedBundleData: originalBundleData, 420 rancherExpectedBundleData: updatedBundleData, 421 rancherRestartRequired: true, 422 }, 423 { 424 name: "mc-bundle-secret-does-not-exist", 425 description: `TLS CA bundle updated, but MC bundle secret does not initially exist; MC bundle secret should be created`, 426 cli: fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects( 427 &corev1.Secret{ 428 ObjectMeta: v1.ObjectMeta{Namespace: rancherTLSCATestSecret.Namespace, Name: rancherTLSCATestSecret.Name}, 429 Data: map[string][]byte{ 430 vzconst.RancherTLSCAKey: originalBundleData, 431 }, 432 }, 433 &corev1.Secret{ 434 ObjectMeta: v1.ObjectMeta{Name: vzPrivateCABundleSecret.Name, Namespace: vzPrivateCABundleSecret.Namespace}, 435 Data: map[string][]byte{ 436 vzconst.CABundleKey: originalBundleData, 437 }, 438 }, 439 clusterIssuerSecretUpdated, 440 &corev1.Namespace{ 441 ObjectMeta: v1.ObjectMeta{Name: constants.VerrazzanoMultiClusterNamespace}, 442 }, 443 &appsv1.Deployment{ 444 ObjectMeta: v1.ObjectMeta{Name: rancherDeploymentName, Namespace: vzconst.RancherSystemNamespace}, 445 }, 446 ).Build(), 447 privateCAExpectedBundleData: updatedBundleData, 448 mcExpectedBundleData: updatedBundleData, 449 rancherExpectedBundleData: updatedBundleData, 450 rancherRestartRequired: true, 451 }, 452 } 453 for _, tt := range tests { 454 t.Run(tt.name, func(t *testing.T) { 455 r := &VerrazzanoSecretsReconciler{ 456 Client: tt.cli, 457 Scheme: scheme, 458 log: log, 459 StatusUpdater: updater, 460 } 461 wantErr := defaultWantErr 462 if tt.wantErr != nil { 463 wantErr = tt.wantErr 464 } 465 466 privateCABundleSecretWantErr := defaultBundleWantErr 467 if tt.privateCABundleSecretWantErr != nil { 468 privateCABundleSecretWantErr = tt.privateCABundleSecretWantErr 469 } 470 471 mcBundleSecretWantErr := defaultBundleWantErr 472 if tt.mcBundleSecretWantErr != nil { 473 mcBundleSecretWantErr = tt.mcBundleSecretWantErr 474 } 475 476 rancherBundleSecretWantErr := defaultBundleWantErr 477 if tt.rancherBundleSecretWantErr != nil { 478 rancherBundleSecretWantErr = tt.rancherBundleSecretWantErr 479 } 480 481 sourceSecret := clusterIssuerSecretUpdated 482 if tt.sourceSecret != nil { 483 sourceSecret = tt.sourceSecret 484 } 485 486 sourceSecretKey := corev1.TLSCertKey 487 if len(tt.sourceSecretKey) > 0 { 488 sourceSecretKey = tt.sourceSecretKey 489 } 490 491 got, err := r.reconcileVerrazzanoTLS(context.TODO(), types.NamespacedName{Namespace: sourceSecret.Namespace, Name: sourceSecret.Name}, sourceSecretKey) 492 assert.NoError(t, err) 493 assert.False(t, got.Requeue) 494 495 got, err = r.reconcileVerrazzanoCABundleCopies() 496 if !wantErr(t, err, "reconcileVerrazzanoCABundleCopies did not get expected error result") { 497 return 498 } 499 assert.Equal(t, tt.requeueRequired, got.Requeue, "Did not get expected result") 500 501 //if tt.rancherRestartRequired { 502 deployment := &appsv1.Deployment{} 503 assert.NoError(t, tt.cli.Get(context.TODO(), rancherDeploymentNSName, deployment)) 504 _, foundRestartAnnotation := deployment.Spec.Template.ObjectMeta.Annotations[vzconst.VerrazzanoRestartAnnotation] 505 assert.Equal(t, tt.rancherRestartRequired, foundRestartAnnotation, "Rancher restart check failed, expected %v", tt.rancherRestartRequired) 506 //} 507 // check that the VZ private CA bundle secret was updated if necessary 508 assertTargetCopy(t, tt.cli, vzPrivateCABundleSecret, vzconst.CABundleKey, tt.privateCAExpectedBundleData, privateCABundleSecretWantErr) 509 assertTargetCopy(t, tt.cli, multiclusterCASecret, mcCABundleKey, tt.mcExpectedBundleData, mcBundleSecretWantErr) 510 assertTargetCopy(t, tt.cli, rancherTLSCATestSecret, vzconst.RancherTLSCAKey, tt.rancherExpectedBundleData, rancherBundleSecretWantErr) 511 }) 512 } 513 } 514 515 func assertTargetCopy(t *testing.T, cli client.Client, targetSecretName types.NamespacedName, key string, expectedBundleData []byte, bundleSecretWantErr assert.ErrorAssertionFunc) { 516 bundleSecret := &corev1.Secret{} 517 err := cli.Get(context.TODO(), targetSecretName, bundleSecret) 518 if !bundleSecretWantErr(t, err, fmt.Sprintf("Bundle secret get err %v", err)) { 519 return 520 } 521 byteSlicesEqualTrimmedWhitespace(t, expectedBundleData, bundleSecret.Data[key], fmt.Sprintf("CA bundle copy for %s did not match", targetSecretName)) 522 } 523 524 func byteSlicesEqualTrimmedWhitespace(t *testing.T, byteSlice1, byteSlice2 []byte, msg string) bool { 525 a := bytes.Trim(byteSlice1, " \t\n\r") 526 b := bytes.Trim(byteSlice2, " \t\n\r") 527 return assert.Equal(t, a, b, msg) 528 }