@@ -366,7 +366,7 @@ func (r *NovaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (resul
366366 // Create TransportURLs to access the message buses of each cell. Cell0
367367 // message bus is always the same as the top level API message bus so
368368 // we create API MQ separately first
369- apiTransportURL , apiMQStatus , apiMQError := r .ensureMQ (
369+ apiTransportURL , apiQuorumQueues , apiMQStatus , apiMQError := r .ensureMQ (
370370 ctx , h , instance , instance .Name + "-api-transport" , instance .Spec .APIMessageBusInstance )
371371 switch apiMQStatus {
372372 case nova .MQFailed :
@@ -403,7 +403,7 @@ func (r *NovaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (resul
403403
404404 notificationTransportURLName := instance .Name + "-notification-transport"
405405 if notificationBusName != "" {
406- notificationTransportURL , notificationMQStatus , notificationMQError = r .ensureMQ (
406+ notificationTransportURL , _ , notificationMQStatus , notificationMQError = r .ensureMQ (
407407 ctx , h , instance , notificationTransportURLName , notificationBusName )
408408
409409 switch notificationMQStatus {
@@ -459,14 +459,16 @@ func (r *NovaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (resul
459459 var status nova.MessageBusStatus
460460 var err error
461461 cellTemplate := instance .Spec .CellTemplates [cellName ]
462+ var cellQuorumQueues bool
462463 // cell0 does not need its own cell message bus it uses the
463464 // API message bus instead
464465 if cellName == novav1 .Cell0Name {
465466 cellTransportURL = apiTransportURL
467+ cellQuorumQueues = apiQuorumQueues
466468 status = apiMQStatus
467469 err = apiMQError
468470 } else {
469- cellTransportURL , status , err = r .ensureMQ (
471+ cellTransportURL , cellQuorumQueues , status , err = r .ensureMQ (
470472 ctx , h , instance , instance .Name + "-" + cellName + "-transport" , cellTemplate .CellMessageBusInstance )
471473 }
472474 switch status {
@@ -478,7 +480,7 @@ func (r *NovaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (resul
478480 default :
479481 return ctrl.Result {}, fmt .Errorf ("%w from ensureMQ: %d for cell %s" , util .ErrInvalidStatus , status , cellName )
480482 }
481- cellMQs [cellName ] = & nova.MessageBus {TransportURL : cellTransportURL , Status : status }
483+ cellMQs [cellName ] = & nova.MessageBus {TransportURL : cellTransportURL , QuorumQueues : cellQuorumQueues , Status : status }
482484 }
483485 if len (failedMQs ) > 0 {
484486 instance .Status .Conditions .Set (condition .FalseCondition (
@@ -541,7 +543,7 @@ func (r *NovaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (resul
541543 }
542544 cell , status , err := r .ensureCell (
543545 ctx , h , instance , cellName , cellTemplate ,
544- cellDB .Database , apiDB , cellMQ .TransportURL , notificationTransportURL ,
546+ cellDB .Database , apiDB , cellMQ .TransportURL , cellMQ . QuorumQueues , notificationTransportURL ,
545547 keystoneInternalAuthURL , secret ,
546548 )
547549 cells [cellName ] = cell
@@ -608,7 +610,7 @@ func (r *NovaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (resul
608610
609611 topLevelSecretName , err := r .ensureTopLevelSecret (
610612 ctx , h , instance ,
611- apiTransportURL ,
613+ apiTransportURL , apiQuorumQueues ,
612614 notificationTransportURL ,
613615 secret )
614616 if err != nil {
@@ -1196,6 +1198,7 @@ func (r *NovaReconciler) ensureCell(
11961198 cellDB * mariadbv1.Database ,
11971199 apiDB * mariadbv1.Database ,
11981200 cellTransportURL string ,
1201+ cellQuorumQueues bool ,
11991202 notificationTransportURL string ,
12001203 keystoneAuthURL string ,
12011204 secret corev1.Secret ,
@@ -1204,7 +1207,7 @@ func (r *NovaReconciler) ensureCell(
12041207
12051208 cellSecretName , err := r .ensureCellSecret (
12061209 ctx , h , instance , cellName , cellTemplate ,
1207- cellTransportURL , notificationTransportURL ,
1210+ cellTransportURL , cellQuorumQueues , notificationTransportURL ,
12081211 secret )
12091212 if err != nil {
12101213 return nil , nova .CellDeploying , err
@@ -1708,7 +1711,7 @@ func (r *NovaReconciler) ensureMQ(
17081711 instance * novav1.Nova ,
17091712 transportName string ,
17101713 messageBusInstanceName string ,
1711- ) (string , nova.MessageBusStatus , error ) {
1714+ ) (string , bool , nova.MessageBusStatus , error ) {
17121715 Log := r .GetLogger (ctx )
17131716 transportURL := & rabbitmqv1.TransportURL {
17141717 ObjectMeta : metav1.ObjectMeta {
@@ -1725,7 +1728,7 @@ func (r *NovaReconciler) ensureMQ(
17251728 })
17261729
17271730 if err != nil && ! k8s_errors .IsNotFound (err ) {
1728- return "" , nova .MQFailed , util .WrapErrorForObject (
1731+ return "" , false , nova .MQFailed , util .WrapErrorForObject (
17291732 fmt .Sprintf ("Error create or update TransportURL object %s" , transportName ),
17301733 transportURL ,
17311734 err ,
@@ -1734,20 +1737,20 @@ func (r *NovaReconciler) ensureMQ(
17341737
17351738 if op != controllerutil .OperationResultNone {
17361739 Log .Info (fmt .Sprintf ("TransportURL object %s created or patched" , transportName ))
1737- return "" , nova .MQCreating , nil
1740+ return "" , false , nova .MQCreating , nil
17381741 }
17391742
17401743 err = r .Client .Get (ctx , types.NamespacedName {Namespace : instance .Namespace , Name : transportName }, transportURL )
17411744 if err != nil && ! k8s_errors .IsNotFound (err ) {
1742- return "" , nova .MQFailed , util .WrapErrorForObject (
1745+ return "" , false , nova .MQFailed , util .WrapErrorForObject (
17431746 fmt .Sprintf ("Error reading TransportURL object %s" , transportName ),
17441747 transportURL ,
17451748 err ,
17461749 )
17471750 }
17481751
17491752 if k8s_errors .IsNotFound (err ) || ! transportURL .IsReady () || transportURL .Status .SecretName == "" {
1750- return "" , nova .MQCreating , nil
1753+ return "" , false , nova .MQCreating , nil
17511754 }
17521755
17531756 secretName := types.NamespacedName {Namespace : instance .Namespace , Name : transportURL .Status .SecretName }
@@ -1756,17 +1759,24 @@ func (r *NovaReconciler) ensureMQ(
17561759 err = h .GetClient ().Get (ctx , secretName , secret )
17571760 if err != nil {
17581761 if k8s_errors .IsNotFound (err ) {
1759- return "" , nova .MQCreating , nil
1762+ return "" , false , nova .MQCreating , nil
17601763 }
1761- return "" , nova .MQFailed , err
1764+ return "" , false , nova .MQFailed , err
17621765 }
17631766
17641767 url , ok := secret .Data [TransportURLSelector ]
17651768 if ! ok {
1766- return "" , nova .MQFailed , fmt .Errorf (
1769+ return "" , false , nova .MQFailed , fmt .Errorf (
17671770 "%w: the TransportURL secret %s does not have 'transport_url' field" , util .ErrFieldNotFound , transportURL .Status .SecretName )
17681771 }
1769- return string (url ), nova .MQCompleted , nil
1772+
1773+ // Check if quorum queues are enabled
1774+ quorumQueues := false
1775+ if val , ok := secret .Data [QuorumQueuesSelector ]; ok {
1776+ quorumQueues = string (val ) == "true"
1777+ }
1778+
1779+ return string (url ), quorumQueues , nova .MQCompleted , nil
17701780}
17711781
17721782func (r * NovaReconciler ) ensureMQDeleted (
@@ -1993,15 +2003,22 @@ func (r *NovaReconciler) ensureCellSecret(
19932003 cellName string ,
19942004 cellTemplate novav1.NovaCellTemplate ,
19952005 cellTransportURL string ,
2006+ cellQuorumQueues bool ,
19962007 notificationTransportURL string ,
19972008 externalSecret corev1.Secret ,
19982009) (string , error ) {
19992010 // NOTE(gibi): We can move other sensitive data to the internal Secret from
20002011 // the NovaCellSpec fields, possibly hostnames or usernames.
2012+ quorumQueuesValue := "false"
2013+ if cellQuorumQueues {
2014+ quorumQueuesValue = "true"
2015+ }
2016+
20012017 data := map [string ]string {
20022018 ServicePasswordSelector : string (externalSecret .Data [instance .Spec .PasswordSelectors .Service ]),
20032019 TransportURLSelector : cellTransportURL ,
20042020 NotificationTransportURLSelector : notificationTransportURL ,
2021+ QuorumQueuesTemplateKey : quorumQueuesValue ,
20052022 }
20062023
20072024 // If metadata is enabled in the cell then the cell secret needs the
@@ -2045,16 +2062,23 @@ func (r *NovaReconciler) ensureTopLevelSecret(
20452062 h * helper.Helper ,
20462063 instance * novav1.Nova ,
20472064 apiTransportURL string ,
2065+ apiQuorumQueues bool ,
20482066 notificationTransportURL string ,
20492067 externalSecret corev1.Secret ,
20502068) (string , error ) {
20512069 // NOTE(gibi): We can move other sensitive data to the internal Secret from
20522070 // the subCR fields, possibly hostnames or usernames.
2071+ quorumQueuesValue := "false"
2072+ if apiQuorumQueues {
2073+ quorumQueuesValue = "true"
2074+ }
2075+
20532076 data := map [string ]string {
20542077 ServicePasswordSelector : string (externalSecret .Data [instance .Spec .PasswordSelectors .Service ]),
20552078 MetadataSecretSelector : string (externalSecret .Data [instance .Spec .PasswordSelectors .MetadataSecret ]),
20562079 TransportURLSelector : apiTransportURL ,
20572080 NotificationTransportURLSelector : notificationTransportURL ,
2081+ QuorumQueuesTemplateKey : quorumQueuesValue ,
20582082 }
20592083
20602084 // NOTE(gibi): When we switch to immutable secrets then we need to include
0 commit comments