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
462 changes: 434 additions & 28 deletions api/bases/core.openstack.org_openstackcontrolplanes.yaml

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions api/core/v1beta1/openstackcontrolplane_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,27 @@ type OpenStackControlPlaneSpec struct {
// Rabbitmq - Parameters related to the Rabbitmq service
Rabbitmq RabbitmqSection `json:"rabbitmq,omitempty"`

// +kubebuilder:validation:Optional
// MessagingBus configuration (username, vhost, and cluster) for RPC communication.
// This is the default configuration for all services.
// Individual services can override by setting their own Template.MessagingBus.
MessagingBus *rabbitmqv1.RabbitMqConfig `json:"messagingBus,omitempty"`

// +kubebuilder:validation:Optional
// NotificationsBusInstance - the name of RabbitMQ Cluster CR to select a Messaging
// Bus Service instance used by all services that produce or consume notifications.
// Avoid colocating it with RabbitMQ services used for PRC.
// That instance will be pushed down for services, unless overriden in templates.
// Deprecated: Use NotificationsBus.Cluster instead
NotificationsBusInstance *string `json:"notificationsBusInstance,omitempty"`

// +kubebuilder:validation:Optional
// NotificationsBus configuration (username, vhost, and cluster) for notifications.
// This is the default configuration for all services.
// Individual services can override by setting their own Template.NotificationsBus.
// Avoid colocating with MessagingBus used for RPC.
NotificationsBus *rabbitmqv1.RabbitMqConfig `json:"notificationsBus,omitempty"`

// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec
// Memcached - Parameters related to the Memcached service
Expand Down
251 changes: 225 additions & 26 deletions api/core/v1beta1/openstackcontrolplane_webhook.go

Large diffs are not rendered by default.

124 changes: 124 additions & 0 deletions api/core/v1beta1/openstackcontrolplane_webhook_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package v1beta1

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1"
"k8s.io/apimachinery/pkg/util/validation/field"
)

var _ = Describe("OpenStackControlPlane Webhook", func() {

Context("ValidateMessagingBusConfig", func() {
var instance *OpenStackControlPlane
var basePath *field.Path

BeforeEach(func() {
instance = &OpenStackControlPlane{
Spec: OpenStackControlPlaneSpec{},
}
basePath = field.NewPath("spec")
})

It("should allow only Cluster field in messagingBus", func() {
instance.Spec.MessagingBus = &rabbitmqv1.RabbitMqConfig{
Cluster: "rabbitmq",
}

errs := instance.ValidateMessagingBusConfig(basePath)
Expect(errs).To(BeEmpty())
})

It("should allow Cluster and Vhost fields in messagingBus", func() {
instance.Spec.MessagingBus = &rabbitmqv1.RabbitMqConfig{
Cluster: "rabbitmq",
Vhost: "/openstack",
}

errs := instance.ValidateMessagingBusConfig(basePath)
Expect(errs).To(BeEmpty())
})

It("should reject User field in messagingBus", func() {
instance.Spec.MessagingBus = &rabbitmqv1.RabbitMqConfig{
Cluster: "rabbitmq",
User: "shared-user",
}

errs := instance.ValidateMessagingBusConfig(basePath)
Expect(errs).To(HaveLen(1))
Expect(errs[0].Type).To(Equal(field.ErrorTypeForbidden))
Expect(errs[0].Field).To(Equal("spec.messagingBus.user"))
Expect(errs[0].Detail).To(ContainSubstring("user field is not allowed at the top level"))
})

It("should reject User field even with other valid fields in messagingBus", func() {
instance.Spec.MessagingBus = &rabbitmqv1.RabbitMqConfig{
Cluster: "rabbitmq",
Vhost: "/openstack",
User: "shared-user",
}

errs := instance.ValidateMessagingBusConfig(basePath)
Expect(errs).To(HaveLen(1))
Expect(errs[0].Type).To(Equal(field.ErrorTypeForbidden))
Expect(errs[0].Field).To(Equal("spec.messagingBus.user"))
})

It("should allow only Cluster field in notificationsBus", func() {
instance.Spec.NotificationsBus = &rabbitmqv1.RabbitMqConfig{
Cluster: "rabbitmq-notifications",
}

errs := instance.ValidateMessagingBusConfig(basePath)
Expect(errs).To(BeEmpty())
})

It("should allow Cluster and Vhost fields in notificationsBus", func() {
instance.Spec.NotificationsBus = &rabbitmqv1.RabbitMqConfig{
Cluster: "rabbitmq-notifications",
Vhost: "/notifications",
}

errs := instance.ValidateMessagingBusConfig(basePath)
Expect(errs).To(BeEmpty())
})

It("should reject User field in notificationsBus", func() {
instance.Spec.NotificationsBus = &rabbitmqv1.RabbitMqConfig{
Cluster: "rabbitmq-notifications",
User: "shared-user",
}

errs := instance.ValidateMessagingBusConfig(basePath)
Expect(errs).To(HaveLen(1))
Expect(errs[0].Type).To(Equal(field.ErrorTypeForbidden))
Expect(errs[0].Field).To(Equal("spec.notificationsBus.user"))
Expect(errs[0].Detail).To(ContainSubstring("user field is not allowed at the top level"))
})

It("should reject User field in both messagingBus and notificationsBus", func() {
instance.Spec.MessagingBus = &rabbitmqv1.RabbitMqConfig{
Cluster: "rabbitmq",
User: "rpc-user",
}
instance.Spec.NotificationsBus = &rabbitmqv1.RabbitMqConfig{
Cluster: "rabbitmq-notifications",
User: "notif-user",
}

errs := instance.ValidateMessagingBusConfig(basePath)
Expect(errs).To(HaveLen(2))
Expect(errs[0].Field).To(Equal("spec.messagingBus.user"))
Expect(errs[1].Field).To(Equal("spec.notificationsBus.user"))
})

It("should allow nil messagingBus and notificationsBus", func() {
instance.Spec.MessagingBus = nil
instance.Spec.NotificationsBus = nil

errs := instance.ValidateMessagingBusConfig(basePath)
Expect(errs).To(BeEmpty())
})
})
})
10 changes: 10 additions & 0 deletions api/core/v1beta1/zz_generated.deepcopy.go

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

