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
17 changes: 17 additions & 0 deletions api/bases/keystone.openstack.org_keystoneapis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1280,6 +1280,23 @@ spec:
description: NodeSelector to target subset of worker nodes running
this service
type: object
notificationsBus:
description: NotificationsBus 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
override:
description: Override, provides the ability to override the generated
manifest of several child resources.
Expand Down
7 changes: 5 additions & 2 deletions api/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/google/uuid v1.6.0
github.com/gophercloud/gophercloud/v2 v2.8.0
github.com/onsi/gomega v1.38.2
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251205192058-5cfbada0ab96
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251217131115-0f117a938d4e
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251122131503-b76943960b6c
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251122131503-b76943960b6c
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251122131503-b76943960b6c
Expand All @@ -24,7 +24,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 @@ -51,6 +50,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 Expand Up @@ -96,4 +96,7 @@ 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

// custom RabbitmqClusterSpecCore for OpenStackControlplane (v2.16.0_patches)
replace github.com/rabbitmq/cluster-operator/v2 => github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250929174222-a0d328fa4dec //allow-merging

replace k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20250627150254-e9823e99808e //allow-merging
7 changes: 5 additions & 2 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 @@ -85,8 +86,8 @@ github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e h1:E1OdwSpqWuDPCedyUt0GEdoAE+r5TXy7YS21yNEo+2U=
github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo=
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251205192058-5cfbada0ab96 h1:hPgCcrbRHBPfngaEPe6coaCtcauMolI71lfcLdinrKI=
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251205192058-5cfbada0ab96/go.mod h1:ZuglN7IqXfIo75WcJwe0NLHhu82Fs3k/5IXptqnO1H4=
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251217131115-0f117a938d4e h1:PIjcXzMMwfvBRFgFpaq/W9tqy0t2cYvcWX+kq6uNtTM=
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251217131115-0f117a938d4e/go.mod h1:ex8ou6/3ms6ovR+CMXD6XhTlNakm1GhB6UZgagVRNW8=
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251122131503-b76943960b6c h1:wM8qXCB5mQwSosCvtaydzuXitWVVKBHTzH0A2znQ+Jg=
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251122131503-b76943960b6c/go.mod h1:+Me0raWPPdz8gRi9D4z1khmvUgS9vIKAVC8ckg1yJZU=
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251122131503-b76943960b6c h1:l7FO+XoQRnD4aT5p/JXVY2uezQLdC7D50KrwrTmzCfg=
Expand All @@ -95,6 +96,8 @@ github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.202511221
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251122131503-b76943960b6c/go.mod h1:fy1lvz3uuzzh01DKKdgroXvmJgMpJBsvl2r9eTtAll0=
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20251122131503-b76943960b6c h1:YdTv3RXKfFg2QHXtLJSnKaPruslyp1Fd+ArcsxLcy6k=
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20251122131503-b76943960b6c/go.mod h1:lgYyrXEYA2BPsq4Kg6dqa+QsHgOjMPyOsEYrvyYW3jk=
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
5 changes: 5 additions & 0 deletions api/v1beta1/keystoneapi_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,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"
condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
"github.com/openstack-k8s-operators/lib-common/modules/common/endpoint"
Expand Down Expand Up @@ -213,6 +214,10 @@ type KeystoneAPISpecCore struct {
// This is only needed when multiple realms are federated.
// Config files mount path is set to /var/lib/httpd/metadata/
FederatedRealmConfig string `json:"federatedRealmConfig"`

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

// APIOverrideSpec to override the generated manifest of several child resources.
Expand Down
11 changes: 10 additions & 1 deletion api/v1beta1/keystoneapi_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"
"github.com/openstack-k8s-operators/lib-common/modules/common/service"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -76,6 +77,7 @@ func (spec *KeystoneAPISpecCore) Default() {
if spec.APITimeout == 0 {
spec.APITimeout = keystoneAPIDefaults.APITimeout
}
rabbitmqv1.DefaultRabbitMqConfig(&spec.NotificationsBus, spec.RabbitMqClusterName)
}

var _ webhook.Validator = &KeystoneAPI{}
Expand Down Expand Up @@ -148,9 +150,16 @@ func (spec *KeystoneAPISpec) ValidateUpdate(old KeystoneAPISpec, basePath *field
}

// ValidateUpdate validates the KeystoneAPISpecCore spec during update
func (spec *KeystoneAPISpecCore) ValidateUpdate(_ KeystoneAPISpecCore, basePath *field.Path, namespace string) field.ErrorList {
func (spec *KeystoneAPISpecCore) ValidateUpdate(old KeystoneAPISpecCore, basePath *field.Path, namespace string) field.ErrorList {
var allErrs field.ErrorList

// Reject changes to deprecated RabbitMqClusterName field - users should use the new notificationsBus.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 notificationsBus.cluster instead"))
}

// validate the service override key is valid
allErrs = append(allErrs, service.ValidateRoutedOverrides(basePath.Child("override").Child("service"), spec.Override.Service)...)

Expand Down
1 change: 1 addition & 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.

17 changes: 17 additions & 0 deletions config/crd/bases/keystone.openstack.org_keystoneapis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1280,6 +1280,23 @@ spec:
description: NodeSelector to target subset of worker nodes running
this service
type: object
notificationsBus:
description: NotificationsBus 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
override:
description: Override, provides the ability to override the generated
manifest of several child resources.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ spec:
- name: Keystone Operator
url: https://github.com/openstack-k8s-operators/keystone-operator
maturity: beta
minKubeVersion: 0.0.0
provider:
name: Red Hat Inc.
url: https://redhat.com/
version: 0.0.0
minKubeVersion: 0.0.0
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.7
github.com/onsi/ginkgo/v2 v2.27.2
github.com/onsi/gomega v1.38.2
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251205192058-5cfbada0ab96
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251217131115-0f117a938d4e
github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240213125925-e40975f3db7e
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251122131503-b76943960b6c
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251122131503-b76943960b6c
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e h1:E1OdwSpqWuDPCedyUt0GEdoAE+r5TXy7YS21yNEo+2U=
github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo=
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251205192058-5cfbada0ab96 h1:hPgCcrbRHBPfngaEPe6coaCtcauMolI71lfcLdinrKI=
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251205192058-5cfbada0ab96/go.mod h1:ZuglN7IqXfIo75WcJwe0NLHhu82Fs3k/5IXptqnO1H4=
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251217131115-0f117a938d4e h1:PIjcXzMMwfvBRFgFpaq/W9tqy0t2cYvcWX+kq6uNtTM=
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251217131115-0f117a938d4e/go.mod h1:ex8ou6/3ms6ovR+CMXD6XhTlNakm1GhB6UZgagVRNW8=
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251122131503-b76943960b6c h1:wM8qXCB5mQwSosCvtaydzuXitWVVKBHTzH0A2znQ+Jg=
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251122131503-b76943960b6c/go.mod h1:+Me0raWPPdz8gRi9D4z1khmvUgS9vIKAVC8ckg1yJZU=
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251122131503-b76943960b6c h1:l7FO+XoQRnD4aT5p/JXVY2uezQLdC7D50KrwrTmzCfg=
Expand Down
10 changes: 7 additions & 3 deletions internal/controller/keystoneapi_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -1286,9 +1286,13 @@ func (r *KeystoneAPIReconciler) transportURLCreateOrUpdate(
},
}
op, err := controllerutil.CreateOrUpdate(ctx, r.Client, transportURL, func() error {
transportURL.Spec.RabbitmqClusterName = instance.Spec.RabbitMqClusterName
err := controllerutil.SetControllerReference(instance, transportURL, r.Scheme)
return err
transportURL.Spec.RabbitmqClusterName = instance.Spec.NotificationsBus.Cluster
if instance.Spec.NotificationsBus.User != "" {
transportURL.Spec.Username = instance.Spec.NotificationsBus.User
}
// Always set Vhost - empty string means use default "/" vhost
transportURL.Spec.Vhost = instance.Spec.NotificationsBus.Vhost
return controllerutil.SetControllerReference(instance, transportURL, r.Scheme)
})

return transportURL, op, err
Expand Down
74 changes: 74 additions & 0 deletions test/functional/keystone_webhook_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
Copyright 2025.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package functional_test

import (
"errors"

. "github.com/onsi/ginkgo/v2" //revive:disable:dot-imports
. "github.com/onsi/gomega" //revive:disable:dot-imports

k8s_errors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)

var _ = Describe("KeystoneAPI webhook", func() {
It("rejects update to deprecated rabbitMqClusterName field", func() {
spec := GetDefaultKeystoneAPISpec()
spec["rabbitMqClusterName"] = "rabbitmq"

keystoneName := types.NamespacedName{
Namespace: namespace,
Name: "keystone-webhook-test",
}

raw := map[string]any{
"apiVersion": "keystone.openstack.org/v1beta1",
"kind": "KeystoneAPI",
"metadata": map[string]any{
"name": keystoneName.Name,
"namespace": keystoneName.Namespace,
},
"spec": spec,
}

// Create the KeystoneAPI instance
unstructuredObj := &unstructured.Unstructured{Object: raw}
_, err := controllerutil.CreateOrPatch(
ctx, k8sClient, unstructuredObj, func() error { return nil })
Expect(err).ShouldNot(HaveOccurred())

// Try to update rabbitMqClusterName
Eventually(func(g Gomega) {
g.Expect(k8sClient.Get(ctx, keystoneName, unstructuredObj)).Should(Succeed())
specMap := unstructuredObj.Object["spec"].(map[string]any)
specMap["rabbitMqClusterName"] = "rabbitmq2"
err := k8sClient.Update(ctx, unstructuredObj)
g.Expect(err).Should(HaveOccurred())

var statusError *k8s_errors.StatusError
g.Expect(errors.As(err, &statusError)).To(BeTrue())
g.Expect(statusError.ErrStatus.Details.Kind).To(Equal("KeystoneAPI"))
g.Expect(statusError.ErrStatus.Message).To(
ContainSubstring("rabbitMqClusterName is deprecated and cannot be changed"))
g.Expect(statusError.ErrStatus.Message).To(
ContainSubstring("Please use notificationsBus.cluster instead"))
}, timeout, interval).Should(Succeed())
})
})
Loading