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
55 changes: 55 additions & 0 deletions api/bases/heat.openstack.org_heats.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1959,12 +1959,45 @@ spec:
default: memcached
description: Memcached instance name.
type: string
messagingBus:
description: MessagingBus - Messaging Bus configuration
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
description: NodeSelector to target subset of worker nodes for running
the Heat services
type: object
notificationsBus:
description: NotificationsBus - Notifications Bus configuration (optional,
separate from MessagingBus)
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
passwordSelectors:
default:
authEncryptionKey: HeatAuthEncryptionKey
Expand Down Expand Up @@ -1999,6 +2032,24 @@ spec:
RabbitMQ instance name
Needed to request a transportURL that is created and used in Heat
type: string
rabbitmq:
description: |-
RabbitMQ - RabbitMQ configuration overrides
Deprecated: Use MessagingBus instead
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
secret:
description: |-
Secret containing OpenStack password information for heat HeatDatabasePassword, HeatPassword
Expand Down Expand Up @@ -2100,6 +2151,10 @@ spec:
description: ReadyCount of Heat Engine instance
format: int32
type: integer
notificationsTransportURLSecret:
description: NotificationsTransportURLSecret - Secret containing Notifications
RabbitMQ transportURL
type: string
observedGeneration:
description: |-
ObservedGeneration - the most recent generation observed for this
Expand Down
2 changes: 1 addition & 1 deletion api/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,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 Down Expand Up @@ -45,6 +44,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
18 changes: 18 additions & 0 deletions api/v1beta1/conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ const (

// HeatStackDomainReadyCondition ...
HeatStackDomainReadyCondition condition.Type = "HeatStackDomainReady"

// HeatNotificationBusReadyCondition ...
HeatNotificationBusReadyCondition condition.Type = "HeatNotificationBusReady"
)

// Common Messages used by API objects.
Expand Down Expand Up @@ -76,4 +79,19 @@ const (

// HeatStackDomainReadyErrorMessage
HeatStackDomainReadyErrorMessage = "HeatStackDomain error occured %s"

//
// HeatNotificationBusReady condition messages
//
// HeatNotificationBusReadyInitMessage
HeatNotificationBusReadyInitMessage = "HeatNotificationBus not started"

// HeatNotificationBusReadyRunningMessage
HeatNotificationBusReadyRunningMessage = "HeatNotificationBus creation in progress"

// HeatNotificationBusReadyMessage
HeatNotificationBusReadyMessage = "HeatNotificationBus successfully created"

// HeatNotificationBusReadyErrorMessage
HeatNotificationBusReadyErrorMessage = "HeatNotificationBus error occured %s"
)
19 changes: 19 additions & 0 deletions api/v1beta1/heat_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/common/util"
Expand All @@ -41,6 +42,7 @@ const (
HeatDatabaseMigrationAnnotation = "heat.openstack.org/database-migration"
)


