Skip to content

Commit 9b72000

Browse files
committed
Adds notification transporturl
1 - human operator will update rabbitmq in openstackcontrolplane CR a) under rabbitmq: add new rabbitmq, ex: rabbitmq-broadcaster, something like rabbitmq-broadcaster: replicas: 1 2 - human operator will update Nova in openstackcontrolplane CR a) under nova.template.spec: register new rabbit (as we do for new cell but not inside celltemplate, as this one is top-level) nova: template: spec: apiContainerImageURL: image_url apiMessageBusInstance: rabbitmq // new var notificationsBusInstance: rabbitmq-broadcaster in Nova CR instance.Spec.NotificationsBusInstance value nil : means not mentioned in CR, so disable it. "" : disable notification rabbitmq-broadcaster : notification to a bus rabbitmq-broadcaster 3 - nova-operator will recognize notificationsBusInstance and retrieve transport_url of new rabbit (rabbitmq-broadcaster) 4 - nova-operator will set this transport_url in nova.conf Closes: OSPRH-15392
1 parent b7ffbe7 commit 9b72000

11 files changed

Lines changed: 231 additions & 123 deletions

api/v1beta1/conditions.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ const (
5454
NovaAllControlPlaneComputesReadyCondition condition.Type = "NovaAllControlPlaneComputesReady"
5555
//NovaCellsDeletionCondition indicates that the NovaCells deletion is in progress
5656
NovaCellsDeletionCondition condition.Type = "NovaCellsDeletion"
57+
58+
// notifications
59+
// NovaNotificationMQReadyCondition indicated that the top level notification message bus is ready
60+
NovaNotificationMQReadyCondition condition.Type = "NovaNotificationMQReady"
5761
)
5862

5963
// Common Messages used by API objects.
@@ -183,4 +187,19 @@ const (
183187

184188
// NovaCellsDeletionConditionReadyMessage
185189
NovaCellsDeletionConditionReadyMessage = "There is no more NovaCells to delete"
190+
// notifications
191+
// NovaNotificationMQReadyInitMessage
192+
NovaNotificationMQReadyInitMessage = "Notification message bus not started"
193+
194+
// NovaNotificationMQNotRequestedMessage
195+
NovaNotificationMQNotRequestedMessage = "Notification message bus not requested"
196+
197+
// NovaNotificationMQReadyErrorMessage
198+
NovaNotificationMQReadyErrorMessage = "Notification message bus creation failed: %s"
199+
200+
// NovaNotificationMQReadyCreatingMessage
201+
NovaNotificationMQReadyCreatingMessage = "Notification message bus creation ongoing"
202+
203+
// NovaNotificationMQReadyMessage
204+
NovaNotificationMQReadyMessage = "Notification message bus created successfully"
186205
)

