Skip to content

Commit 228d3f7

Browse files
committed
move notificationsbusinstance migration to controller
1 parent 0cc24a2 commit 228d3f7

3 files changed

Lines changed: 106 additions & 7 deletions

File tree

api/core/v1beta1/openstackcontrolplane_webhook.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -872,13 +872,9 @@ func setOverrideSpec(override **route.OverrideSpec, anno map[string]string) {
872872

873873
// DefaultServices - common function for calling individual services' defaulting functions
874874
func (r *OpenStackControlPlane) DefaultServices() {
875-
// Default NotificationsBus if NotificationsBusInstance is specified
876-
if r.Spec.NotificationsBusInstance != nil && *r.Spec.NotificationsBusInstance != "" {
877-
if r.Spec.NotificationsBus == nil {
878-
r.Spec.NotificationsBus = &rabbitmqv1.RabbitMqConfig{}
879-
}
880-
rabbitmqv1.DefaultRabbitMqConfig(r.Spec.NotificationsBus, *r.Spec.NotificationsBusInstance)
881-
}
875+
// Top-level NotificationsBusInstance migration is handled in the reconcile loop
876+
// to properly support migration from the deprecated field. The webhook doesn't
877+
// have access to the old object to distinguish between user overrides and defaults.
882878

883879
// Cinder
884880
if r.Spec.Cinder.Enabled || r.Spec.Cinder.Template != nil {

internal/controller/core/openstackcontrolplane_controller.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,19 @@ func (r *OpenStackControlPlaneReconciler) reconcileNormal(ctx context.Context, i
402402
instance.Status.Conditions.MarkTrue(condition.TopologyReadyCondition, condition.TopologyReadyMessage)
403403
}
404404

405+
// Migration: Migrate top-level deprecated NotificationsBusInstance to NotificationsBus
406+
// This must happen before service reconciliation so services can inherit the migrated value
407+
if instance.Spec.NotificationsBusInstance != nil && *instance.Spec.NotificationsBusInstance != "" {
408+
if instance.Spec.NotificationsBus == nil {
409+
instance.Spec.NotificationsBus = &rabbitmqv1.RabbitMqConfig{}
410+
}
411+
if instance.Spec.NotificationsBus.Cluster == "" {
412+
instance.Spec.NotificationsBus.Cluster = *instance.Spec.NotificationsBusInstance
413+
}
414+
// Clear deprecated field once migrated
415+
instance.Spec.NotificationsBusInstance = nil
416+
}
417+
405418
ctrlResult, err := openstack.ReconcileCAs(ctx, instance, helper)
406419
if err != nil {
407420
return ctrl.Result{}, err

internal/openstack/migration_logic_test.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,96 @@ func TestEdgeCases(t *testing.T) {
370370
})
371371
}
372372

373+
// TestTopLevelNotificationsBusInstanceMigration tests the top-level NotificationsBusInstance
374+
// migration that happens in the controller's reconcileNormal function
375+
func TestTopLevelNotificationsBusInstanceMigration(t *testing.T) {
376+
g := NewWithT(t)
377+
378+
testCases := []struct {
379+
name string
380+
notificationsBusInstance *string
381+
notificationsBus *rabbitmqv1.RabbitMqConfig
382+
expectedCluster string
383+
expectedInstanceNil bool
384+
description string
385+
}{
386+
{
387+
name: "Migrate from NotificationsBusInstance",
388+
notificationsBusInstance: stringPtr("rabbitmq-notifications"),
389+
notificationsBus: nil,
390+
expectedCluster: "rabbitmq-notifications",
391+
expectedInstanceNil: true,
392+
description: "Should create NotificationsBus and migrate value",
393+
},
394+
{
395+
name: "Migrate to existing empty NotificationsBus",
396+
notificationsBusInstance: stringPtr("rabbitmq-notifications"),
397+
notificationsBus: &rabbitmqv1.RabbitMqConfig{Cluster: ""},
398+
expectedCluster: "rabbitmq-notifications",
399+
expectedInstanceNil: true,
400+
description: "Should populate existing NotificationsBus",
401+
},
402+
{
403+
name: "New field takes precedence",
404+
notificationsBusInstance: stringPtr("old-value"),
405+
notificationsBus: &rabbitmqv1.RabbitMqConfig{Cluster: "new-value"},
406+
expectedCluster: "new-value",
407+
expectedInstanceNil: true,
408+
description: "Should keep new field value and clear deprecated",
409+
},
410+
{
411+
name: "Already migrated",
412+
notificationsBusInstance: nil,
413+
notificationsBus: &rabbitmqv1.RabbitMqConfig{Cluster: "rabbitmq-notifications"},
414+
expectedCluster: "rabbitmq-notifications",
415+
expectedInstanceNil: true,
416+
description: "Should leave already-migrated config unchanged",
417+
},
418+
{
419+
name: "Empty deprecated field",
420+
notificationsBusInstance: stringPtr(""),
421+
notificationsBus: nil,
422+
expectedCluster: "",
423+
expectedInstanceNil: false,
424+
description: "Empty string in deprecated field should not trigger migration",
425+
},
426+
}
427+
428+
for _, tc := range testCases {
429+
t.Run(tc.name, func(t *testing.T) {
430+
notificationsBusInstance := tc.notificationsBusInstance
431+
notificationsBus := tc.notificationsBus
432+
433+
// Simulate the controller migration logic
434+
if notificationsBusInstance != nil && *notificationsBusInstance != "" {
435+
if notificationsBus == nil {
436+
notificationsBus = &rabbitmqv1.RabbitMqConfig{}
437+
}
438+
if notificationsBus.Cluster == "" {
439+
notificationsBus.Cluster = *notificationsBusInstance
440+
}
441+
// Clear deprecated field once migrated
442+
notificationsBusInstance = nil
443+
}
444+
445+
// Verify results
446+
if tc.expectedCluster != "" {
447+
g.Expect(notificationsBus).ToNot(BeNil(), tc.description+" - NotificationsBus should not be nil")
448+
g.Expect(notificationsBus.Cluster).To(Equal(tc.expectedCluster),
449+
tc.description+" - Cluster value mismatch")
450+
} else if tc.notificationsBus == nil && tc.expectedCluster == "" {
451+
// For the empty deprecated field case, NotificationsBus should remain nil
452+
g.Expect(notificationsBus).To(BeNil(), tc.description+" - NotificationsBus should be nil")
453+
}
454+
455+
if tc.expectedInstanceNil {
456+
g.Expect(notificationsBusInstance).To(BeNil(),
457+
tc.description+" - Deprecated field should be nil after migration")
458+
}
459+
})
460+
}
461+
}
462+
373463
// Helper function to create string pointers
374464
func stringPtr(s string) *string {
375465
return &s

0 commit comments

Comments
 (0)