Skip to content

Commit a55d41f

Browse files
committed
Rabbitmq vhost and user support
Add new messagingBus and notificationsBus interfaces to hold cluster, user and vhost names for optional usage. The controller adds these values to the TransportURL create request when present. Additionally, we migrate RabbitMQ cluster name to RabbitMq config struct using DefaultRabbitMqConfig from infra-operator to automatically populate the new Cluster field from legacy RabbitMqClusterName. Example usage: spec: messagingBus: cluster: rpc-rabbitmq user: rpc-user vhost: rpc-vhost notificationsBus: cluster: notifications-rabbitmq user: notifications-user vhost: notifications-vhost Finally, we add the rabbitmquser crs to the secret so they can be stored for dataplane finalizers management and do auto cleanup of orphaned users after credential rotations. Jira: https://issues.redhat.com/browse/OSPRH-22697
1 parent 044464a commit a55d41f

File tree

18 files changed

+438
-48
lines changed

18 files changed

+438
-48
lines changed

api/bases/nova.openstack.org_nova.yaml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,23 @@ spec:
540540
MemcachedInstance is the name of the Memcached CR that the services in the cell will use.
541541
If defined then this takes precedence over Nova.Spec.MemcachedInstance for this cel
542542
type: string
543+
messagingBus:
544+
description: MessagingBus configuration (username, vhost, and
545+
cluster)
546+
properties:
547+
cluster:
548+
description: Name of the cluster
549+
minLength: 1
550+
type: string
551+
user:
552+
description: User - RabbitMQ username
553+
type: string
554+
vhost:
555+
description: Vhost - RabbitMQ vhost name
556+
type: string
557+
required:
558+
- cluster
559+
type: object
543560
metadataServiceTemplate:
544561
description: |-
545562
MetadataServiceTemplate - defines the metadata service dedicated for the
@@ -1340,6 +1357,22 @@ spec:
13401357
description: MemcachedInstance is the name of the Memcached CR that
13411358
all nova service will use.
13421359
type: string
1360+
messagingBus:
1361+
description: MessagingBus configuration (username, vhost, and cluster)
1362+
properties:
1363+
cluster:
1364+
description: Name of the cluster
1365+
minLength: 1
1366+
type: string
1367+
user:
1368+
description: User - RabbitMQ username
1369+
type: string
1370+
vhost:
1371+
description: Vhost - RabbitMQ vhost name
1372+
type: string
1373+
required:
1374+
- cluster
1375+
type: object
13431376
metadataContainerImageURL:
13441377
description: MetadataContainerImageURL
13451378
type: string
@@ -1648,6 +1681,23 @@ spec:
16481681
NodeSelector here acts as a default value and can be overridden by service
16491682
specific NodeSelector Settings.
16501683
type: object
1684+
notificationsBus:
1685+
description: NotificationsBus configuration (username, vhost, and
1686+
cluster) for notifications
1687+
properties:
1688+
cluster:
1689+
description: Name of the cluster
1690+
minLength: 1
1691+
type: string
1692+
user:
1693+
description: User - RabbitMQ username
1694+
type: string
1695+
vhost:
1696+
description: Vhost - RabbitMQ vhost name
1697+
type: string
1698+
required:
1699+
- cluster
1700+
type: object
16511701
notificationsBusInstance:
16521702
description: |-
16531703
NotificationsBusInstance is the name of the RabbitMqCluster CR to select

