Skip to content

Commit e71908f

Browse files
committed
Rabbitmq vhost and user support
Add support for a dedicated rabbitmq cluster for notifications. 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 Jira: https://issues.redhat.com/browse/OSPRH-22695
1 parent 5ce22bc commit e71908f

File tree

15 files changed

+599
-17
lines changed

15 files changed

+599
-17
lines changed

api/bases/heat.openstack.org_heats.yaml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1959,12 +1959,45 @@ spec:
19591959
default: memcached
19601960
description: Memcached instance name.
19611961
type: string
1962+
messagingBus:
1963+
description: MessagingBus - Messaging Bus configuration
1964+
properties:
1965+
cluster:
1966+
description: Name of the cluster
1967+
minLength: 1
1968+
type: string
1969+
user:
1970+
description: User - RabbitMQ username
1971+
type: string
1972+
vhost:
1973+
description: Vhost - RabbitMQ vhost name
1974+
type: string
1975+
required:
1976+
- cluster
1977+
type: object
19621978
nodeSelector:
19631979
additionalProperties:
19641980
type: string
19651981
description: NodeSelector to target subset of worker nodes for running
19661982
the Heat services
19671983
type: object
1984+
notificationsBus:
1985+
description: NotificationsBus - Notifications Bus configuration (optional,
1986+
separate from MessagingBus)
1987+
properties:
1988+
cluster:
1989+
description: Name of the cluster
1990+
minLength: 1
1991+
type: string
1992+
user:
1993+
description: User - RabbitMQ username
1994+
type: string
1995+
vhost:
1996+
description: Vhost - RabbitMQ vhost name
1997+
type: string
1998+
required:
1999+
- cluster
2000+
type: object
19682001
passwordSelectors:
19692002
default:
19702003
authEncryptionKey: HeatAuthEncryptionKey
@@ -1999,6 +2032,24 @@ spec:
19992032
RabbitMQ instance name
20002033
Needed to request a transportURL that is created and used in Heat
20012034
type: string
2035+
rabbitmq:
2036+
description: |-
2037+
RabbitMQ - RabbitMQ configuration overrides
2038+
Deprecated: Use MessagingBus instead
2039+
properties:
2040+
cluster:
2041+
description: Name of the cluster
2042+
minLength: 1
2043+
type: string
2044+
user:
2045+
description: User - RabbitMQ username
2046+
type: string
2047+
vhost:
2048+
description: Vhost - RabbitMQ vhost name
2049+
type: string
2050+
required:
2051+
- cluster
2052+
type: object
20022053
secret:
20032054
description: |-
20042055
Secret containing OpenStack password information for heat HeatDatabasePassword, HeatPassword
@@ -2100,6 +2151,10 @@ spec:
21002151
description: ReadyCount of Heat Engine instance
21012152
format: int32
21022153
type: integer
2154+
notificationsTransportURLSecret:
2155+
description: NotificationsTransportURLSecret - Secret containing Notifications
2156+
RabbitMQ transportURL
2157+
type: string
21032158
observedGeneration:
21042159
description: |-
21052160
ObservedGeneration - the most recent generation observed for this

api/go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/openstack-k8s-operators/heat-operator/api
33
go 1.24.4
44

