Skip to content

Commit e03f2d6

Browse files
committed
DNM draft implementation of common notifications
Signed-off-by: Bohdan Dobrelia <bdobreli@redhat.com>
1 parent 0ba95b9 commit e03f2d6

7 files changed

Lines changed: 110 additions & 3 deletions

File tree

apis/bases/core.openstack.org_openstackcontrolplanes.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9980,6 +9980,8 @@ spec:
99809980
additionalProperties:
99819981
type: string
99829982
type: object
9983+
notificationsBusInstance:
9984+
type: string
99839985
passwordSelectors:
99849986
default:
99859987
service: NovaPassword

config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9980,6 +9980,8 @@ spec:
99809980
additionalProperties:
99819981
type: string
99829982
type: object
9983+
notificationsBusInstance:
9984+
type: string
99839985
passwordSelectors:
99849986
default:
99859987
service: NovaPassword

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,5 @@ replace github.com/openshift/api => github.com/openshift/api v0.0.0-202408300231
127127

128128
// custom RabbitmqClusterSpecCore for OpenStackControlplane (v2.9.0_patches_tag)
129129
replace github.com/rabbitmq/cluster-operator/v2 => github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20241017142550-a3524acedd49 //allow-merging
130+
131+
replace github.com/openstack-k8s-operators/nova-operator/api => ../nova-operator/api

go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,6 @@ github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20250415060817-
134134
github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20250415060817-dc849adfa27e/go.mod h1:ZgHSxZSgpgHg1FhKPnBm/cqxAJbVFbKiBkqQoRohn3Q=
135135
github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20250422103409-9ddf83d0f545 h1:m+0pOigO5fx+AynqTxd28XnXwDLYlCx87Elc1Hw7EI0=
136136
github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20250422103409-9ddf83d0f545/go.mod h1:v1HVsDjShu8h/jh/Ql35N0H6icGxfqOtoTJD6+SeWnM=
137-
github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20250422095814-99e0f2e04f20 h1:cmou6VfxDe5RE66ZrmwGzozD5TCYkHLCI+PTKf9QiOI=
138-
github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20250422095814-99e0f2e04f20/go.mod h1:TV2Q8RsQUj4rFCGJezrSM1MRybPw3zBqdWtBzkuF5WI=
139137
github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20250422141120-3b3a002bcbd6 h1:yhyspgVZ2DiGL4bzHSQepk9OUyk7HDhxKxrHdTBgzns=
140138
github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20250422141120-3b3a002bcbd6/go.mod h1:5p6SbWrnXSKs8sG4plfdXuJ1fGxKQP/kPwBYT5iZbuY=
141139
github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.6.1-0.20250422102839-2ae63e63226d h1:x0nZgS+DNtxmdM5BDfjd4oTJbKu8+dON2iqLIYMY3yI=

pkg/openstack/nova.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,25 @@ func ReconcileNova(ctx context.Context, instance *corev1beta1.OpenStackControlPl
8080
instance.Spec.Nova.Template.TopologyRef = instance.Spec.TopologyRef
8181
}
8282