api/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ require (
1818
github.com/cespare/xxhash/v2 v2.3.0 // indirect
1919
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
2020
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
21-
github.com/evanphx/json-patch v5.9.11+incompatible // indirect
2221
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
2322
github.com/fsnotify/fsnotify v1.9.0 // indirect
2423
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
@@ -44,6 +43,7 @@ require (
4443
github.com/prometheus/client_model v0.6.2 // indirect
4544
github.com/prometheus/common v0.65.0 // indirect
4645
github.com/prometheus/procfs v0.16.1 // indirect
46+
github.com/rabbitmq/cluster-operator/v2 v2.16.0 // indirect
4747
github.com/spf13/pflag v1.0.7 // indirect
4848
github.com/x448/float16 v0.8.4 // indirect
4949
go.yaml.in/yaml/v2 v2.4.2 // indirect

api/go.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
12
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
23
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
34
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -82,6 +83,8 @@ github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251223124749-e
8283
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251223124749-eedb97238c5f/go.mod h1:ex8ou6/3ms6ovR+CMXD6XhTlNakm1GhB6UZgagVRNW8=
8384
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251230215914-6ba873b49a35 h1:pF3mJ3nwq6r4qwom+rEWZNquZpcQW/iftHlJ1KPIDsk=
8485
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251230215914-6ba873b49a35/go.mod h1:kycZyoe7OZdW1HUghr2nI3N7wSJtNahXf6b/ypD14f4=
86+
github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250929174222-a0d328fa4dec h1:saovr368HPAKHN0aRPh8h8n9s9dn3d8Frmfua0UYRlc=
87+
github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250929174222-a0d328fa4dec/go.mod h1:Nh2NEePLjovUQof2krTAg4JaAoLacqtPTZQXK6izNfg=
8588
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
8689
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
8790
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=

api/v1beta1/nova_types.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package v1beta1
1818

1919
import (
20+
rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1"
2021
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
2122
condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
2223
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -49,6 +50,10 @@ type NovaSpecCore struct {
4950
// communicate.
5051
APIMessageBusInstance string `json:"apiMessageBusInstance"`
5152

53+
// +kubebuilder:validation:Optional
54+
// MessagingBus configuration (username, vhost, and cluster)
55+
MessagingBus rabbitmqv1.RabbitMqConfig `json:"messagingBus,omitempty"`
56+
5257
// +kubebuilder:validation:Optional
5358
// +kubebuilder:default={cell0: {cellDatabaseAccount: nova-cell0, hasAPIAccess: true}, cell1: {cellDatabaseAccount: nova-cell1, cellDatabaseInstance: openstack-cell1, cellMessageBusInstance: rabbitmq-cell1, hasAPIAccess: true}}
5459
// Cells is a mapping of cell names to NovaCellTemplate objects defining
@@ -131,6 +136,10 @@ type NovaSpecCore struct {
131136
// Avoid colocating it with RabbitMqClusterName, APIMessageBusInstance or CellMessageBusInstance used for RPC.
132137
// For particular Nova cells, notifications cannot be disabled, nor configured differently.
133138
NotificationsBusInstance *string `json:"notificationsBusInstance,omitempty"`
139+
140+
// +kubebuilder:validation:Optional
141+
// NotificationsBus configuration (username, vhost, and cluster) for notifications
142+
NotificationsBus *rabbitmqv1.RabbitMqConfig `json:"notificationsBus,omitempty"`
134143
}
135144

136145
// NovaSpec defines the desired state of Nova

api/v1beta1/nova_webhook.go

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"fmt"
2727

2828
"github.com/google/go-cmp/cmp"
29+
rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1"
2930
service "github.com/openstack-k8s-operators/lib-common/modules/common/service"
3031
"github.com/robfig/cron/v3"
3132

@@ -88,6 +89,24 @@ func (spec *NovaSpecCore) Default() {
8889
spec.APITimeout = novaDefaults.APITimeout
8990
}
9091

92+
// Default MessagingBus.Cluster from APIMessageBusInstance if not already set
93+
if spec.MessagingBus.Cluster == "" {
94+
spec.MessagingBus.Cluster = spec.APIMessageBusInstance
95+
}
96+
97+
// Default NotificationsBus if NotificationsBusInstance is specified
98+
if spec.NotificationsBusInstance != nil && *spec.NotificationsBusInstance != "" {
99+
if spec.NotificationsBus == nil {
100+
// Initialize empty NotificationsBus - credentials will be created dynamically
101+
// to ensure separation from MessagingBus (RPC and notifications should never share credentials)
102+
spec.NotificationsBus = &rabbitmqv1.RabbitMqConfig{}
103+
}
104+
// Default cluster name if not already set
105+
if spec.NotificationsBus.Cluster == "" {
106+
spec.NotificationsBus.Cluster = *spec.NotificationsBusInstance
107+
}
108+
}
109+
91110
for cellName, cellTemplate := range spec.CellTemplates {
92111

93112
if cellTemplate.MetadataServiceTemplate.Enabled == nil {
@@ -106,6 +125,11 @@ func (spec *NovaSpecCore) Default() {
106125
}
107126
}
108127

128+
// Default MessagingBus.Cluster from CellMessageBusInstance if not already set
129+
if cellTemplate.MessagingBus.Cluster == "" {
130+
cellTemplate.MessagingBus.Cluster = cellTemplate.CellMessageBusInstance
131+
}
132+
109133
// "cellTemplate" is a by-value copy, so we need to re-inject the updated version of it into the map
110134
spec.CellTemplates[cellName] = cellTemplate
111135
}
@@ -315,7 +339,34 @@ func (spec *NovaSpec) ValidateUpdate(old NovaSpec, basePath *field.Path, namespa
315339
// expected to be called by the validation webhook in the higher level meta
316340
// operator
317341
func (spec *NovaSpecCore) ValidateUpdate(old NovaSpecCore, basePath *field.Path, namespace string) field.ErrorList {
318-
errors := spec.ValidateCellTemplates(basePath, namespace)
342+
var errors field.ErrorList
343+
344+
// Reject changes to deprecated messagingBusInstance fields - users should use the new messagingBus fields instead
345+
if spec.APIMessageBusInstance != old.APIMessageBusInstance {
346+
errors = append(errors, field.Forbidden(
347+
basePath.Child("apiMessageBusInstance"),
348+
"apiMessageBusInstance is deprecated and cannot be changed. Please use messagingBus.cluster instead"))
349+
}
350+
351+
if spec.NotificationsBusInstance != nil && old.NotificationsBusInstance != nil &&
352+
*spec.NotificationsBusInstance != *old.NotificationsBusInstance {
353+
errors = append(errors, field.Forbidden(
354+
basePath.Child("notificationsBusInstance"),
355+
"notificationsBusInstance is deprecated and cannot be changed. Please use notificationsBus.cluster instead"))
356+
}
357+
358+
// Check cell template changes
359+
for cellName, cellTemplate := range spec.CellTemplates {
360+
if oldCell, exists := old.CellTemplates[cellName]; exists {
361+
if cellTemplate.CellMessageBusInstance != oldCell.CellMessageBusInstance {
362+
errors = append(errors, field.Forbidden(
363+
basePath.Child("cellTemplates").Key(cellName).Child("cellMessageBusInstance"),
364+
"cellMessageBusInstance is deprecated and cannot be changed. Please use messagingBus.cluster instead"))
365+
}
366+
}
367+
}
368+
369+
errors = append(errors, spec.ValidateCellTemplates(basePath, namespace)...)
319370
// Validate top-level TopologyRef
320371
errors = append(errors, topologyv1.ValidateTopologyRef(
321372
spec.TopologyRef, *basePath.Child("topologyRef"), namespace)...)

api/v1beta1/novacell_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package v1beta1
1818

1919
import (
20+
rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1"
2021
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
2122
condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
2223
"github.com/openstack-k8s-operators/lib-common/modules/common/tls"
@@ -51,6 +52,10 @@ type NovaCellTemplate struct {
5152
// communicate in this cell. For cell0 it is unused.
5253
CellMessageBusInstance string `json:"cellMessageBusInstance"`
5354

55+
// +kubebuilder:validation:Optional
56+
// MessagingBus configuration (username, vhost, and cluster)
57+
MessagingBus rabbitmqv1.RabbitMqConfig `json:"messagingBus,omitempty"`
58+
5459
// +kubebuilder:validation:Required
5560
// HasAPIAccess defines if this Cell is configured to have access to the
5661
// API DB and message bus.

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/nova.openstack.org_nova.yaml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,23 @@ spec:
540540
MemcachedInstance is the name of the Memcached CR that the services in the cell will use.
541541
If defined then this takes precedence over Nova.Spec.MemcachedInstance for this cel
542542
type: string
543+
messagingBus:
544+
description: MessagingBus configuration (username, vhost, and
545+
cluster)
546+
properties:
547+
cluster:
548+
description: Name of the cluster
549+
minLength: 1
550+
type: string
551+
user:
552+
description: User - RabbitMQ username
553+
type: string
554+
vhost:
555+
description: Vhost - RabbitMQ vhost name
556+
type: string
557+
required:
558+
- cluster
559+
type: object
543560
metadataServiceTemplate:
544561
description: |-
545562
MetadataServiceTemplate - defines the metadata service dedicated for the
@@ -1340,6 +1357,22 @@ spec:
13401357
description: MemcachedInstance is the name of the Memcached CR that
13411358
all nova service will use.
13421359
type: string
1360+
messagingBus:
1361+
description: MessagingBus configuration (username, vhost, and cluster)
1362+
properties:
1363+
cluster:
1364+
description: Name of the cluster
1365+
minLength: 1
1366+
type: string
1367+
user:
1368+
description: User - RabbitMQ username
1369+
type: string
1370+
vhost:
1371+
description: Vhost - RabbitMQ vhost name
1372+
type: string
1373+
required:
1374+
- cluster
1375+
type: object
13431376
metadataContainerImageURL:
13441377
description: MetadataContainerImageURL
13451378
type: string
@@ -1648,6 +1681,23 @@ spec:
16481681
NodeSelector here acts as a default value and can be overridden by service
16491682
specific NodeSelector Settings.
16501683
type: object
1684+
notificationsBus:
1685+
description: NotificationsBus configuration (username, vhost, and
1686+
cluster) for notifications
1687+
properties:
1688+
cluster:
1689+
description: Name of the cluster
1690+
minLength: 1
1691+
type: string
1692+
user:
1693+
description: User - RabbitMQ username
1694+
type: string
1695+
vhost:
1696+
description: Vhost - RabbitMQ vhost name
1697+
type: string
1698+
required:
1699+
- cluster
1700+
type: object
16511701
notificationsBusInstance:
16521702
description: |-
16531703
NotificationsBusInstance is the name of the RabbitMqCluster CR to select

internal/controller/common.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,14 @@ const (
110110
// the message bus quorum queues configuration
111111
QuorumQueuesTemplateKey = "quorum_queues"
112112

113+
// RabbitmqUserNameSelector is the name of key in the internal Secret for
114+
// the RabbitMQUser CR name for the RPC/messaging bus
115+
RabbitmqUserNameSelector = "rabbitmq_user_name"
116+
117+
// NotificationRabbitmqUserNameSelector is the name of key in the internal
118+
// Secret for the RabbitMQUser CR name for the notifications bus
119+
NotificationRabbitmqUserNameSelector = "notification_rabbitmq_user_name"
120+
113121
// fields to index to reconcile when change
114122
passwordSecretField = ".spec.secret"
115123
caBundleSecretNameField = ".spec.tls.caBundleSecretName" // #nosec G101

0 commit comments

Comments
 (0)