// HeatSpec defines the desired state of Heat
type HeatSpec struct {
HeatSpecBase `json:",inline"`
Expand Down Expand Up @@ -95,6 +97,19 @@ type HeatSpecBase struct {
// Needed to request a transportURL that is created and used in Heat
RabbitMqClusterName string `json:"rabbitMqClusterName"`

// +kubebuilder:validation:Optional
// MessagingBus - Messaging Bus configuration
MessagingBus rabbitmqv1.RabbitMqConfig `json:"messagingBus,omitempty"`

// +kubebuilder:validation:Optional
// NotificationsBus - Notifications Bus configuration (optional, separate from MessagingBus)
NotificationsBus *rabbitmqv1.RabbitMqConfig `json:"notificationsBus,omitempty"`

// +kubebuilder:validation:Optional
// RabbitMQ - RabbitMQ configuration overrides
// Deprecated: Use MessagingBus instead
RabbitMQ *rabbitmqv1.RabbitMqConfig `json:"rabbitmq,omitempty"`

// +kubebuilder:validation:Optional
// CustomServiceConfig - customize the service config using this parameter to change service defaults,
// or overwrite rendered information using raw OpenStack config format. The content gets added to
Expand Down Expand Up @@ -151,6 +166,9 @@ type HeatStatus struct {
// TransportURLSecret - Secret containing RabbitMQ transportURL
TransportURLSecret string `json:"transportURLSecret,omitempty"`

// NotificationsTransportURLSecret - Secret containing Notifications RabbitMQ transportURL
NotificationsTransportURLSecret string `json:"notificationsTransportURLSecret,omitempty"`

// ReadyCount of Heat API instance
HeatAPIReadyCount int32 `json:"heatApiReadyCount,omitempty"`

Expand Down Expand Up @@ -222,6 +240,7 @@ func (instance Heat) StatusConditionsList() condition.Conditions {
condition.UnknownCondition(condition.DBSyncReadyCondition, condition.InitReason, condition.DBSyncReadyInitMessage),
condition.UnknownCondition(condition.MemcachedReadyCondition, condition.InitReason, condition.MemcachedReadyInitMessage),
condition.UnknownCondition(condition.RabbitMqTransportURLReadyCondition, condition.InitReason, condition.RabbitMqTransportURLReadyInitMessage),
condition.UnknownCondition(HeatNotificationBusReadyCondition, condition.InitReason, HeatNotificationBusReadyInitMessage),
condition.UnknownCondition(condition.InputReadyCondition, condition.InitReason, condition.InputReadyInitMessage),
condition.UnknownCondition(condition.ServiceConfigReadyCondition, condition.InitReason, condition.ServiceConfigReadyInitMessage),
condition.UnknownCondition(HeatStackDomainReadyCondition, condition.InitReason, HeatStackDomainReadyInitMessage),
Expand Down
68 changes: 67 additions & 1 deletion api/v1beta1/heat_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ package v1beta1
import (
"fmt"

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"
apierrors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -65,6 +66,7 @@ func (r *Heat) Default() {

// Default - set defaults for this Heat spec
func (spec *HeatSpec) Default() {
spec.HeatSpecBase.Default()
if spec.HeatAPI.ContainerImage == "" {
spec.HeatAPI.ContainerImage = heatDefaults.APIContainerImageURL
}
Expand All @@ -76,10 +78,34 @@ func (spec *HeatSpec) Default() {
}
}

// Default - set defaults for this HeatSpecBase
func (spec *HeatSpecBase) Default() {
// Handle legacy RabbitMQ field and populate MessagingBus
if spec.RabbitMQ != nil {
// Copy legacy RabbitMQ config to MessagingBus if it's not set
if spec.MessagingBus.Cluster == "" {
spec.MessagingBus = *spec.RabbitMQ
}
}

// Default MessagingBus with RabbitMqClusterName
rabbitmqv1.DefaultRabbitMqConfig(&spec.MessagingBus, spec.RabbitMqClusterName)

// Default NotificationsBus if it's specified
// Note: user/vhost are NOT inherited from MessagingBus to ensure separation
// (RPC and notifications should never share credentials)
if spec.NotificationsBus != nil {
// Ensure cluster name is set if not already
if spec.NotificationsBus.Cluster != "" {
rabbitmqv1.DefaultRabbitMqConfig(spec.NotificationsBus, spec.NotificationsBus.Cluster)
}
}
}

// Default - set defaults for this Heat spec core. This version is called
// by the OpenStackControlplane
func (spec *HeatSpecCore) Default() {
// nothing here yet
spec.HeatSpecBase.Default()
}

var _ webhook.Validator = &Heat{}
Expand Down Expand Up @@ -173,6 +199,26 @@ func (r *Heat) ValidateUpdate(old runtime.Object) (admission.Warnings, error) {
func (r *HeatSpec) ValidateUpdate(old HeatSpec, basePath *field.Path, annotations map[string]string, namespace string) field.ErrorList {
var allErrs field.ErrorList

// Validate deprecated fields and their new equivalents
// Don't allow setting both old and new fields with different values
// Users can either set both to the same value, or null out the old field and set the new one
if r.RabbitMqClusterName != "" && r.MessagingBus.Cluster != "" &&
r.RabbitMqClusterName != r.MessagingBus.Cluster {
allErrs = append(allErrs, field.Invalid(
basePath.Child("messagingBus").Child("cluster"),
r.MessagingBus.Cluster,
fmt.Sprintf("messagingBus.cluster cannot differ from deprecated rabbitMqClusterName (%s). "+
"Either use the new messagingBus.cluster field or the deprecated rabbitMqClusterName, but not both with different values",
r.RabbitMqClusterName)))
}

// Reject changes to deprecated field unless nulling it out
if r.RabbitMqClusterName != old.RabbitMqClusterName && r.RabbitMqClusterName != "" {
allErrs = append(allErrs, field.Forbidden(
basePath.Child("rabbitMqClusterName"),
"rabbitMqClusterName is deprecated and cannot be changed. Please use messagingBus.cluster instead"))
}

// Allow users to bypass this validation in cases where they have independently verified
// the validity of their new database to ensure consistency with the current one.
if _, ok := annotations[HeatDatabaseMigrationAnnotation]; !ok {
Expand Down Expand Up @@ -203,6 +249,26 @@ func (r *HeatSpec) ValidateUpdate(old HeatSpec, basePath *field.Path, annotation
func (r *HeatSpecCore) ValidateUpdate(old HeatSpecCore, basePath *field.Path, namespace string) field.ErrorList {
var allErrs field.ErrorList

// Validate deprecated fields and their new equivalents
// Don't allow setting both old and new fields with different values
// Users can either set both to the same value, or null out the old field and set the new one
if r.RabbitMqClusterName != "" && r.MessagingBus.Cluster != "" &&
r.RabbitMqClusterName != r.MessagingBus.Cluster {
allErrs = append(allErrs, field.Invalid(
basePath.Child("messagingBus").Child("cluster"),
r.MessagingBus.Cluster,
fmt.Sprintf("messagingBus.cluster cannot differ from deprecated rabbitMqClusterName (%s). "+
"Either use the new messagingBus.cluster field or the deprecated rabbitMqClusterName, but not both with different values",
r.RabbitMqClusterName)))
}

// Reject changes to deprecated field unless nulling it out
if r.RabbitMqClusterName != old.RabbitMqClusterName && r.RabbitMqClusterName != "" {
allErrs = append(allErrs, field.Forbidden(
basePath.Child("rabbitMqClusterName"),
"rabbitMqClusterName is deprecated and cannot be changed. Please use messagingBus.cluster instead"))
}

// We currently have no logic in place to perform database migrations. Changing databases
// would render all of the existing stacks unmanageable. We should block changes to the
// databaseInstance to protect existing workloads.
Expand Down
12 changes: 12 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.

Loading