|
4 | 4 | "fmt" |
5 | 5 |
|
6 | 6 | . "github.com/onsi/ginkgo/v2" |
| 7 | + . "github.com/onsi/gomega" |
7 | 8 | configv1 "github.com/openshift/api/config/v1" |
8 | 9 | mapiv1beta1 "github.com/openshift/api/machine/v1beta1" |
9 | 10 | mapiframework "github.com/openshift/cluster-api-actuator-pkg/pkg/framework" |
@@ -298,4 +299,154 @@ var _ = Describe("[sig-cluster-lifecycle][OCPFeatureGate:MachineAPIMigration] Ma |
298 | 299 | }) |
299 | 300 | })*/ |
300 | 301 | }) |
| 302 | + |
| 303 | + var _ = Describe("Update CAPI Machine", Ordered, func() { |
| 304 | + var capiUpdateTestName = "machine-update-capi-test" |
| 305 | + var newMapiMachine *mapiv1beta1.Machine |
| 306 | + var newCapiMachine *clusterv1.Machine |
| 307 | + var previousState *MachineState |
| 308 | + Context("with spec.authoritativeAPI: ClusterAPI (both MAPI and CAPI machine exist)", func() { |
| 309 | + BeforeAll(func() { |
| 310 | + newMapiMachine = createMAPIMachineWithAuthority(ctx, cl, capiUpdateTestName, mapiv1beta1.MachineAuthorityClusterAPI) |
| 311 | + newCapiMachine = capiframework.GetMachine(cl, newMapiMachine.Name, capiframework.CAPINamespace) |
| 312 | + verifyMachineRunning(cl, newCapiMachine) |
| 313 | + |
| 314 | + DeferCleanup(func() { |
| 315 | + By("Cleaning up machine resources") |
| 316 | + cleanupMachineResources( |
| 317 | + ctx, |
| 318 | + cl, |
| 319 | + []*clusterv1.Machine{newCapiMachine}, |
| 320 | + []*mapiv1beta1.Machine{newMapiMachine}, |
| 321 | + ) |
| 322 | + }) |
| 323 | + }) |
| 324 | + |
| 325 | + It("should add labels/annotations on CAPI machine", func() { |
| 326 | + // Capture state before the update |
| 327 | + previousState = captureMachineStateBeforeUpdate(cl, newMapiMachine.Name) |
| 328 | + Eventually(func() error { |
| 329 | + currentCapiMachine := capiframework.GetMachine(cl, newCapiMachine.Name, capiframework.CAPINamespace) |
| 330 | + if currentCapiMachine.Labels == nil { |
| 331 | + currentCapiMachine.Labels = make(map[string]string) |
| 332 | + } |
| 333 | + if currentCapiMachine.Annotations == nil { |
| 334 | + currentCapiMachine.Annotations = make(map[string]string) |
| 335 | + } |
| 336 | + currentCapiMachine.Labels["test-capi-label"] = "test-capi-label-value" |
| 337 | + currentCapiMachine.Annotations["test-capi-annotation"] = "test-capi-annotation-value" |
| 338 | + return cl.Update(ctx, currentCapiMachine) |
| 339 | + }, capiframework.WaitMedium, capiframework.RetryMedium).Should(Succeed(), "Failed to add CAPI Machine labels/annotations") |
| 340 | + }) |
| 341 | + |
| 342 | + It("should synchronize added labels/annotations to both metadata and spec on MAPI", func() { |
| 343 | + Eventually(func() error { |
| 344 | + currentMAPIMachine, err := mapiframework.GetMachine(cl, newMapiMachine.Name) |
| 345 | + if err != nil { |
| 346 | + return err |
| 347 | + } |
| 348 | + // Check metadata |
| 349 | + if currentMAPIMachine.Labels["test-capi-label"] != "test-capi-label-value" { |
| 350 | + return fmt.Errorf("MAPI Machine metadata label not synchronized") |
| 351 | + } |
| 352 | + if currentMAPIMachine.Annotations["test-capi-annotation"] != "test-capi-annotation-value" { |
| 353 | + return fmt.Errorf("MAPI Machine annotation not synchronized") |
| 354 | + } |
| 355 | + // Check spec template metadata |
| 356 | + if currentMAPIMachine.Spec.ObjectMeta.Labels["test-capi-label"] != "test-capi-label-value" { |
| 357 | + return fmt.Errorf("MAPI Machine spec.objectMeta label not synchronized") |
| 358 | + } |
| 359 | + if currentMAPIMachine.Spec.ObjectMeta.Annotations["test-capi-annotation"] != "test-capi-annotation-value" { |
| 360 | + return fmt.Errorf("MAPI Machine spec.objectMeta annotation not synchronized") |
| 361 | + } |
| 362 | + newMapiMachine = currentMAPIMachine |
| 363 | + return nil |
| 364 | + }, capiframework.WaitMedium, capiframework.RetryMedium).Should(Succeed(), "Added labels should be copied to both metadata and spec on MAPI Machine") |
| 365 | + }) |
| 366 | + |
| 367 | + It("should verify MAPI generation changed and synchronized time changed after syncing labels to spec", func() { |
| 368 | + verifyMachineStateChanged(cl, newMapiMachine, previousState, mapiv1beta1.MachineAuthorityClusterAPI, "adding labels/annotations") |
| 369 | + }) |
| 370 | + |
| 371 | + It("should modify existing labels/annotations on CAPI machine", func() { |
| 372 | + // Capture state before the update |
| 373 | + previousState = captureMachineStateBeforeUpdate(cl, newMapiMachine.Name) |
| 374 | + Eventually(func() error { |
| 375 | + currentCapiMachine := capiframework.GetMachine(cl, newCapiMachine.Name, capiframework.CAPINamespace) |
| 376 | + currentCapiMachine.Labels["test-capi-label"] = "modified-capi-label-value" |
| 377 | + currentCapiMachine.Annotations["test-capi-annotation"] = "modified-capi-annotation-value" |
| 378 | + return cl.Update(ctx, currentCapiMachine) |
| 379 | + }, capiframework.WaitMedium, capiframework.RetryMedium).Should(Succeed(), "Failed to modify CAPI Machine labels/annotations") |
| 380 | + }) |
| 381 | + |
| 382 | + It("should synchronize modified labels/annotations to both metadata and spec on MAPI", func() { |
| 383 | + Eventually(func() error { |
| 384 | + currentMAPIMachine, err := mapiframework.GetMachine(cl, newMapiMachine.Name) |
| 385 | + if err != nil { |
| 386 | + return err |
| 387 | + } |
| 388 | + // Check metadata |
| 389 | + if currentMAPIMachine.Labels["test-capi-label"] != "modified-capi-label-value" { |
| 390 | + return fmt.Errorf("MAPI Machine modified label not synchronized") |
| 391 | + } |
| 392 | + if currentMAPIMachine.Annotations["test-capi-annotation"] != "modified-capi-annotation-value" { |
| 393 | + return fmt.Errorf("MAPI Machine modified annotation not synchronized") |
| 394 | + } |
| 395 | + // Check spec template metadata |
| 396 | + if currentMAPIMachine.Spec.ObjectMeta.Labels["test-capi-label"] != "modified-capi-label-value" { |
| 397 | + return fmt.Errorf("MAPI Machine spec.objectMeta modified label not synchronized") |
| 398 | + } |
| 399 | + if currentMAPIMachine.Spec.ObjectMeta.Annotations["test-capi-annotation"] != "modified-capi-annotation-value" { |
| 400 | + return fmt.Errorf("MAPI Machine spec.objectMeta modified annotation not synchronized") |
| 401 | + } |
| 402 | + newMapiMachine = currentMAPIMachine |
| 403 | + return nil |
| 404 | + }, capiframework.WaitMedium, capiframework.RetryMedium).Should(Succeed(), "Modified labels/annotations should be synchronized to both metadata and spec on MAPI Machine") |
| 405 | + }) |
| 406 | + |
| 407 | + It("should verify MAPI generation changed and synchronized time changed after syncing modified labels to spec", func() { |
| 408 | + verifyMachineStateChanged(cl, newMapiMachine, previousState, mapiv1beta1.MachineAuthorityClusterAPI, "modifying labels/annotations") |
| 409 | + }) |
| 410 | + |
| 411 | + It("should delete labels/annotations on CAPI machine", func() { |
| 412 | + // Capture state before the update |
| 413 | + previousState = captureMachineStateBeforeUpdate(cl, newMapiMachine.Name) |
| 414 | + Eventually(func() error { |
| 415 | + currentCapiMachine := capiframework.GetMachine(cl, newCapiMachine.Name, capiframework.CAPINamespace) |
| 416 | + delete(currentCapiMachine.Labels, "test-capi-label") |
| 417 | + delete(currentCapiMachine.Annotations, "test-capi-annotation") |
| 418 | + return cl.Update(ctx, currentCapiMachine) |
| 419 | + }, capiframework.WaitMedium, capiframework.RetryMedium).Should(Succeed(), "Failed to delete CAPI Machine labels/annotations") |
| 420 | + }) |
| 421 | + |
| 422 | + It("should synchronize label/annotation deletion to both metadata and spec on MAPI", func() { |
| 423 | + Eventually(func() error { |
| 424 | + currentMAPIMachine, err := mapiframework.GetMachine(cl, newMapiMachine.Name) |
| 425 | + if err != nil { |
| 426 | + return err |
| 427 | + } |
| 428 | + // Check metadata deletion |
| 429 | + if _, exists := currentMAPIMachine.Labels["test-capi-label"]; exists { |
| 430 | + return fmt.Errorf("MAPI Machine label deletion not synchronized") |
| 431 | + } |
| 432 | + if _, exists := currentMAPIMachine.Annotations["test-capi-annotation"]; exists { |
| 433 | + return fmt.Errorf("MAPI Machine annotation deletion not synchronized") |
| 434 | + } |
| 435 | + // Verify deleted labels are also removed from spec |
| 436 | + if _, exists := currentMAPIMachine.Spec.ObjectMeta.Labels["test-capi-label"]; exists { |
| 437 | + return fmt.Errorf("MAPI Machine spec.objectMeta label deletion not synchronized") |
| 438 | + } |
| 439 | + if _, exists := currentMAPIMachine.Spec.ObjectMeta.Annotations["test-capi-annotation"]; exists { |
| 440 | + return fmt.Errorf("MAPI Machine spec.objectMeta annotation deletion not synchronized") |
| 441 | + } |
| 442 | + newMapiMachine = currentMAPIMachine |
| 443 | + return nil |
| 444 | + }, capiframework.WaitMedium, capiframework.RetryMedium).Should(Succeed(), "Deleted labels/annotations should be synchronized to both metadata and spec on MAPI Machine") |
| 445 | + }) |
| 446 | + |
| 447 | + It("should verify MAPI generation changed and synchronized time changed after syncing deleted labels to spec", func() { |
| 448 | + verifyMachineStateChanged(cl, newMapiMachine, previousState, mapiv1beta1.MachineAuthorityClusterAPI, "deleting labels/annotations") |
| 449 | + }) |
| 450 | + }) |
| 451 | + }) |
301 | 452 | }) |
0 commit comments