83+
// When there's no NotificationsBusInstance referenced in the Service Template,
84+
// inject the top-level one. Allow overriding notifications bus instance locally
85+
// in the services templates, unless it is "" top scope, which always wins.
86+
87+
// TODO(bogdando): extend this to other services as they start supporting this interface
88+
// TODO(bogdando): add webhook validation of the nova's value as an emitter should be matching the consumer's (ceiloneter) value
89+
if instance.Spec.NotificationsBus.RabbitMqClusterName != nil {
90+
if instance.Spec.Nova.Template.NotificationsBusInstance == nil {
91+
instance.Spec.Nova.Template.NotificationsBusInstance = instance.Spec.NotificationsBus.RabbitMqClusterName
92+
}
93+
if *instance.Spec.NotificationsBus.RabbitMqClusterName == "" {
94+
// NOTE(bogdando): a special handling that should forcefully disable notifications for all services.
95+
// We do not do that centrally from this place, but we expect that from the services controllers.
96+
Log.Info("Requested to disable notifications for Nova", "Nova.Namespace",
97+
instance.Namespace, "Nova.Name", nova.Name)
98+
instance.Spec.Nova.Template.NotificationsBusInstance = ptr.To("")
99+
}
100+
}
101+
83102
// When component services got created check if there is the need to create routes and certificates
84103
if err := helper.GetClient().Get(ctx, types.NamespacedName{Name: "nova", Namespace: instance.Namespace}, nova); err != nil {
85104
if !k8s_errors.IsNotFound(err) {

tests/functional/ctlplane/base_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525

2626
k8s_corev1 "k8s.io/api/core/v1"
2727
"k8s.io/apimachinery/pkg/types"
28+
"k8s.io/utils/ptr"
2829
"sigs.k8s.io/controller-runtime/pkg/client"
2930

3031
cinderv1 "github.com/openstack-k8s-operators/cinder-operator/api/v1beta1"
@@ -57,6 +58,7 @@ type Names struct {
5758
HorizonName types.NamespacedName
5859
HeatName types.NamespacedName
5960
TelemetryName types.NamespacedName
61+
NovaName types.NamespacedName
6062
DBName types.NamespacedName
6163
DBCertName types.NamespacedName
6264
DBCell1Name types.NamespacedName
@@ -65,6 +67,7 @@ type Names struct {
6567
RabbitMQCertName types.NamespacedName
6668
RabbitMQCell1Name types.NamespacedName
6769
RabbitMQCell1CertName types.NamespacedName
70+
RabbitMQNotificationsName types.NamespacedName
6871
ServiceAccountName types.NamespacedName
6972
RoleName types.NamespacedName
7073
RoleBindingName types.NamespacedName
@@ -168,6 +171,10 @@ func CreateNames(openstackControlplaneName types.NamespacedName) Names {
168171
Namespace: openstackControlplaneName.Namespace,
169172
Name: "telemetry",
170173
},
174+
NovaName: types.NamespacedName{
175+
Namespace: openstackControlplaneName.Namespace,
176+
Name: "nova",
177+
},
171178
DBName: types.NamespacedName{
172179
Namespace: openstackControlplaneName.Namespace,
173180
Name: "openstack",
@@ -196,6 +203,10 @@ func CreateNames(openstackControlplaneName types.NamespacedName) Names {
196203
Namespace: openstackControlplaneName.Namespace,
197204
Name: "rabbitmq-cell1",
198205
},
206+
RabbitMQNotificationsName: types.NamespacedName{
207+
Namespace: openstackControlplaneName.Namespace,
208+
Name: "rabbitmq-notifications",
209+
},
199210
RabbitMQCell1CertName: types.NamespacedName{
200211
Namespace: openstackControlplaneName.Namespace,
201212
Name: "cert-rabbitmq-cell1-svc",
@@ -484,6 +495,9 @@ func GetDefaultOpenStackControlPlaneSpec() map[string]interface{} {
484495
names.RabbitMQCell1Name.Name: map[string]interface{}{
485496
"replicas": 1,
486497
},
498+
names.RabbitMQNotificationsName.Name: map[string]interface{}{
499+
"replicas": 1,
500+
},
487501
}
488502
galeraTemplate := map[string]interface{}{
489503
names.DBName.Name: map[string]interface{}{
@@ -525,6 +539,9 @@ func GetDefaultOpenStackControlPlaneSpec() map[string]interface{} {
525539
return map[string]interface{}{
526540
"secret": "osp-secret",
527541
"storageClass": "local-storage",
542+
"notificationsBus": map[string]interface{}{
543+
"rabbitMqClusterName": ptr.To("rabbitmq-notifications"),
544+
},
528545
"galera": map[string]interface{}{
529546
"enabled": true,
530547
"templates": galeraTemplate,

tests/functional/ctlplane/openstackoperator_controller_test.go

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1807,6 +1807,73 @@ var _ = Describe("OpenStackOperator controller", func() {
18071807
})
18081808
})
18091809

1810+
When("A OpenStackControlplane instance is created with top-scope notifications config pushed down", func() {
1811+
BeforeEach(func() {
1812+
spec := GetDefaultOpenStackControlPlaneSpec()
1813+
spec["tls"] = GetTLSPublicSpec()
1814+
spec["nova"] = map[string]interface{}{
1815+
"enabled": false,
1816+
"template": map[string]interface{}{},
1817+
}
1818+
DeferCleanup(
1819+
th.DeleteInstance,
1820+
CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec),
1821+
)
1822+
})
1823+
1824+
It("should have Nova notifications bus instance configured by inheritance", func() {
1825+
OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName)
1826+
Expect(OSCtlplane.Spec.Nova.Template).Should(HaveKeyWithValue("notificationsBusInstance", "rabbitmq-notifications"))
1827+
})
1828+
})
1829+
1830+
When("A OpenStackControlplane instance is created with notifications config override", func() {
1831+
BeforeEach(func() {
1832+
spec := GetDefaultOpenStackControlPlaneSpec()
1833+
spec["tls"] = GetTLSPublicSpec()
1834+
spec["nova"] = map[string]interface{}{
1835+
"enabled": false,
1836+
"template": map[string]interface{}{
1837+
"notificationsBusInstance": ptr.To("rabbitmq-custom"),
1838+
},
1839+
}
1840+
DeferCleanup(
1841+
th.DeleteInstance,
1842+
CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec),
1843+
)
1844+
})
1845+
1846+
It("should have Nova notifications bus instance configured from local templates", func() {
1847+
OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName)
1848+
Expect(OSCtlplane.Spec.Nova.Template).Should(HaveKeyWithValue("notificationsBusInstance", "rabbitmq-custom"))
1849+
})
1850+
})
1851+
1852+
When("A OpenStackControlplane instance is created with notifications config force-disabled", func() {
1853+
BeforeEach(func() {
1854+
spec := GetDefaultOpenStackControlPlaneSpec()
1855+
spec["tls"] = GetTLSPublicSpec()
1856+
spec["notificationsBus"] = map[string]interface{}{
1857+
"rabbitMqClusterName": ptr.To(""),
1858+
}
1859+
spec["nova"] = map[string]interface{}{
1860+
"enabled": false,
1861+
"template": map[string]interface{}{
1862+
"notificationsBusInstance": ptr.To("rabbitmq-maybe"),
1863+
},
1864+
}
1865+
DeferCleanup(
1866+
th.DeleteInstance,
1867+
CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec),
1868+
)
1869+
})
1870+
1871+
It("should have Nova enabled and its notifications bus instance configured for a special empty value", func() {
1872+
OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName)
1873+
Expect(OSCtlplane.Spec.Nova.Template).Should(HaveKeyWithValue("notificationsBusInstance", ""))
1874+
})
1875+
})
1876+
18101877
When("OpenStackControlplane instance is deleted", func() {
18111878
BeforeEach(func() {
18121879
DeferCleanup(
@@ -3064,7 +3131,7 @@ var _ = Describe("OpenStackOperator controller galera and rabbitmq", func() {
30643131
Eventually(func(g Gomega) {
30653132
OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName)
30663133
rabbitTemplates := *(OSCtlplane.Spec.Rabbitmq.Templates)
3067-
g.Expect(rabbitTemplates).Should(HaveLen(2))
3134+
g.Expect(rabbitTemplates).Should(HaveLen(3))
30683135
delete(rabbitTemplates, names.RabbitMQCell1Name.Name)
30693136
OSCtlplane.Spec.Rabbitmq.Templates = &rabbitTemplates
30703137
g.Expect(k8sClient.Update(ctx, OSCtlplane)).Should(Succeed())

0 commit comments

Comments
 (0)