Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions api/bases/cinder.openstack.org_cinders.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2024,6 +2024,22 @@ spec:
default: memcached
description: Memcached instance name.
type: string
messagingBus:
description: MessagingBus configuration (username, vhost, and cluster)
properties:
cluster:
description: Name of the cluster
minLength: 1
type: string
user:
description: User - RabbitMQ username
type: string
vhost:
description: Vhost - RabbitMQ vhost name
type: string
required:
- cluster
type: object
nodeSelector:
additionalProperties:
type: string
Expand All @@ -2032,6 +2048,23 @@ spec:
NodeSelector here acts as a default value and can be overridden by service
specific NodeSelector Settings.
type: object
notificationsBus:
description: NotificationsBus configuration (username, vhost, and
cluster) for notifications
properties:
cluster:
description: Name of the cluster
minLength: 1
type: string
user:
description: User - RabbitMQ username
type: string
vhost:
description: Vhost - RabbitMQ vhost name
type: string
required:
- cluster
type: object
notificationsBusInstance:
description: |-
RabbitMQ instance name used to request a transportURL that is used for
Expand Down
2 changes: 1 addition & 1 deletion api/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
github.com/evanphx/json-patch v5.9.11+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
Expand All @@ -44,6 +43,7 @@ require (
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.65.0 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/rabbitmq/cluster-operator/v2 v2.16.0 // indirect
github.com/spf13/pflag v1.0.7 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
Expand Down
3 changes: 3 additions & 0 deletions api/go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
Expand Down Expand Up @@ -84,6 +85,8 @@ github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.2025123021
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251230215914-6ba873b49a35/go.mod h1:kycZyoe7OZdW1HUghr2nI3N7wSJtNahXf6b/ypD14f4=
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251230215914-6ba873b49a35 h1:8WZYfCt1VJHa5sJRX0UhpmoXud/fn8LHQhXsakdYXuQ=
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251230215914-6ba873b49a35/go.mod h1:H0aQANk8iJPRhS2Bg9n6cYb/IHF0Cks9g7+uZG04Rhk=
github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250929174222-a0d328fa4dec h1:saovr368HPAKHN0aRPh8h8n9s9dn3d8Frmfua0UYRlc=
github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250929174222-a0d328fa4dec/go.mod h1:Nh2NEePLjovUQof2krTAg4JaAoLacqtPTZQXK6izNfg=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand Down
9 changes: 9 additions & 0 deletions api/v1beta1/cinder_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1beta1

import (
rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1"
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
"github.com/openstack-k8s-operators/lib-common/modules/storage"
Expand Down Expand Up @@ -70,6 +71,14 @@ type CinderSpecBase struct {
// Needed to request a transportURL that is created and used in Cinder
RabbitMqClusterName string `json:"rabbitMqClusterName"`

// +kubebuilder:validation:Optional
// MessagingBus configuration (username, vhost, and cluster)
MessagingBus rabbitmqv1.RabbitMqConfig `json:"messagingBus,omitempty"`

// +kubebuilder:validation:Optional
// NotificationsBus configuration (username, vhost, and cluster) for notifications
NotificationsBus *rabbitmqv1.RabbitMqConfig `json:"notificationsBus,omitempty"`

// +kubebuilder:validation:Required
// +kubebuilder:default=memcached
// Memcached instance name.
Expand Down
45 changes: 45 additions & 0 deletions api/v1beta1/cinder_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (

"golang.org/x/exp/maps"

rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1"
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
"github.com/openstack-k8s-operators/lib-common/modules/common/service"
"github.com/openstack-k8s-operators/lib-common/modules/common/util"
Expand Down Expand Up @@ -111,6 +112,20 @@ func (r *Cinder) Default() {

// Default - set defaults for this Cinder spec
func (spec *CinderSpecBase) Default() {
rabbitmqv1.DefaultRabbitMqConfig(&spec.MessagingBus, spec.RabbitMqClusterName)

// Default NotificationsBus if NotificationsBusInstance is specified
if spec.NotificationsBusInstance != nil && *spec.NotificationsBusInstance != "" {
if spec.NotificationsBus == nil {
// Initialize empty NotificationsBus - credentials will be created dynamically
// to ensure separation from MessagingBus (RPC and notifications should never share credentials)
spec.NotificationsBus = &rabbitmqv1.RabbitMqConfig{}
}
// Always default the Cluster field from NotificationsBusInstance if it's empty
if spec.NotificationsBus.Cluster == "" {
rabbitmqv1.DefaultRabbitMqConfig(spec.NotificationsBus, *spec.NotificationsBusInstance)
}
}

if spec.DBPurge.Age == 0 {
spec.DBPurge.Age = cinderDefaults.DBPurgeAge
Expand Down Expand Up @@ -275,6 +290,21 @@ func (spec *CinderSpec) ValidateUpdate(
var allErrs field.ErrorList
var allWarns []string

// Reject changes to deprecated RabbitMqClusterName field - users should use the new messagingBus.cluster field instead
if spec.RabbitMqClusterName != old.RabbitMqClusterName {
allErrs = append(allErrs, field.Forbidden(
basePath.Child("rabbitMqClusterName"),
"rabbitMqClusterName is deprecated and cannot be changed. Please use messagingBus.cluster instead"))
}

// Reject changes to deprecated NotificationsBusInstance field
if spec.NotificationsBusInstance != nil && old.NotificationsBusInstance != nil &&
*spec.NotificationsBusInstance != *old.NotificationsBusInstance {
allErrs = append(allErrs, field.Forbidden(
basePath.Child("notificationsBusInstance"),
"notificationsBusInstance is deprecated and cannot be changed. Please use notificationsBus.cluster instead"))
}

// validate the service override key is valid
allErrs = append(allErrs, service.ValidateRoutedOverrides(
basePath.Child("cinderAPI").Child("override").Child("service"),
Expand All @@ -301,6 +331,21 @@ func (spec *CinderSpecCore) ValidateUpdate(
var allErrs field.ErrorList
var allWarns []string

// Reject changes to deprecated RabbitMqClusterName field - users should use the new messagingBus.cluster field instead
if spec.RabbitMqClusterName != old.RabbitMqClusterName {
allErrs = append(allErrs, field.Forbidden(
basePath.Child("rabbitMqClusterName"),
"rabbitMqClusterName is deprecated and cannot be changed. Please use messagingBus.cluster instead"))
}

// Reject changes to deprecated NotificationsBusInstance field
if spec.NotificationsBusInstance != nil && old.NotificationsBusInstance != nil &&
*spec.NotificationsBusInstance != *old.NotificationsBusInstance {
allErrs = append(allErrs, field.Forbidden(
basePath.Child("notificationsBusInstance"),
"notificationsBusInstance is deprecated and cannot be changed. Please use notificationsBus.cluster instead"))
}

// validate the service override key is valid
allErrs = append(allErrs, service.ValidateRoutedOverrides(
basePath.Child("cinderAPI").Child("override").Child("service"),
Expand Down
18 changes: 18 additions & 0 deletions api/v1beta1/conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ const (

// CinderVolumeReadyCondition Status=True condition which indicates if the CinderVolume is configured and operational
CinderVolumeReadyCondition condition.Type = "CinderVolumeReady"

// CinderNotificationBusReadyCondition Status=True condition which indicates if the NotificationBus is configured
CinderNotificationBusReadyCondition condition.Type = "CinderNotificationBusReady"
)

// Cinder Reasons used by API objects.
Expand Down Expand Up @@ -77,4 +80,19 @@ const (

// CinderVolumeReadyRunningMessage
CinderVolumeReadyRunningMessage = "CinderVolume deployments in progress"

//
// CinderNotificationBusReady condition messages
//
// CinderNotificationBusReadyInitMessage
CinderNotificationBusReadyInitMessage = "CinderNotificationBus not started"

// CinderNotificationBusReadyRunningMessage
CinderNotificationBusReadyRunningMessage = "CinderNotificationBus creation in progress"

// CinderNotificationBusReadyMessage
CinderNotificationBusReadyMessage = "CinderNotificationBus successfully created"

// CinderNotificationBusReadyErrorMessage
CinderNotificationBusReadyErrorMessage = "CinderNotificationBus error occured %s"
)
7 changes: 7 additions & 0 deletions api/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions config/crd/bases/cinder.openstack.org_cinders.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2024,6 +2024,22 @@ spec:
default: memcached
description: Memcached instance name.
type: string
messagingBus:
description: MessagingBus configuration (username, vhost, and cluster)
properties:
cluster:
description: Name of the cluster
minLength: 1
type: string
user:
description: User - RabbitMQ username
type: string
vhost:
description: Vhost - RabbitMQ vhost name
type: string
required:
- cluster
type: object
nodeSelector:
additionalProperties:
type: string
Expand All @@ -2032,6 +2048,23 @@ spec:
NodeSelector here acts as a default value and can be overridden by service
specific NodeSelector Settings.
type: object
notificationsBus:
description: NotificationsBus configuration (username, vhost, and
cluster) for notifications
properties:
cluster:
description: Name of the cluster
minLength: 1
type: string
user:
description: User - RabbitMQ username
type: string
vhost:
description: Vhost - RabbitMQ vhost name
type: string
required:
- cluster
type: object
notificationsBusInstance:
description: |-
RabbitMQ instance name used to request a transportURL that is used for
Expand Down
41 changes: 26 additions & 15 deletions internal/controller/cinder_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ func (r *CinderReconciler) reconcileNormal(ctx context.Context, instance *cinder
// create RabbitMQ transportURL CR and get the actual URL from the associated secret that is created
//

transportURL, op, err := r.transportURLCreateOrUpdate(ctx, instance, serviceLabels, "")
transportURL, op, err := r.transportURLCreateOrUpdate(ctx, instance, serviceLabels, "", instance.Spec.MessagingBus)
if err != nil {
instance.Status.Conditions.Set(condition.FalseCondition(
condition.RabbitMqTransportURLReadyCondition,
Expand Down Expand Up @@ -561,19 +561,26 @@ func (r *CinderReconciler) reconcileNormal(ctx context.Context, instance *cinder
// associated secret that is created
//

// Request TransportURL when the parameter is provided in the CR
// and it does not match with the existing RabbitMqClusterName
if instance.Spec.NotificationsBusInstance != nil {
// init .Status.NotificationURLSecret
instance.Status.NotificationsURLSecret = ptr.To("")

// Determine if notifications are enabled by checking NotificationsBus.Cluster
// (the webhook defaults this from the deprecated NotificationsBusInstance field)
var notificationBusName string
notificationsEnabled := instance.Spec.NotificationsBus != nil && instance.Spec.NotificationsBus.Cluster != ""
if notificationsEnabled {
// setting notificationBusName to an empty string ensures that we do not
// request a new transportURL unless the two spec fields do not match
var notificationBusName string
if *instance.Spec.NotificationsBusInstance != instance.Spec.RabbitMqClusterName {
notificationBusName = *instance.Spec.NotificationsBusInstance
if instance.Spec.NotificationsBus.Cluster != instance.Spec.RabbitMqClusterName {
notificationBusName = instance.Spec.NotificationsBus.Cluster
}
notificationBusInstanceURL, op, err := r.transportURLCreateOrUpdate(ctx, instance, serviceLabels, notificationBusName)
}

// Request TransportURL when notifications are enabled
if notificationsEnabled {
// init .Status.NotificationURLSecret
instance.Status.NotificationsURLSecret = ptr.To("")

// Use NotificationsBus config (never fall back to MessagingBus to ensure separation)
notificationsRabbitMqConfig := *instance.Spec.NotificationsBus
notificationBusInstanceURL, op, err := r.transportURLCreateOrUpdate(ctx, instance, serviceLabels, notificationBusName, notificationsRabbitMqConfig)
if err != nil {
instance.Status.Conditions.Set(condition.FalseCondition(
condition.NotificationBusInstanceReadyCondition,
Expand Down Expand Up @@ -603,7 +610,7 @@ func (r *CinderReconciler) reconcileNormal(ctx context.Context, instance *cinder
instance.Status.Conditions.MarkTrue(condition.NotificationBusInstanceReadyCondition, condition.NotificationBusInstanceReadyMessage)
} else {
// make sure we do not have an entry in the status if
// .Spec.NotificationsURLSecret is not provided
// notifications are not enabled
instance.Status.NotificationsURLSecret = nil
}

Expand Down Expand Up @@ -1192,6 +1199,7 @@ func (r *CinderReconciler) transportURLCreateOrUpdate(
instance *cinderv1beta1.Cinder,
serviceLabels map[string]string,
rabbitMqClusterName string,
rabbitMqConfig rabbitmqv1.RabbitMqConfig,
) (*rabbitmqv1.TransportURL, controllerutil.OperationResult, error) {

// Default values used for regular messagingBus transportURL and explicitly
Expand All @@ -1215,9 +1223,12 @@ func (r *CinderReconciler) transportURLCreateOrUpdate(

op, err := controllerutil.CreateOrUpdate(ctx, r.Client, transportURL, func() error {
transportURL.Spec.RabbitmqClusterName = transportURLName

err := controllerutil.SetControllerReference(instance, transportURL, r.Scheme)
return err
if rabbitMqConfig.User != "" {
transportURL.Spec.Username = rabbitMqConfig.User
}
// Always set Vhost - empty string means use default "/" vhost
transportURL.Spec.Vhost = rabbitMqConfig.Vhost
return controllerutil.SetControllerReference(instance, transportURL, r.Scheme)
})

return transportURL, op, err
Expand Down
Loading