32 changes: 30 additions & 2 deletions api/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ require (
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260128074606-03b808364e4a
github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20260126092810-cd39d45b6c0e
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260126175636-114b4c65a959
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260126081203-efc2df9207eb
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260128142552-e2c25eccae5a
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260126081203-efc2df9207eb
github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20260124125332-5046d6342e48
github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260127154438-ff95971883bb
Expand Down Expand Up @@ -80,7 +80,7 @@ require (
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/openshift/api v3.9.0+incompatible // indirect
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251230215914-6ba873b49a35 // indirect
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20260126081203-efc2df9207eb // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.22.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
Expand Down Expand Up @@ -143,3 +143,31 @@ replace k8s.io/code-generator => k8s.io/code-generator v0.31.14 //allow-merging
replace k8s.io/component-base => k8s.io/component-base v0.31.14 //allow-merging

replace github.com/cert-manager/cmctl/v2 => github.com/cert-manager/cmctl/v2 v2.1.2-0.20241127223932-88edb96860cf //allow-merging

replace github.com/openstack-k8s-operators/barbican-operator/api => github.com/lmiccini/barbican-operator/api v0.0.0-20260130153748-c0862ee80f6b

replace github.com/openstack-k8s-operators/cinder-operator/api => github.com/lmiccini/cinder-operator/api v0.0.0-20260130153803-4053d7cddf84

replace github.com/openstack-k8s-operators/designate-operator/api => github.com/lmiccini/designate-operator/api v0.0.0-20260129195526-07a2bbdbbbc6

replace github.com/openstack-k8s-operators/glance-operator/api => github.com/lmiccini/glance-operator/api v0.0.0-20260130212835-b5113d4d6c7a

replace github.com/openstack-k8s-operators/heat-operator/api => github.com/lmiccini/heat-operator/api v0.0.0-20260130153836-0162a8fbe588

replace github.com/openstack-k8s-operators/ironic-operator/api => github.com/lmiccini/ironic-operator/api v0.0.0-20260131142856-7901596a1d2d

replace github.com/openstack-k8s-operators/keystone-operator/api => github.com/lmiccini/keystone-operator/api v0.0.0-20260130154009-73911b575f47

replace github.com/openstack-k8s-operators/manila-operator/api => github.com/lmiccini/manila-operator/api v0.0.0-20260130154445-952d437ac6ed

replace github.com/openstack-k8s-operators/neutron-operator/api => github.com/lmiccini/neutron-operator/api v0.0.0-20260130154215-206cdc241686

replace github.com/openstack-k8s-operators/nova-operator/api => github.com/lmiccini/nova-operator/api v0.0.0-20260130154456-145dc1dc3e11

replace github.com/openstack-k8s-operators/octavia-operator/api => github.com/lmiccini/octavia-operator/api v0.0.0-20260131142608-b5b99abd4e39

replace github.com/openstack-k8s-operators/swift-operator/api => github.com/lmiccini/swift-operator/api v0.0.0-20260131142507-37af5d9a247d

replace github.com/openstack-k8s-operators/telemetry-operator/api => github.com/lmiccini/telemetry-operator/api v0.0.0-20260131062257-ce08c2f17769

replace github.com/openstack-k8s-operators/watcher-operator/api => github.com/lmiccini/watcher-operator/api v0.0.0-20260130155151-6da48495bd84
Loading
Loading