controllers/common.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ const (
9696
// Secret for the cell message bus transport URL
9797
TransportURLSelector = "transport_url"
9898

99+
// NotificationTransportURLSelector is the name of
100+
// top level notification message bus transport URL
101+
NotificationTransportURLSelector = "notification_transport_url"
102+
99103
// fields to index to reconcile when change
100104
passwordSecretField = ".spec.secret"
101105
caBundleSecretNameField = ".spec.tls.caBundleSecretName" // #nosec G101

controllers/nova_controller.go

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,49 @@ func (r *NovaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (resul
391391
return ctrl.Result{}, fmt.Errorf("%w from for the API MQ: %d", util.ErrInvalidStatus, apiMQStatus)
392392
}
393393

394+
// nova broadcaster rabbit
395+
notificationBusName := ""
396+
if instance.Spec.NotificationsBusInstance != nil {
397+
notificationBusName = *instance.Spec.NotificationsBusInstance
398+
}
399+
400+
var notificationTransportURL string
401+
var notificationMQStatus nova.MessageBusStatus
402+
var notificationMQError error
403+
404+
if notificationBusName != "" {
405+
notificationTransportURL, notificationMQStatus, notificationMQError = r.ensureMQ(
406+
ctx, h, instance, instance.Name+"-notification-transport", notificationBusName)
407+
408+
switch notificationMQStatus {
409+
case nova.MQFailed:
410+
instance.Status.Conditions.Set(condition.FalseCondition(
411+
novav1.NovaNotificationMQReadyCondition,
412+
condition.ErrorReason,
413+
condition.SeverityError,
414+
novav1.NovaNotificationMQReadyErrorMessage,
415+
notificationMQError.Error(),
416+
))
417+
case nova.MQCreating:
418+
instance.Status.Conditions.Set(condition.FalseCondition(
419+
novav1.NovaNotificationMQReadyCondition,
420+
condition.ErrorReason,
421+
condition.SeverityError,
422+
novav1.NovaNotificationMQReadyCreatingMessage,
423+
))
424+
case nova.MQCompleted:
425+
instance.Status.Conditions.MarkTrue(
426+
novav1.NovaNotificationMQReadyCondition, novav1.NovaNotificationMQReadyMessage)
427+
default:
428+
return ctrl.Result{}, fmt.Errorf("%w from for the Notification MQ: %d",
429+
util.ErrInvalidStatus, notificationMQStatus)
430+
}
431+
} else {
432+
instance.Status.Conditions.MarkTrue(
433+
novav1.NovaNotificationMQReadyCondition, novav1.NovaNotificationMQNotRequestedMessage)
434+
435+
}
436+
394437
cellMQs := map[string]*nova.MessageBus{}
395438
var failedMQs []string
396439
var creatingMQs []string
@@ -481,7 +524,7 @@ func (r *NovaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (resul
481524
}
482525
cell, status, err := r.ensureCell(
483526
ctx, h, instance, cellName, cellTemplate,
484-
cellDB.Database, apiDB, cellMQ.TransportURL,
527+
cellDB.Database, apiDB, cellMQ.TransportURL, notificationTransportURL,
485528
keystoneInternalAuthURL, secret,
486529
)
487530
cells[cellName] = cell
@@ -546,7 +589,11 @@ func (r *NovaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (resul
546589
return ctrl.Result{}, nil
547590
}
548591

549-
topLevelSecretName, err := r.ensureTopLevelSecret(ctx, h, instance, apiTransportURL, secret)
592+
topLevelSecretName, err := r.ensureTopLevelSecret(
593+
ctx, h, instance,
594+
apiTransportURL,
595+
notificationTransportURL,
596+
secret)
550597
if err != nil {
551598
return ctrl.Result{}, err
552599
}
@@ -936,6 +983,11 @@ func (r *NovaReconciler) initConditions(
936983
condition.InitReason,
937984
condition.MemcachedReadyInitMessage,
938985
),
986+
condition.UnknownCondition(
987+
novav1.NovaNotificationMQReadyCondition,
988+
condition.InitReason,
989+
novav1.NovaNotificationMQReadyInitMessage,
990+
),
939991
)
940992
instance.Status.Conditions.Init(&cl)
941993
return nil
@@ -1133,12 +1185,16 @@ func (r *NovaReconciler) ensureCell(
11331185
cellDB *mariadbv1.Database,
11341186
apiDB *mariadbv1.Database,
11351187
cellTransportURL string,
1188+
notificationTransportURL string,
11361189
keystoneAuthURL string,
11371190
secret corev1.Secret,
11381191
) (*novav1.NovaCell, nova.CellDeploymentStatus, error) {
11391192
Log := r.GetLogger(ctx)
11401193

1141-
cellSecretName, err := r.ensureCellSecret(ctx, h, instance, cellName, cellTemplate, cellTransportURL, secret)
1194+
cellSecretName, err := r.ensureCellSecret(
1195+
ctx, h, instance, cellName, cellTemplate,
1196+
cellTransportURL, notificationTransportURL,
1197+
secret)
11421198
if err != nil {
11431199
return nil, nova.CellDeploying, err
11441200
}
@@ -1684,6 +1740,7 @@ func (r *NovaReconciler) ensureMQ(
16841740
}
16851741

16861742
secretName := types.NamespacedName{Namespace: instance.Namespace, Name: transportURL.Status.SecretName}
1743+
16871744
secret := &corev1.Secret{}
16881745
err = h.GetClient().Get(ctx, secretName, secret)
16891746
if err != nil {
@@ -1698,7 +1755,6 @@ func (r *NovaReconciler) ensureMQ(
16981755
return "", nova.MQFailed, fmt.Errorf(
16991756
"%w: the TransportURL secret %s does not have 'transport_url' field", util.ErrFieldNotFound, transportURL.Status.SecretName)
17001757
}
1701-
17021758
return string(url), nova.MQCompleted, nil
17031759
}
17041760

@@ -1902,13 +1958,15 @@ func (r *NovaReconciler) ensureCellSecret(
19021958
cellName string,
19031959
cellTemplate novav1.NovaCellTemplate,
19041960
cellTransportURL string,
1961+
notificationTransportURL string,
19051962
externalSecret corev1.Secret,
19061963
) (string, error) {
19071964
// NOTE(gibi): We can move other sensitive data to the internal Secret from
19081965
// the NovaCellSpec fields, possibly hostnames or usernames.
19091966
data := map[string]string{
1910-
ServicePasswordSelector: string(externalSecret.Data[instance.Spec.PasswordSelectors.Service]),
1911-
TransportURLSelector: cellTransportURL,
1967+
ServicePasswordSelector: string(externalSecret.Data[instance.Spec.PasswordSelectors.Service]),
1968+
TransportURLSelector: cellTransportURL,
1969+
NotificationTransportURLSelector: notificationTransportURL,
19121970
}
19131971

19141972
// If metadata is enabled in the cell then the cell secret needs the
@@ -1952,14 +2010,16 @@ func (r *NovaReconciler) ensureTopLevelSecret(
19522010
h *helper.Helper,
19532011
instance *novav1.Nova,
19542012
apiTransportURL string,
2013+
notificationTransportURL string,
19552014
externalSecret corev1.Secret,
19562015
) (string, error) {
19572016
// NOTE(gibi): We can move other sensitive data to the internal Secret from
19582017
// the subCR fields, possibly hostnames or usernames.
19592018
data := map[string]string{
1960-
ServicePasswordSelector: string(externalSecret.Data[instance.Spec.PasswordSelectors.Service]),
1961-
MetadataSecretSelector: string(externalSecret.Data[instance.Spec.PasswordSelectors.MetadataSecret]),
1962-
TransportURLSelector: apiTransportURL,
2019+
ServicePasswordSelector: string(externalSecret.Data[instance.Spec.PasswordSelectors.Service]),
2020+
MetadataSecretSelector: string(externalSecret.Data[instance.Spec.PasswordSelectors.MetadataSecret]),
2021+
TransportURLSelector: apiTransportURL,
2022+
NotificationTransportURLSelector: notificationTransportURL,
19632023
}
19642024

19652025
// NOTE(gibi): When we switch to immutable secrets then we need to include

controllers/novaapi_controller.go

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -183,16 +183,19 @@ func (r *NovaAPIReconciler) Reconcile(ctx context.Context, req ctrl.Request) (re
183183
// detect if something is changed.
184184
hashes := make(map[string]env.Setter)
185185

186-
secretHash, result, secret, err := ensureSecret(
187-
ctx,
188-
types.NamespacedName{Namespace: instance.Namespace, Name: instance.Spec.Secret},
186+
requiredSecretFields := []string{
189187
// TODO(gibi): add keystoneAuthURL here is that is also passed via
190188
// the Secret. Also add DB and MQ user name here too if those are
191189
// passed via the Secret
192-
[]string{
193-
ServicePasswordSelector,
194-
TransportURLSelector,
195-
},
190+
ServicePasswordSelector,
191+
TransportURLSelector,
192+
NotificationTransportURLSelector,
193+
}
194+
195+
secretHash, result, secret, err := ensureSecret(
196+
ctx,
197+
types.NamespacedName{Namespace: instance.Namespace, Name: instance.Spec.Secret},
198+
requiredSecretFields,
196199
h.GetClient(),
197200
&instance.Status.Conditions,
198201
r.RequeueTimeout,
@@ -473,28 +476,29 @@ func (r *NovaAPIReconciler) generateConfigs(
473476
"keystone_internal_url": instance.Spec.KeystoneAuthURL,
474477
// NOTE(gibi): As per the definition of www_authenticate_uri this
475478
// always needs to point to the public keystone endpoint.
476-
"www_authenticate_uri": instance.Spec.KeystonePublicAuthURL,
477-
"nova_keystone_user": instance.Spec.ServiceUser,
478-
"nova_keystone_password": string(secret.Data[ServicePasswordSelector]),
479-
"api_db_name": NovaAPIDatabaseName,
480-
"api_db_user": apiDatabaseAccount.Spec.UserName,
481-
"api_db_password": string(apiDbSecret.Data[mariadbv1.DatabasePasswordSelector]),
482-
"api_db_address": instance.Spec.APIDatabaseHostname,
483-
"api_db_port": 3306,
484-
"cell_db_name": NovaCell0DatabaseName,
485-
"cell_db_user": cellDatabaseAccount.Spec.UserName,
486-
"cell_db_password": string(cellDbSecret.Data[mariadbv1.DatabasePasswordSelector]),
487-
"cell_db_address": instance.Spec.Cell0DatabaseHostname,
488-
"cell_db_port": 3306,
489-
"openstack_region_name": "regionOne", // fixme
490-
"default_project_domain": "Default", // fixme
491-
"default_user_domain": "Default", // fixme
492-
"transport_url": string(secret.Data[TransportURLSelector]),
493-
"log_file": "/var/log/nova/nova-api.log",
494-
"tls": false,
495-
"MemcachedServers": memcachedInstance.GetMemcachedServerListString(),
496-
"MemcachedServersWithInet": memcachedInstance.GetMemcachedServerListWithInetString(),
497-
"MemcachedTLS": memcachedInstance.GetMemcachedTLSSupport(),
479+
"www_authenticate_uri": instance.Spec.KeystonePublicAuthURL,
480+
"nova_keystone_user": instance.Spec.ServiceUser,
481+
"nova_keystone_password": string(secret.Data[ServicePasswordSelector]),
482+
"api_db_name": NovaAPIDatabaseName,
483+
"api_db_user": apiDatabaseAccount.Spec.UserName,
484+
"api_db_password": string(apiDbSecret.Data[mariadbv1.DatabasePasswordSelector]),
485+
"api_db_address": instance.Spec.APIDatabaseHostname,
486+
"api_db_port": 3306,
487+
"cell_db_name": NovaCell0DatabaseName,
488+
"cell_db_user": cellDatabaseAccount.Spec.UserName,
489+
"cell_db_password": string(cellDbSecret.Data[mariadbv1.DatabasePasswordSelector]),
490+
"cell_db_address": instance.Spec.Cell0DatabaseHostname,
491+
"cell_db_port": 3306,
492+
"openstack_region_name": "regionOne", // fixme
493+
"default_project_domain": "Default", // fixme
494+
"default_user_domain": "Default", // fixme
495+
"transport_url": string(secret.Data[TransportURLSelector]),
496+
"notification_transport_url": string(secret.Data[NotificationTransportURLSelector]),
497+
"log_file": "/var/log/nova/nova-api.log",
498+
"tls": false,
499+
"MemcachedServers": memcachedInstance.GetMemcachedServerListString(),
500+
"MemcachedServersWithInet": memcachedInstance.GetMemcachedServerListWithInetString(),
501+
"MemcachedTLS": memcachedInstance.GetMemcachedTLSSupport(),
498502
}
499503
// create httpd vhost template parameters
500504
httpdVhostConfig := map[string]interface{}{}

controllers/novacell_controller.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,17 @@ func (r *NovaCellReconciler) Reconcile(ctx context.Context, req ctrl.Request) (r
144144
}
145145
}()
146146

147+
requiredSecretFields := []string{
148+
ServicePasswordSelector,
149+
TransportURLSelector,
150+
NotificationTransportURLSelector,
151+
}
152+
147153
// For the compute config generation we need to read the input secrets
148154
_, result, secret, err := ensureSecret(
149155
ctx,
150156
types.NamespacedName{Namespace: instance.Namespace, Name: instance.Spec.Secret},
151-
[]string{
152-
ServicePasswordSelector,
153-
TransportURLSelector,
154-
},
157+
requiredSecretFields,
155158
h.GetClient(),
156159
&instance.Status.Conditions,
157160
r.RequeueTimeout,
@@ -767,15 +770,16 @@ func (r *NovaCellReconciler) generateComputeConfigs(
767770
secret corev1.Secret, vncProxyURL *string,
768771
) error {
769772
templateParameters := map[string]interface{}{
770-
"service_name": "nova-compute",
771-
"keystone_internal_url": instance.Spec.KeystoneAuthURL,
772-
"nova_keystone_user": instance.Spec.ServiceUser,
773-
"nova_keystone_password": string(secret.Data[ServicePasswordSelector]),
774-
"openstack_region_name": "regionOne", // fixme
775-
"default_project_domain": "Default", // fixme
776-
"default_user_domain": "Default", // fixme
777-
"compute_driver": "libvirt.LibvirtDriver",
778-
"transport_url": string(secret.Data[TransportURLSelector]),
773+
"service_name": "nova-compute",
774+
"keystone_internal_url": instance.Spec.KeystoneAuthURL,
775+
"nova_keystone_user": instance.Spec.ServiceUser,
776+
"nova_keystone_password": string(secret.Data[ServicePasswordSelector]),
777+
"openstack_region_name": "regionOne", // fixme
778+
"default_project_domain": "Default", // fixme
779+
"default_user_domain": "Default", // fixme
780+
"compute_driver": "libvirt.LibvirtDriver",
781+
"transport_url": string(secret.Data[TransportURLSelector]),
782+
"notification_transport_url": string(secret.Data[NotificationTransportURLSelector]),
779783
}
780784
// vnc is optional so we only need to configure it for the compute
781785
// if the proxy service is deployed in the cell

controllers/novacompute_controller.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,16 @@ func (r *NovaComputeReconciler) Reconcile(ctx context.Context, req ctrl.Request)
158158

159159
hashes := make(map[string]env.Setter)
160160

161+
requiredSecretFields := []string{
162+
ServicePasswordSelector,
163+
TransportURLSelector,
164+
NotificationTransportURLSelector,
165+
}
166+
161167
secretHash, result, secret, err := ensureSecret(
162168
ctx,
163169
types.NamespacedName{Namespace: instance.Namespace, Name: instance.Spec.Secret},
164-
[]string{
165-
ServicePasswordSelector,
166-
TransportURLSelector,
167-
},
170+
requiredSecretFields,
168171
h.GetClient(),
169172
&instance.Status.Conditions,
170173
r.RequeueTimeout,
@@ -336,15 +339,16 @@ func (r *NovaComputeReconciler) generateConfigs(
336339
ctx context.Context, h *helper.Helper, instance *novav1.NovaCompute, hashes *map[string]env.Setter, secret corev1.Secret,
337340
) error {
338341
templateParameters := map[string]interface{}{
339-
"service_name": NovaComputeLabelPrefix,
340-
"keystone_internal_url": instance.Spec.KeystoneAuthURL,
341-
"nova_keystone_user": instance.Spec.ServiceUser,
342-
"nova_keystone_password": string(secret.Data[ServicePasswordSelector]),
343-
"openstack_region_name": "regionOne", // fixme
344-
"default_project_domain": "Default", // fixme
345-
"default_user_domain": "Default", // fixme
346-
"transport_url": string(secret.Data[TransportURLSelector]),
347-
"compute_driver": instance.Spec.ComputeDriver,
342+
"service_name": NovaComputeLabelPrefix,
343+
"keystone_internal_url": instance.Spec.KeystoneAuthURL,
344+
"nova_keystone_user": instance.Spec.ServiceUser,
345+
"nova_keystone_password": string(secret.Data[ServicePasswordSelector]),
346+
"openstack_region_name": "regionOne", // fixme
347+
"default_project_domain": "Default", // fixme
348+
"default_user_domain": "Default", // fixme
349+
"transport_url": string(secret.Data[TransportURLSelector]),
350+
"notification_transport_url": string(secret.Data[NotificationTransportURLSelector]),
351+
"compute_driver": instance.Spec.ComputeDriver,
348352
// Neither the ironic driver nor the fake driver support VNC
349353
"vnc_enabled": false,
350354
}

0 commit comments

Comments
 (0)