55
require (
6-
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251206161943-786269345f99
6+
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251217131115-0f117a938d4e
77
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251122131503-b76943960b6c
88
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251122131503-b76943960b6c
99
k8s.io/api v0.31.14
@@ -16,7 +16,6 @@ require (
1616
github.com/cespare/xxhash/v2 v2.3.0 // indirect
1717
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
1818
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
19-
github.com/evanphx/json-patch v5.9.11+incompatible // indirect
2019
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
2120
github.com/fsnotify/fsnotify v1.9.0 // indirect
2221
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
@@ -43,6 +42,7 @@ require (
4342
github.com/prometheus/client_model v0.6.2 // indirect
4443
github.com/prometheus/common v0.65.0 // indirect
4544
github.com/prometheus/procfs v0.16.1 // indirect
45+
github.com/rabbitmq/cluster-operator/v2 v2.16.0 // indirect
4646
github.com/spf13/pflag v1.0.7 // indirect
4747
github.com/x448/float16 v0.8.4 // indirect
4848
go.yaml.in/yaml/v2 v2.4.2 // indirect

api/go.sum

Lines changed: 5 additions & 2 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=
@@ -78,12 +79,14 @@ github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns
7879
github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
7980
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
8081
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
81-
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251206161943-786269345f99 h1:J9SzxfFmQQEMpfoCtpKUd87LtQXLWGZORL+6nBdtP+w=
82-
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251206161943-786269345f99/go.mod h1:UgaMi5mHTvaGYLdPKwewSnYiSm75P+vowRqbqknHlbw=
82+
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251217131115-0f117a938d4e h1:PIjcXzMMwfvBRFgFpaq/W9tqy0t2cYvcWX+kq6uNtTM=
83+
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251217131115-0f117a938d4e/go.mod h1:ex8ou6/3ms6ovR+CMXD6XhTlNakm1GhB6UZgagVRNW8=
8384
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251122131503-b76943960b6c h1:wM8qXCB5mQwSosCvtaydzuXitWVVKBHTzH0A2znQ+Jg=
8485
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251122131503-b76943960b6c/go.mod h1:+Me0raWPPdz8gRi9D4z1khmvUgS9vIKAVC8ckg1yJZU=
8586
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251122131503-b76943960b6c h1:dVIaDL5BeIdJjERGaN/XlcvZVplfkzh0uUfiVUHj/6Q=
8687
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251122131503-b76943960b6c/go.mod h1:fy1lvz3uuzzh01DKKdgroXvmJgMpJBsvl2r9eTtAll0=
88+
github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250929174222-a0d328fa4dec h1:saovr368HPAKHN0aRPh8h8n9s9dn3d8Frmfua0UYRlc=
89+
github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250929174222-a0d328fa4dec/go.mod h1:Nh2NEePLjovUQof2krTAg4JaAoLacqtPTZQXK6izNfg=
8790
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
8891
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
8992
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=

api/v1beta1/conditions.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ const (
3131

3232
// HeatStackDomainReadyCondition ...
3333
HeatStackDomainReadyCondition condition.Type = "HeatStackDomainReady"
34+
35+
// HeatNotificationBusReadyCondition ...
36+
HeatNotificationBusReadyCondition condition.Type = "HeatNotificationBusReady"
3437
)
3538

3639
// Common Messages used by API objects.
@@ -76,4 +79,19 @@ const (
7679

7780
// HeatStackDomainReadyErrorMessage
7881
HeatStackDomainReadyErrorMessage = "HeatStackDomain error occured %s"
82+
83+
//
84+
// HeatNotificationBusReady condition messages
85+
//
86+
// HeatNotificationBusReadyInitMessage
87+
HeatNotificationBusReadyInitMessage = "HeatNotificationBus not started"
88+
89+
// HeatNotificationBusReadyRunningMessage
90+
HeatNotificationBusReadyRunningMessage = "HeatNotificationBus creation in progress"
91+
92+
// HeatNotificationBusReadyMessage
93+
HeatNotificationBusReadyMessage = "HeatNotificationBus successfully created"
94+
95+
// HeatNotificationBusReadyErrorMessage
96+
HeatNotificationBusReadyErrorMessage = "HeatNotificationBus error occured %s"
7997
)

api/v1beta1/heat_types.go

Lines changed: 19 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
"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
2223
"github.com/openstack-k8s-operators/lib-common/modules/common/util"
@@ -41,6 +42,7 @@ const (
4142
HeatDatabaseMigrationAnnotation = "heat.openstack.org/database-migration"
4243
)
4344

45+
4446
// HeatSpec defines the desired state of Heat
4547
type HeatSpec struct {
4648
HeatSpecBase `json:",inline"`
@@ -95,6 +97,19 @@ type HeatSpecBase struct {
9597
// Needed to request a transportURL that is created and used in Heat
9698
RabbitMqClusterName string `json:"rabbitMqClusterName"`
9799

100+
// +kubebuilder:validation:Optional
101+
// MessagingBus - Messaging Bus configuration
102+
MessagingBus rabbitmqv1.RabbitMqConfig `json:"messagingBus,omitempty"`
103+
104+
// +kubebuilder:validation:Optional
105+
// NotificationsBus - Notifications Bus configuration (optional, separate from MessagingBus)
106+
NotificationsBus *rabbitmqv1.RabbitMqConfig `json:"notificationsBus,omitempty"`
107+
108+
// +kubebuilder:validation:Optional
109+
// RabbitMQ - RabbitMQ configuration overrides
110+
// Deprecated: Use MessagingBus instead
111+
RabbitMQ *rabbitmqv1.RabbitMqConfig `json:"rabbitmq,omitempty"`
112+
98113
// +kubebuilder:validation:Optional
99114
// CustomServiceConfig - customize the service config using this parameter to change service defaults,
100115
// or overwrite rendered information using raw OpenStack config format. The content gets added to
@@ -151,6 +166,9 @@ type HeatStatus struct {
151166
// TransportURLSecret - Secret containing RabbitMQ transportURL
152167
TransportURLSecret string `json:"transportURLSecret,omitempty"`
153168

169+
// NotificationsTransportURLSecret - Secret containing Notifications RabbitMQ transportURL
170+
NotificationsTransportURLSecret string `json:"notificationsTransportURLSecret,omitempty"`
171+
154172
// ReadyCount of Heat API instance
155173
HeatAPIReadyCount int32 `json:"heatApiReadyCount,omitempty"`
156174

@@ -222,6 +240,7 @@ func (instance Heat) StatusConditionsList() condition.Conditions {
222240
condition.UnknownCondition(condition.DBSyncReadyCondition, condition.InitReason, condition.DBSyncReadyInitMessage),
223241
condition.UnknownCondition(condition.MemcachedReadyCondition, condition.InitReason, condition.MemcachedReadyInitMessage),
224242
condition.UnknownCondition(condition.RabbitMqTransportURLReadyCondition, condition.InitReason, condition.RabbitMqTransportURLReadyInitMessage),
243+
condition.UnknownCondition(HeatNotificationBusReadyCondition, condition.InitReason, HeatNotificationBusReadyInitMessage),
225244
condition.UnknownCondition(condition.InputReadyCondition, condition.InitReason, condition.InputReadyInitMessage),
226245
condition.UnknownCondition(condition.ServiceConfigReadyCondition, condition.InitReason, condition.ServiceConfigReadyInitMessage),
227246
condition.UnknownCondition(HeatStackDomainReadyCondition, condition.InitReason, HeatStackDomainReadyInitMessage),

api/v1beta1/heat_webhook.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ package v1beta1
2525
import (
2626
"fmt"
2727

28+
rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1"
2829
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
2930
"github.com/openstack-k8s-operators/lib-common/modules/common/service"
3031
apierrors "k8s.io/apimachinery/pkg/api/errors"
@@ -65,6 +66,7 @@ func (r *Heat) Default() {
6566

6667
// Default - set defaults for this Heat spec
6768
func (spec *HeatSpec) Default() {
69+
spec.HeatSpecBase.Default()
6870
if spec.HeatAPI.ContainerImage == "" {
6971
spec.HeatAPI.ContainerImage = heatDefaults.APIContainerImageURL
7072
}
@@ -76,10 +78,39 @@ func (spec *HeatSpec) Default() {
7678
}
7779
}
7880

81+
// Default - set defaults for this HeatSpecBase
82+
func (spec *HeatSpecBase) Default() {
83+
// Handle legacy RabbitMQ field and populate MessagingBus
84+
if spec.RabbitMQ != nil {
85+
// Copy legacy RabbitMQ config to MessagingBus if it's not set
86+
if spec.MessagingBus.Cluster == "" {
87+
spec.MessagingBus = *spec.RabbitMQ
88+
}
89+
}
90+
91+
// Default MessagingBus with RabbitMqClusterName
92+
rabbitmqv1.DefaultRabbitMqConfig(&spec.MessagingBus, spec.RabbitMqClusterName)
93+
94+
// Default NotificationsBus if it's specified
95+
if spec.NotificationsBus != nil {
96+
// If NotificationsBus doesn't have user/vhost set, inherit from MessagingBus
97+
if spec.NotificationsBus.User == "" {
98+
spec.NotificationsBus.User = spec.MessagingBus.User
99+
}
100+
if spec.NotificationsBus.Vhost == "" {
101+
spec.NotificationsBus.Vhost = spec.MessagingBus.Vhost
102+
}
103+
// Ensure cluster name is set if not already
104+
if spec.NotificationsBus.Cluster != "" {
105+
rabbitmqv1.DefaultRabbitMqConfig(spec.NotificationsBus, spec.NotificationsBus.Cluster)
106+
}
107+
}
108+
}
109+
79110
// Default - set defaults for this Heat spec core. This version is called
80111
// by the OpenStackControlplane
81112
func (spec *HeatSpecCore) Default() {
82-
// nothing here yet
113+
spec.HeatSpecBase.Default()
83114
}
84115

85116
var _ webhook.Validator = &Heat{}
@@ -173,6 +204,13 @@ func (r *Heat) ValidateUpdate(old runtime.Object) (admission.Warnings, error) {
173204
func (r *HeatSpec) ValidateUpdate(old HeatSpec, basePath *field.Path, annotations map[string]string, namespace string) field.ErrorList {
174205
var allErrs field.ErrorList
175206

207+
// Reject changes to deprecated RabbitMqClusterName field - users should use the new messagingBus.cluster field instead
208+
if r.RabbitMqClusterName != old.RabbitMqClusterName {
209+
allErrs = append(allErrs, field.Forbidden(
210+
basePath.Child("rabbitMqClusterName"),
211+
"rabbitMqClusterName is deprecated and cannot be changed. Please use messagingBus.cluster instead"))
212+
}
213+
176214
// Allow users to bypass this validation in cases where they have independently verified
177215
// the validity of their new database to ensure consistency with the current one.
178216
if _, ok := annotations[HeatDatabaseMigrationAnnotation]; !ok {
@@ -203,6 +241,13 @@ func (r *HeatSpec) ValidateUpdate(old HeatSpec, basePath *field.Path, annotation
203241
func (r *HeatSpecCore) ValidateUpdate(old HeatSpecCore, basePath *field.Path, namespace string) field.ErrorList {
204242
var allErrs field.ErrorList
205243

244+
// Reject changes to deprecated RabbitMqClusterName field - users should use the new messagingBus.cluster field instead
245+
if r.RabbitMqClusterName != old.RabbitMqClusterName {
246+
allErrs = append(allErrs, field.Forbidden(
247+
basePath.Child("rabbitMqClusterName"),
248+
"rabbitMqClusterName is deprecated and cannot be changed. Please use messagingBus.cluster instead"))
249+
}
250+
206251
// We currently have no logic in place to perform database migrations. Changing databases
207252
// would render all of the existing stacks unmanageable. We should block changes to the
208253
// databaseInstance to protect existing workloads.

api/v1beta1/zz_generated.deepcopy.go

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

0 commit comments

Comments
 (0)