diff --git a/.gitignore b/.gitignore index 5734e0467..d6d3b6d91 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,9 @@ config/samples/tls/custom_route_cert/placement-cert-data.yaml # Test binary, build with `go test -c` *.test +# Test artifacts +test/functional/*/default.etcd/ + # Output of the go coverage tool, specifically when used with LiteIDE *.out diff --git a/api/bases/core.openstack.org_openstackcontrolplanes.yaml b/api/bases/core.openstack.org_openstackcontrolplanes.yaml index b6bf0f89c..7d24a53e3 100644 --- a/api/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/api/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -574,10 +574,34 @@ spec: - simple_crypto - pkcs11 type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object passwordSelectors: default: service: BarbicanPassword @@ -615,7 +639,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string secret: default: osp-secret @@ -640,7 +663,6 @@ spec: - barbicanKeystoneListener - barbicanWorker - databaseInstance - - rabbitMqClusterName - serviceAccount type: object type: object @@ -1744,10 +1766,34 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string passwordSelectors: @@ -1762,7 +1808,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string secret: type: string @@ -1781,7 +1826,6 @@ spec: - cinderScheduler - databaseInstance - memcachedInstance - - rabbitMqClusterName - secret type: object uniquePodNames: @@ -2918,10 +2962,34 @@ spec: transportURLSecret: type: string type: object + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nsRecords: items: properties: @@ -2949,7 +3017,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string redisServiceName: default: designate-redis @@ -3007,7 +3074,6 @@ spec: - designateMdns - designateProducer - designateWorker - - rabbitMqClusterName - secret type: object type: object @@ -4627,6 +4693,18 @@ spec: type: object notificationBusInstance: type: string + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object passwordSelectors: default: service: GlancePassword @@ -5866,10 +5944,34 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object passwordSelectors: default: authEncryptionKey: HeatAuthEncryptionKey @@ -5889,7 +5991,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string secret: type: string @@ -5909,7 +6010,6 @@ spec: - heatCfnAPI - heatEngine - memcachedInstance - - rabbitMqClusterName - secret type: object type: object @@ -7444,12 +7544,35 @@ spec: additionalProperties: type: string type: object + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object rabbitMqClusterName: - default: rabbitmq type: string replicas: default: 1 @@ -7498,10 +7621,34 @@ spec: type: string type: object type: object + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object passwordSelectors: default: service: IronicPassword @@ -7514,7 +7661,6 @@ spec: default: true type: boolean rabbitMqClusterName: - default: rabbitmq type: string rpcTransport: type: string @@ -8248,6 +8394,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object override: properties: service: @@ -8312,7 +8470,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string region: default: regionOne @@ -8395,7 +8552,6 @@ spec: required: - databaseInstance - memcachedInstance - - rabbitMqClusterName - secret type: object type: object @@ -9383,10 +9539,34 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string passwordSelectors: @@ -9401,7 +9581,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string secret: type: string @@ -9420,7 +9599,6 @@ spec: - manilaAPI - manilaScheduler - memcachedInstance - - rabbitMqClusterName type: object type: object memcached: @@ -9515,6 +9693,18 @@ spec: type: object type: object type: object + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object neutron: properties: apiOverride: @@ -10225,6 +10415,18 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object ml2MechanismDrivers: default: - ovn @@ -10239,6 +10441,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string override: @@ -10305,7 +10519,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string replicas: default: 1 @@ -10384,7 +10597,6 @@ spec: required: - databaseInstance - memcachedInstance - - rabbitMqClusterName - secret type: object type: object @@ -10392,6 +10604,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string nova: @@ -10706,7 +10930,6 @@ spec: default: openstack type: string apiMessageBusInstance: - default: rabbitmq type: string apiServiceTemplate: default: @@ -10861,7 +11084,6 @@ spec: default: openstack type: string cellMessageBusInstance: - default: rabbitmq type: string conductorServiceTemplate: properties: @@ -10940,6 +11162,18 @@ spec: type: boolean memcachedInstance: type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object metadataServiceTemplate: properties: customServiceConfig: @@ -11280,8 +11514,9 @@ spec: cell1: cellDatabaseAccount: nova-cell1 cellDatabaseInstance: openstack-cell1 - cellMessageBusInstance: rabbitmq-cell1 hasAPIAccess: true + messagingBus: + cluster: rabbitmq-cell1 type: object keystoneInstance: default: keystone @@ -11289,6 +11524,18 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object metadataServiceTemplate: default: enabled: true @@ -11415,6 +11662,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string passwordSelectors: @@ -11755,10 +12014,34 @@ spec: default: true type: boolean type: object + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object octaviaAPI: properties: apiTimeout: @@ -11790,6 +12073,8 @@ spec: additionalProperties: type: string type: object + notificationsTransportURLSecret: + type: string override: properties: service: @@ -12009,6 +12294,8 @@ spec: additionalProperties: type: string type: object + notificationsTransportURLSecret: + type: string octaviaProviderSubnetCIDR: type: string octaviaProviderSubnetExtraCIDRs: @@ -12166,6 +12453,8 @@ spec: additionalProperties: type: string type: object + notificationsTransportURLSecret: + type: string octaviaProviderSubnetCIDR: type: string octaviaProviderSubnetExtraCIDRs: @@ -12429,6 +12718,8 @@ spec: additionalProperties: type: string type: object + notificationsTransportURLSecret: + type: string octaviaProviderSubnetCIDR: type: string octaviaProviderSubnetExtraCIDRs: @@ -12543,7 +12834,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string redisServiceName: default: octavia-redis @@ -12610,7 +12900,6 @@ spec: - databaseInstance - octaviaAPI - octaviaNetworkAttachment - - rabbitMqClusterName - secret type: object type: object @@ -14538,6 +14827,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object override: properties: service: @@ -14599,7 +14900,6 @@ spec: type: string type: object rabbitMqClusterName: - default: rabbitmq type: string replicas: default: 1 @@ -14646,7 +14946,6 @@ spec: type: object required: - memcachedInstance - - rabbitMqClusterName - replicas - secret - serviceUser @@ -15440,6 +15739,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object override: properties: service: @@ -15510,7 +15821,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string secret: default: osp-secret @@ -15630,6 +15940,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object passwordSelector: default: ceilometerService: CeilometerPassword @@ -15645,7 +15967,6 @@ spec: type: string type: object rabbitMqClusterName: - default: rabbitmq type: string secret: default: osp-secret @@ -15916,6 +16237,18 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string @@ -15963,7 +16296,6 @@ spec: type: object x-kubernetes-map-type: atomic rabbitMqClusterName: - default: rabbitmq type: string s3StorageConfig: default: @@ -17385,10 +17717,34 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string passwordSelectors: @@ -17406,7 +17762,6 @@ spec: default: metric-storage-prometheus-endpoint type: string rabbitMqClusterName: - default: rabbitmq type: string secret: default: osp-secret @@ -17426,7 +17781,6 @@ spec: - applierServiceTemplate - databaseInstance - decisionengineServiceTemplate - - rabbitMqClusterName type: object type: object required: diff --git a/api/core/v1beta1/openstackcontrolplane_types.go b/api/core/v1beta1/openstackcontrolplane_types.go index 937d030b1..737e2ebeb 100644 --- a/api/core/v1beta1/openstackcontrolplane_types.go +++ b/api/core/v1beta1/openstackcontrolplane_types.go @@ -137,13 +137,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 diff --git a/api/core/v1beta1/openstackcontrolplane_webhook.go b/api/core/v1beta1/openstackcontrolplane_webhook.go index ff0f2c879..f4a32fce3 100644 --- a/api/core/v1beta1/openstackcontrolplane_webhook.go +++ b/api/core/v1beta1/openstackcontrolplane_webhook.go @@ -199,15 +199,21 @@ func (r *OpenStackControlPlane) ValidateCreate(ctx context.Context, c client.Cli return nil, err } - allWarn, errs := r.ValidateCreateServices(basePath) + // Validate deprecated fields using centralized validation + warnings, errs := r.validateDeprecatedFieldsCreate(basePath) + allWarn = append(allWarn, warnings...) + allErrs = append(allErrs, errs...) + + warns, errs := r.ValidateCreateServices(basePath) + allWarn = append(allWarn, warns...) allErrs = append(allErrs, errs...) if err := r.ValidateTopology(basePath); err != nil { allErrs = append(allErrs, err) } - if err := r.ValidateNotificationsBusInstance(basePath); err != nil { - allErrs = append(allErrs, err) + if errs := r.ValidateMessagingBusConfig(basePath); len(errs) != 0 { + allErrs = append(allErrs, errs...) } if len(allErrs) != 0 { @@ -228,19 +234,37 @@ func (r *OpenStackControlPlane) ValidateUpdate(ctx context.Context, old runtime. return nil, apierrors.NewInternalError(fmt.Errorf("unable to convert existing object")) } + // Handle annotation-triggered migration from controller + const reconcileTriggerAnnotation = "openstack.org/reconcile-trigger" + if annotations := r.GetAnnotations(); annotations != nil { + if _, exists := annotations[reconcileTriggerAnnotation]; exists { + openstackcontrolplanelog.Info("Reconcile trigger annotation detected, performing migration", + "instance", r.Name) + r.migrateDeprecatedFields() + delete(annotations, reconcileTriggerAnnotation) + r.SetAnnotations(annotations) + } + } + var allWarn []string var allErrs field.ErrorList basePath := field.NewPath("spec") - allWarn, errs := r.ValidateUpdateServices(oldControlPlane.Spec, basePath) + // Validate deprecated fields using centralized validation + warnings, errs := r.validateDeprecatedFieldsUpdate(*oldControlPlane, basePath) + allWarn = append(allWarn, warnings...) + allErrs = append(allErrs, errs...) + + warns, errs := r.ValidateUpdateServices(oldControlPlane.Spec, basePath) + allWarn = append(allWarn, warns...) allErrs = append(allErrs, errs...) if err := r.ValidateTopology(basePath); err != nil { allErrs = append(allErrs, err) } - if err := r.ValidateNotificationsBusInstance(basePath); err != nil { - allErrs = append(allErrs, err) + if errs := r.ValidateMessagingBusConfig(basePath); len(errs) != 0 { + allErrs = append(allErrs, errs...) } if len(allErrs) != 0 { @@ -356,17 +380,23 @@ func (r *OpenStackControlPlane) ValidateCreateServices(basePath *field.Path) (ad // Call internal validation logic for individual service operators if r.Spec.Keystone.Enabled { - errors = append(errors, r.Spec.Keystone.Template.ValidateCreate(basePath.Child("keystone").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Keystone.Template.ValidateCreate(basePath.Child("keystone").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Keystone.APIOverride.Route, basePath.Child("keystone").Child("apiOverride").Child("route"))...) } if r.Spec.Ironic.Enabled { - errors = append(errors, r.Spec.Ironic.Template.ValidateCreate(basePath.Child("ironic").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Ironic.Template.ValidateCreate(basePath.Child("ironic").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Ironic.APIOverride.Route, basePath.Child("ironic").Child("apiOverride").Child("route"))...) } if r.Spec.Nova.Enabled { - errors = append(errors, r.Spec.Nova.Template.ValidateCreate(basePath.Child("nova").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Nova.Template.ValidateCreate(basePath.Child("nova").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Nova.APIOverride.Route, basePath.Child("nova").Child("apiOverride").Child("route"))...) } @@ -376,12 +406,16 @@ func (r *OpenStackControlPlane) ValidateCreateServices(basePath *field.Path) (ad } if r.Spec.Barbican.Enabled { - errors = append(errors, r.Spec.Barbican.Template.ValidateCreate(basePath.Child("barbican").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Barbican.Template.ValidateCreate(basePath.Child("barbican").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Barbican.APIOverride.Route, basePath.Child("barbican").Child("apiOverride").Child("route"))...) } if r.Spec.Neutron.Enabled { - errors = append(errors, r.Spec.Neutron.Template.ValidateCreate(basePath.Child("neutron").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Neutron.Template.ValidateCreate(basePath.Child("neutron").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Neutron.APIOverride.Route, basePath.Child("neutron").Child("apiOverride").Child("route"))...) } @@ -394,7 +428,9 @@ func (r *OpenStackControlPlane) ValidateCreateServices(basePath *field.Path) (ad glancev1.GetCrMaxLengthCorrection(glanceName, glanceAPI.Type)) // omit issue with statefulset pod label "controller-revision-hash": "-" errors = append(errors, err...) } - errors = append(errors, r.Spec.Glance.Template.ValidateCreate(basePath.Child("glance").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Glance.Template.ValidateCreate(basePath.Child("glance").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) for key, override := range r.Spec.Glance.APIOverride { overridePath := basePath.Child("glance").Child("apiOverride").Key(key) @@ -416,12 +452,16 @@ func (r *OpenStackControlPlane) ValidateCreateServices(basePath *field.Path) (ad } if r.Spec.Heat.Enabled { - errors = append(errors, r.Spec.Heat.Template.ValidateCreate(basePath.Child("heat").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Heat.Template.ValidateCreate(basePath.Child("heat").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Heat.APIOverride.Route, basePath.Child("heat").Child("apiOverride").Child("route"))...) } if r.Spec.Manila.Enabled { - errors = append(errors, r.Spec.Manila.Template.ValidateCreate(basePath.Child("manila").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Manila.Template.ValidateCreate(basePath.Child("manila").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Manila.APIOverride.Route, basePath.Child("manila").Child("apiOverride").Child("route"))...) } @@ -431,22 +471,30 @@ func (r *OpenStackControlPlane) ValidateCreateServices(basePath *field.Path) (ad } if r.Spec.Octavia.Enabled { - errors = append(errors, r.Spec.Octavia.Template.ValidateCreate(basePath.Child("octavia").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Octavia.Template.ValidateCreate(basePath.Child("octavia").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Octavia.APIOverride.Route, basePath.Child("octavia").Child("apiOverride").Child("route"))...) } if r.Spec.Designate.Enabled { - errors = append(errors, r.Spec.Designate.Template.ValidateCreate(basePath.Child("designate").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Designate.Template.ValidateCreate(basePath.Child("designate").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Designate.APIOverride.Route, basePath.Child("designate").Child("apiOverride").Child("route"))...) } if r.Spec.Watcher.Enabled { - errors = append(errors, r.Spec.Watcher.Template.ValidateCreate(basePath.Child("watcher").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Watcher.Template.ValidateCreate(basePath.Child("watcher").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Watcher.APIOverride.Route, basePath.Child("watcher").Child("apiOverride").Child("route"))...) } if r.Spec.Telemetry.Enabled { - errors = append(errors, r.Spec.Telemetry.Template.ValidateCreate(basePath.Child("telemetry").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Telemetry.Template.ValidateCreate(basePath.Child("telemetry").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Telemetry.AodhAPIOverride.Route, basePath.Child("telemetry").Child("aodhApiOverride").Child("route"))...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Telemetry.PrometheusOverride.Route, basePath.Child("telemetry").Child("prometheusOverride").Child("route"))...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Telemetry.AlertmanagerOverride.Route, basePath.Child("telemetry").Child("alertmanagerOverride").Child("route"))...) @@ -522,7 +570,9 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane if old.Keystone.Template == nil { old.Keystone.Template = &keystonev1.KeystoneAPISpecCore{} } - errors = append(errors, r.Spec.Keystone.Template.ValidateUpdate(*old.Keystone.Template, basePath.Child("keystone").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Keystone.Template.ValidateUpdate(*old.Keystone.Template, basePath.Child("keystone").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Keystone.APIOverride.Route, basePath.Child("keystone").Child("apiOverride").Child("route"))...) } @@ -530,7 +580,9 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane if old.Ironic.Template == nil { old.Ironic.Template = &ironicv1.IronicSpecCore{} } - errors = append(errors, r.Spec.Ironic.Template.ValidateUpdate(*old.Ironic.Template, basePath.Child("ironic").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Ironic.Template.ValidateUpdate(*old.Ironic.Template, basePath.Child("ironic").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Ironic.APIOverride.Route, basePath.Child("ironic").Child("apiOverride").Child("route"))...) } @@ -538,7 +590,9 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane if old.Nova.Template == nil { old.Nova.Template = &novav1.NovaSpecCore{} } - errors = append(errors, r.Spec.Nova.Template.ValidateUpdate(*old.Nova.Template, basePath.Child("nova").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Nova.Template.ValidateUpdate(*old.Nova.Template, basePath.Child("nova").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Nova.APIOverride.Route, basePath.Child("nova").Child("apiOverride").Child("route"))...) } @@ -554,7 +608,9 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane if old.Barbican.Template == nil { old.Barbican.Template = &barbicanv1.BarbicanSpecCore{} } - errors = append(errors, r.Spec.Barbican.Template.ValidateUpdate(*old.Barbican.Template, basePath.Child("barbican").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Barbican.Template.ValidateUpdate(*old.Barbican.Template, basePath.Child("barbican").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Barbican.APIOverride.Route, basePath.Child("barbican").Child("apiOverride").Child("route"))...) } @@ -562,7 +618,9 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane if old.Neutron.Template == nil { old.Neutron.Template = &neutronv1.NeutronAPISpecCore{} } - errors = append(errors, r.Spec.Neutron.Template.ValidateUpdate(*old.Neutron.Template, basePath.Child("neutron").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Neutron.Template.ValidateUpdate(*old.Neutron.Template, basePath.Child("neutron").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Neutron.APIOverride.Route, basePath.Child("neutron").Child("apiOverride").Child("route"))...) } @@ -578,7 +636,9 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane glancev1.GetCrMaxLengthCorrection(glanceName, glanceAPI.Type)) // omit issue with statefulset pod label "controller-revision-hash": "-" errors = append(errors, err...) } - errors = append(errors, r.Spec.Glance.Template.ValidateUpdate(*old.Glance.Template, basePath.Child("glance").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Glance.Template.ValidateUpdate(*old.Glance.Template, basePath.Child("glance").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) for key, override := range r.Spec.Glance.APIOverride { overridePath := basePath.Child("glance").Child("apiOverride").Key(key) @@ -606,7 +666,9 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane if old.Heat.Template == nil { old.Heat.Template = &heatv1.HeatSpecCore{} } - errors = append(errors, r.Spec.Heat.Template.ValidateUpdate(*old.Heat.Template, basePath.Child("heat").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Heat.Template.ValidateUpdate(*old.Heat.Template, basePath.Child("heat").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Heat.APIOverride.Route, basePath.Child("heat").Child("apiOverride").Child("route"))...) } @@ -614,7 +676,9 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane if old.Manila.Template == nil { old.Manila.Template = &manilav1.ManilaSpecCore{} } - errors = append(errors, r.Spec.Manila.Template.ValidateUpdate(*old.Manila.Template, basePath.Child("manila").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Manila.Template.ValidateUpdate(*old.Manila.Template, basePath.Child("manila").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Manila.APIOverride.Route, basePath.Child("manila").Child("apiOverride").Child("route"))...) } @@ -630,7 +694,9 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane if old.Octavia.Template == nil { old.Octavia.Template = &octaviav1.OctaviaSpecCore{} } - errors = append(errors, r.Spec.Octavia.Template.ValidateUpdate(*old.Octavia.Template, basePath.Child("octavia").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Octavia.Template.ValidateUpdate(*old.Octavia.Template, basePath.Child("octavia").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Octavia.APIOverride.Route, basePath.Child("octavia").Child("apiOverride").Child("route"))...) } @@ -638,7 +704,9 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane if old.Designate.Template == nil { old.Designate.Template = &designatev1.DesignateSpecCore{} } - errors = append(errors, r.Spec.Designate.Template.ValidateUpdate(*old.Designate.Template, basePath.Child("designate").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Designate.Template.ValidateUpdate(*old.Designate.Template, basePath.Child("designate").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Designate.APIOverride.Route, basePath.Child("designate").Child("apiOverride").Child("route"))...) } @@ -646,14 +714,18 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane if old.Watcher.Template == nil { old.Watcher.Template = &watcherv1.WatcherSpecCore{} } - errors = append(errors, r.Spec.Watcher.Template.ValidateUpdate(*old.Watcher.Template, basePath.Child("watcher").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Watcher.Template.ValidateUpdate(*old.Watcher.Template, basePath.Child("watcher").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Watcher.APIOverride.Route, basePath.Child("watcher").Child("apiOverride").Child("route"))...) } if r.Spec.Telemetry.Enabled { if old.Telemetry.Template == nil { old.Telemetry.Template = &telemetryv1.TelemetrySpecCore{} } - errors = append(errors, r.Spec.Telemetry.Template.ValidateUpdate(*old.Telemetry.Template, basePath.Child("telemetry").Child("template"), r.Namespace)...) + warns, errs := r.Spec.Telemetry.Template.ValidateUpdate(*old.Telemetry.Template, basePath.Child("telemetry").Child("template"), r.Namespace) + errors = append(errors, errs...) + warnings = append(warnings, warns...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Telemetry.AodhAPIOverride.Route, basePath.Child("telemetry").Child("aodhApiOverride").Child("route"))...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Telemetry.PrometheusOverride.Route, basePath.Child("telemetry").Child("prometheusOverride").Child("route"))...) errors = append(errors, validateTLSOverrideSpec(&r.Spec.Telemetry.AlertmanagerOverride.Route, basePath.Child("telemetry").Child("alertmanagerOverride").Child("route"))...) @@ -872,6 +944,7 @@ func (r *OpenStackControlPlane) Default() { openstackcontrolplanelog.Info("default", "name", r.Name) r.DefaultLabel() + r.migrateDeprecatedFields() r.DefaultServices() } @@ -967,15 +1040,12 @@ func (r *OpenStackControlPlane) DefaultServices() { r.Spec.Ironic.Template = &ironicv1.IronicSpecCore{} } - // Default Secret if r.Spec.Ironic.Template.Secret == "" { r.Spec.Ironic.Template.Secret = r.Spec.Secret } - // Default DatabaseInstance if r.Spec.Ironic.Template.DatabaseInstance == "" { r.Spec.Ironic.Template.DatabaseInstance = "openstack" } - // Default StorageClass if r.Spec.Ironic.Template.StorageClass == "" { r.Spec.Ironic.Template.StorageClass = r.Spec.StorageClass } @@ -1228,6 +1298,39 @@ func (r *OpenStackControlPlane) ValidateTopology(basePath *field.Path) *field.Er return nil } +// ValidateMessagingBusConfig validates that the User field is not set in top-level +// messagingBus and notificationsBus configurations. Setting a shared username would +// cause webhook validation failures in infra-operator when multiple services try to +// create RabbitMQUser resources with the same username. The Cluster and Vhost fields +// are allowed at the top level since they can be safely shared across services. +func (r *OpenStackControlPlane) ValidateMessagingBusConfig(basePath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + // Validate messagingBus + if r.Spec.MessagingBus != nil { + messagingBusPath := basePath.Child("messagingBus") + if r.Spec.MessagingBus.User != "" { + allErrs = append(allErrs, field.Forbidden( + messagingBusPath.Child("user"), + "user field is not allowed at the top level. Each service operator creates its own TransportURL with a unique user. Set user in individual service templates if needed.", + )) + } + } + + // Validate notificationsBus + if r.Spec.NotificationsBus != nil { + notificationsBusPath := basePath.Child("notificationsBus") + if r.Spec.NotificationsBus.User != "" { + allErrs = append(allErrs, field.Forbidden( + notificationsBusPath.Child("user"), + "user field is not allowed at the top level. Each service operator creates its own TransportURL with a unique user. Set user in individual service templates if needed.", + )) + } + } + + return allErrs +} + // ValidateNotificationsBusInstance - returns an error if the notificationsBusInstance // parameter is not valid. // - nil or empty string must be raised as an error @@ -1252,3 +1355,373 @@ func (r *OpenStackControlPlane) ValidateNotificationsBusInstance(basePath *field } return field.Invalid(notificationsField, *r.Spec.NotificationsBusInstance, "notificationsBusInstance must match an existing RabbitMQ instance name") } + +// getDeprecatedFields returns the centralized list of deprecated fields for OpenStackControlPlane +func (r *OpenStackControlPlane) getDeprecatedFields(old *OpenStackControlPlane) []common_webhook.DeprecatedFieldUpdate { + // Handle NewValue pointer - NotificationsBus can be nil + var newValue *string + if r.Spec.NotificationsBus != nil { + newValue = &r.Spec.NotificationsBus.Cluster + } + + deprecatedFields := []common_webhook.DeprecatedFieldUpdate{ + { + DeprecatedFieldName: "notificationsBusInstance", + NewFieldPath: []string{"notificationsBus", "cluster"}, + NewDeprecatedValue: r.Spec.NotificationsBusInstance, + NewValue: newValue, + }, + } + + // If old spec is provided (UPDATE operation), add old values + if old != nil { + deprecatedFields[0].OldDeprecatedValue = old.Spec.NotificationsBusInstance + } + + return deprecatedFields +} + +// validateDeprecatedFieldsCreate validates deprecated fields during CREATE operations +func (r *OpenStackControlPlane) validateDeprecatedFieldsCreate(basePath *field.Path) ([]string, field.ErrorList) { + // Get deprecated fields list (without old values for CREATE) + deprecatedFieldsUpdate := r.getDeprecatedFields(nil) + + // Convert to DeprecatedField list for CREATE validation + deprecatedFields := make([]common_webhook.DeprecatedField, len(deprecatedFieldsUpdate)) + for i, df := range deprecatedFieldsUpdate { + deprecatedFields[i] = common_webhook.DeprecatedField{ + DeprecatedFieldName: df.DeprecatedFieldName, + NewFieldPath: df.NewFieldPath, + DeprecatedValue: df.NewDeprecatedValue, + NewValue: df.NewValue, + } + } + + return common_webhook.ValidateDeprecatedFieldsCreate(deprecatedFields, basePath), nil +} + +// validateDeprecatedFieldsUpdate validates deprecated fields during UPDATE operations +func (r *OpenStackControlPlane) validateDeprecatedFieldsUpdate(old OpenStackControlPlane, basePath *field.Path) ([]string, field.ErrorList) { + // Get deprecated fields list with old values + deprecatedFields := r.getDeprecatedFields(&old) + return common_webhook.ValidateDeprecatedFieldsUpdate(deprecatedFields, basePath) +} + +// migrateDeprecatedFields performs migration from deprecated fields to new fields. +// This is called during CREATE (from Default()) and UPDATE (when triggered by annotation). +// It transparently migrates: +// - Top-level: NotificationsBusInstance -> NotificationsBus.Cluster +// - Service-level: .template.rabbitMqClusterName -> .template.messagingBus.cluster +func (r *OpenStackControlPlane) migrateDeprecatedFields() { + // Migration: Top-level NotificationsBusInstance -> NotificationsBus.Cluster + if r.Spec.NotificationsBusInstance != nil && *r.Spec.NotificationsBusInstance != "" { + // Initialize NotificationsBus if needed + if r.Spec.NotificationsBus == nil { + r.Spec.NotificationsBus = &rabbitmqv1.RabbitMqConfig{} + } + // Migrate the cluster name if not already set + if r.Spec.NotificationsBus.Cluster == "" { + r.Spec.NotificationsBus.Cluster = *r.Spec.NotificationsBusInstance + openstackcontrolplanelog.Info("Migrated notificationsBusInstance to notificationsBus.cluster", + "instance", r.Name, + "cluster", r.Spec.NotificationsBus.Cluster) + } + // Clear the deprecated field after migration + r.Spec.NotificationsBusInstance = nil + } + + // Service-level migrations: rabbitMqClusterName -> messagingBus.cluster + // Each service follows the priority: deprecated field -> top-level -> default + // Only services that have both MessagingBus and RabbitMqClusterName fields + + // Cinder + if r.Spec.Cinder.Template != nil { + r.migrateServiceMessagingBus( + &r.Spec.Cinder.Template.MessagingBus, + &r.Spec.Cinder.Template.RabbitMqClusterName, + "cinder", + ) + r.migrateServiceNotificationsBusInstance( + &r.Spec.Cinder.Template.NotificationsBus, + &r.Spec.Cinder.Template.NotificationsBusInstance, + "cinder", + ) + } + + // Manila + if r.Spec.Manila.Template != nil { + r.migrateServiceMessagingBus( + &r.Spec.Manila.Template.MessagingBus, + &r.Spec.Manila.Template.RabbitMqClusterName, + "manila", + ) + r.migrateServiceNotificationsBusInstance( + &r.Spec.Manila.Template.NotificationsBus, + &r.Spec.Manila.Template.NotificationsBusInstance, + "manila", + ) + } + + // Neutron + if r.Spec.Neutron.Template != nil { + r.migrateServiceMessagingBus( + &r.Spec.Neutron.Template.MessagingBus, + &r.Spec.Neutron.Template.RabbitMqClusterName, + "neutron", + ) + r.migrateServiceNotificationsBusInstance( + &r.Spec.Neutron.Template.NotificationsBus, + &r.Spec.Neutron.Template.NotificationsBusInstance, + "neutron", + ) + } + + // Heat + if r.Spec.Heat.Template != nil { + r.migrateServiceMessagingBus( + &r.Spec.Heat.Template.MessagingBus, + &r.Spec.Heat.Template.RabbitMqClusterName, + "heat", + ) + } + + // Ironic - has main template and IronicNeutronAgent + if r.Spec.Ironic.Template != nil { + r.migrateServiceMessagingBus( + &r.Spec.Ironic.Template.MessagingBus, + &r.Spec.Ironic.Template.RabbitMqClusterName, + "ironic", + ) + + // IronicNeutronAgent has its own messaging bus - only migrate from deprecated field + if r.Spec.Ironic.Template.IronicNeutronAgent.MessagingBus.Cluster == "" && r.Spec.Ironic.Template.IronicNeutronAgent.RabbitMqClusterName != "" { + r.Spec.Ironic.Template.IronicNeutronAgent.MessagingBus.Cluster = r.Spec.Ironic.Template.IronicNeutronAgent.RabbitMqClusterName + openstackcontrolplanelog.Info("Migrated ironic neutron agent rabbitMqClusterName to messagingBus.cluster", + "instance", r.Name, + "cluster", r.Spec.Ironic.Template.IronicNeutronAgent.MessagingBus.Cluster) + } + if r.Spec.Ironic.Template.IronicNeutronAgent.MessagingBus.Cluster != "" { + r.Spec.Ironic.Template.IronicNeutronAgent.RabbitMqClusterName = "" + } + } + + // Barbican + if r.Spec.Barbican.Template != nil { + r.migrateServiceMessagingBus( + &r.Spec.Barbican.Template.MessagingBus, + &r.Spec.Barbican.Template.RabbitMqClusterName, + "barbican", + ) + } + + // Designate + if r.Spec.Designate.Template != nil { + r.migrateServiceMessagingBus( + &r.Spec.Designate.Template.MessagingBus, + &r.Spec.Designate.Template.RabbitMqClusterName, + "designate", + ) + } + + // Octavia + if r.Spec.Octavia.Template != nil { + r.migrateServiceMessagingBus( + &r.Spec.Octavia.Template.MessagingBus, + &r.Spec.Octavia.Template.RabbitMqClusterName, + "octavia", + ) + } + + // Watcher (RabbitMqClusterName is *string, so handle specially) + if r.Spec.Watcher.Template != nil && r.Spec.Watcher.Template.RabbitMqClusterName != nil { + r.migrateServiceMessagingBus( + &r.Spec.Watcher.Template.MessagingBus, + r.Spec.Watcher.Template.RabbitMqClusterName, + "watcher", + ) + // Set pointer to nil instead of empty string (Watcher uses *string) + r.Spec.Watcher.Template.RabbitMqClusterName = nil + } + + // Watcher - migrate notificationsBusInstance + if r.Spec.Watcher.Template != nil { + r.migrateServiceNotificationsBusInstance( + &r.Spec.Watcher.Template.NotificationsBus, + &r.Spec.Watcher.Template.NotificationsBusInstance, + "watcher", + ) + } + + // Keystone - uses NotificationsBus instead of MessagingBus + if r.Spec.Keystone.Template != nil { + r.migrateServiceNotificationsBus( + &r.Spec.Keystone.Template.NotificationsBus, + &r.Spec.Keystone.Template.RabbitMqClusterName, + "keystone", + ) + } + + // Swift - SwiftProxy uses NotificationsBus for Ceilometer middleware + if r.Spec.Swift.Template != nil { + r.migrateServiceNotificationsBus( + &r.Spec.Swift.Template.SwiftProxy.NotificationsBus, + &r.Spec.Swift.Template.SwiftProxy.RabbitMqClusterName, + "swift-proxy", + ) + } + + // Nova - has API-level and per-cell messaging bus fields + if r.Spec.Nova.Template != nil { + // API-level migration - only migrate from deprecated field + if r.Spec.Nova.Template.MessagingBus.Cluster == "" && r.Spec.Nova.Template.APIMessageBusInstance != "" { + r.Spec.Nova.Template.MessagingBus.Cluster = r.Spec.Nova.Template.APIMessageBusInstance + openstackcontrolplanelog.Info("Migrated nova APIMessageBusInstance to messagingBus.cluster", + "instance", r.Name, + "cluster", r.Spec.Nova.Template.MessagingBus.Cluster) + } + + // Clear deprecated field after migration + if r.Spec.Nova.Template.MessagingBus.Cluster != "" { + r.Spec.Nova.Template.APIMessageBusInstance = "" + } + + // Per-cell migration - only migrate from deprecated field + if r.Spec.Nova.Template.CellTemplates != nil { + for cellName, cellTemplate := range r.Spec.Nova.Template.CellTemplates { + if cellTemplate.MessagingBus.Cluster == "" && cellTemplate.CellMessageBusInstance != "" { + cellTemplate.MessagingBus.Cluster = cellTemplate.CellMessageBusInstance + openstackcontrolplanelog.Info("Migrated nova cell cellMessageBusInstance to messagingBus.cluster", + "instance", r.Name, + "cell", cellName, + "cluster", cellTemplate.MessagingBus.Cluster) + } + + // Clear deprecated field after migration + if cellTemplate.MessagingBus.Cluster != "" { + cellTemplate.CellMessageBusInstance = "" + } + + // Save back to map + r.Spec.Nova.Template.CellTemplates[cellName] = cellTemplate + } + } + + // Migrate notificationsBusInstance + r.migrateServiceNotificationsBusInstance( + &r.Spec.Nova.Template.NotificationsBus, + &r.Spec.Nova.Template.NotificationsBusInstance, + "nova", + ) + } + + // Telemetry - has multiple sub-services with different bus types + if r.Spec.Telemetry.Template != nil { + // CloudKitty uses MessagingBus - only migrate from deprecated field + if r.Spec.Telemetry.Template.CloudKitty.MessagingBus.Cluster == "" && r.Spec.Telemetry.Template.CloudKitty.RabbitMqClusterName != "" { + r.Spec.Telemetry.Template.CloudKitty.MessagingBus.Cluster = r.Spec.Telemetry.Template.CloudKitty.RabbitMqClusterName + openstackcontrolplanelog.Info("Migrated telemetry cloudkitty rabbitMqClusterName to messagingBus.cluster", + "instance", r.Name, + "cluster", r.Spec.Telemetry.Template.CloudKitty.MessagingBus.Cluster) + } + if r.Spec.Telemetry.Template.CloudKitty.MessagingBus.Cluster != "" { + r.Spec.Telemetry.Template.CloudKitty.RabbitMqClusterName = "" + } + + // Autoscaling.Aodh uses NotificationsBus + r.migrateServiceNotificationsBus( + &r.Spec.Telemetry.Template.Autoscaling.Aodh.NotificationsBus, + &r.Spec.Telemetry.Template.Autoscaling.Aodh.RabbitMqClusterName, + "telemetry.autoscaling.aodh", + ) + + // Ceilometer uses NotificationsBus + r.migrateServiceNotificationsBus( + &r.Spec.Telemetry.Template.Ceilometer.NotificationsBus, + &r.Spec.Telemetry.Template.Ceilometer.RabbitMqClusterName, + "telemetry.ceilometer", + ) + } +} + +// migrateServiceMessagingBus migrates a service-level rabbitMqClusterName to messagingBus.cluster +// Only handles migration from deprecated field to new field. +// Inheritance from top-level and defaults are handled at runtime in service reconciliation. +func (r *OpenStackControlPlane) migrateServiceMessagingBus( + serviceMessagingBus *rabbitmqv1.RabbitMqConfig, + deprecatedField *string, + serviceName string, +) { + // Only migrate if the new field is not already set and deprecated field has a value + if serviceMessagingBus.Cluster == "" && deprecatedField != nil && *deprecatedField != "" { + serviceMessagingBus.Cluster = *deprecatedField + openstackcontrolplanelog.Info("Migrated service rabbitMqClusterName to messagingBus.cluster", + "instance", r.Name, + "service", serviceName, + "cluster", serviceMessagingBus.Cluster) + } + + // Clear deprecated field after migration + if serviceMessagingBus.Cluster != "" && deprecatedField != nil { + *deprecatedField = "" + } +} + +// migrateServiceNotificationsBus migrates a service-level rabbitMqClusterName to notificationsBus.cluster +// This is used for services like Keystone that use notifications instead of messaging. +// Only handles migration from deprecated field to new field. +// Inheritance from top-level is handled at runtime in service reconciliation. +func (r *OpenStackControlPlane) migrateServiceNotificationsBus( + serviceNotificationsBus **rabbitmqv1.RabbitMqConfig, + deprecatedField *string, + serviceName string, +) { + // Only migrate if deprecated field is set + if deprecatedField != nil && *deprecatedField != "" { + // Initialize NotificationsBus if needed + if *serviceNotificationsBus == nil { + *serviceNotificationsBus = &rabbitmqv1.RabbitMqConfig{} + } + + // Only migrate if cluster is not already set + if (*serviceNotificationsBus).Cluster == "" { + (*serviceNotificationsBus).Cluster = *deprecatedField + openstackcontrolplanelog.Info("Migrated service rabbitMqClusterName to notificationsBus.cluster", + "instance", r.Name, + "service", serviceName, + "cluster", (*serviceNotificationsBus).Cluster) + } + + // Clear deprecated field after migration + *deprecatedField = "" + } +} + +// migrateServiceNotificationsBusInstance migrates a service-level notificationsBusInstance to notificationsBus.cluster +// This handles the deprecated string field notificationsBusInstance that exists on some service specs. +// Only handles migration from deprecated field to new field. +// Inheritance from top-level is handled at runtime in service reconciliation. +func (r *OpenStackControlPlane) migrateServiceNotificationsBusInstance( + serviceNotificationsBus **rabbitmqv1.RabbitMqConfig, + deprecatedField **string, + serviceName string, +) { + // Only migrate if deprecated field is set + if deprecatedField != nil && *deprecatedField != nil && **deprecatedField != "" { + // Initialize NotificationsBus if needed + if *serviceNotificationsBus == nil { + *serviceNotificationsBus = &rabbitmqv1.RabbitMqConfig{} + } + + // Only migrate if cluster is not already set + if (*serviceNotificationsBus).Cluster == "" { + (*serviceNotificationsBus).Cluster = **deprecatedField + openstackcontrolplanelog.Info("Migrated service notificationsBusInstance to notificationsBus.cluster", + "instance", r.Name, + "service", serviceName, + "cluster", (*serviceNotificationsBus).Cluster) + } + + // Clear deprecated field after migration + *deprecatedField = nil + } +} diff --git a/api/core/v1beta1/openstackcontrolplane_webhook_test.go b/api/core/v1beta1/openstackcontrolplane_webhook_test.go new file mode 100644 index 000000000..877393361 --- /dev/null +++ b/api/core/v1beta1/openstackcontrolplane_webhook_test.go @@ -0,0 +1,945 @@ +package v1beta1 + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + barbicanv1 "github.com/openstack-k8s-operators/barbican-operator/api/v1beta1" + cinderv1 "github.com/openstack-k8s-operators/cinder-operator/api/v1beta1" + designatev1 "github.com/openstack-k8s-operators/designate-operator/api/v1beta1" + heatv1 "github.com/openstack-k8s-operators/heat-operator/api/v1beta1" + rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1" + ironicv1 "github.com/openstack-k8s-operators/ironic-operator/api/v1beta1" + keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" + manilav1 "github.com/openstack-k8s-operators/manila-operator/api/v1beta1" + neutronv1 "github.com/openstack-k8s-operators/neutron-operator/api/v1beta1" + novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" + octaviav1 "github.com/openstack-k8s-operators/octavia-operator/api/v1beta1" + swiftv1 "github.com/openstack-k8s-operators/swift-operator/api/v1beta1" + telemetryv1 "github.com/openstack-k8s-operators/telemetry-operator/api/v1beta1" + watcherv1 "github.com/openstack-k8s-operators/watcher-operator/api/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "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()) + }) + }) + + Context("migrateDeprecatedFields", func() { + var instance *OpenStackControlPlane + + BeforeEach(func() { + instance = &OpenStackControlPlane{ + Spec: OpenStackControlPlaneSpec{}, + } + }) + + It("should migrate NotificationsBusInstance to NotificationsBus.Cluster", func() { + deprecatedValue := "rabbitmq-notifications" + instance.Spec.NotificationsBusInstance = &deprecatedValue + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.NotificationsBus.Cluster).To(Equal("rabbitmq-notifications")) + Expect(instance.Spec.NotificationsBusInstance).To(BeNil()) + }) + + It("should not overwrite existing NotificationsBus.Cluster", func() { + deprecatedValue := "rabbitmq-old" + instance.Spec.NotificationsBusInstance = &deprecatedValue + instance.Spec.NotificationsBus = &rabbitmqv1.RabbitMqConfig{ + Cluster: "rabbitmq-new", + } + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.NotificationsBus.Cluster).To(Equal("rabbitmq-new")) + Expect(instance.Spec.NotificationsBusInstance).To(BeNil()) + }) + + It("should handle empty NotificationsBusInstance", func() { + emptyValue := "" + instance.Spec.NotificationsBusInstance = &emptyValue + + instance.migrateDeprecatedFields() + + // Should not create NotificationsBus for empty deprecated value + Expect(instance.Spec.NotificationsBus).To(BeNil()) + Expect(instance.Spec.NotificationsBusInstance).To(Equal(&emptyValue)) + }) + + It("should handle nil NotificationsBusInstance", func() { + instance.Spec.NotificationsBusInstance = nil + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.NotificationsBus).To(BeNil()) + Expect(instance.Spec.NotificationsBusInstance).To(BeNil()) + }) + + It("should preserve other NotificationsBus fields during migration", func() { + deprecatedValue := "rabbitmq-cluster" + instance.Spec.NotificationsBusInstance = &deprecatedValue + instance.Spec.NotificationsBus = &rabbitmqv1.RabbitMqConfig{ + Vhost: "/custom-vhost", + } + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.NotificationsBus.Cluster).To(Equal("rabbitmq-cluster")) + Expect(instance.Spec.NotificationsBus.Vhost).To(Equal("/custom-vhost")) + Expect(instance.Spec.NotificationsBusInstance).To(BeNil()) + }) + }) + + Context("ValidateUpdate with annotation trigger", func() { + const reconcileTriggerAnnotation = "openstack.org/reconcile-trigger" + + It("should perform migration when reconcile trigger annotation is present", func() { + deprecatedValue := "rabbitmq-notifications" + instance := &OpenStackControlPlane{ + Spec: OpenStackControlPlaneSpec{ + NotificationsBusInstance: &deprecatedValue, + }, + } + instance.SetAnnotations(map[string]string{ + reconcileTriggerAnnotation: "2024-01-01T00:00:00Z", + }) + + oldInstance := &OpenStackControlPlane{ + Spec: OpenStackControlPlaneSpec{ + NotificationsBusInstance: &deprecatedValue, + }, + } + + _, err := instance.ValidateUpdate(nil, oldInstance, nil) + Expect(err).ToNot(HaveOccurred()) + + // Migration should have occurred + Expect(instance.Spec.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.NotificationsBus.Cluster).To(Equal("rabbitmq-notifications")) + Expect(instance.Spec.NotificationsBusInstance).To(BeNil()) + + // Annotation should be removed + Expect(instance.GetAnnotations()).ToNot(HaveKey(reconcileTriggerAnnotation)) + }) + + It("should not perform migration when annotation is absent", func() { + deprecatedValue := "rabbitmq-notifications" + instance := &OpenStackControlPlane{ + Spec: OpenStackControlPlaneSpec{ + NotificationsBusInstance: &deprecatedValue, + }, + } + + oldInstance := &OpenStackControlPlane{ + Spec: OpenStackControlPlaneSpec{ + NotificationsBusInstance: &deprecatedValue, + }, + } + + _, err := instance.ValidateUpdate(nil, oldInstance, nil) + Expect(err).ToNot(HaveOccurred()) + + // Migration should NOT have occurred + Expect(instance.Spec.NotificationsBus).To(BeNil()) + Expect(instance.Spec.NotificationsBusInstance).To(Equal(&deprecatedValue)) + }) + }) + + Context("Service-level messaging bus migrations", func() { + var instance *OpenStackControlPlane + + BeforeEach(func() { + instance = &OpenStackControlPlane{ + Spec: OpenStackControlPlaneSpec{}, + } + }) + + It("should migrate all service-level rabbitMqClusterName to messagingBus.cluster", func() { + // Cinder + cinderTemplate := &cinderv1.CinderSpecCore{} + cinderTemplate.RabbitMqClusterName = "cinder-rmq" + instance.Spec.Cinder.Template = cinderTemplate + + // Manila + manilaTemplate := &manilav1.ManilaSpecCore{} + manilaTemplate.RabbitMqClusterName = "manila-rmq" + instance.Spec.Manila.Template = manilaTemplate + + // Neutron + neutronTemplate := &neutronv1.NeutronAPISpecCore{} + neutronTemplate.RabbitMqClusterName = "neutron-rmq" + instance.Spec.Neutron.Template = neutronTemplate + + // Heat + heatTemplate := &heatv1.HeatSpecCore{} + heatTemplate.RabbitMqClusterName = "heat-rmq" + instance.Spec.Heat.Template = heatTemplate + + // Ironic + ironicTemplate := &ironicv1.IronicSpecCore{} + ironicTemplate.RabbitMqClusterName = "ironic-rmq" + instance.Spec.Ironic.Template = ironicTemplate + + // Barbican + barbicanTemplate := &barbicanv1.BarbicanSpecCore{} + barbicanTemplate.RabbitMqClusterName = "barbican-rmq" + instance.Spec.Barbican.Template = barbicanTemplate + + // Designate + designateTemplate := &designatev1.DesignateSpecCore{} + designateTemplate.RabbitMqClusterName = "designate-rmq" + instance.Spec.Designate.Template = designateTemplate + + // Octavia + octaviaTemplate := &octaviav1.OctaviaSpecCore{} + octaviaTemplate.RabbitMqClusterName = "octavia-rmq" + instance.Spec.Octavia.Template = octaviaTemplate + + // Watcher (uses pointer for RabbitMqClusterName) + watcherTemplate := &watcherv1.WatcherSpecCore{} + watcherRmq := "watcher-rmq" + watcherTemplate.RabbitMqClusterName = &watcherRmq + instance.Spec.Watcher.Template = watcherTemplate + + // Execute migration + instance.migrateDeprecatedFields() + + // Verify: All services migrated and deprecated fields cleared + Expect(instance.Spec.Cinder.Template.MessagingBus.Cluster).To(Equal("cinder-rmq")) + Expect(instance.Spec.Cinder.Template.RabbitMqClusterName).To(Equal("")) + + Expect(instance.Spec.Manila.Template.MessagingBus.Cluster).To(Equal("manila-rmq")) + Expect(instance.Spec.Manila.Template.RabbitMqClusterName).To(Equal("")) + + Expect(instance.Spec.Neutron.Template.MessagingBus.Cluster).To(Equal("neutron-rmq")) + Expect(instance.Spec.Neutron.Template.RabbitMqClusterName).To(Equal("")) + + Expect(instance.Spec.Heat.Template.MessagingBus.Cluster).To(Equal("heat-rmq")) + Expect(instance.Spec.Heat.Template.RabbitMqClusterName).To(Equal("")) + + Expect(instance.Spec.Ironic.Template.MessagingBus.Cluster).To(Equal("ironic-rmq")) + Expect(instance.Spec.Ironic.Template.RabbitMqClusterName).To(Equal("")) + + Expect(instance.Spec.Barbican.Template.MessagingBus.Cluster).To(Equal("barbican-rmq")) + Expect(instance.Spec.Barbican.Template.RabbitMqClusterName).To(Equal("")) + + Expect(instance.Spec.Designate.Template.MessagingBus.Cluster).To(Equal("designate-rmq")) + Expect(instance.Spec.Designate.Template.RabbitMqClusterName).To(Equal("")) + + Expect(instance.Spec.Octavia.Template.MessagingBus.Cluster).To(Equal("octavia-rmq")) + Expect(instance.Spec.Octavia.Template.RabbitMqClusterName).To(Equal("")) + + Expect(instance.Spec.Watcher.Template.MessagingBus.Cluster).To(Equal("watcher-rmq")) + Expect(instance.Spec.Watcher.Template.RabbitMqClusterName).To(BeNil()) + }) + + It("should migrate Keystone rabbitMqClusterName to notificationsBus.cluster", func() { + keystoneTemplate := &keystonev1.KeystoneAPISpecCore{} + keystoneTemplate.RabbitMqClusterName = "keystone-rmq" + instance.Spec.Keystone.Template = keystoneTemplate + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.Keystone.Template.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.Keystone.Template.NotificationsBus.Cluster).To(Equal("keystone-rmq")) + Expect(instance.Spec.Keystone.Template.RabbitMqClusterName).To(Equal("")) + }) + + It("should migrate Swift SwiftProxy rabbitMqClusterName to notificationsBus.cluster", func() { + swiftTemplate := &swiftv1.SwiftSpecCore{} + swiftTemplate.SwiftProxy.RabbitMqClusterName = "swift-rmq" + instance.Spec.Swift.Template = swiftTemplate + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.Swift.Template.SwiftProxy.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.Swift.Template.SwiftProxy.NotificationsBus.Cluster).To(Equal("swift-rmq")) + Expect(instance.Spec.Swift.Template.SwiftProxy.RabbitMqClusterName).To(Equal("")) + }) + + It("should migrate Nova API and cell-level messaging bus fields", func() { + novaTemplate := &novav1.NovaSpecCore{} + novaTemplate.APIMessageBusInstance = "nova-api-rmq" + novaTemplate.CellTemplates = map[string]novav1.NovaCellTemplate{ + "cell0": { + CellMessageBusInstance: "nova-cell0-rmq", + }, + "cell1": { + CellMessageBusInstance: "nova-cell1-rmq", + }, + } + instance.Spec.Nova.Template = novaTemplate + + instance.migrateDeprecatedFields() + + // Verify API-level migration + Expect(instance.Spec.Nova.Template.MessagingBus.Cluster).To(Equal("nova-api-rmq")) + Expect(instance.Spec.Nova.Template.APIMessageBusInstance).To(Equal("")) + + // Verify cell-level migrations + Expect(instance.Spec.Nova.Template.CellTemplates["cell0"].MessagingBus.Cluster).To(Equal("nova-cell0-rmq")) + Expect(instance.Spec.Nova.Template.CellTemplates["cell0"].CellMessageBusInstance).To(Equal("")) + + Expect(instance.Spec.Nova.Template.CellTemplates["cell1"].MessagingBus.Cluster).To(Equal("nova-cell1-rmq")) + Expect(instance.Spec.Nova.Template.CellTemplates["cell1"].CellMessageBusInstance).To(Equal("")) + }) + + It("should migrate Telemetry sub-services correctly", func() { + telemetryTemplate := &telemetryv1.TelemetrySpecCore{} + + // CloudKitty - uses MessagingBus + telemetryTemplate.CloudKitty.RabbitMqClusterName = "cloudkitty-rmq" + + // Aodh - uses NotificationsBus + telemetryTemplate.Autoscaling.Aodh.RabbitMqClusterName = "aodh-rmq" + + // Ceilometer - uses NotificationsBus + telemetryTemplate.Ceilometer.RabbitMqClusterName = "ceilometer-rmq" + + instance.Spec.Telemetry.Template = telemetryTemplate + + instance.migrateDeprecatedFields() + + // CloudKitty uses MessagingBus + Expect(instance.Spec.Telemetry.Template.CloudKitty.MessagingBus.Cluster).To(Equal("cloudkitty-rmq")) + Expect(instance.Spec.Telemetry.Template.CloudKitty.RabbitMqClusterName).To(Equal("")) + + // Aodh uses NotificationsBus + Expect(instance.Spec.Telemetry.Template.Autoscaling.Aodh.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.Telemetry.Template.Autoscaling.Aodh.NotificationsBus.Cluster).To(Equal("aodh-rmq")) + Expect(instance.Spec.Telemetry.Template.Autoscaling.Aodh.RabbitMqClusterName).To(Equal("")) + + // Ceilometer uses NotificationsBus + Expect(instance.Spec.Telemetry.Template.Ceilometer.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.Telemetry.Template.Ceilometer.NotificationsBus.Cluster).To(Equal("ceilometer-rmq")) + Expect(instance.Spec.Telemetry.Template.Ceilometer.RabbitMqClusterName).To(Equal("")) + }) + + It("should migrate IronicNeutronAgent with parent-service inheritance", func() { + ironicTemplate := &ironicv1.IronicSpecCore{} + ironicTemplate.RabbitMqClusterName = "ironic-rmq" + ironicTemplate.IronicNeutronAgent.RabbitMqClusterName = "ironic-agent-rmq" + instance.Spec.Ironic.Template = ironicTemplate + + instance.migrateDeprecatedFields() + + // Verify Ironic main template migrated + Expect(instance.Spec.Ironic.Template.MessagingBus.Cluster).To(Equal("ironic-rmq")) + Expect(instance.Spec.Ironic.Template.RabbitMqClusterName).To(Equal("")) + + // Verify IronicNeutronAgent migrated + Expect(instance.Spec.Ironic.Template.IronicNeutronAgent.MessagingBus.Cluster).To(Equal("ironic-agent-rmq")) + Expect(instance.Spec.Ironic.Template.IronicNeutronAgent.RabbitMqClusterName).To(Equal("")) + }) + + It("should only migrate IronicNeutronAgent when deprecated field is set", func() { + ironicTemplate := &ironicv1.IronicSpecCore{} + ironicTemplate.RabbitMqClusterName = "ironic-rmq" + ironicTemplate.IronicNeutronAgent.RabbitMqClusterName = "neutron-agent-rmq" + instance.Spec.Ironic.Template = ironicTemplate + + instance.migrateDeprecatedFields() + + // Ironic migrated + Expect(instance.Spec.Ironic.Template.MessagingBus.Cluster).To(Equal("ironic-rmq")) + + // IronicNeutronAgent migrated from its own deprecated field + Expect(instance.Spec.Ironic.Template.IronicNeutronAgent.MessagingBus.Cluster).To(Equal("neutron-agent-rmq")) + }) + + It("should NOT persist top-level messagingBus to service when service deprecated field is empty", func() { + instance.Spec.MessagingBus = &rabbitmqv1.RabbitMqConfig{ + Cluster: "top-level-rmq", + Vhost: "/custom", + } + cinderTemplate := &cinderv1.CinderSpecCore{} + // No RabbitMqClusterName set - should NOT inherit in webhook + instance.Spec.Cinder.Template = cinderTemplate + + instance.migrateDeprecatedFields() + + // Service-level field should remain empty - inheritance happens at runtime + Expect(instance.Spec.Cinder.Template.MessagingBus.Cluster).To(Equal("")) + }) + + It("should NOT persist top-level notificationsBus to Keystone when deprecated field is empty", func() { + instance.Spec.NotificationsBus = &rabbitmqv1.RabbitMqConfig{ + Cluster: "top-level-notifications", + } + keystoneTemplate := &keystonev1.KeystoneAPISpecCore{} + // No RabbitMqClusterName set - should NOT inherit in webhook + instance.Spec.Keystone.Template = keystoneTemplate + + instance.migrateDeprecatedFields() + + // Service-level field should remain nil - inheritance happens at runtime + Expect(instance.Spec.Keystone.Template.NotificationsBus).To(BeNil()) + }) + + It("should NOT apply default when no deprecated field is set", func() { + cinderTemplate := &cinderv1.CinderSpecCore{} + // No RabbitMqClusterName, no top-level - should NOT set default in webhook + instance.Spec.Cinder.Template = cinderTemplate + + instance.migrateDeprecatedFields() + + // Service-level field should remain empty - defaults applied at runtime + Expect(instance.Spec.Cinder.Template.MessagingBus.Cluster).To(Equal("")) + }) + + It("should NOT default notificationsBus (optional field)", func() { + keystoneTemplate := &keystonev1.KeystoneAPISpecCore{} + // No RabbitMqClusterName, no top-level - should remain nil + instance.Spec.Keystone.Template = keystoneTemplate + + instance.migrateDeprecatedFields() + + // NotificationsBus is optional, so it should remain nil + Expect(instance.Spec.Keystone.Template.NotificationsBus).To(BeNil()) + }) + + It("should migrate all service-level notificationsBusInstance to notificationsBus.cluster", func() { + // Cinder + cinderTemplate := &cinderv1.CinderSpecCore{} + cinderNotif := "cinder-notif-rmq" + cinderTemplate.NotificationsBusInstance = &cinderNotif + instance.Spec.Cinder.Template = cinderTemplate + + // Manila + manilaTemplate := &manilav1.ManilaSpecCore{} + manilaNotif := "manila-notif-rmq" + manilaTemplate.NotificationsBusInstance = &manilaNotif + instance.Spec.Manila.Template = manilaTemplate + + // Neutron + neutronTemplate := &neutronv1.NeutronAPISpecCore{} + neutronNotif := "neutron-notif-rmq" + neutronTemplate.NotificationsBusInstance = &neutronNotif + instance.Spec.Neutron.Template = neutronTemplate + + // Nova + novaTemplate := &novav1.NovaSpecCore{} + novaNotif := "nova-notif-rmq" + novaTemplate.NotificationsBusInstance = &novaNotif + instance.Spec.Nova.Template = novaTemplate + + // Watcher + watcherTemplate := &watcherv1.WatcherSpecCore{} + watcherNotif := "watcher-notif-rmq" + watcherTemplate.NotificationsBusInstance = &watcherNotif + instance.Spec.Watcher.Template = watcherTemplate + + // Execute migration + instance.migrateDeprecatedFields() + + // Verify: All services migrated and deprecated fields cleared + Expect(instance.Spec.Cinder.Template.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.Cinder.Template.NotificationsBus.Cluster).To(Equal("cinder-notif-rmq")) + Expect(instance.Spec.Cinder.Template.NotificationsBusInstance).To(BeNil()) + + Expect(instance.Spec.Manila.Template.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.Manila.Template.NotificationsBus.Cluster).To(Equal("manila-notif-rmq")) + Expect(instance.Spec.Manila.Template.NotificationsBusInstance).To(BeNil()) + + Expect(instance.Spec.Neutron.Template.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.Neutron.Template.NotificationsBus.Cluster).To(Equal("neutron-notif-rmq")) + Expect(instance.Spec.Neutron.Template.NotificationsBusInstance).To(BeNil()) + + Expect(instance.Spec.Nova.Template.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.Nova.Template.NotificationsBus.Cluster).To(Equal("nova-notif-rmq")) + Expect(instance.Spec.Nova.Template.NotificationsBusInstance).To(BeNil()) + + Expect(instance.Spec.Watcher.Template.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.Watcher.Template.NotificationsBus.Cluster).To(Equal("watcher-notif-rmq")) + Expect(instance.Spec.Watcher.Template.NotificationsBusInstance).To(BeNil()) + }) + + It("should not overwrite existing service-level notificationsBus.cluster", func() { + // Cinder - has deprecated field but also has new field set + cinderTemplate := &cinderv1.CinderSpecCore{} + cinderDeprecated := "cinder-old" + cinderTemplate.NotificationsBusInstance = &cinderDeprecated + cinderTemplate.NotificationsBus = &rabbitmqv1.RabbitMqConfig{ + Cluster: "cinder-new", + } + instance.Spec.Cinder.Template = cinderTemplate + + instance.migrateDeprecatedFields() + + // Should keep the existing value, not overwrite + Expect(instance.Spec.Cinder.Template.NotificationsBus.Cluster).To(Equal("cinder-new")) + Expect(instance.Spec.Cinder.Template.NotificationsBusInstance).To(BeNil()) + }) + + It("should NOT persist top-level notificationsBus when service-level is nil", func() { + // Set top-level notificationsBus + instance.Spec.NotificationsBus = &rabbitmqv1.RabbitMqConfig{ + Cluster: "top-level-notif", + } + + // Cinder has no notificationsBusInstance and no notificationsBus + cinderTemplate := &cinderv1.CinderSpecCore{} + instance.Spec.Cinder.Template = cinderTemplate + + instance.migrateDeprecatedFields() + + // Should NOT inherit in webhook - inheritance happens at runtime + Expect(instance.Spec.Cinder.Template.NotificationsBus).To(BeNil()) + }) + }) + + Context("Comprehensive migration and inheritance scenarios", func() { + var instance *OpenStackControlPlane + + BeforeEach(func() { + instance = &OpenStackControlPlane{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "test-namespace", + }, + Spec: OpenStackControlPlaneSpec{}, + } + }) + + Context("Scenario 1: Migration from deprecated fields", func() { + It("should migrate top-level notificationsBusInstance to notificationsBus", func() { + notifInstance := "top-notif-cluster" + instance.Spec.NotificationsBusInstance = ¬ifInstance + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.NotificationsBus.Cluster).To(Equal("top-notif-cluster")) + Expect(instance.Spec.NotificationsBusInstance).To(BeNil()) + }) + + It("should migrate service-level rabbitMqClusterName to messagingBus.cluster", func() { + cinderTemplate := &cinderv1.CinderSpecCore{} + cinderTemplate.RabbitMqClusterName = "cinder-rabbit" + instance.Spec.Cinder.Template = cinderTemplate + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.Cinder.Template.MessagingBus.Cluster).To(Equal("cinder-rabbit")) + Expect(instance.Spec.Cinder.Template.RabbitMqClusterName).To(Equal("")) + }) + + It("should migrate Nova API-level APIMessageBusInstance", func() { + novaTemplate := &novav1.NovaSpecCore{} + novaTemplate.APIMessageBusInstance = "nova-api-rabbit" + instance.Spec.Nova.Template = novaTemplate + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.Nova.Template.MessagingBus.Cluster).To(Equal("nova-api-rabbit")) + Expect(instance.Spec.Nova.Template.APIMessageBusInstance).To(Equal("")) + }) + + It("should migrate Nova cell-level CellMessageBusInstance", func() { + novaTemplate := &novav1.NovaSpecCore{ + CellTemplates: make(map[string]novav1.NovaCellTemplate), + } + novaTemplate.CellTemplates["cell1"] = novav1.NovaCellTemplate{ + CellMessageBusInstance: "cell1-rabbit", + } + instance.Spec.Nova.Template = novaTemplate + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.Nova.Template.CellTemplates["cell1"].MessagingBus.Cluster).To(Equal("cell1-rabbit")) + Expect(instance.Spec.Nova.Template.CellTemplates["cell1"].CellMessageBusInstance).To(Equal("")) + }) + + It("should migrate Telemetry CloudKitty rabbitMqClusterName", func() { + telemetryTemplate := &telemetryv1.TelemetrySpecCore{} + telemetryTemplate.CloudKitty.RabbitMqClusterName = "cloudkitty-rabbit" + instance.Spec.Telemetry.Template = telemetryTemplate + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.Telemetry.Template.CloudKitty.MessagingBus.Cluster).To(Equal("cloudkitty-rabbit")) + Expect(instance.Spec.Telemetry.Template.CloudKitty.RabbitMqClusterName).To(Equal("")) + }) + + It("should migrate Ironic and IronicNeutronAgent separately", func() { + ironicTemplate := &ironicv1.IronicSpecCore{} + ironicTemplate.RabbitMqClusterName = "ironic-rabbit" + ironicTemplate.IronicNeutronAgent.RabbitMqClusterName = "neutron-agent-rabbit" + instance.Spec.Ironic.Template = ironicTemplate + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.Ironic.Template.MessagingBus.Cluster).To(Equal("ironic-rabbit")) + Expect(instance.Spec.Ironic.Template.IronicNeutronAgent.MessagingBus.Cluster).To(Equal("neutron-agent-rabbit")) + }) + }) + + Context("Scenario 2: Top-level parameters without deprecated fields", func() { + It("should NOT persist top-level messagingBus to service-level in webhook", func() { + instance.Spec.MessagingBus = &rabbitmqv1.RabbitMqConfig{ + Cluster: "global-rabbit", + Vhost: "/global", + } + cinderTemplate := &cinderv1.CinderSpecCore{} + instance.Spec.Cinder.Template = cinderTemplate + + instance.migrateDeprecatedFields() + + // Webhook should NOT persist the inheritance + Expect(instance.Spec.Cinder.Template.MessagingBus.Cluster).To(Equal("")) + }) + + It("should NOT persist top-level notificationsBus to service-level in webhook", func() { + instance.Spec.NotificationsBus = &rabbitmqv1.RabbitMqConfig{ + Cluster: "global-notif", + } + cinderTemplate := &cinderv1.CinderSpecCore{} + instance.Spec.Cinder.Template = cinderTemplate + + instance.migrateDeprecatedFields() + + // Webhook should NOT persist the inheritance + Expect(instance.Spec.Cinder.Template.NotificationsBus).To(BeNil()) + }) + + It("should NOT persist top-level messagingBus to Nova cells in webhook", func() { + instance.Spec.MessagingBus = &rabbitmqv1.RabbitMqConfig{ + Cluster: "global-rabbit", + } + novaTemplate := &novav1.NovaSpecCore{ + CellTemplates: make(map[string]novav1.NovaCellTemplate), + } + novaTemplate.CellTemplates["cell0"] = novav1.NovaCellTemplate{} + novaTemplate.CellTemplates["cell1"] = novav1.NovaCellTemplate{} + instance.Spec.Nova.Template = novaTemplate + + instance.migrateDeprecatedFields() + + // Webhook should NOT persist the inheritance to cells + Expect(instance.Spec.Nova.Template.MessagingBus.Cluster).To(Equal("")) + Expect(instance.Spec.Nova.Template.CellTemplates["cell0"].MessagingBus.Cluster).To(Equal("")) + Expect(instance.Spec.Nova.Template.CellTemplates["cell1"].MessagingBus.Cluster).To(Equal("")) + }) + }) + + Context("Scenario 3: Top-level with per-service overrides", func() { + It("should migrate deprecated field and ignore top-level when service has deprecated field", func() { + instance.Spec.MessagingBus = &rabbitmqv1.RabbitMqConfig{ + Cluster: "global-rabbit", + } + cinderTemplate := &cinderv1.CinderSpecCore{} + cinderTemplate.RabbitMqClusterName = "cinder-specific-rabbit" + instance.Spec.Cinder.Template = cinderTemplate + + instance.migrateDeprecatedFields() + + // Service-level deprecated field takes precedence + Expect(instance.Spec.Cinder.Template.MessagingBus.Cluster).To(Equal("cinder-specific-rabbit")) + Expect(instance.Spec.Cinder.Template.RabbitMqClusterName).To(Equal("")) + }) + + It("should preserve explicit service-level messagingBus when it exists", func() { + instance.Spec.MessagingBus = &rabbitmqv1.RabbitMqConfig{ + Cluster: "global-rabbit", + } + cinderTemplate := &cinderv1.CinderSpecCore{} + cinderTemplate.MessagingBus = rabbitmqv1.RabbitMqConfig{ + Cluster: "cinder-explicit", + Vhost: "/cinder", + } + instance.Spec.Cinder.Template = cinderTemplate + + instance.migrateDeprecatedFields() + + // Explicit service-level should be preserved + Expect(instance.Spec.Cinder.Template.MessagingBus.Cluster).To(Equal("cinder-explicit")) + Expect(instance.Spec.Cinder.Template.MessagingBus.Vhost).To(Equal("/cinder")) + }) + + It("should handle mixed scenario: some services with deprecated, some without", func() { + instance.Spec.MessagingBus = &rabbitmqv1.RabbitMqConfig{ + Cluster: "global-rabbit", + } + + // Cinder has deprecated field + cinderTemplate := &cinderv1.CinderSpecCore{} + cinderTemplate.RabbitMqClusterName = "cinder-rabbit" + instance.Spec.Cinder.Template = cinderTemplate + + // Manila has no deprecated field + manilaTemplate := &manilav1.ManilaSpecCore{} + instance.Spec.Manila.Template = manilaTemplate + + instance.migrateDeprecatedFields() + + // Cinder should migrate from deprecated field + Expect(instance.Spec.Cinder.Template.MessagingBus.Cluster).To(Equal("cinder-rabbit")) + + // Manila should remain empty (inheritance happens at runtime, not in webhook) + Expect(instance.Spec.Manila.Template.MessagingBus.Cluster).To(Equal("")) + }) + + It("should handle Nova with top-level, API-level deprecated, and cell-level explicit", func() { + instance.Spec.MessagingBus = &rabbitmqv1.RabbitMqConfig{ + Cluster: "global-rabbit", + } + + novaTemplate := &novav1.NovaSpecCore{ + APIMessageBusInstance: "nova-api-rabbit", + CellTemplates: make(map[string]novav1.NovaCellTemplate), + } + // cell0 with deprecated field + novaTemplate.CellTemplates["cell0"] = novav1.NovaCellTemplate{ + CellMessageBusInstance: "cell0-rabbit", + } + // cell1 with explicit messagingBus + novaTemplate.CellTemplates["cell1"] = novav1.NovaCellTemplate{ + MessagingBus: rabbitmqv1.RabbitMqConfig{ + Cluster: "cell1-explicit", + }, + } + instance.Spec.Nova.Template = novaTemplate + + instance.migrateDeprecatedFields() + + // API-level should migrate + Expect(instance.Spec.Nova.Template.MessagingBus.Cluster).To(Equal("nova-api-rabbit")) + // cell0 should migrate from deprecated field + Expect(instance.Spec.Nova.Template.CellTemplates["cell0"].MessagingBus.Cluster).To(Equal("cell0-rabbit")) + // cell1 should keep explicit value + Expect(instance.Spec.Nova.Template.CellTemplates["cell1"].MessagingBus.Cluster).To(Equal("cell1-explicit")) + }) + }) + + Context("Scenario 4: NotificationsBus-specific services", func() { + It("should migrate Keystone rabbitMqClusterName to notificationsBus", func() { + keystoneTemplate := &keystonev1.KeystoneAPISpecCore{} + keystoneTemplate.RabbitMqClusterName = "keystone-rabbit" + instance.Spec.Keystone.Template = keystoneTemplate + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.Keystone.Template.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.Keystone.Template.NotificationsBus.Cluster).To(Equal("keystone-rabbit")) + Expect(instance.Spec.Keystone.Template.RabbitMqClusterName).To(Equal("")) + }) + + It("should migrate Swift SwiftProxy rabbitMqClusterName to notificationsBus", func() { + swiftTemplate := &swiftv1.SwiftSpecCore{} + swiftTemplate.SwiftProxy.RabbitMqClusterName = "swift-rabbit" + instance.Spec.Swift.Template = swiftTemplate + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.Swift.Template.SwiftProxy.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.Swift.Template.SwiftProxy.NotificationsBus.Cluster).To(Equal("swift-rabbit")) + Expect(instance.Spec.Swift.Template.SwiftProxy.RabbitMqClusterName).To(Equal("")) + }) + + It("should migrate Telemetry Aodh and Ceilometer rabbitMqClusterName", func() { + telemetryTemplate := &telemetryv1.TelemetrySpecCore{} + telemetryTemplate.Autoscaling.Aodh.RabbitMqClusterName = "aodh-rabbit" + telemetryTemplate.Ceilometer.RabbitMqClusterName = "ceilometer-rabbit" + instance.Spec.Telemetry.Template = telemetryTemplate + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.Telemetry.Template.Autoscaling.Aodh.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.Telemetry.Template.Autoscaling.Aodh.NotificationsBus.Cluster).To(Equal("aodh-rabbit")) + Expect(instance.Spec.Telemetry.Template.Ceilometer.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.Telemetry.Template.Ceilometer.NotificationsBus.Cluster).To(Equal("ceilometer-rabbit")) + }) + }) + + Context("Scenario 5: Services with both MessagingBus and NotificationsBus", func() { + It("should migrate both rabbitMqClusterName and notificationsBusInstance for Cinder", func() { + cinderTemplate := &cinderv1.CinderSpecCore{} + cinderTemplate.RabbitMqClusterName = "cinder-rpc-rabbit" + notifInstance := "cinder-notif-rabbit" + cinderTemplate.NotificationsBusInstance = ¬ifInstance + instance.Spec.Cinder.Template = cinderTemplate + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.Cinder.Template.MessagingBus.Cluster).To(Equal("cinder-rpc-rabbit")) + Expect(instance.Spec.Cinder.Template.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.Cinder.Template.NotificationsBus.Cluster).To(Equal("cinder-notif-rabbit")) + Expect(instance.Spec.Cinder.Template.RabbitMqClusterName).To(Equal("")) + Expect(instance.Spec.Cinder.Template.NotificationsBusInstance).To(BeNil()) + }) + + It("should handle Watcher with pointer-type RabbitMqClusterName", func() { + watcherTemplate := &watcherv1.WatcherSpecCore{} + rabbitCluster := "watcher-rabbit" + watcherTemplate.RabbitMqClusterName = &rabbitCluster + notifInstance := "watcher-notif" + watcherTemplate.NotificationsBusInstance = ¬ifInstance + instance.Spec.Watcher.Template = watcherTemplate + + instance.migrateDeprecatedFields() + + Expect(instance.Spec.Watcher.Template.MessagingBus.Cluster).To(Equal("watcher-rabbit")) + Expect(instance.Spec.Watcher.Template.NotificationsBus).ToNot(BeNil()) + Expect(instance.Spec.Watcher.Template.NotificationsBus.Cluster).To(Equal("watcher-notif")) + Expect(instance.Spec.Watcher.Template.RabbitMqClusterName).To(BeNil()) + Expect(instance.Spec.Watcher.Template.NotificationsBusInstance).To(BeNil()) + }) + }) + + Context("Scenario 6: Edge cases", func() { + It("should not overwrite existing new field when migrating deprecated field", func() { + cinderTemplate := &cinderv1.CinderSpecCore{} + cinderTemplate.RabbitMqClusterName = "old-cinder-rabbit" + cinderTemplate.MessagingBus = rabbitmqv1.RabbitMqConfig{ + Cluster: "new-cinder-rabbit", + Vhost: "/cinder", + } + instance.Spec.Cinder.Template = cinderTemplate + + instance.migrateDeprecatedFields() + + // Should keep the new field value, not overwrite with deprecated + Expect(instance.Spec.Cinder.Template.MessagingBus.Cluster).To(Equal("new-cinder-rabbit")) + Expect(instance.Spec.Cinder.Template.MessagingBus.Vhost).To(Equal("/cinder")) + // Deprecated field should still be cleared + Expect(instance.Spec.Cinder.Template.RabbitMqClusterName).To(Equal("")) + }) + + It("should handle empty string deprecated field gracefully", func() { + cinderTemplate := &cinderv1.CinderSpecCore{} + cinderTemplate.RabbitMqClusterName = "" + instance.Spec.Cinder.Template = cinderTemplate + + instance.migrateDeprecatedFields() + + // Should not migrate empty string + Expect(instance.Spec.Cinder.Template.MessagingBus.Cluster).To(Equal("")) + }) + + It("should handle nil deprecated pointer field gracefully", func() { + watcherTemplate := &watcherv1.WatcherSpecCore{} + watcherTemplate.RabbitMqClusterName = nil + instance.Spec.Watcher.Template = watcherTemplate + + instance.migrateDeprecatedFields() + + // Should not panic, messagingBus should remain empty + Expect(instance.Spec.Watcher.Template.MessagingBus.Cluster).To(Equal("")) + }) + }) + }) +}) diff --git a/api/core/v1beta1/zz_generated.deepcopy.go b/api/core/v1beta1/zz_generated.deepcopy.go index 950361fe3..b8b1cf7fe 100644 --- a/api/core/v1beta1/zz_generated.deepcopy.go +++ b/api/core/v1beta1/zz_generated.deepcopy.go @@ -1293,11 +1293,21 @@ func (in *OpenStackControlPlaneSpec) DeepCopyInto(out *OpenStackControlPlaneSpec in.Cinder.DeepCopyInto(&out.Cinder) in.Galera.DeepCopyInto(&out.Galera) in.Rabbitmq.DeepCopyInto(&out.Rabbitmq) + if in.MessagingBus != nil { + in, out := &in.MessagingBus, &out.MessagingBus + *out = new(rabbitmqv1beta1.RabbitMqConfig) + **out = **in + } if in.NotificationsBusInstance != nil { in, out := &in.NotificationsBusInstance, &out.NotificationsBusInstance *out = new(string) **out = **in } + if in.NotificationsBus != nil { + in, out := &in.NotificationsBus, &out.NotificationsBus + *out = new(rabbitmqv1beta1.RabbitMqConfig) + **out = **in + } in.Memcached.DeepCopyInto(&out.Memcached) in.Ovn.DeepCopyInto(&out.Ovn) in.Neutron.DeepCopyInto(&out.Neutron) diff --git a/api/go.mod b/api/go.mod index 1092e7927..50c918180 100644 --- a/api/go.mod +++ b/api/go.mod @@ -7,28 +7,28 @@ require ( github.com/go-playground/validator/v10 v10.30.1 github.com/onsi/ginkgo/v2 v2.28.1 github.com/onsi/gomega v1.39.1 - github.com/openstack-k8s-operators/barbican-operator/api v0.6.1-0.20260130161218-ed22e21b9035 - github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20260203100410-bec3d87f42df - github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20260130194629-8145dc930d49 - github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20260203172717-de34ba474e77 - github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20260205152457-97ee6babce57 - github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20260126110912-72d03020e1a5 + github.com/openstack-k8s-operators/barbican-operator/api v0.6.1-0.20260206192347-aab776857909 + github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20260206174955-5bf43d6c75a6 + github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20260206181913-24f48ca5ba86 + github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20260206173306-e0a322fced68 + github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20260207082315-6c0673338be7 + github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20260207061358-9a5362005f8a 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.20260205123033-c9cd3795f8c6 - github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260126175636-114b4c65a959 + github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20260207081358-6dce1a518688 + github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260206181019-26ebc8a46afe github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260205083029-d03e9df035ef - github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260128142552-e2c25eccae5a - github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20260203154427-fb9213e462a4 + github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260205083029-d03e9df035ef + github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20260206173305-72969ece6ed4 github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260127154438-ff95971883bb - github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20260130110557-870de6f217b5 - github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20260205135859-d785b91fa1d7 - github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20260130160650-fee89a8e7044 + github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20260206181305-f3366b4bd37b + github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20260207082315-2e0a55b6d766 + github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20260206221031-ca09bc20f265 github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.6.1-0.20260126123727-b3f88d69956c github.com/openstack-k8s-operators/ovn-operator/api v0.6.1-0.20260126160735-3254731d17a8 github.com/openstack-k8s-operators/placement-operator/api v0.6.1-0.20260203072749-c46bb493557d - github.com/openstack-k8s-operators/swift-operator/api v0.6.1-0.20260201211658-98f018aea931 - github.com/openstack-k8s-operators/telemetry-operator/api v0.6.1-0.20260205110928-7d95eaebdfe4 - github.com/openstack-k8s-operators/watcher-operator/api v0.6.1-0.20260206073930-3cd4f1433bff + github.com/openstack-k8s-operators/swift-operator/api v0.6.1-0.20260206221909-c0927c3803e6 + github.com/openstack-k8s-operators/telemetry-operator/api v0.6.1-0.20260206181610-fe8dc27febad + github.com/openstack-k8s-operators/watcher-operator/api v0.6.1-0.20260207082017-e2c9f69be82c github.com/rhobs/obo-prometheus-operator/pkg/apis/monitoring v0.71.0-rhobs1 // indirect github.com/rhobs/observability-operator v0.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect @@ -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 diff --git a/api/go.sum b/api/go.sum index 30fa1eba7..e31d80739 100644 --- a/api/go.sum +++ b/api/go.sum @@ -114,40 +114,40 @@ github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= 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/barbican-operator/api v0.6.1-0.20260130161218-ed22e21b9035 h1:ZbEYqSRTtyXbOATlY1bDYBa0Rp3MMZjcaR0yHSgLW24= -github.com/openstack-k8s-operators/barbican-operator/api v0.6.1-0.20260130161218-ed22e21b9035/go.mod h1:tfNU2Cy1ofpDtVj+afn0u79/RDQPc7OrRE4RjurwAEQ= -github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20260203100410-bec3d87f42df h1:ry1fl+Sp4dXjt+nTe2PkCm0ZpTpiKkqStzjoPq68tuc= -github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20260203100410-bec3d87f42df/go.mod h1:j0JH8VRZHOP6pNkKSWK1Zfj8ov1yVkUwNNheu1xLbwE= -github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20260130194629-8145dc930d49 h1:wSG2ZEorUADT8VOUmKB7cOXmvYOwZMvy6ERd+6PehPg= -github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20260130194629-8145dc930d49/go.mod h1:rTrAkG8KR+P+UVXwJjrlTAuxwx3HKMPmrb24qrxLHpM= -github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20260203172717-de34ba474e77 h1:qQF4eugVDwMIFSivIq/mcsO/rDNgWZO3nEUdEEivN40= -github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20260203172717-de34ba474e77/go.mod h1:SHocUrLIilw67T26C2wMbJs6IXSWIv1PF/1VqFGxe4Q= -github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20260205152457-97ee6babce57 h1:zTujRvfAMy0o/OyebVaMhv+8wn+/8C5QvVeMmlXFdDI= -github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20260205152457-97ee6babce57/go.mod h1:mScOSRv5YDbjEPfirc2K+L7kJYZE4PoueTkFoU+BRQ0= -github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20260126110912-72d03020e1a5 h1:Rhqx9iFaZgC2VhE2IiCGqPxJtc5A4hoz/5Rv8a+gtDY= -github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20260126110912-72d03020e1a5/go.mod h1:x8muLIctcCLObcdeynPgycfQ+6ddWIDlSOQ9NElG43M= +github.com/openstack-k8s-operators/barbican-operator/api v0.6.1-0.20260206192347-aab776857909 h1:EFYSJkh2ioLxc7tm5TY7Fbd9o0KWjU/ho8rcjDVH1DU= +github.com/openstack-k8s-operators/barbican-operator/api v0.6.1-0.20260206192347-aab776857909/go.mod h1:KQnoNfCO5HHB/P6MAOE2u9V1wQbQxy5n51p8W7Dki4E= +github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20260206174955-5bf43d6c75a6 h1:3DndxajP+nBHGwLnM5UATgn2dfgRDcenaEWZrSN6LNg= +github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20260206174955-5bf43d6c75a6/go.mod h1:EzMRjjhQf66iBj1XW+87MTohQttxkVh/u0PnhKR/RQI= +github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20260206181913-24f48ca5ba86 h1:mCt50YggftseJ/Z1yx+xedmHR0yZ53b6DuhWpbIozwY= +github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20260206181913-24f48ca5ba86/go.mod h1:2tyAJhSJSiGGG0NJqqvbh64EmVCCVKNZDqkWm/KdBZA= +github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20260206173306-e0a322fced68 h1:I2GqzPBsx4DsQ432xXuScVJg/zkU75IYAOUynB2pQ74= +github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20260206173306-e0a322fced68/go.mod h1:exyWfAY4rY5VtN86WwmpaAe0Us/PCA8IdwkmfJMWz/4= +github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20260207082315-6c0673338be7 h1:quPMDHqFrMgdGXg59uehz5W3nY1hCUatXjpVBD8I5kA= +github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20260207082315-6c0673338be7/go.mod h1:T5lLlPNIJZuXRh8J1PwA1sZL3fgERGYHfisfcKZm2bI= +github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20260207061358-9a5362005f8a h1:d9KDJmBmvhyBCF30jjGc8GUr54imeyXjpt6c0aRJzEI= +github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20260207061358-9a5362005f8a/go.mod h1:36WkVJYX2dUCbg5ebp4b3RLtqz8KF0v7y98q/bw8OjI= github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260128074606-03b808364e4a h1:uJL923hT6ZJE1fKq+/FA0mVX46AgE3H+OClpL2DXq4Y= github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260128074606-03b808364e4a/go.mod h1:ZXwFlspJCdZEUjMbmaf61t5AMB4u2vMyAMMoe/vJroE= -github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20260205123033-c9cd3795f8c6 h1:NOo/jBBjvIufuuWS0ve7jsnSPH8lxJnyDJrNR0eoQ8c= -github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20260205123033-c9cd3795f8c6/go.mod h1:tsE9DPDd7XKJPYfH+cts6cbo084rargXgmeFWtw3FwA= -github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260126175636-114b4c65a959 h1:8FSpTYAoLq27ElDGe3igPl2QUq9IYD6RJGu2Xu+Ymus= -github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260126175636-114b4c65a959/go.mod h1:pN/s+czXvApiE9nxeTtDeRTXWcaaCLZSrtoyOSUb37k= +github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20260207081358-6dce1a518688 h1:PMW5Kfozot9XD8TlhdkgFCG+MuUXSW4gKTmIL4MGEw4= +github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20260207081358-6dce1a518688/go.mod h1:EL98j7yLMTRBMZsgP0LxP01qTV8SV3bGVzbHoOb+saM= +github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260206181019-26ebc8a46afe h1:Zz+qAaIumkEJuVk/XEKboZ9aMgGculN+02lYphH/Ofo= +github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260206181019-26ebc8a46afe/go.mod h1:JdQ8vvaokQZbeMaY2Qb6hu0iVUyxzaFl2l9Ej08F2lU= github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260205083029-d03e9df035ef h1:SgzLekXtZuApbRylC3unCXnMaUClT5FPuqsxzIjt3Go= github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260205083029-d03e9df035ef/go.mod h1:ndqfy1KbVorHH6+zlUFPIrCRhMSxO3ImYJUGaooE0x0= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251230215914-6ba873b49a35 h1:IdcI8DFvW8rXtchONSzbDmhhRp1YyO2YaBJDBXr44Gk= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251230215914-6ba873b49a35/go.mod h1:zOX7Y05keiSppIvLabuyh42QHBMhCcoskAtxFRbwXKo= -github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260128142552-e2c25eccae5a h1:teKxfVLDxJD9ahjeh29GlKHiXNUFDkVRmkpJdeKAvGE= -github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260128142552-e2c25eccae5a/go.mod h1:jofj+VqDszxLCZSBYo794KGkCjMo01xzhQ/gffYzf3I= -github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20260203154427-fb9213e462a4 h1:Ynrdr1X4RE0gDcgyAlos39AYFKV4I2WfTaZ2oAjU7d0= -github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20260203154427-fb9213e462a4/go.mod h1:xOLjSMU4f5F05L0DiCu6Uvz0dOIDmCyQmSVS+ZHaam0= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20260126081203-efc2df9207eb h1:E59YGRP8XWq8vi6AUUxyYyBD1ahzcr3RKDkZmxpi+qs= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20260126081203-efc2df9207eb/go.mod h1:zOX7Y05keiSppIvLabuyh42QHBMhCcoskAtxFRbwXKo= +github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260205083029-d03e9df035ef h1:2wJUSZ2ybE6JVjEyuk/HEaJ1in64jf/lrPOs8NrRHFo= +github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260205083029-d03e9df035ef/go.mod h1:jofj+VqDszxLCZSBYo794KGkCjMo01xzhQ/gffYzf3I= +github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20260206173305-72969ece6ed4 h1:vajN31pc7Qnv4yKreu/wjMVHUl4uOBWuAC7m4YDxmjg= +github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20260206173305-72969ece6ed4/go.mod h1:MKN/V7xTOfBVZCoAZyoZXv9Xm1WK++dIVN7Itl2x64I= github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260127154438-ff95971883bb h1:Zv7GXyG1wND4wNzCmfMI8oAWsDlrU2QFxq8tsnIKFs0= github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260127154438-ff95971883bb/go.mod h1:X6W8pIULiWUc6smaTqiNocjxoXaRLgXediwpI/dxD9s= -github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20260130110557-870de6f217b5 h1:VswZKlc2SGulbTNITVfddofnXLHGMqpUHjZabRU2V+8= -github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20260130110557-870de6f217b5/go.mod h1:Uu/8M93x55zd7amJpRKGJz4vCmvZvBfzaN6CwnOjDNY= -github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20260205135859-d785b91fa1d7 h1:oWCSoyfvh87ueqU3yMSoDR6pW+nWptXGsARK+ypIky8= -github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20260205135859-d785b91fa1d7/go.mod h1:bo00y0fC762qzXbn3tgpTT35n0CpSPxkZq7jCyE7LYQ= -github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20260130160650-fee89a8e7044 h1:IWidpe8G47CpthKIGKVUP0DmtpsCnYn1q4pDB8/pjhM= -github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20260130160650-fee89a8e7044/go.mod h1:Phcw9t23H4RbOpUqBhFldFBKEbkx+f4c0QGnfFOPh50= +github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20260206181305-f3366b4bd37b h1:mEp0NBejze4hEKzQQGD4zjMHMBqDRSqPPUYmyuEOFxg= +github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20260206181305-f3366b4bd37b/go.mod h1:P2br9yVt4dMCG1EgPj6k1wKc+QNvKaIFueLuRICwpi4= +github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20260207082315-2e0a55b6d766 h1:pq4n3ufAn2sNRMhp/G9vG/MPjoqfgXMDmJKh1KPmqRU= +github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20260207082315-2e0a55b6d766/go.mod h1:pX1Ht6fzob3F6Lhl3MV9MAJquWrosle62VXFsNyNmVU= +github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20260206221031-ca09bc20f265 h1:F8CxdhdExxz/OlxQAI4lBhFWU+FnnypbZfWfMh/icis= +github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20260206221031-ca09bc20f265/go.mod h1:U+xQIGQ6U3F+plwX3QTG1x/D6+tk/16h91/YbHPFRGU= github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.6.1-0.20260126123727-b3f88d69956c h1:5gY2Y9OjgHWltvw0jtQWDaoXnfJRObRNozC0dBLz0GQ= github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.6.1-0.20260126123727-b3f88d69956c/go.mod h1:8Ge7K0IfcMSpoyp9p0lnW36f3nvCf6lnoc4TWoIlazw= github.com/openstack-k8s-operators/ovn-operator/api v0.6.1-0.20260126160735-3254731d17a8 h1:70ennIUokh4YvGdzE7zzRYIHVJ0xnYRNvmrO/f0wk9A= @@ -156,12 +156,12 @@ github.com/openstack-k8s-operators/placement-operator/api v0.6.1-0.2026020307274 github.com/openstack-k8s-operators/placement-operator/api v0.6.1-0.20260203072749-c46bb493557d/go.mod h1:eWED9YYc2NLXutgocqK5m3LsnQ+aT0MeWgmnsqi6A0Y= 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/openstack-k8s-operators/swift-operator/api v0.6.1-0.20260201211658-98f018aea931 h1:iAa/ahDlWAHFa2WUQJ07SEyzFtYUBkEwtt8vZNQ1V9A= -github.com/openstack-k8s-operators/swift-operator/api v0.6.1-0.20260201211658-98f018aea931/go.mod h1:/2Qd/Xr1bPLaddKmKxhqHP5Zsj7YYz3TkzWOM8miaK0= -github.com/openstack-k8s-operators/telemetry-operator/api v0.6.1-0.20260205110928-7d95eaebdfe4 h1:kygc6YDl7kPwj1Ol2wMC6pLuhmpBK2IqULwlaZ7k/rA= -github.com/openstack-k8s-operators/telemetry-operator/api v0.6.1-0.20260205110928-7d95eaebdfe4/go.mod h1:l/jz/k6Al6GSleFlcbfuLjEkZynJZKvI/H4ZlyMCqAg= -github.com/openstack-k8s-operators/watcher-operator/api v0.6.1-0.20260206073930-3cd4f1433bff h1:45zoZ6GbBbTsd/WK0G4MxrxzHIkjQ+5m6ayv+QRX29c= -github.com/openstack-k8s-operators/watcher-operator/api v0.6.1-0.20260206073930-3cd4f1433bff/go.mod h1:1DeGo19yp7py2C+D98Mbv8P8UHYARmPTvfBAuTNXj5Q= +github.com/openstack-k8s-operators/swift-operator/api v0.6.1-0.20260206221909-c0927c3803e6 h1:D8OYnPApTJKIXD9++xs7PWhSYRZTmuNgciHAbaUz5YI= +github.com/openstack-k8s-operators/swift-operator/api v0.6.1-0.20260206221909-c0927c3803e6/go.mod h1:cQmm3SMOGD5AEsN8d7eF99c6LPgRkWEEBAY4K6ZHbs8= +github.com/openstack-k8s-operators/telemetry-operator/api v0.6.1-0.20260206181610-fe8dc27febad h1:/lMNHUDrUnIxhrRapDeHM9je77I9xdPMjJa+X3gCiDE= +github.com/openstack-k8s-operators/telemetry-operator/api v0.6.1-0.20260206181610-fe8dc27febad/go.mod h1:XMn2KWjSbLhQ6Jczs3ZhPEAyNmz9b94bz3jKsdDVpag= +github.com/openstack-k8s-operators/watcher-operator/api v0.6.1-0.20260207082017-e2c9f69be82c h1:NkrMXwoXhD5HomNEpm10QcyIUPYxwn7lAuCGTZCZEvI= +github.com/openstack-k8s-operators/watcher-operator/api v0.6.1-0.20260207082017-e2c9f69be82c/go.mod h1:XEJp64OcVDbT9G1gHowBBruWcZngWN4C5Z8UgpOoqvk= 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= diff --git a/bindata/crds/barbican.openstack.org_barbicanapis.yaml b/bindata/crds/barbican.openstack.org_barbicanapis.yaml index 5929795d5..6cad33613 100644 --- a/bindata/crds/barbican.openstack.org_barbicanapis.yaml +++ b/bindata/crds/barbican.openstack.org_barbicanapis.yaml @@ -116,6 +116,22 @@ spec: - simple_crypto - pkcs11 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 networkAttachments: description: NetworkAttachments is a list of NetworkAttachment resource names to expose the services to the given network @@ -129,6 +145,27 @@ spec: NodeSelector to target subset of worker nodes running this component. Setting here overrides any global NodeSelector settings within the Barbican CR. 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 + notificationsURLSecret: + description: NotificationsURLSecret - Secret containing notifications + transport URL + type: string override: description: Override, provides the ability to override the generated manifest of several child resources. @@ -336,10 +373,10 @@ spec: - loginSecret type: object rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Barbican + Deprecated: Use MessagingBus.Cluster instead type: string replicas: default: 1 @@ -481,7 +518,6 @@ spec: - containerImage - databaseHostname - databaseInstance - - rabbitMqClusterName - serviceAccount type: object status: diff --git a/bindata/crds/barbican.openstack.org_barbicankeystonelisteners.yaml b/bindata/crds/barbican.openstack.org_barbicankeystonelisteners.yaml index b2224c5b3..5ff545705 100644 --- a/bindata/crds/barbican.openstack.org_barbicankeystonelisteners.yaml +++ b/bindata/crds/barbican.openstack.org_barbicankeystonelisteners.yaml @@ -108,6 +108,22 @@ spec: - simple_crypto - pkcs11 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 networkAttachments: description: NetworkAttachments is a list of NetworkAttachment resource names to expose the services to the given network @@ -121,6 +137,27 @@ spec: NodeSelector to target subset of worker nodes running this component. Setting here overrides any global NodeSelector settings within the Barbican CR. 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 + notificationsURLSecret: + description: NotificationsURLSecret - Secret containing notifications + transport URL + type: string passwordSelectors: default: service: BarbicanPassword @@ -169,10 +206,10 @@ spec: - loginSecret type: object rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Barbican + Deprecated: Use MessagingBus.Cluster instead type: string replicas: default: 1 @@ -291,7 +328,6 @@ spec: - containerImage - databaseHostname - databaseInstance - - rabbitMqClusterName - serviceAccount type: object status: diff --git a/bindata/crds/barbican.openstack.org_barbicans.yaml b/bindata/crds/barbican.openstack.org_barbicans.yaml index 54d73b245..e69ecdd5a 100644 --- a/bindata/crds/barbican.openstack.org_barbicans.yaml +++ b/bindata/crds/barbican.openstack.org_barbicans.yaml @@ -697,6 +697,22 @@ spec: - simple_crypto - pkcs11 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 @@ -704,6 +720,23 @@ spec: NodeSelector to target subset of worker nodes running this component. Setting here overrides any global NodeSelector settings within the Barbican CR. 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 passwordSelectors: default: service: BarbicanPassword @@ -757,10 +790,10 @@ spec: e.g. to check logs type: boolean rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Barbican + Deprecated: Use MessagingBus.Cluster instead type: string secret: default: osp-secret @@ -802,7 +835,6 @@ spec: - barbicanKeystoneListener - barbicanWorker - databaseInstance - - rabbitMqClusterName - serviceAccount type: object status: @@ -870,6 +902,9 @@ spec: type: string description: Map of hashes to track e.g. job status type: object + notificationsURLSecret: + description: NotificationsURLSecret - Secret containing RabbitMQ notificationsURL + type: string observedGeneration: description: |- ObservedGeneration - the most recent generation observed for this diff --git a/bindata/crds/barbican.openstack.org_barbicanworkers.yaml b/bindata/crds/barbican.openstack.org_barbicanworkers.yaml index 8e719a11c..87cef8d24 100644 --- a/bindata/crds/barbican.openstack.org_barbicanworkers.yaml +++ b/bindata/crds/barbican.openstack.org_barbicanworkers.yaml @@ -106,6 +106,22 @@ spec: - simple_crypto - pkcs11 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 networkAttachments: description: NetworkAttachments is a list of NetworkAttachment resource names to expose the services to the given network @@ -119,6 +135,27 @@ spec: NodeSelector to target subset of worker nodes running this component. Setting here overrides any global NodeSelector settings within the Barbican CR. 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 + notificationsURLSecret: + description: NotificationsURLSecret - Secret containing notifications + transport URL + type: string passwordSelectors: default: service: BarbicanPassword @@ -167,10 +204,10 @@ spec: - loginSecret type: object rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Barbican + Deprecated: Use MessagingBus.Cluster instead type: string replicas: default: 1 @@ -289,7 +326,6 @@ spec: - containerImage - databaseHostname - databaseInstance - - rabbitMqClusterName - serviceAccount type: object status: diff --git a/bindata/crds/cinder.openstack.org_cinders.yaml b/bindata/crds/cinder.openstack.org_cinders.yaml index c74415046..56949ed05 100644 --- a/bindata/crds/cinder.openstack.org_cinders.yaml +++ b/bindata/crds/cinder.openstack.org_cinders.yaml @@ -2032,6 +2032,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 @@ -2040,10 +2056,28 @@ 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 notification purposes + Deprecated: Use NotificationsBus.Cluster instead type: string passwordSelectors: default: @@ -2063,10 +2097,10 @@ spec: e.g. to check logs type: boolean rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Cinder + Deprecated: Use MessagingBus.Cluster instead type: string secret: description: Secret containing OpenStack password information @@ -2098,7 +2132,6 @@ spec: - cinderScheduler - databaseInstance - memcachedInstance - - rabbitMqClusterName - secret type: object status: diff --git a/bindata/crds/crds.yaml b/bindata/crds/crds.yaml index 53c111dee..a3a1c0971 100644 --- a/bindata/crds/crds.yaml +++ b/bindata/crds/crds.yaml @@ -839,10 +839,34 @@ spec: - simple_crypto - pkcs11 type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object passwordSelectors: default: service: BarbicanPassword @@ -880,7 +904,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string secret: default: osp-secret @@ -905,7 +928,6 @@ spec: - barbicanKeystoneListener - barbicanWorker - databaseInstance - - rabbitMqClusterName - serviceAccount type: object type: object @@ -2009,10 +2031,34 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string passwordSelectors: @@ -2027,7 +2073,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string secret: type: string @@ -2046,7 +2091,6 @@ spec: - cinderScheduler - databaseInstance - memcachedInstance - - rabbitMqClusterName - secret type: object uniquePodNames: @@ -3183,10 +3227,34 @@ spec: transportURLSecret: type: string type: object + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nsRecords: items: properties: @@ -3214,7 +3282,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string redisServiceName: default: designate-redis @@ -3272,7 +3339,6 @@ spec: - designateMdns - designateProducer - designateWorker - - rabbitMqClusterName - secret type: object type: object @@ -4892,6 +4958,18 @@ spec: type: object notificationBusInstance: type: string + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object passwordSelectors: default: service: GlancePassword @@ -6131,10 +6209,34 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object passwordSelectors: default: authEncryptionKey: HeatAuthEncryptionKey @@ -6154,7 +6256,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string secret: type: string @@ -6174,7 +6275,6 @@ spec: - heatCfnAPI - heatEngine - memcachedInstance - - rabbitMqClusterName - secret type: object type: object @@ -7709,12 +7809,35 @@ spec: additionalProperties: type: string type: object + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object rabbitMqClusterName: - default: rabbitmq type: string replicas: default: 1 @@ -7763,10 +7886,34 @@ spec: type: string type: object type: object + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object passwordSelectors: default: service: IronicPassword @@ -7779,7 +7926,6 @@ spec: default: true type: boolean rabbitMqClusterName: - default: rabbitmq type: string rpcTransport: type: string @@ -8513,6 +8659,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object override: properties: service: @@ -8577,7 +8735,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string region: default: regionOne @@ -8660,7 +8817,6 @@ spec: required: - databaseInstance - memcachedInstance - - rabbitMqClusterName - secret type: object type: object @@ -9648,10 +9804,34 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string passwordSelectors: @@ -9666,7 +9846,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string secret: type: string @@ -9685,7 +9864,6 @@ spec: - manilaAPI - manilaScheduler - memcachedInstance - - rabbitMqClusterName type: object type: object memcached: @@ -9780,6 +9958,18 @@ spec: type: object type: object type: object + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object neutron: properties: apiOverride: @@ -10490,6 +10680,18 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object ml2MechanismDrivers: default: - ovn @@ -10504,6 +10706,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string override: @@ -10570,7 +10784,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string replicas: default: 1 @@ -10649,7 +10862,6 @@ spec: required: - databaseInstance - memcachedInstance - - rabbitMqClusterName - secret type: object type: object @@ -10657,6 +10869,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string nova: @@ -10971,7 +11195,6 @@ spec: default: openstack type: string apiMessageBusInstance: - default: rabbitmq type: string apiServiceTemplate: default: @@ -11126,7 +11349,6 @@ spec: default: openstack type: string cellMessageBusInstance: - default: rabbitmq type: string conductorServiceTemplate: properties: @@ -11205,6 +11427,18 @@ spec: type: boolean memcachedInstance: type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object metadataServiceTemplate: properties: customServiceConfig: @@ -11545,8 +11779,9 @@ spec: cell1: cellDatabaseAccount: nova-cell1 cellDatabaseInstance: openstack-cell1 - cellMessageBusInstance: rabbitmq-cell1 hasAPIAccess: true + messagingBus: + cluster: rabbitmq-cell1 type: object keystoneInstance: default: keystone @@ -11554,6 +11789,18 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object metadataServiceTemplate: default: enabled: true @@ -11680,6 +11927,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string passwordSelectors: @@ -12020,10 +12279,34 @@ spec: default: true type: boolean type: object + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object octaviaAPI: properties: apiTimeout: @@ -12055,6 +12338,8 @@ spec: additionalProperties: type: string type: object + notificationsTransportURLSecret: + type: string override: properties: service: @@ -12274,6 +12559,8 @@ spec: additionalProperties: type: string type: object + notificationsTransportURLSecret: + type: string octaviaProviderSubnetCIDR: type: string octaviaProviderSubnetExtraCIDRs: @@ -12431,6 +12718,8 @@ spec: additionalProperties: type: string type: object + notificationsTransportURLSecret: + type: string octaviaProviderSubnetCIDR: type: string octaviaProviderSubnetExtraCIDRs: @@ -12694,6 +12983,8 @@ spec: additionalProperties: type: string type: object + notificationsTransportURLSecret: + type: string octaviaProviderSubnetCIDR: type: string octaviaProviderSubnetExtraCIDRs: @@ -12808,7 +13099,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string redisServiceName: default: octavia-redis @@ -12875,7 +13165,6 @@ spec: - databaseInstance - octaviaAPI - octaviaNetworkAttachment - - rabbitMqClusterName - secret type: object type: object @@ -14803,6 +15092,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object override: properties: service: @@ -14864,7 +15165,6 @@ spec: type: string type: object rabbitMqClusterName: - default: rabbitmq type: string replicas: default: 1 @@ -14911,7 +15211,6 @@ spec: type: object required: - memcachedInstance - - rabbitMqClusterName - replicas - secret - serviceUser @@ -15705,6 +16004,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object override: properties: service: @@ -15775,7 +16086,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string secret: default: osp-secret @@ -15895,6 +16205,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object passwordSelector: default: ceilometerService: CeilometerPassword @@ -15910,7 +16232,6 @@ spec: type: string type: object rabbitMqClusterName: - default: rabbitmq type: string secret: default: osp-secret @@ -16181,6 +16502,18 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string @@ -16228,7 +16561,6 @@ spec: type: object x-kubernetes-map-type: atomic rabbitMqClusterName: - default: rabbitmq type: string s3StorageConfig: default: @@ -17650,10 +17982,34 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string passwordSelectors: @@ -17671,7 +18027,6 @@ spec: default: metric-storage-prometheus-endpoint type: string rabbitMqClusterName: - default: rabbitmq type: string secret: default: osp-secret @@ -17691,7 +18046,6 @@ spec: - applierServiceTemplate - databaseInstance - decisionengineServiceTemplate - - rabbitMqClusterName type: object type: object required: diff --git a/bindata/crds/designate.openstack.org_designates.yaml b/bindata/crds/designate.openstack.org_designates.yaml index 70a37dfe3..ad7cb9871 100644 --- a/bindata/crds/designate.openstack.org_designates.yaml +++ b/bindata/crds/designate.openstack.org_designates.yaml @@ -2094,12 +2094,45 @@ spec: required: - containerImage type: object + messagingBus: + description: MessagingBus configuration (cluster, username, and vhost) + 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 running this service type: object + notificationsBus: + description: NotificationsBus configuration (cluster, username, and + vhost) 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 nsRecords: description: NSRecords contains the list of nameserver records for the Designate pool @@ -2138,10 +2171,10 @@ spec: e.g. to check logs type: boolean rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Designate + Deprecated: Use MessagingBus.Cluster instead type: string redisServiceName: default: designate-redis @@ -2243,7 +2276,6 @@ spec: - designateMdns - designateProducer - designateWorker - - rabbitMqClusterName - secret type: object status: @@ -2332,6 +2364,10 @@ spec: type: string description: Map of hashes to track e.g. job status type: object + notificationsTransportURLSecret: + description: NotificationsTransportURLSecret - Secret containing RabbitMQ + notifications transportURL + type: string observedGeneration: description: |- ObservedGeneration - the most recent generation observed for this diff --git a/bindata/crds/glance.openstack.org_glances.yaml b/bindata/crds/glance.openstack.org_glances.yaml index 732a319e1..730a56fb5 100644 --- a/bindata/crds/glance.openstack.org_glances.yaml +++ b/bindata/crds/glance.openstack.org_glances.yaml @@ -1630,7 +1630,25 @@ spec: RabbitMQ instance name Needed to request a transportURL that is created and used for notification purposes + deprecated: Use NotificationsBus.Cluster instead type: string + 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 passwordSelectors: default: service: GlancePassword diff --git a/bindata/crds/heat.openstack.org_heats.yaml b/bindata/crds/heat.openstack.org_heats.yaml index b3cfc5f6a..85f1f33c9 100644 --- a/bindata/crds/heat.openstack.org_heats.yaml +++ b/bindata/crds/heat.openstack.org_heats.yaml @@ -1982,12 +1982,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 @@ -2017,10 +2050,10 @@ spec: e.g. to check logs type: boolean rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Heat + Deprecated: Use MessagingBus.Cluster instead type: string secret: description: |- @@ -2055,7 +2088,6 @@ spec: - heatCfnAPI - heatEngine - memcachedInstance - - rabbitMqClusterName - secret type: object status: @@ -2123,6 +2155,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 diff --git a/bindata/crds/ironic.openstack.org_ironicapis.yaml b/bindata/crds/ironic.openstack.org_ironicapis.yaml index 525b98fc7..a4bc99345 100644 --- a/bindata/crds/ironic.openstack.org_ironicapis.yaml +++ b/bindata/crds/ironic.openstack.org_ironicapis.yaml @@ -114,6 +114,9 @@ spec: NodeSelector to target subset of worker nodes running this service. Setting here overrides any global NodeSelector settings within the Ironic CR type: object + notificationsURLSecret: + description: Secret containing RabbitMq notifications URL + type: string override: description: Override, provides the ability to override the generated manifest of several child resources. diff --git a/bindata/crds/ironic.openstack.org_ironicconductors.yaml b/bindata/crds/ironic.openstack.org_ironicconductors.yaml index 7da22e51b..dd816e72a 100644 --- a/bindata/crds/ironic.openstack.org_ironicconductors.yaml +++ b/bindata/crds/ironic.openstack.org_ironicconductors.yaml @@ -163,6 +163,9 @@ spec: NodeSelector to target subset of worker nodes running this service. Setting here overrides any global NodeSelector settings within the Ironic CR type: object + notificationsURLSecret: + description: Secret containing RabbitMq notifications URL + type: string novncproxyImage: description: NoVNCProxyImage - Ironic NoVNCProxy Container Image type: string diff --git a/bindata/crds/ironic.openstack.org_ironicinspectors.yaml b/bindata/crds/ironic.openstack.org_ironicinspectors.yaml index 56ef2e10b..410f85ec3 100644 --- a/bindata/crds/ironic.openstack.org_ironicinspectors.yaml +++ b/bindata/crds/ironic.openstack.org_ironicinspectors.yaml @@ -139,6 +139,23 @@ spec: description: IronicPythonAgentImage - Image containing the ironic-python-agent kernel and ramdisk type: string + messagingBus: + description: MessagingBus configuration (username, vhost, and cluster) + for RPC messaging + 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 networkAttachments: description: NetworkAttachments is a list of NetworkAttachment resource names to expose the services to the given network @@ -152,6 +169,23 @@ spec: NodeSelector to target subset of worker nodes running this service. Setting here overrides any global NodeSelector settings within the Ironic CR 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 override: description: Override, provides the ability to override the generated manifest of several child resources. @@ -333,10 +367,10 @@ spec: Image type: string rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Ironic Inspector + Deprecated: Use MessagingBus.Cluster instead type: string replicas: default: 1 @@ -563,6 +597,10 @@ spec: type: array description: NetworkAttachments status of the deployment pods type: object + notificationsURLSecret: + description: NotificationsURLSecret - Secret containing RabbitMQ notifications + URL + type: string observedGeneration: description: |- ObservedGeneration - the most recent generation observed for this diff --git a/bindata/crds/ironic.openstack.org_ironicneutronagents.yaml b/bindata/crds/ironic.openstack.org_ironicneutronagents.yaml index 5bf614b75..ad2dbba11 100644 --- a/bindata/crds/ironic.openstack.org_ironicneutronagents.yaml +++ b/bindata/crds/ironic.openstack.org_ironicneutronagents.yaml @@ -81,6 +81,23 @@ spec: ConfigOverwrite - interface to overwrite default config files like e.g. policy.json. But can also be used to add additional files. Those get added to the service config dir in /etc/ . type: object + messagingBus: + description: MessagingBus configuration (username, vhost, and cluster) + for RPC messaging + 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 @@ -88,6 +105,23 @@ spec: NodeSelector to target subset of worker nodes running this service. Setting here overrides any global NodeSelector settings within the Ironic CR 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 passwordSelectors: default: service: IronicPassword @@ -101,10 +135,10 @@ spec: type: string type: object rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Ironic + Deprecated: Use MessagingBus.Cluster instead type: string replicas: default: 1 @@ -275,6 +309,10 @@ spec: current project type: string type: object + notificationsURLSecret: + description: NotificationsURLSecret - Secret containing RabbitMQ notifications + URL + type: string observedGeneration: description: |- ObservedGeneration - the most recent generation observed for this diff --git a/bindata/crds/ironic.openstack.org_ironics.yaml b/bindata/crds/ironic.openstack.org_ironics.yaml index 4cea34122..dd2ba00c7 100644 --- a/bindata/crds/ironic.openstack.org_ironics.yaml +++ b/bindata/crds/ironic.openstack.org_ironics.yaml @@ -1032,6 +1032,23 @@ spec: ConfigOverwrite - interface to overwrite default config files like e.g. policy.json. But can also be used to add additional files. Those get added to the service config dir in /etc/ . type: object + messagingBus: + description: MessagingBus configuration (username, vhost, and + cluster) for RPC messaging + 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 @@ -1039,11 +1056,28 @@ spec: NodeSelector to target subset of worker nodes running this service. Setting here overrides any global NodeSelector settings within the Ironic CR 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 rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Ironic + Deprecated: Use MessagingBus.Cluster instead type: string replicas: default: 1 @@ -1132,6 +1166,23 @@ spec: type: string type: object type: object + messagingBus: + description: MessagingBus configuration (username, vhost, and cluster) + for RPC messaging + 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 @@ -1140,6 +1191,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 passwordSelectors: default: service: IronicPassword @@ -1158,10 +1226,10 @@ spec: e.g. to check logs type: boolean rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Ironic + Deprecated: Use MessagingBus.Cluster instead type: string rpcTransport: description: |- @@ -1292,6 +1360,10 @@ spec: description: ReadyCount of Ironic Neutron Agent instance format: int32 type: integer + notificationsURLSecret: + description: NotificationsURLSecret - Secret containing RabbitMQ notifications + URL + type: string observedGeneration: description: |- ObservedGeneration - the most recent generation observed for this diff --git a/bindata/crds/keystone.openstack.org_keystoneapis.yaml b/bindata/crds/keystone.openstack.org_keystoneapis.yaml index 7753829fa..dfb1b0e0a 100644 --- a/bindata/crds/keystone.openstack.org_keystoneapis.yaml +++ b/bindata/crds/keystone.openstack.org_keystoneapis.yaml @@ -1285,6 +1285,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. @@ -1462,10 +1479,10 @@ spec: e.g. to check logs type: boolean rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Keystone + Deprecated: Use NotificationsBus.Cluster instead type: string region: default: regionOne @@ -1608,7 +1625,6 @@ spec: - containerImage - databaseInstance - memcachedInstance - - rabbitMqClusterName - secret type: object status: diff --git a/bindata/crds/manila.openstack.org_manilas.yaml b/bindata/crds/manila.openstack.org_manilas.yaml index 5d484fec3..32859e0e1 100644 --- a/bindata/crds/manila.openstack.org_manilas.yaml +++ b/bindata/crds/manila.openstack.org_manilas.yaml @@ -1796,6 +1796,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 @@ -1804,10 +1820,28 @@ 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 notification purposes + Deprecated: Use NotificationsBus.Cluster instead type: string passwordSelectors: default: @@ -1827,10 +1861,10 @@ spec: e.g. to check logs type: boolean rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Manila + Deprecated: Use MessagingBus.Cluster instead type: string secret: description: Secret containing OpenStack password information for @@ -1863,7 +1897,6 @@ spec: - manilaAPI - manilaScheduler - memcachedInstance - - rabbitMqClusterName type: object status: description: ManilaStatus defines the observed state of Manila diff --git a/bindata/crds/neutron.openstack.org_neutronapis.yaml b/bindata/crds/neutron.openstack.org_neutronapis.yaml index bbef3ca2b..56b8dc321 100644 --- a/bindata/crds/neutron.openstack.org_neutronapis.yaml +++ b/bindata/crds/neutron.openstack.org_neutronapis.yaml @@ -1223,6 +1223,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 ml2MechanismDrivers: default: - ovn @@ -1243,6 +1259,23 @@ spec: description: NodeSelector to target subset of worker nodes running this service 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: |- NotificationsBusInstance is the name of the RabbitMqCluster CR to select @@ -1428,10 +1461,10 @@ spec: e.g. to check logs type: boolean rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Neutron + Deprecated: Use MessagingBus.Cluster instead type: string replicas: default: 1 @@ -1569,7 +1602,6 @@ spec: - containerImage - databaseInstance - memcachedInstance - - rabbitMqClusterName - secret type: object status: diff --git a/bindata/crds/nova.openstack.org_nova.yaml b/bindata/crds/nova.openstack.org_nova.yaml index 13b3b428c..2ddc8f42e 100644 --- a/bindata/crds/nova.openstack.org_nova.yaml +++ b/bindata/crds/nova.openstack.org_nova.yaml @@ -54,11 +54,11 @@ spec: Service instance used for the Nova API DB. type: string apiMessageBusInstance: - default: rabbitmq description: |- APIMessageBusInstance is the name of the RabbitMqCluster CR to select the Message Bus Service instance used by the Nova top level services to communicate. + Deprecated: Use MessagingBus.Cluster instead type: string apiServiceTemplate: default: @@ -398,11 +398,11 @@ spec: Service instance used as the DB of this cell. type: string cellMessageBusInstance: - default: rabbitmq description: |- CellMessageBusInstance is the name of the RabbitMqCluster CR to select the Message Bus Service instance used by the nova services to communicate in this cell. For cell0 it is unused. + Deprecated: Use MessagingBus.Cluster instead type: string conductorServiceTemplate: description: ConductorServiceTemplate - defines the cell conductor @@ -550,6 +550,23 @@ spec: MemcachedInstance is the name of the Memcached CR that the services in the cell will use. If defined then this takes precedence over Nova.Spec.MemcachedInstance for this cel 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 metadataServiceTemplate: description: |- MetadataServiceTemplate - defines the metadata service dedicated for the @@ -1325,8 +1342,9 @@ spec: cell1: cellDatabaseAccount: nova-cell1 cellDatabaseInstance: openstack-cell1 - cellMessageBusInstance: rabbitmq-cell1 hasAPIAccess: true + messagingBus: + cluster: rabbitmq-cell1 description: |- Cells is a mapping of cell names to NovaCellTemplate objects defining the cells in the deployment. The "cell0" cell is a mandatory cell in @@ -1350,6 +1368,22 @@ spec: description: MemcachedInstance is the name of the Memcached CR that all nova service will use. 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 metadataContainerImageURL: description: MetadataContainerImageURL type: string @@ -1658,6 +1692,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: |- NotificationsBusInstance is the name of the RabbitMqCluster CR to select diff --git a/bindata/crds/octavia.openstack.org_octaviaamphoracontrollers.yaml b/bindata/crds/octavia.openstack.org_octaviaamphoracontrollers.yaml index 6f8416a68..931383616 100644 --- a/bindata/crds/octavia.openstack.org_octaviaamphoracontrollers.yaml +++ b/bindata/crds/octavia.openstack.org_octaviaamphoracontrollers.yaml @@ -140,6 +140,10 @@ spec: description: NodeSelector to target subset of worker nodes running this service type: object + notificationsTransportURLSecret: + description: NotificationsTransportURLSecret - Secret containing RabbitMQ + notifications transportURL + type: string octaviaProviderSubnetCIDR: description: OctaviaProviderSubnetCIDR - type: string diff --git a/bindata/crds/octavia.openstack.org_octaviaapis.yaml b/bindata/crds/octavia.openstack.org_octaviaapis.yaml index f36b90742..e94794165 100644 --- a/bindata/crds/octavia.openstack.org_octaviaapis.yaml +++ b/bindata/crds/octavia.openstack.org_octaviaapis.yaml @@ -108,6 +108,10 @@ spec: description: NodeSelector to target subset of worker nodes running this service type: object + notificationsTransportURLSecret: + description: NotificationsTransportURLSecret - Secret containing RabbitMQ + notifications transportURL + type: string override: description: Override, provides the ability to override the generated manifest of several child resources. diff --git a/bindata/crds/octavia.openstack.org_octavias.yaml b/bindata/crds/octavia.openstack.org_octavias.yaml index ef07cef32..804b9bc6a 100644 --- a/bindata/crds/octavia.openstack.org_octavias.yaml +++ b/bindata/crds/octavia.openstack.org_octavias.yaml @@ -157,12 +157,45 @@ spec: creates the Neutron resources needed for its Management Network type: boolean type: object + messagingBus: + description: MessagingBus configuration (cluster, username, and vhost) + 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 running this service type: object + notificationsBus: + description: NotificationsBus configuration (cluster, username, and + vhost) for a dedicated notifications RabbitMQ 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 octaviaAPI: description: OctaviaAPI - Spec definition for the API service of the Octavia deployment @@ -223,6 +256,10 @@ spec: description: NodeSelector to target subset of worker nodes running this service type: object + notificationsTransportURLSecret: + description: NotificationsTransportURLSecret - Secret containing + RabbitMQ notifications transportURL + type: string override: description: Override, provides the ability to override the generated manifest of several child resources. @@ -658,6 +695,10 @@ spec: description: NodeSelector to target subset of worker nodes running this service type: object + notificationsTransportURLSecret: + description: NotificationsTransportURLSecret - Secret containing + RabbitMQ notifications transportURL + type: string octaviaProviderSubnetCIDR: description: OctaviaProviderSubnetCIDR - type: string @@ -914,6 +955,10 @@ spec: description: NodeSelector to target subset of worker nodes running this service type: object + notificationsTransportURLSecret: + description: NotificationsTransportURLSecret - Secret containing + RabbitMQ notifications transportURL + type: string octaviaProviderSubnetCIDR: description: OctaviaProviderSubnetCIDR - type: string @@ -1346,6 +1391,10 @@ spec: description: NodeSelector to target subset of worker nodes running this service type: object + notificationsTransportURLSecret: + description: NotificationsTransportURLSecret - Secret containing + RabbitMQ notifications transportURL + type: string octaviaProviderSubnetCIDR: description: OctaviaProviderSubnetCIDR - type: string @@ -1539,10 +1588,10 @@ spec: e.g. to check logs type: boolean rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Octavia + Deprecated: Use MessagingBus.Cluster instead type: string redisServiceName: default: octavia-redis @@ -1662,7 +1711,6 @@ spec: - databaseInstance - octaviaAPI - octaviaNetworkAttachment - - rabbitMqClusterName - secret type: object status: @@ -1730,6 +1778,10 @@ spec: description: ReadyCount of octavia Housekeeping instances format: int32 type: integer + notificationsTransportURLSecret: + description: NotificationsTransportURLSecret - Secret containing RabbitMQ + notifications transportURL + type: string observedGeneration: description: |- ObservedGeneration - the most recent generation observed for this diff --git a/bindata/crds/swift.openstack.org_swiftproxies.yaml b/bindata/crds/swift.openstack.org_swiftproxies.yaml index 7b4e7a0a3..774737b57 100644 --- a/bindata/crds/swift.openstack.org_swiftproxies.yaml +++ b/bindata/crds/swift.openstack.org_swiftproxies.yaml @@ -101,6 +101,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. @@ -273,9 +290,9 @@ spec: type: string type: object rabbitMqClusterName: - default: rabbitmq - description: RabbitMQ instance name to request a transportURL for - Ceilometer middleware + description: |- + Deprecated: Use NotificationsBus.Cluster instead + RabbitMQ instance name to request a transportURL for Ceilometer middleware type: string replicas: default: 1 @@ -351,7 +368,6 @@ spec: required: - containerImageProxy - memcachedInstance - - rabbitMqClusterName - replicas - secret - serviceUser diff --git a/bindata/crds/swift.openstack.org_swifts.yaml b/bindata/crds/swift.openstack.org_swifts.yaml index 5a98bf38b..a611db7c7 100644 --- a/bindata/crds/swift.openstack.org_swifts.yaml +++ b/bindata/crds/swift.openstack.org_swifts.yaml @@ -135,6 +135,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. @@ -307,9 +324,9 @@ spec: type: string type: object rabbitMqClusterName: - default: rabbitmq - description: RabbitMQ instance name to request a transportURL - for Ceilometer middleware + description: |- + Deprecated: Use NotificationsBus.Cluster instead + RabbitMQ instance name to request a transportURL for Ceilometer middleware type: string replicas: default: 1 @@ -386,7 +403,6 @@ spec: required: - containerImageProxy - memcachedInstance - - rabbitMqClusterName - replicas - secret - serviceUser diff --git a/bindata/crds/telemetry.openstack.org_autoscalings.yaml b/bindata/crds/telemetry.openstack.org_autoscalings.yaml index c92a5b1ee..fd30f9205 100644 --- a/bindata/crds/telemetry.openstack.org_autoscalings.yaml +++ b/bindata/crds/telemetry.openstack.org_autoscalings.yaml @@ -130,6 +130,23 @@ spec: description: NodeSelector to target subset of worker nodes running this service 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 notifierImage: type: string override: @@ -319,10 +336,10 @@ spec: e.g. to check logs type: boolean rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Aodh + Deprecated: Use NotificationsBus.Cluster instead type: string secret: default: osp-secret @@ -510,6 +527,10 @@ spec: items: type: string type: array + notificationsURLSecret: + description: NotificationsURLSecret - Secret containing RabbitMQ notification + transportURL + type: string observedGeneration: description: |- ObservedGeneration - the most recent generation observed for this diff --git a/bindata/crds/telemetry.openstack.org_ceilometers.yaml b/bindata/crds/telemetry.openstack.org_ceilometers.yaml index 8f8a86876..977224720 100644 --- a/bindata/crds/telemetry.openstack.org_ceilometers.yaml +++ b/bindata/crds/telemetry.openstack.org_ceilometers.yaml @@ -207,6 +207,23 @@ spec: type: object notificationImage: type: string + 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 passwordSelector: default: ceilometerService: CeilometerPassword @@ -232,10 +249,10 @@ spec: proxyImage: type: string rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Telemetry + Deprecated: Use NotificationsBus.Cluster instead type: string secret: default: osp-secret @@ -381,6 +398,10 @@ spec: items: type: string type: array + notificationsURLSecret: + description: NotificationsURLSecret - Secret containing RabbitMQ notification + transportURL + type: string observedGeneration: description: |- ObservedGeneration - the most recent generation observed for this diff --git a/bindata/crds/telemetry.openstack.org_cloudkitties.yaml b/bindata/crds/telemetry.openstack.org_cloudkitties.yaml index b9161b231..17b7539c2 100644 --- a/bindata/crds/telemetry.openstack.org_cloudkitties.yaml +++ b/bindata/crds/telemetry.openstack.org_cloudkitties.yaml @@ -558,6 +558,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 @@ -633,10 +649,10 @@ spec: type: object x-kubernetes-map-type: atomic rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in CloudKitty + Deprecated: Use MessagingBus.Cluster instead type: string s3StorageConfig: default: diff --git a/bindata/crds/telemetry.openstack.org_telemetries.yaml b/bindata/crds/telemetry.openstack.org_telemetries.yaml index e8c535260..46450de3f 100644 --- a/bindata/crds/telemetry.openstack.org_telemetries.yaml +++ b/bindata/crds/telemetry.openstack.org_telemetries.yaml @@ -133,6 +133,23 @@ spec: description: NodeSelector to target subset of worker nodes running this service 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 notifierImage: type: string override: @@ -322,10 +339,10 @@ spec: finished e.g. to check logs type: boolean rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Aodh + Deprecated: Use NotificationsBus.Cluster instead type: string secret: default: osp-secret @@ -543,6 +560,23 @@ spec: type: object notificationImage: type: string + 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 passwordSelector: default: ceilometerService: CeilometerPassword @@ -568,10 +602,10 @@ spec: proxyImage: type: string rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Telemetry + Deprecated: Use NotificationsBus.Cluster instead type: string secret: default: osp-secret @@ -1142,6 +1176,23 @@ 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 @@ -1218,10 +1269,10 @@ spec: type: object x-kubernetes-map-type: atomic rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in CloudKitty + Deprecated: Use MessagingBus.Cluster instead type: string s3StorageConfig: default: diff --git a/bindata/crds/watcher.openstack.org_watchers.yaml b/bindata/crds/watcher.openstack.org_watchers.yaml index 8c20f5a2f..21a9cd9f3 100644 --- a/bindata/crds/watcher.openstack.org_watchers.yaml +++ b/bindata/crds/watcher.openstack.org_watchers.yaml @@ -617,6 +617,22 @@ spec: description: MemcachedInstance is the name of the Memcached CR that all watcher service will use. 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 @@ -624,6 +640,23 @@ spec: NodeSelector to target subset of worker nodes running this component. Setting here overrides any global NodeSelector settings within the Watcher CR. 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: |- NotificationsBusInstance is the name of the RabbitMqCluster CR to select @@ -632,6 +665,7 @@ spec: If undefined, the value will be inherited from OpenStackControlPlane. An empty value "" leaves the notification drivers unconfigured and emitting no notifications at all. Avoid colocating it with RabbitMqClusterName or other message bus instances used for RPC. + Deprecated: Use NotificationsBus.Cluster instead type: string passwordSelectors: default: @@ -655,10 +689,10 @@ spec: description: Secret containing prometheus connection parameters type: string rabbitMqClusterName: - default: rabbitmq description: |- RabbitMQ instance name Needed to request a transportURL that is created and used in Watcher + Deprecated: Use MessagingBus.Cluster instead type: string secret: default: osp-secret @@ -694,7 +728,6 @@ spec: - databaseInstance - decisionengineContainerImageURL - decisionengineServiceTemplate - - rabbitMqClusterName type: object status: description: WatcherStatus defines the observed state of Watcher diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index b6bf0f89c..7d24a53e3 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -574,10 +574,34 @@ spec: - simple_crypto - pkcs11 type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object passwordSelectors: default: service: BarbicanPassword @@ -615,7 +639,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string secret: default: osp-secret @@ -640,7 +663,6 @@ spec: - barbicanKeystoneListener - barbicanWorker - databaseInstance - - rabbitMqClusterName - serviceAccount type: object type: object @@ -1744,10 +1766,34 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string passwordSelectors: @@ -1762,7 +1808,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string secret: type: string @@ -1781,7 +1826,6 @@ spec: - cinderScheduler - databaseInstance - memcachedInstance - - rabbitMqClusterName - secret type: object uniquePodNames: @@ -2918,10 +2962,34 @@ spec: transportURLSecret: type: string type: object + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nsRecords: items: properties: @@ -2949,7 +3017,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string redisServiceName: default: designate-redis @@ -3007,7 +3074,6 @@ spec: - designateMdns - designateProducer - designateWorker - - rabbitMqClusterName - secret type: object type: object @@ -4627,6 +4693,18 @@ spec: type: object notificationBusInstance: type: string + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object passwordSelectors: default: service: GlancePassword @@ -5866,10 +5944,34 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object passwordSelectors: default: authEncryptionKey: HeatAuthEncryptionKey @@ -5889,7 +5991,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string secret: type: string @@ -5909,7 +6010,6 @@ spec: - heatCfnAPI - heatEngine - memcachedInstance - - rabbitMqClusterName - secret type: object type: object @@ -7444,12 +7544,35 @@ spec: additionalProperties: type: string type: object + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object rabbitMqClusterName: - default: rabbitmq type: string replicas: default: 1 @@ -7498,10 +7621,34 @@ spec: type: string type: object type: object + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object passwordSelectors: default: service: IronicPassword @@ -7514,7 +7661,6 @@ spec: default: true type: boolean rabbitMqClusterName: - default: rabbitmq type: string rpcTransport: type: string @@ -8248,6 +8394,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object override: properties: service: @@ -8312,7 +8470,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string region: default: regionOne @@ -8395,7 +8552,6 @@ spec: required: - databaseInstance - memcachedInstance - - rabbitMqClusterName - secret type: object type: object @@ -9383,10 +9539,34 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string passwordSelectors: @@ -9401,7 +9581,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string secret: type: string @@ -9420,7 +9599,6 @@ spec: - manilaAPI - manilaScheduler - memcachedInstance - - rabbitMqClusterName type: object type: object memcached: @@ -9515,6 +9693,18 @@ spec: type: object type: object type: object + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object neutron: properties: apiOverride: @@ -10225,6 +10415,18 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object ml2MechanismDrivers: default: - ovn @@ -10239,6 +10441,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string override: @@ -10305,7 +10519,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string replicas: default: 1 @@ -10384,7 +10597,6 @@ spec: required: - databaseInstance - memcachedInstance - - rabbitMqClusterName - secret type: object type: object @@ -10392,6 +10604,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string nova: @@ -10706,7 +10930,6 @@ spec: default: openstack type: string apiMessageBusInstance: - default: rabbitmq type: string apiServiceTemplate: default: @@ -10861,7 +11084,6 @@ spec: default: openstack type: string cellMessageBusInstance: - default: rabbitmq type: string conductorServiceTemplate: properties: @@ -10940,6 +11162,18 @@ spec: type: boolean memcachedInstance: type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object metadataServiceTemplate: properties: customServiceConfig: @@ -11280,8 +11514,9 @@ spec: cell1: cellDatabaseAccount: nova-cell1 cellDatabaseInstance: openstack-cell1 - cellMessageBusInstance: rabbitmq-cell1 hasAPIAccess: true + messagingBus: + cluster: rabbitmq-cell1 type: object keystoneInstance: default: keystone @@ -11289,6 +11524,18 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object metadataServiceTemplate: default: enabled: true @@ -11415,6 +11662,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string passwordSelectors: @@ -11755,10 +12014,34 @@ spec: default: true type: boolean type: object + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object octaviaAPI: properties: apiTimeout: @@ -11790,6 +12073,8 @@ spec: additionalProperties: type: string type: object + notificationsTransportURLSecret: + type: string override: properties: service: @@ -12009,6 +12294,8 @@ spec: additionalProperties: type: string type: object + notificationsTransportURLSecret: + type: string octaviaProviderSubnetCIDR: type: string octaviaProviderSubnetExtraCIDRs: @@ -12166,6 +12453,8 @@ spec: additionalProperties: type: string type: object + notificationsTransportURLSecret: + type: string octaviaProviderSubnetCIDR: type: string octaviaProviderSubnetExtraCIDRs: @@ -12429,6 +12718,8 @@ spec: additionalProperties: type: string type: object + notificationsTransportURLSecret: + type: string octaviaProviderSubnetCIDR: type: string octaviaProviderSubnetExtraCIDRs: @@ -12543,7 +12834,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string redisServiceName: default: octavia-redis @@ -12610,7 +12900,6 @@ spec: - databaseInstance - octaviaAPI - octaviaNetworkAttachment - - rabbitMqClusterName - secret type: object type: object @@ -14538,6 +14827,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object override: properties: service: @@ -14599,7 +14900,6 @@ spec: type: string type: object rabbitMqClusterName: - default: rabbitmq type: string replicas: default: 1 @@ -14646,7 +14946,6 @@ spec: type: object required: - memcachedInstance - - rabbitMqClusterName - replicas - secret - serviceUser @@ -15440,6 +15739,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object override: properties: service: @@ -15510,7 +15821,6 @@ spec: default: false type: boolean rabbitMqClusterName: - default: rabbitmq type: string secret: default: osp-secret @@ -15630,6 +15940,18 @@ spec: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object passwordSelector: default: ceilometerService: CeilometerPassword @@ -15645,7 +15967,6 @@ spec: type: string type: object rabbitMqClusterName: - default: rabbitmq type: string secret: default: osp-secret @@ -15916,6 +16237,18 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string @@ -15963,7 +16296,6 @@ spec: type: object x-kubernetes-map-type: atomic rabbitMqClusterName: - default: rabbitmq type: string s3StorageConfig: default: @@ -17385,10 +17717,34 @@ spec: memcachedInstance: default: memcached type: string + messagingBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object nodeSelector: additionalProperties: type: string type: object + notificationsBus: + properties: + cluster: + minLength: 1 + type: string + user: + type: string + vhost: + type: string + required: + - cluster + type: object notificationsBusInstance: type: string passwordSelectors: @@ -17406,7 +17762,6 @@ spec: default: metric-storage-prometheus-endpoint type: string rabbitMqClusterName: - default: rabbitmq type: string secret: default: osp-secret @@ -17426,7 +17781,6 @@ spec: - applierServiceTemplate - databaseInstance - decisionengineServiceTemplate - - rabbitMqClusterName type: object type: object required: diff --git a/config/operator/manager_operator_images.yaml b/config/operator/manager_operator_images.yaml index a3794228d..5704c9418 100644 --- a/config/operator/manager_operator_images.yaml +++ b/config/operator/manager_operator_images.yaml @@ -14,33 +14,33 @@ spec: - name: operator env: - name: RELATED_IMAGE_BARBICAN_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/barbican-operator@sha256:10bdb8674a5c5a0120a68ded4e8d007f03c8f33592eed1a9ff2ae9e53d377d87 + value: quay.io/openstack-k8s-operators/barbican-operator@sha256:c5f4c50443436152f7d6ff8b07e972c201828520e56485758483f2e2919a52b5 - name: RELATED_IMAGE_CINDER_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/cinder-operator@sha256:5461f69440de95db8df5b1242b3bb08644e215e025b17345b33325633e3dfba6 + value: quay.io/openstack-k8s-operators/cinder-operator@sha256:06e8e0c6db135450d10abedef818f02a770f7b77bbc02cdf4ceb25cd0951aef4 - name: RELATED_IMAGE_DESIGNATE_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/designate-operator@sha256:a2e056d17d1ad90966fa943a1ec1e7c51b0f1f7842d0c0cc16a847bc3a34719e + value: quay.io/openstack-k8s-operators/designate-operator@sha256:1e7c7f2f83137d0311388255d109fac9a29b43683ae6c7c4f72bc65a1b5cfbda - name: RELATED_IMAGE_GLANCE_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/glance-operator@sha256:df7752c1cb7e57607e010dd1dfe92f9dbf926a8eda1cd69003e8f7f4d0ee5ace + value: quay.io/openstack-k8s-operators/glance-operator@sha256:8aaa025e23c55589801d88029000d412df67b464138ba3fe0e23d1fb78a4a9ad - name: RELATED_IMAGE_HEAT_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/heat-operator@sha256:51076be2b4311bd451e68e4e51ed32094e52834de769ee8635978914f0be99e4 + value: quay.io/openstack-k8s-operators/heat-operator@sha256:a707a15a7500b9636679d2e23c35195edf690c8fb0032dd1602dde1930c5926d - name: RELATED_IMAGE_HORIZON_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/horizon-operator@sha256:027cd7ab61ef5071d9ad6b729c95a98e51cd254642f01dc019d44cc98a9232f8 + value: quay.io/openstack-k8s-operators/horizon-operator@sha256:4790f820f56e247c4ba6d357d989c99a9035611abc019b98ae0ac8ad57da0109 - name: RELATED_IMAGE_INFRA_OPERATOR_MANAGER_IMAGE_URL value: quay.io/openstack-k8s-operators/infra-operator@sha256:a504ab83288310bbd8e39f3a01faaa3c210a14d94bbd32124e9eadd46227d6b3 - name: RELATED_IMAGE_IRONIC_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/ironic-operator@sha256:f09760446d12b8ca3f8383ab7711c4dd4cc3e47e04528e2d8dfe8cbdb39dc9f2 + value: quay.io/openstack-k8s-operators/ironic-operator@sha256:5e95e6956488bd86fb59e65ac795cc5b71b6d596051e27aeaa58fdf5c99b0481 - name: RELATED_IMAGE_KEYSTONE_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/keystone-operator@sha256:319c969e88f109b26487a9f5a67203682803d7386424703ab7ca0340be99ae17 + value: quay.io/openstack-k8s-operators/keystone-operator@sha256:9ae333f2bb6a4fe19c8a50aa1bf0e3c0e41e520a6586f5cf357be464475c506d - name: RELATED_IMAGE_MANILA_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/manila-operator@sha256:b8612e20df8c6a317a5e25884052455e2def210c704e1a8105253ead6eb35e87 + value: quay.io/openstack-k8s-operators/manila-operator@sha256:fffc4e59b4b6b1e2bd11dcd5ca2a9072c3909494ad7986b57aa3bb316bdc30be - name: RELATED_IMAGE_MARIADB_OPERATOR_MANAGER_IMAGE_URL value: quay.io/openstack-k8s-operators/mariadb-operator@sha256:2d493137559b74e23edb4788b7fbdb38b3e239df0f2d7e6e540e50b2355fc3cf - name: RELATED_IMAGE_NEUTRON_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/neutron-operator@sha256:7b45b0b511f6147f199989a554339aee505f0a3dd50092e2efc236706aabde09 + value: quay.io/openstack-k8s-operators/neutron-operator@sha256:e0e08055345eceebc62fd708d00ce52a327ffb407842fb8fc1a7466a9d964048 - name: RELATED_IMAGE_NOVA_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/nova-operator@sha256:7f230a842e37afd8ddfc543f6ed8514217e5916aa003b592ee0c044a1005f8c4 + value: quay.io/openstack-k8s-operators/nova-operator@sha256:2da857a0ddc880a136e2a9a18bf58c20672bc57407843bf1b93c7aa4ba819862 - name: RELATED_IMAGE_OCTAVIA_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/octavia-operator@sha256:aa637692c9fe546c05a5fb53604cbd8cb532a071fbd63f09f60e56d5794a6569 + value: quay.io/openstack-k8s-operators/octavia-operator@sha256:a6f09c4b637d091bbbc0ffc8970b30fbaf3e286a6a88466f8597e913895d087d - name: RELATED_IMAGE_OPENSTACK_BAREMETAL_OPERATOR_MANAGER_IMAGE_URL value: quay.io/openstack-k8s-operators/openstack-baremetal-operator@sha256:89f6fd332fabefd2fff5619432986b37c1c6d197dd1c510f21dfe4609939b8a6 - name: RELATED_IMAGE_OVN_OPERATOR_MANAGER_IMAGE_URL @@ -50,10 +50,10 @@ spec: - name: RELATED_IMAGE_RABBITMQ_CLUSTER_OPERATOR_MANAGER_IMAGE_URL value: quay.io/openstack-k8s-operators/rabbitmq-cluster-operator@sha256:893e66303c1b0bc1d00a299a3f0380bad55c8dc813c8a1c6a4aab379f5aa12a2 - name: RELATED_IMAGE_SWIFT_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/swift-operator@sha256:77388e446bc3af6f05ac372dbdb120da5d4d64e2ca1cd20b86e66ed4b69e63f8 + value: quay.io/openstack-k8s-operators/swift-operator@sha256:c8fc4442fe24bf4fcc9266b5e2875adfac049cb04e58e288290c1a01e6adf44c - name: RELATED_IMAGE_TELEMETRY_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/telemetry-operator@sha256:53ab303c58b5cbff65d21afc524b4cc31f546a32209bf0c75535077446d6d6dc + value: quay.io/openstack-k8s-operators/telemetry-operator@sha256:5dcca96e7bd6ed933c414cd759c88fa2165c8f42c863eb11058743c928d27076 - name: RELATED_IMAGE_TEST_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/test-operator@sha256:3e01e99d3ca1b6c20b1bb015b00cfcbffc584f22a93dc6fe4019d63b813c0241 + value: quay.io/openstack-k8s-operators/test-operator@sha256:8ef15ec7d5e79b47a1cf89e858f29f6919f67761bf1839f7a885399c325fc8b0 - name: RELATED_IMAGE_WATCHER_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/watcher-operator@sha256:13e69f6777cfc6c8ecd5b9b0e85f420eeb3fd2a7303da030b9942abf76184c78 + value: quay.io/openstack-k8s-operators/watcher-operator@sha256:7b444da19e6ea46b92286a7a22f9ee7c2f05712aed9f3fb2e65c128f532960a8 diff --git a/config/samples/base/openstackcontrolplane/core_v1beta1_openstackcontrolplane.yaml b/config/samples/base/openstackcontrolplane/core_v1beta1_openstackcontrolplane.yaml index acf7508f4..f072a1579 100644 --- a/config/samples/base/openstackcontrolplane/core_v1beta1_openstackcontrolplane.yaml +++ b/config/samples/base/openstackcontrolplane/core_v1beta1_openstackcontrolplane.yaml @@ -9,6 +9,8 @@ spec: template: databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for Barbican KeystoneListener galera: templates: openstack: @@ -42,6 +44,8 @@ spec: template: databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Match Keystone for complete notification integration barbicanAPI: replicas: 1 barbicanWorker: @@ -166,10 +170,14 @@ spec: databaseAccount: aodh databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services heatInstance: heat ceilometer: enabled: true secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services logging: enabled: false ipaddr: 172.17.0.80 diff --git a/config/samples/core_v1beta1_openstackcontrolplane_collapsed_cell.yaml b/config/samples/core_v1beta1_openstackcontrolplane_collapsed_cell.yaml index b2fb8eb37..7842b4b90 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_collapsed_cell.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_collapsed_cell.yaml @@ -9,6 +9,8 @@ spec: template: databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for Barbican KeystoneListener galera: templates: openstack: @@ -32,6 +34,8 @@ spec: template: databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Match Keystone for complete notification integration barbicanAPI: replicas: 1 barbicanWorker: @@ -114,7 +118,8 @@ spec: cell1: cellDatabaseAccount: nova-cell1 cellDatabaseInstance: openstack - cellMessageBusInstance: rabbitmq + messagingBus: + cluster: rabbitmq conductorServiceTemplate: replicas: 1 hasAPIAccess: true @@ -151,10 +156,14 @@ spec: databaseAccount: aodh databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services heatInstance: heat ceilometer: enabled: true secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services logging: enabled: false ipaddr: 172.17.0.80 diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera.yaml index fa42679b1..b266ff5b7 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera.yaml @@ -9,6 +9,8 @@ spec: template: databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for Barbican KeystoneListener galera: templates: openstack: @@ -40,6 +42,8 @@ spec: template: databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Match Keystone for complete notification integration barbicanAPI: replicas: 1 barbicanWorker: @@ -125,14 +129,16 @@ spec: cell0: cellDatabaseAccount: nova-cell0 cellDatabaseInstance: openstack - cellMessageBusInstance: rabbitmq + messagingBus: + cluster: rabbitmq conductorServiceTemplate: replicas: 1 hasAPIAccess: true cell1: cellDatabaseAccount: nova-cell1 cellDatabaseInstance: openstack-cell1 - cellMessageBusInstance: rabbitmq-cell1 + messagingBus: + cluster: rabbitmq-cell1 conductorServiceTemplate: replicas: 1 hasAPIAccess: true @@ -179,10 +185,14 @@ spec: databaseAccount: aodh databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services heatInstance: heat ceilometer: enabled: true secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services logging: enabled: false ipaddr: 172.17.0.80 diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_3replicas.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_3replicas.yaml index b7c744b16..57dae1fe7 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_3replicas.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_3replicas.yaml @@ -9,6 +9,8 @@ spec: template: databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for Barbican KeystoneListener galera: templates: openstack: @@ -40,6 +42,8 @@ spec: template: databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Match Keystone for complete notification integration barbicanAPI: replicas: 1 barbicanWorker: @@ -125,14 +129,16 @@ spec: cell0: cellDatabaseAccount: nova-cell0 cellDatabaseInstance: openstack - cellMessageBusInstance: rabbitmq + messagingBus: + cluster: rabbitmq conductorServiceTemplate: replicas: 1 hasAPIAccess: true cell1: cellDatabaseAccount: nova-cell1 cellDatabaseInstance: openstack-cell1 - cellMessageBusInstance: rabbitmq-cell1 + messagingBus: + cluster: rabbitmq-cell1 conductorServiceTemplate: replicas: 1 hasAPIAccess: true @@ -169,10 +175,14 @@ spec: databaseAccount: aodh databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services heatInstance: heat ceilometer: enabled: true secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services logging: enabled: false ipaddr: 172.17.0.80 diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml index 3cc7097de..15ed60fe5 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation.yaml @@ -103,6 +103,8 @@ spec: type: LoadBalancer databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for Barbican KeystoneListener galera: templates: openstack: @@ -141,6 +143,8 @@ spec: template: databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Match Keystone for complete notification integration barbicanAPI: replicas: 1 override: @@ -171,14 +175,16 @@ spec: cell0: cellDatabaseAccount: nova-cell0 cellDatabaseInstance: openstack - cellMessageBusInstance: rabbitmq + messagingBus: + cluster: rabbitmq conductorServiceTemplate: replicas: 1 hasAPIAccess: true cell1: cellDatabaseAccount: nova-cell1 cellDatabaseInstance: openstack-cell1 - cellMessageBusInstance: rabbitmq-cell1 + messagingBus: + cluster: rabbitmq-cell1 conductorServiceTemplate: replicas: 1 hasAPIAccess: true @@ -346,10 +352,14 @@ spec: databaseAccount: aodh databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services heatInstance: heat ceilometer: enabled: true secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services logging: enabled: false ipaddr: 172.17.0.80 @@ -388,12 +398,13 @@ spec: databaseInstance: openstack enabled: false memcachedInstance: memcached + messagingBus: + cluster: rabbitmq passwordSelector: aodhService: AodhPassword ceilometerService: CeilometerPassword cloudKittyService: CloudKittyPassword preserveJobs: false - rabbitMqClusterName: rabbitmq s3StorageConfig: schemas: - effectiveDate: "2024-11-18" diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml index de4c833df..8227c658c 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas.yaml @@ -55,6 +55,8 @@ spec: template: databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Match Keystone for complete notification integration barbicanAPI: replicas: 1 override: @@ -125,6 +127,8 @@ spec: type: LoadBalancer databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for Barbican KeystoneListener galera: templates: openstack: @@ -171,14 +175,16 @@ spec: cell0: cellDatabaseAccount: nova-cell0 cellDatabaseInstance: openstack - cellMessageBusInstance: rabbitmq + messagingBus: + cluster: rabbitmq conductorServiceTemplate: replicas: 1 hasAPIAccess: true cell1: cellDatabaseAccount: nova-cell1 cellDatabaseInstance: openstack-cell1 - cellMessageBusInstance: rabbitmq-cell1 + messagingBus: + cluster: rabbitmq-cell1 conductorServiceTemplate: replicas: 1 hasAPIAccess: true @@ -348,10 +354,14 @@ spec: databaseAccount: aodh databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services heatInstance: heat ceilometer: enabled: true secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services logging: enabled: false ipaddr: 172.17.0.80 diff --git a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas_only_default_enabled_services.yaml b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas_only_default_enabled_services.yaml index 06eedb768..50d319025 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas_only_default_enabled_services.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_3replicas_only_default_enabled_services.yaml @@ -55,6 +55,8 @@ spec: template: databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Match Keystone for complete notification integration barbicanAPI: replicas: 1 override: @@ -125,6 +127,8 @@ spec: type: LoadBalancer databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for Barbican KeystoneListener galera: templates: openstack: @@ -165,14 +169,16 @@ spec: cell0: cellDatabaseAccount: nova-cell0 cellDatabaseInstance: openstack - cellMessageBusInstance: rabbitmq + messagingBus: + cluster: rabbitmq conductorServiceTemplate: replicas: 1 hasAPIAccess: true cell1: cellDatabaseAccount: nova-cell1 cellDatabaseInstance: openstack-cell1 - cellMessageBusInstance: rabbitmq-cell1 + messagingBus: + cluster: rabbitmq-cell1 conductorServiceTemplate: replicas: 1 hasAPIAccess: true @@ -268,10 +274,14 @@ spec: databaseAccount: aodh databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services heatInstance: heat ceilometer: enabled: true secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services logging: enabled: false ipaddr: 172.17.0.80 diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml index 971778a0f..8b01dc469 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation.yaml @@ -55,6 +55,8 @@ spec: template: databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Match Keystone for complete notification integration barbicanAPI: replicas: 1 override: @@ -125,6 +127,8 @@ spec: type: LoadBalancer databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for Barbican KeystoneListener galera: templates: openstack: @@ -167,14 +171,16 @@ spec: cell0: cellDatabaseAccount: nova-cell0 cellDatabaseInstance: openstack - cellMessageBusInstance: rabbitmq + messagingBus: + cluster: rabbitmq conductorServiceTemplate: replicas: 1 hasAPIAccess: true cell1: cellDatabaseAccount: nova-cell1 cellDatabaseInstance: openstack-cell1 - cellMessageBusInstance: rabbitmq-cell1 + messagingBus: + cluster: rabbitmq-cell1 conductorServiceTemplate: replicas: 1 hasAPIAccess: true @@ -342,10 +348,14 @@ spec: databaseAccount: aodh databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services heatInstance: heat ceilometer: enabled: true secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services logging: enabled: false ipaddr: 172.17.0.80 diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml index 86525cd39..c157f710f 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_ceph.yaml @@ -47,6 +47,8 @@ spec: template: databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Match Keystone for complete notification integration barbicanAPI: replicas: 1 override: @@ -158,6 +160,8 @@ spec: type: LoadBalancer databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for Barbican KeystoneListener galera: templates: openstack: @@ -200,14 +204,16 @@ spec: cell0: cellDatabaseAccount: nova-cell0 cellDatabaseInstance: openstack - cellMessageBusInstance: rabbitmq + messagingBus: + cluster: rabbitmq conductorServiceTemplate: replicas: 1 hasAPIAccess: true cell1: cellDatabaseAccount: nova-cell1 cellDatabaseInstance: openstack-cell1 - cellMessageBusInstance: rabbitmq-cell1 + messagingBus: + cluster: rabbitmq-cell1 conductorServiceTemplate: replicas: 1 hasAPIAccess: true @@ -392,10 +398,14 @@ spec: databaseAccount: aodh databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services heatInstance: heat ceilometer: enabled: true secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services logging: enabled: false ipaddr: 172.17.0.80 diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_tls_public_endpoint.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_tls_public_endpoint.yaml index 021abff32..b28093c30 100644 --- a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_tls_public_endpoint.yaml +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_tls_public_endpoint.yaml @@ -58,6 +58,8 @@ spec: template: databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Match Keystone for complete notification integration barbicanAPI: replicas: 1 override: @@ -128,6 +130,8 @@ spec: type: LoadBalancer databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for Barbican KeystoneListener galera: templates: openstack: @@ -170,14 +174,16 @@ spec: cell0: cellDatabaseAccount: nova-cell0 cellDatabaseInstance: openstack - cellMessageBusInstance: rabbitmq + messagingBus: + cluster: rabbitmq conductorServiceTemplate: replicas: 1 hasAPIAccess: true cell1: cellDatabaseAccount: nova-cell1 cellDatabaseInstance: openstack-cell1 - cellMessageBusInstance: rabbitmq-cell1 + messagingBus: + cluster: rabbitmq-cell1 conductorServiceTemplate: replicas: 1 hasAPIAccess: true @@ -345,10 +351,14 @@ spec: databaseAccount: aodh databaseInstance: openstack secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services heatInstance: heat ceilometer: enabled: true secret: osp-secret + notificationsBus: + cluster: rabbitmq # Required for receiving notifications from OpenStack services logging: enabled: false ipaddr: 172.17.0.80 diff --git a/go.mod b/go.mod index f1a765121..f471db4cb 100644 --- a/go.mod +++ b/go.mod @@ -12,33 +12,33 @@ require ( github.com/onsi/ginkgo/v2 v2.28.1 github.com/onsi/gomega v1.39.1 github.com/openshift/api v3.9.0+incompatible - github.com/openstack-k8s-operators/barbican-operator/api v0.6.1-0.20260130161218-ed22e21b9035 - github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20260203100410-bec3d87f42df - github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20260130194629-8145dc930d49 - github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20260203172717-de34ba474e77 - github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20260205152457-97ee6babce57 - github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20260126110912-72d03020e1a5 + github.com/openstack-k8s-operators/barbican-operator/api v0.6.1-0.20260206192347-aab776857909 + github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20260206174955-5bf43d6c75a6 + github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20260206181913-24f48ca5ba86 + github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20260206173306-e0a322fced68 + github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20260207082315-6c0673338be7 + github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20260207061358-9a5362005f8a 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.20260205123033-c9cd3795f8c6 - github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260126175636-114b4c65a959 - github.com/openstack-k8s-operators/lib-common/modules/ansible v0.6.1-0.20260126081203-efc2df9207eb - github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.6.1-0.20260126081203-efc2df9207eb + github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20260207081358-6dce1a518688 + github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260206181019-26ebc8a46afe + github.com/openstack-k8s-operators/lib-common/modules/ansible v0.6.1-0.20260205083029-d03e9df035ef + github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.6.1-0.20260205083029-d03e9df035ef github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260205083029-d03e9df035ef - github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260128142552-e2c25eccae5a - github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260126081203-efc2df9207eb - github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20260203154427-fb9213e462a4 + github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260205083029-d03e9df035ef + github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260205083029-d03e9df035ef + github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20260206173305-72969ece6ed4 github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260127154438-ff95971883bb - github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20260130110557-870de6f217b5 - github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20260205135859-d785b91fa1d7 - github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20260130160650-fee89a8e7044 + github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20260206181305-f3366b4bd37b + github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20260207082315-2e0a55b6d766 + github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20260206221031-ca09bc20f265 github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.6.1-0.20260126123727-b3f88d69956c github.com/openstack-k8s-operators/openstack-operator/api v0.0.0-00010101000000-000000000000 github.com/openstack-k8s-operators/ovn-operator/api v0.6.1-0.20260126160735-3254731d17a8 github.com/openstack-k8s-operators/placement-operator/api v0.6.1-0.20260203072749-c46bb493557d - github.com/openstack-k8s-operators/swift-operator/api v0.6.1-0.20260201211658-98f018aea931 - github.com/openstack-k8s-operators/telemetry-operator/api v0.6.1-0.20260205110928-7d95eaebdfe4 - github.com/openstack-k8s-operators/test-operator/api v0.6.1-0.20260128101443-e227c7785ffa - github.com/openstack-k8s-operators/watcher-operator/api v0.6.1-0.20260206073930-3cd4f1433bff + github.com/openstack-k8s-operators/swift-operator/api v0.6.1-0.20260206221909-c0927c3803e6 + github.com/openstack-k8s-operators/telemetry-operator/api v0.6.1-0.20260206181610-fe8dc27febad + github.com/openstack-k8s-operators/test-operator/api v0.6.1-0.20260205123034-b5099bd5da4e + github.com/openstack-k8s-operators/watcher-operator/api v0.6.1-0.20260207082017-e2c9f69be82c github.com/pkg/errors v0.9.1 github.com/rabbitmq/cluster-operator/v2 v2.16.0 github.com/stretchr/testify v1.11.1 @@ -95,7 +95,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // 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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.22.0 // indirect github.com/prometheus/client_model v0.6.2 // indirect diff --git a/go.sum b/go.sum index e238ac7a4..d8134dce6 100644 --- a/go.sum +++ b/go.sum @@ -138,46 +138,46 @@ github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= 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/barbican-operator/api v0.6.1-0.20260130161218-ed22e21b9035 h1:ZbEYqSRTtyXbOATlY1bDYBa0Rp3MMZjcaR0yHSgLW24= -github.com/openstack-k8s-operators/barbican-operator/api v0.6.1-0.20260130161218-ed22e21b9035/go.mod h1:tfNU2Cy1ofpDtVj+afn0u79/RDQPc7OrRE4RjurwAEQ= -github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20260203100410-bec3d87f42df h1:ry1fl+Sp4dXjt+nTe2PkCm0ZpTpiKkqStzjoPq68tuc= -github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20260203100410-bec3d87f42df/go.mod h1:j0JH8VRZHOP6pNkKSWK1Zfj8ov1yVkUwNNheu1xLbwE= -github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20260130194629-8145dc930d49 h1:wSG2ZEorUADT8VOUmKB7cOXmvYOwZMvy6ERd+6PehPg= -github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20260130194629-8145dc930d49/go.mod h1:rTrAkG8KR+P+UVXwJjrlTAuxwx3HKMPmrb24qrxLHpM= -github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20260203172717-de34ba474e77 h1:qQF4eugVDwMIFSivIq/mcsO/rDNgWZO3nEUdEEivN40= -github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20260203172717-de34ba474e77/go.mod h1:SHocUrLIilw67T26C2wMbJs6IXSWIv1PF/1VqFGxe4Q= -github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20260205152457-97ee6babce57 h1:zTujRvfAMy0o/OyebVaMhv+8wn+/8C5QvVeMmlXFdDI= -github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20260205152457-97ee6babce57/go.mod h1:mScOSRv5YDbjEPfirc2K+L7kJYZE4PoueTkFoU+BRQ0= -github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20260126110912-72d03020e1a5 h1:Rhqx9iFaZgC2VhE2IiCGqPxJtc5A4hoz/5Rv8a+gtDY= -github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20260126110912-72d03020e1a5/go.mod h1:x8muLIctcCLObcdeynPgycfQ+6ddWIDlSOQ9NElG43M= +github.com/openstack-k8s-operators/barbican-operator/api v0.6.1-0.20260206192347-aab776857909 h1:EFYSJkh2ioLxc7tm5TY7Fbd9o0KWjU/ho8rcjDVH1DU= +github.com/openstack-k8s-operators/barbican-operator/api v0.6.1-0.20260206192347-aab776857909/go.mod h1:KQnoNfCO5HHB/P6MAOE2u9V1wQbQxy5n51p8W7Dki4E= +github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20260206174955-5bf43d6c75a6 h1:3DndxajP+nBHGwLnM5UATgn2dfgRDcenaEWZrSN6LNg= +github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20260206174955-5bf43d6c75a6/go.mod h1:EzMRjjhQf66iBj1XW+87MTohQttxkVh/u0PnhKR/RQI= +github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20260206181913-24f48ca5ba86 h1:mCt50YggftseJ/Z1yx+xedmHR0yZ53b6DuhWpbIozwY= +github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20260206181913-24f48ca5ba86/go.mod h1:2tyAJhSJSiGGG0NJqqvbh64EmVCCVKNZDqkWm/KdBZA= +github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20260206173306-e0a322fced68 h1:I2GqzPBsx4DsQ432xXuScVJg/zkU75IYAOUynB2pQ74= +github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20260206173306-e0a322fced68/go.mod h1:exyWfAY4rY5VtN86WwmpaAe0Us/PCA8IdwkmfJMWz/4= +github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20260207082315-6c0673338be7 h1:quPMDHqFrMgdGXg59uehz5W3nY1hCUatXjpVBD8I5kA= +github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20260207082315-6c0673338be7/go.mod h1:T5lLlPNIJZuXRh8J1PwA1sZL3fgERGYHfisfcKZm2bI= +github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20260207061358-9a5362005f8a h1:d9KDJmBmvhyBCF30jjGc8GUr54imeyXjpt6c0aRJzEI= +github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20260207061358-9a5362005f8a/go.mod h1:36WkVJYX2dUCbg5ebp4b3RLtqz8KF0v7y98q/bw8OjI= github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260128074606-03b808364e4a h1:uJL923hT6ZJE1fKq+/FA0mVX46AgE3H+OClpL2DXq4Y= github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260128074606-03b808364e4a/go.mod h1:ZXwFlspJCdZEUjMbmaf61t5AMB4u2vMyAMMoe/vJroE= -github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20260205123033-c9cd3795f8c6 h1:NOo/jBBjvIufuuWS0ve7jsnSPH8lxJnyDJrNR0eoQ8c= -github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20260205123033-c9cd3795f8c6/go.mod h1:tsE9DPDd7XKJPYfH+cts6cbo084rargXgmeFWtw3FwA= -github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260126175636-114b4c65a959 h1:8FSpTYAoLq27ElDGe3igPl2QUq9IYD6RJGu2Xu+Ymus= -github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260126175636-114b4c65a959/go.mod h1:pN/s+czXvApiE9nxeTtDeRTXWcaaCLZSrtoyOSUb37k= -github.com/openstack-k8s-operators/lib-common/modules/ansible v0.6.1-0.20260126081203-efc2df9207eb h1:35v30c6nI9WtnNnkfh4nRnC/lU9O6rM2Y8onhEAl45g= -github.com/openstack-k8s-operators/lib-common/modules/ansible v0.6.1-0.20260126081203-efc2df9207eb/go.mod h1:tXxVkkk8HlATwTmDA5RTP3b+c8apfuMM15mZ2wW5iNs= -github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.6.1-0.20260126081203-efc2df9207eb h1:pCyizgwvB2tgFGhGtAV5rXV0kSu9l5RoR2XA+Gd5BuY= -github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.6.1-0.20260126081203-efc2df9207eb/go.mod h1:chsg6x4P7376/8MlmsC3OiasuDatbOLwC5D5KRD9fbo= +github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20260207081358-6dce1a518688 h1:PMW5Kfozot9XD8TlhdkgFCG+MuUXSW4gKTmIL4MGEw4= +github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20260207081358-6dce1a518688/go.mod h1:EL98j7yLMTRBMZsgP0LxP01qTV8SV3bGVzbHoOb+saM= +github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260206181019-26ebc8a46afe h1:Zz+qAaIumkEJuVk/XEKboZ9aMgGculN+02lYphH/Ofo= +github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260206181019-26ebc8a46afe/go.mod h1:JdQ8vvaokQZbeMaY2Qb6hu0iVUyxzaFl2l9Ej08F2lU= +github.com/openstack-k8s-operators/lib-common/modules/ansible v0.6.1-0.20260205083029-d03e9df035ef h1:eLasep300hXw2Nla26712zcATTwq/0RalQQGr4VFVT4= +github.com/openstack-k8s-operators/lib-common/modules/ansible v0.6.1-0.20260205083029-d03e9df035ef/go.mod h1:tXxVkkk8HlATwTmDA5RTP3b+c8apfuMM15mZ2wW5iNs= +github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.6.1-0.20260205083029-d03e9df035ef h1:Zz6hT/q9dX7xphYRg8GE/5AvATeyASgJ9WMoZfpJQiw= +github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.6.1-0.20260205083029-d03e9df035ef/go.mod h1:chsg6x4P7376/8MlmsC3OiasuDatbOLwC5D5KRD9fbo= github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260205083029-d03e9df035ef h1:SgzLekXtZuApbRylC3unCXnMaUClT5FPuqsxzIjt3Go= github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260205083029-d03e9df035ef/go.mod h1:ndqfy1KbVorHH6+zlUFPIrCRhMSxO3ImYJUGaooE0x0= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251230215914-6ba873b49a35 h1:IdcI8DFvW8rXtchONSzbDmhhRp1YyO2YaBJDBXr44Gk= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251230215914-6ba873b49a35/go.mod h1:zOX7Y05keiSppIvLabuyh42QHBMhCcoskAtxFRbwXKo= -github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260128142552-e2c25eccae5a h1:teKxfVLDxJD9ahjeh29GlKHiXNUFDkVRmkpJdeKAvGE= -github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260128142552-e2c25eccae5a/go.mod h1:jofj+VqDszxLCZSBYo794KGkCjMo01xzhQ/gffYzf3I= -github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260126081203-efc2df9207eb h1:Fh9yjyogiR9P4oV3a2pSlSUyYzfbWbvlU6RFIjZoxsg= -github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260126081203-efc2df9207eb/go.mod h1:sqKTKvYhSzu4Opnjx/J+zzetXKRqYrhxsfvrST/NjoU= -github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20260203154427-fb9213e462a4 h1:Ynrdr1X4RE0gDcgyAlos39AYFKV4I2WfTaZ2oAjU7d0= -github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20260203154427-fb9213e462a4/go.mod h1:xOLjSMU4f5F05L0DiCu6Uvz0dOIDmCyQmSVS+ZHaam0= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20260126081203-efc2df9207eb h1:E59YGRP8XWq8vi6AUUxyYyBD1ahzcr3RKDkZmxpi+qs= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20260126081203-efc2df9207eb/go.mod h1:zOX7Y05keiSppIvLabuyh42QHBMhCcoskAtxFRbwXKo= +github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260205083029-d03e9df035ef h1:2wJUSZ2ybE6JVjEyuk/HEaJ1in64jf/lrPOs8NrRHFo= +github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260205083029-d03e9df035ef/go.mod h1:jofj+VqDszxLCZSBYo794KGkCjMo01xzhQ/gffYzf3I= +github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260205083029-d03e9df035ef h1:Z4NHYzslSvwPVsoqSVCbGm/9mWG0mhc0WP92WSRh0CM= +github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260205083029-d03e9df035ef/go.mod h1:sqKTKvYhSzu4Opnjx/J+zzetXKRqYrhxsfvrST/NjoU= +github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20260206173305-72969ece6ed4 h1:vajN31pc7Qnv4yKreu/wjMVHUl4uOBWuAC7m4YDxmjg= +github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20260206173305-72969ece6ed4/go.mod h1:MKN/V7xTOfBVZCoAZyoZXv9Xm1WK++dIVN7Itl2x64I= github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260127154438-ff95971883bb h1:Zv7GXyG1wND4wNzCmfMI8oAWsDlrU2QFxq8tsnIKFs0= github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260127154438-ff95971883bb/go.mod h1:X6W8pIULiWUc6smaTqiNocjxoXaRLgXediwpI/dxD9s= -github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20260130110557-870de6f217b5 h1:VswZKlc2SGulbTNITVfddofnXLHGMqpUHjZabRU2V+8= -github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20260130110557-870de6f217b5/go.mod h1:Uu/8M93x55zd7amJpRKGJz4vCmvZvBfzaN6CwnOjDNY= -github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20260205135859-d785b91fa1d7 h1:oWCSoyfvh87ueqU3yMSoDR6pW+nWptXGsARK+ypIky8= -github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20260205135859-d785b91fa1d7/go.mod h1:bo00y0fC762qzXbn3tgpTT35n0CpSPxkZq7jCyE7LYQ= -github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20260130160650-fee89a8e7044 h1:IWidpe8G47CpthKIGKVUP0DmtpsCnYn1q4pDB8/pjhM= -github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20260130160650-fee89a8e7044/go.mod h1:Phcw9t23H4RbOpUqBhFldFBKEbkx+f4c0QGnfFOPh50= +github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20260206181305-f3366b4bd37b h1:mEp0NBejze4hEKzQQGD4zjMHMBqDRSqPPUYmyuEOFxg= +github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20260206181305-f3366b4bd37b/go.mod h1:P2br9yVt4dMCG1EgPj6k1wKc+QNvKaIFueLuRICwpi4= +github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20260207082315-2e0a55b6d766 h1:pq4n3ufAn2sNRMhp/G9vG/MPjoqfgXMDmJKh1KPmqRU= +github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20260207082315-2e0a55b6d766/go.mod h1:pX1Ht6fzob3F6Lhl3MV9MAJquWrosle62VXFsNyNmVU= +github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20260206221031-ca09bc20f265 h1:F8CxdhdExxz/OlxQAI4lBhFWU+FnnypbZfWfMh/icis= +github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20260206221031-ca09bc20f265/go.mod h1:U+xQIGQ6U3F+plwX3QTG1x/D6+tk/16h91/YbHPFRGU= github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.6.1-0.20260126123727-b3f88d69956c h1:5gY2Y9OjgHWltvw0jtQWDaoXnfJRObRNozC0dBLz0GQ= github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.6.1-0.20260126123727-b3f88d69956c/go.mod h1:8Ge7K0IfcMSpoyp9p0lnW36f3nvCf6lnoc4TWoIlazw= github.com/openstack-k8s-operators/ovn-operator/api v0.6.1-0.20260126160735-3254731d17a8 h1:70ennIUokh4YvGdzE7zzRYIHVJ0xnYRNvmrO/f0wk9A= @@ -186,14 +186,14 @@ github.com/openstack-k8s-operators/placement-operator/api v0.6.1-0.2026020307274 github.com/openstack-k8s-operators/placement-operator/api v0.6.1-0.20260203072749-c46bb493557d/go.mod h1:eWED9YYc2NLXutgocqK5m3LsnQ+aT0MeWgmnsqi6A0Y= 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/openstack-k8s-operators/swift-operator/api v0.6.1-0.20260201211658-98f018aea931 h1:iAa/ahDlWAHFa2WUQJ07SEyzFtYUBkEwtt8vZNQ1V9A= -github.com/openstack-k8s-operators/swift-operator/api v0.6.1-0.20260201211658-98f018aea931/go.mod h1:/2Qd/Xr1bPLaddKmKxhqHP5Zsj7YYz3TkzWOM8miaK0= -github.com/openstack-k8s-operators/telemetry-operator/api v0.6.1-0.20260205110928-7d95eaebdfe4 h1:kygc6YDl7kPwj1Ol2wMC6pLuhmpBK2IqULwlaZ7k/rA= -github.com/openstack-k8s-operators/telemetry-operator/api v0.6.1-0.20260205110928-7d95eaebdfe4/go.mod h1:l/jz/k6Al6GSleFlcbfuLjEkZynJZKvI/H4ZlyMCqAg= -github.com/openstack-k8s-operators/test-operator/api v0.6.1-0.20260128101443-e227c7785ffa h1:nTQKjQTyL2riSceHvEAbDhNfTcgJ8V2V9CUQF/9DJYY= -github.com/openstack-k8s-operators/test-operator/api v0.6.1-0.20260128101443-e227c7785ffa/go.mod h1:ju4G2suFa006GBnFRzxpchcm/d8vnmr/wI5Um4SHqK0= -github.com/openstack-k8s-operators/watcher-operator/api v0.6.1-0.20260206073930-3cd4f1433bff h1:45zoZ6GbBbTsd/WK0G4MxrxzHIkjQ+5m6ayv+QRX29c= -github.com/openstack-k8s-operators/watcher-operator/api v0.6.1-0.20260206073930-3cd4f1433bff/go.mod h1:1DeGo19yp7py2C+D98Mbv8P8UHYARmPTvfBAuTNXj5Q= +github.com/openstack-k8s-operators/swift-operator/api v0.6.1-0.20260206221909-c0927c3803e6 h1:D8OYnPApTJKIXD9++xs7PWhSYRZTmuNgciHAbaUz5YI= +github.com/openstack-k8s-operators/swift-operator/api v0.6.1-0.20260206221909-c0927c3803e6/go.mod h1:cQmm3SMOGD5AEsN8d7eF99c6LPgRkWEEBAY4K6ZHbs8= +github.com/openstack-k8s-operators/telemetry-operator/api v0.6.1-0.20260206181610-fe8dc27febad h1:/lMNHUDrUnIxhrRapDeHM9je77I9xdPMjJa+X3gCiDE= +github.com/openstack-k8s-operators/telemetry-operator/api v0.6.1-0.20260206181610-fe8dc27febad/go.mod h1:XMn2KWjSbLhQ6Jczs3ZhPEAyNmz9b94bz3jKsdDVpag= +github.com/openstack-k8s-operators/test-operator/api v0.6.1-0.20260205123034-b5099bd5da4e h1:ZnZKS9SVnrwb5zrKVnXU0pPWoaBsiS8AtcFZcrs3EEQ= +github.com/openstack-k8s-operators/test-operator/api v0.6.1-0.20260205123034-b5099bd5da4e/go.mod h1:7WMTzhkjY0IV87K7xCH56yrtEaunjt7bsq/RvcCGjhc= +github.com/openstack-k8s-operators/watcher-operator/api v0.6.1-0.20260207082017-e2c9f69be82c h1:NkrMXwoXhD5HomNEpm10QcyIUPYxwn7lAuCGTZCZEvI= +github.com/openstack-k8s-operators/watcher-operator/api v0.6.1-0.20260207082017-e2c9f69be82c/go.mod h1:XEJp64OcVDbT9G1gHowBBruWcZngWN4C5Z8UgpOoqvk= 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= diff --git a/hack/export_operator_related_images.sh b/hack/export_operator_related_images.sh index 0c0f9642c..24750e89b 100644 --- a/hack/export_operator_related_images.sh +++ b/hack/export_operator_related_images.sh @@ -1,24 +1,24 @@ # NOTE: this file is automatically generated by hack/sync-bindata.sh! -export RELATED_IMAGE_BARBICAN_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/barbican-operator@sha256:10bdb8674a5c5a0120a68ded4e8d007f03c8f33592eed1a9ff2ae9e53d377d87 -export RELATED_IMAGE_CINDER_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/cinder-operator@sha256:5461f69440de95db8df5b1242b3bb08644e215e025b17345b33325633e3dfba6 -export RELATED_IMAGE_DESIGNATE_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/designate-operator@sha256:a2e056d17d1ad90966fa943a1ec1e7c51b0f1f7842d0c0cc16a847bc3a34719e -export RELATED_IMAGE_GLANCE_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/glance-operator@sha256:df7752c1cb7e57607e010dd1dfe92f9dbf926a8eda1cd69003e8f7f4d0ee5ace -export RELATED_IMAGE_HEAT_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/heat-operator@sha256:51076be2b4311bd451e68e4e51ed32094e52834de769ee8635978914f0be99e4 -export RELATED_IMAGE_HORIZON_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/horizon-operator@sha256:027cd7ab61ef5071d9ad6b729c95a98e51cd254642f01dc019d44cc98a9232f8 +export RELATED_IMAGE_BARBICAN_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/barbican-operator@sha256:c5f4c50443436152f7d6ff8b07e972c201828520e56485758483f2e2919a52b5 +export RELATED_IMAGE_CINDER_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/cinder-operator@sha256:06e8e0c6db135450d10abedef818f02a770f7b77bbc02cdf4ceb25cd0951aef4 +export RELATED_IMAGE_DESIGNATE_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/designate-operator@sha256:1e7c7f2f83137d0311388255d109fac9a29b43683ae6c7c4f72bc65a1b5cfbda +export RELATED_IMAGE_GLANCE_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/glance-operator@sha256:8aaa025e23c55589801d88029000d412df67b464138ba3fe0e23d1fb78a4a9ad +export RELATED_IMAGE_HEAT_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/heat-operator@sha256:a707a15a7500b9636679d2e23c35195edf690c8fb0032dd1602dde1930c5926d +export RELATED_IMAGE_HORIZON_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/horizon-operator@sha256:4790f820f56e247c4ba6d357d989c99a9035611abc019b98ae0ac8ad57da0109 export RELATED_IMAGE_INFRA_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/infra-operator@sha256:a504ab83288310bbd8e39f3a01faaa3c210a14d94bbd32124e9eadd46227d6b3 -export RELATED_IMAGE_IRONIC_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/ironic-operator@sha256:f09760446d12b8ca3f8383ab7711c4dd4cc3e47e04528e2d8dfe8cbdb39dc9f2 -export RELATED_IMAGE_KEYSTONE_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/keystone-operator@sha256:319c969e88f109b26487a9f5a67203682803d7386424703ab7ca0340be99ae17 -export RELATED_IMAGE_MANILA_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/manila-operator@sha256:b8612e20df8c6a317a5e25884052455e2def210c704e1a8105253ead6eb35e87 +export RELATED_IMAGE_IRONIC_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/ironic-operator@sha256:5e95e6956488bd86fb59e65ac795cc5b71b6d596051e27aeaa58fdf5c99b0481 +export RELATED_IMAGE_KEYSTONE_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/keystone-operator@sha256:9ae333f2bb6a4fe19c8a50aa1bf0e3c0e41e520a6586f5cf357be464475c506d +export RELATED_IMAGE_MANILA_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/manila-operator@sha256:fffc4e59b4b6b1e2bd11dcd5ca2a9072c3909494ad7986b57aa3bb316bdc30be export RELATED_IMAGE_MARIADB_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/mariadb-operator@sha256:2d493137559b74e23edb4788b7fbdb38b3e239df0f2d7e6e540e50b2355fc3cf -export RELATED_IMAGE_NEUTRON_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/neutron-operator@sha256:7b45b0b511f6147f199989a554339aee505f0a3dd50092e2efc236706aabde09 -export RELATED_IMAGE_NOVA_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/nova-operator@sha256:7f230a842e37afd8ddfc543f6ed8514217e5916aa003b592ee0c044a1005f8c4 -export RELATED_IMAGE_OCTAVIA_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/octavia-operator@sha256:aa637692c9fe546c05a5fb53604cbd8cb532a071fbd63f09f60e56d5794a6569 +export RELATED_IMAGE_NEUTRON_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/neutron-operator@sha256:e0e08055345eceebc62fd708d00ce52a327ffb407842fb8fc1a7466a9d964048 +export RELATED_IMAGE_NOVA_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/nova-operator@sha256:2da857a0ddc880a136e2a9a18bf58c20672bc57407843bf1b93c7aa4ba819862 +export RELATED_IMAGE_OCTAVIA_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/octavia-operator@sha256:a6f09c4b637d091bbbc0ffc8970b30fbaf3e286a6a88466f8597e913895d087d export RELATED_IMAGE_OPENSTACK_BAREMETAL_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/openstack-baremetal-operator@sha256:89f6fd332fabefd2fff5619432986b37c1c6d197dd1c510f21dfe4609939b8a6 export RELATED_IMAGE_OVN_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/ovn-operator@sha256:ea7b72b648a5bde2eebd804c2a5c1608d448a4892176c1b8d000c1eef4bb92b4 export RELATED_IMAGE_PLACEMENT_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/placement-operator@sha256:4218e738cc0f3e20002c03cb0f005d7d290bbcc6a891b87dc06089fabb582ed8 export RELATED_IMAGE_RABBITMQ_CLUSTER_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/rabbitmq-cluster-operator@sha256:893e66303c1b0bc1d00a299a3f0380bad55c8dc813c8a1c6a4aab379f5aa12a2 -export RELATED_IMAGE_SWIFT_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/swift-operator@sha256:77388e446bc3af6f05ac372dbdb120da5d4d64e2ca1cd20b86e66ed4b69e63f8 -export RELATED_IMAGE_TELEMETRY_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/telemetry-operator@sha256:53ab303c58b5cbff65d21afc524b4cc31f546a32209bf0c75535077446d6d6dc -export RELATED_IMAGE_TEST_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/test-operator@sha256:3e01e99d3ca1b6c20b1bb015b00cfcbffc584f22a93dc6fe4019d63b813c0241 -export RELATED_IMAGE_WATCHER_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/watcher-operator@sha256:13e69f6777cfc6c8ecd5b9b0e85f420eeb3fd2a7303da030b9942abf76184c78 +export RELATED_IMAGE_SWIFT_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/swift-operator@sha256:c8fc4442fe24bf4fcc9266b5e2875adfac049cb04e58e288290c1a01e6adf44c +export RELATED_IMAGE_TELEMETRY_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/telemetry-operator@sha256:5dcca96e7bd6ed933c414cd759c88fa2165c8f42c863eb11058743c928d27076 +export RELATED_IMAGE_TEST_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/test-operator@sha256:8ef15ec7d5e79b47a1cf89e858f29f6919f67761bf1839f7a885399c325fc8b0 +export RELATED_IMAGE_WATCHER_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/watcher-operator@sha256:7b444da19e6ea46b92286a7a22f9ee7c2f05712aed9f3fb2e65c128f532960a8 diff --git a/hack/pin-bundle-images.sh b/hack/pin-bundle-images.sh index c5e43b6ba..4887e7cbb 100755 --- a/hack/pin-bundle-images.sh +++ b/hack/pin-bundle-images.sh @@ -43,35 +43,64 @@ for MOD_PATH in ${MOD_PATHS}; do CURL_REGISTRY="quay.io" REPO_CURL_URL="https://${CURL_REGISTRY}/api/v1/repository/openstack-k8s-operators" REPO_URL="${CURL_REGISTRY}/openstack-k8s-operators" - if [[ "$GITHUB_USER" != "openstack-k8s-operators" || "$BASE" == "$IMAGEBASE" ]]; then - if [[ "$IMAGENAMESPACE" != "openstack-k8s-operators" || "${IMAGEREGISTRY}" != "quay.io" ]]; then - REPO_URL="${IMAGEREGISTRY}/${IMAGENAMESPACE}" - CURL_REGISTRY="${IMAGEREGISTRY}" - # Quay registry v2 api does not return all the tags that's why keeping v1 for quay and v2 - # for local registry - if [[ ${LOCAL_REGISTRY} -eq 1 ]]; then - REPO_CURL_URL="${CURL_REGISTRY}/v2/${IMAGENAMESPACE}" - elif [[ "${CURL_REGISTRY}" == "docker.io" ]]; then - # replace docker.io by hub.docker.com to read tags - REPO_CURL_URL="https://hub.docker.com/v2/repositories/${IMAGENAMESPACE}" - else - REPO_CURL_URL="https://${CURL_REGISTRY}/api/v1/repository/${IMAGENAMESPACE}" - fi + + # IMAGEBASE takes precedence - if this operator matches IMAGEBASE, use custom registry + if [[ "$BASE" == "$IMAGEBASE" ]]; then + REPO_URL="${IMAGEREGISTRY}/${IMAGENAMESPACE}" + CURL_REGISTRY="${IMAGEREGISTRY}" + if [[ ${LOCAL_REGISTRY} -eq 1 ]]; then + REPO_CURL_URL="http://${CURL_REGISTRY}/v2/${IMAGENAMESPACE}" + elif [[ "${CURL_REGISTRY}" == "docker.io" ]]; then + REPO_CURL_URL="https://hub.docker.com/v2/repositories/${IMAGENAMESPACE}" + else + REPO_CURL_URL="https://${CURL_REGISTRY}/api/v1/repository/${IMAGENAMESPACE}" + fi + # For operators with replace directives (non-openstack-k8s-operators users), + # bundle images are only on quay.io, not mirrored to local registry + elif [[ "$GITHUB_USER" != "openstack-k8s-operators" ]]; then + # Force quay.io for replaced operators, use the GitHub user's namespace + CURL_REGISTRY="quay.io" + REPO_CURL_URL="https://${CURL_REGISTRY}/api/v1/repository/${GITHUB_USER}" + REPO_URL="${CURL_REGISTRY}/${GITHUB_USER}" + # For standard operators with custom registry settings + elif [[ "$IMAGENAMESPACE" != "openstack-k8s-operators" || "${IMAGEREGISTRY}" != "quay.io" ]]; then + REPO_URL="${IMAGEREGISTRY}/${IMAGENAMESPACE}" + CURL_REGISTRY="${IMAGEREGISTRY}" + # Quay registry v2 api does not return all the tags that's why keeping v1 for quay and v2 + # for local registry + if [[ ${LOCAL_REGISTRY} -eq 1 ]]; then + REPO_CURL_URL="http://${CURL_REGISTRY}/v2/${IMAGENAMESPACE}" + elif [[ "${CURL_REGISTRY}" == "docker.io" ]]; then + # replace docker.io by hub.docker.com to read tags + REPO_CURL_URL="https://hub.docker.com/v2/repositories/${IMAGENAMESPACE}" else - REPO_CURL_URL="https://${CURL_REGISTRY}/api/v1/repository/${GITHUB_USER}" - REPO_URL="${CURL_REGISTRY}/${GITHUB_USER}" + REPO_CURL_URL="https://${CURL_REGISTRY}/api/v1/repository/${IMAGENAMESPACE}" fi fi - if [[ ${LOCAL_REGISTRY} -eq 1 && ( "$GITHUB_USER" != "openstack-k8s-operators" || "$BASE" == "$IMAGEBASE" ) ]]; then - SHA=$(curl -s ${REPO_CURL_URL}/$BASE-operator-bundle/tags/list | jq -r .tags[] | sort -u | grep $REF) + # Query local registry only for standard operators (openstack-k8s-operators) or custom IMAGEBASE + # Replaced operators (e.g., lmiccini/*) always query quay.io since bundles aren't mirrored locally + if [[ ${LOCAL_REGISTRY} -eq 1 && ( "$GITHUB_USER" == "openstack-k8s-operators" || "$BASE" == "$IMAGEBASE" ) ]]; then + SHA=$(curl -s ${REPO_CURL_URL}/$BASE-operator-bundle/tags/list | jq -r '.tags // [] | .[]' | sort -u | { grep $REF || true; }) + # If local registry doesn't have the bundle, fall back to quay.io + if [ -z "$SHA" ]; then + SHA=$(curl -s https://quay.io/api/v1/repository/openstack-k8s-operators/$BASE-operator-bundle/tag/?onlyActiveTags=true\&filter_tag_name=like:$REF | jq -r '.tags // [] | .[].name') + # Update REPO_URL to use quay.io since we're falling back + REPO_URL="quay.io/openstack-k8s-operators" + fi elif [[ "${CURL_REGISTRY}" == "docker.io" ]]; then - SHA=$(curl -s ${REPO_CURL_URL}/$BASE-operator-bundle/tags/?page_size=100 | jq -r .results[].name | sort -u | grep $REF) + SHA=$(curl -s ${REPO_CURL_URL}/$BASE-operator-bundle/tags/?page_size=100 | jq -r '.results // [] | .[].name' | sort -u | { grep $REF || true; }) elif [[ "${CURL_REGISTRY}" != "quay.io" ]]; then # quay.rdoproject.io doesn't support filter_tag_name, so increase limit to 100 - SHA=$(curl -s ${REPO_CURL_URL}/$BASE-operator-bundle/tag/?onlyActiveTags=true?limit=100 | jq -r .tags[].name | sort -u | grep $REF) + SHA=$(curl -s ${REPO_CURL_URL}/$BASE-operator-bundle/tag/?onlyActiveTags=true\&limit=100 | jq -r '.tags // [] | .[].name' | sort -u | { grep $REF || true; }) + # If non-quay.io registry doesn't have the bundle for openstack-k8s-operators, fall back to quay.io + if [[ -z "$SHA" && "$GITHUB_USER" == "openstack-k8s-operators" ]]; then + SHA=$(curl -s https://quay.io/api/v1/repository/openstack-k8s-operators/$BASE-operator-bundle/tag/?onlyActiveTags=true\&filter_tag_name=like:$REF | jq -r '.tags // [] | .[].name') + # Update REPO_URL to use quay.io since we're falling back + REPO_URL="quay.io/openstack-k8s-operators" + fi else - SHA=$(curl -s ${REPO_CURL_URL}/$BASE-operator-bundle/tag/?onlyActiveTags=true\&filter_tag_name=like:$REF | jq -r .tags[].name) + SHA=$(curl -s ${REPO_CURL_URL}/$BASE-operator-bundle/tag/?onlyActiveTags=true\&filter_tag_name=like:$REF | jq -r '.tags // [] | .[].name') fi if [ -z "$SHA" ]; then diff --git a/internal/controller/core/openstackcontrolplane_controller.go b/internal/controller/core/openstackcontrolplane_controller.go index 78ac06c79..7aebc3d29 100644 --- a/internal/controller/core/openstackcontrolplane_controller.go +++ b/internal/controller/core/openstackcontrolplane_controller.go @@ -21,6 +21,7 @@ import ( "context" "fmt" "strings" + "time" certmgrv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" routev1 "github.com/openshift/api/route/v1" @@ -36,6 +37,7 @@ import ( keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" common_helper "github.com/openstack-k8s-operators/lib-common/modules/common/helper" + "github.com/openstack-k8s-operators/lib-common/modules/common/webhook" corev1 "k8s.io/api/core/v1" designatev1 "github.com/openstack-k8s-operators/designate-operator/api/v1beta1" @@ -453,6 +455,36 @@ func (r *OpenStackControlPlaneReconciler) reconcileNormal(ctx context.Context, i deploymentStage := instance.Annotations[corev1beta1.DeploymentStageAnnotation] infrastructureOnly := deploymentStage == corev1beta1.DeploymentStageInfrastructureOnly + // Trigger webhook migration for deprecated messaging bus fields + needsMigration := false + if instance.Spec.NotificationsBusInstance != nil && *instance.Spec.NotificationsBusInstance != "" { + if instance.Spec.NotificationsBus == nil || instance.Spec.NotificationsBus.Cluster == "" { + needsMigration = true + } + } + + // Check service-level rabbitMqClusterName migrations + if !needsMigration { + needsMigration = r.needsServiceLevelMigration(instance) + } + + if needsMigration { + ctrlResult, err := webhook.EnsureWebhookTrigger( + ctx, + instance, + openstack.ReconcileTriggerAnnotation, + "messaging bus migration", + helper.GetLogger(), + 5*time.Minute, + ) + if err != nil { + return ctrl.Result{}, err + } + if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + } + // Reconcile infrastructure components (always run) ctrlResult, err := openstack.ReconcileCAs(ctx, instance, helper) if err != nil { @@ -875,6 +907,167 @@ func (r *OpenStackControlPlaneReconciler) findObjectsForSrc(ctx context.Context, return requests } +// needsServiceLevelMigration checks if any service-level rabbitMqClusterName fields need migration +func (r *OpenStackControlPlaneReconciler) needsServiceLevelMigration(instance *corev1beta1.OpenStackControlPlane) bool { + // Helper function to check if a service needs migration + needsMigration := func(messagingBus *rabbitmqv1.RabbitMqConfig, deprecatedField *string) bool { + if deprecatedField != nil && *deprecatedField != "" { + return messagingBus.Cluster == "" + } + return false + } + + // Helper function to check if a service needs notificationsBusInstance migration + needsNotificationsMigration := func(notificationsBus **rabbitmqv1.RabbitMqConfig, deprecatedField **string) bool { + if deprecatedField != nil && *deprecatedField != nil && **deprecatedField != "" { + return *notificationsBus == nil || (*notificationsBus).Cluster == "" + } + return false + } + + // Check each service that has messaging bus fields + if instance.Spec.Cinder.Template != nil { + if needsMigration(&instance.Spec.Cinder.Template.MessagingBus, &instance.Spec.Cinder.Template.RabbitMqClusterName) { + return true + } + if needsNotificationsMigration(&instance.Spec.Cinder.Template.NotificationsBus, &instance.Spec.Cinder.Template.NotificationsBusInstance) { + return true + } + } + + if instance.Spec.Manila.Template != nil { + if needsMigration(&instance.Spec.Manila.Template.MessagingBus, &instance.Spec.Manila.Template.RabbitMqClusterName) { + return true + } + if needsNotificationsMigration(&instance.Spec.Manila.Template.NotificationsBus, &instance.Spec.Manila.Template.NotificationsBusInstance) { + return true + } + } + + if instance.Spec.Neutron.Template != nil { + if needsMigration(&instance.Spec.Neutron.Template.MessagingBus, &instance.Spec.Neutron.Template.RabbitMqClusterName) { + return true + } + if needsNotificationsMigration(&instance.Spec.Neutron.Template.NotificationsBus, &instance.Spec.Neutron.Template.NotificationsBusInstance) { + return true + } + } + + if instance.Spec.Heat.Template != nil { + if needsMigration(&instance.Spec.Heat.Template.MessagingBus, &instance.Spec.Heat.Template.RabbitMqClusterName) { + return true + } + } + + if instance.Spec.Ironic.Template != nil { + if needsMigration(&instance.Spec.Ironic.Template.MessagingBus, &instance.Spec.Ironic.Template.RabbitMqClusterName) { + return true + } + // IronicNeutronAgent has its own messaging bus + if needsMigration(&instance.Spec.Ironic.Template.IronicNeutronAgent.MessagingBus, + &instance.Spec.Ironic.Template.IronicNeutronAgent.RabbitMqClusterName) { + return true + } + } + + if instance.Spec.Barbican.Template != nil { + if needsMigration(&instance.Spec.Barbican.Template.MessagingBus, &instance.Spec.Barbican.Template.RabbitMqClusterName) { + return true + } + } + + if instance.Spec.Designate.Template != nil { + if needsMigration(&instance.Spec.Designate.Template.MessagingBus, &instance.Spec.Designate.Template.RabbitMqClusterName) { + return true + } + } + + if instance.Spec.Octavia.Template != nil { + if needsMigration(&instance.Spec.Octavia.Template.MessagingBus, &instance.Spec.Octavia.Template.RabbitMqClusterName) { + return true + } + } + + if instance.Spec.Watcher.Template != nil && instance.Spec.Watcher.Template.RabbitMqClusterName != nil { + if needsMigration(&instance.Spec.Watcher.Template.MessagingBus, instance.Spec.Watcher.Template.RabbitMqClusterName) { + return true + } + } + + if instance.Spec.Watcher.Template != nil { + if needsNotificationsMigration(&instance.Spec.Watcher.Template.NotificationsBus, &instance.Spec.Watcher.Template.NotificationsBusInstance) { + return true + } + } + + // Keystone - uses NotificationsBus instead of MessagingBus + if instance.Spec.Keystone.Template != nil && instance.Spec.Keystone.Template.RabbitMqClusterName != "" { + if instance.Spec.Keystone.Template.NotificationsBus == nil || + instance.Spec.Keystone.Template.NotificationsBus.Cluster == "" { + return true + } + } + + // Swift - SwiftProxy uses NotificationsBus for Ceilometer middleware + if instance.Spec.Swift.Template != nil && instance.Spec.Swift.Template.SwiftProxy.RabbitMqClusterName != "" { + if instance.Spec.Swift.Template.SwiftProxy.NotificationsBus == nil || + instance.Spec.Swift.Template.SwiftProxy.NotificationsBus.Cluster == "" { + return true + } + } + + // Nova - has API-level and per-cell messaging bus fields + if instance.Spec.Nova.Template != nil { + // Check API-level migration + if instance.Spec.Nova.Template.APIMessageBusInstance != "" && + instance.Spec.Nova.Template.MessagingBus.Cluster == "" { + return true + } + + // Check per-cell migration + if instance.Spec.Nova.Template.CellTemplates != nil { + for _, cellTemplate := range instance.Spec.Nova.Template.CellTemplates { + if cellTemplate.CellMessageBusInstance != "" && + cellTemplate.MessagingBus.Cluster == "" { + return true + } + } + } + + // Check notificationsBusInstance migration + if needsNotificationsMigration(&instance.Spec.Nova.Template.NotificationsBus, &instance.Spec.Nova.Template.NotificationsBusInstance) { + return true + } + } + + // Telemetry - has multiple sub-services + if instance.Spec.Telemetry.Template != nil { + // CloudKitty uses MessagingBus + if instance.Spec.Telemetry.Template.CloudKitty.RabbitMqClusterName != "" && + instance.Spec.Telemetry.Template.CloudKitty.MessagingBus.Cluster == "" { + return true + } + + // Autoscaling.Aodh uses NotificationsBus + if instance.Spec.Telemetry.Template.Autoscaling.Aodh.RabbitMqClusterName != "" { + if instance.Spec.Telemetry.Template.Autoscaling.Aodh.NotificationsBus == nil || + instance.Spec.Telemetry.Template.Autoscaling.Aodh.NotificationsBus.Cluster == "" { + return true + } + } + + // Ceilometer uses NotificationsBus + if instance.Spec.Telemetry.Template.Ceilometer.RabbitMqClusterName != "" { + if instance.Spec.Telemetry.Template.Ceilometer.NotificationsBus == nil || + instance.Spec.Telemetry.Template.Ceilometer.NotificationsBus.Cluster == "" { + return true + } + } + } + + return false +} + // Verify the referenced topology exists func (r *OpenStackControlPlaneReconciler) checkTopologyRef( ctx context.Context, diff --git a/internal/openstack/barbican.go b/internal/openstack/barbican.go index 60ccf7369..db65d9cbb 100644 --- a/internal/openstack/barbican.go +++ b/internal/openstack/barbican.go @@ -44,6 +44,9 @@ func ReconcileBarbican(ctx context.Context, instance *corev1beta1.OpenStackContr instance.Spec.Barbican.Template = &barbicanv1.BarbicanSpecCore{} } + // Note: Migration from rabbitMqClusterName to messagingBus.cluster is handled by the webhook + // via annotation-based triggers. No direct spec mutation here to avoid GitOps conflicts. + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Barbican.Template.BarbicanAPI.Override.Service == nil { @@ -154,6 +157,22 @@ func ReconcileBarbican(ctx context.Context, instance *corev1beta1.OpenStackContr instance.Spec.Barbican.Template.TopologyRef = instance.Spec.TopologyRef } + // Propagate MessagingBus from top-level to template if not set + // Template-level takes precedence over top-level + if instance.Spec.MessagingBus != nil && instance.Spec.MessagingBus.Cluster != "" { + if instance.Spec.Barbican.Template.MessagingBus.Cluster == "" { + instance.Spec.Barbican.Template.MessagingBus = *instance.Spec.MessagingBus + } + } + + // Propagate NotificationsBus from top-level to template if not set + // Template-level takes precedence over top-level + if instance.Spec.NotificationsBus != nil { + if instance.Spec.Barbican.Template.NotificationsBus == nil { + instance.Spec.Barbican.Template.NotificationsBus = instance.Spec.NotificationsBus + } + } + helper.GetLogger().Info("Reconciling Barbican", "Barbican.Namespace", instance.Namespace, "Barbican.Name", "barbican") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), barbican, func() error { instance.Spec.Barbican.Template.BarbicanSpecBase.DeepCopyInto(&barbican.Spec.BarbicanSpecBase) diff --git a/internal/openstack/cinder.go b/internal/openstack/cinder.go index 7f5fdb5a4..c36d6f8eb 100644 --- a/internal/openstack/cinder.go +++ b/internal/openstack/cinder.go @@ -66,6 +66,9 @@ func ReconcileCinder(ctx context.Context, instance *corev1beta1.OpenStackControl instance.Spec.Cinder.Template = &cinderv1.CinderSpecCore{} } + // Note: Migration from rabbitMqClusterName to messagingBus.cluster is handled by the webhook + // via annotation-based triggers. No direct spec mutation here to avoid GitOps conflicts. + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Cinder.Template.CinderAPI.Override.Service == nil { @@ -177,10 +180,20 @@ func ReconcileCinder(ctx context.Context, instance *corev1beta1.OpenStackControl instance.Spec.Cinder.Template.TopologyRef = instance.Spec.TopologyRef } - // When no NotificationsBusInstance is referenced in the subCR (override) + // Propagate MessagingBus from top-level to template if not set + // Template-level takes precedence over top-level + if instance.Spec.MessagingBus != nil && instance.Spec.MessagingBus.Cluster != "" { + if instance.Spec.Cinder.Template.MessagingBus.Cluster == "" { + instance.Spec.Cinder.Template.MessagingBus = *instance.Spec.MessagingBus + } + } + + // When no NotificationsBus is referenced in the subCR (override) // try to inject the top-level one if defined - if instance.Spec.Cinder.Template.NotificationsBusInstance == nil { - instance.Spec.Cinder.Template.NotificationsBusInstance = instance.Spec.NotificationsBusInstance + if instance.Spec.NotificationsBus != nil { + if instance.Spec.Cinder.Template.NotificationsBus == nil { + instance.Spec.Cinder.Template.NotificationsBus = instance.Spec.NotificationsBus + } } Log.Info("Reconciling Cinder", "Cinder.Namespace", instance.Namespace, "Cinder.Name", cinderName) diff --git a/internal/openstack/common.go b/internal/openstack/common.go index d6d604c5a..7b59dae47 100644 --- a/internal/openstack/common.go +++ b/internal/openstack/common.go @@ -69,6 +69,11 @@ const ( // caCertSelector selector passed to cert-manager to set on the ca cert secret caCertSelector = "ca-cert" + + // ReconcileTriggerAnnotation - Generic annotation to trigger reconciliation and webhook. + // Value is typically a timestamp to ensure annotation changes trigger updates + // Used by controller to trigger UPDATE webhook when needed (e.g., for service name caching, field migrations) + ReconcileTriggerAnnotation = "openstack.org/reconcile-trigger" ) // GetLogger returns a logger object with a prefix of "controller.name" and additional controller context fields diff --git a/internal/openstack/designate.go b/internal/openstack/designate.go index 364b7822d..1b20ed1bc 100644 --- a/internal/openstack/designate.go +++ b/internal/openstack/designate.go @@ -48,6 +48,9 @@ func ReconcileDesignate(ctx context.Context, instance *corev1beta1.OpenStackCont instance.Spec.Designate.Template = &designatev1.DesignateSpecCore{} } + // Note: Migration from rabbitMqClusterName to messagingBus.cluster is handled by the webhook + // via annotation-based triggers. No direct spec mutation here to avoid GitOps conflicts. + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Designate.Template.DesignateAPI.Override.Service == nil { @@ -161,6 +164,22 @@ func ReconcileDesignate(ctx context.Context, instance *corev1beta1.OpenStackCont instance.Spec.Designate.Template.TopologyRef = instance.Spec.TopologyRef } + // Propagate MessagingBus from top-level to template if not set + // Template-level takes precedence over top-level + if instance.Spec.MessagingBus != nil && instance.Spec.MessagingBus.Cluster != "" { + if instance.Spec.Designate.Template.MessagingBus.Cluster == "" { + instance.Spec.Designate.Template.MessagingBus = *instance.Spec.MessagingBus + } + } + + // Propagate NotificationsBus from top-level to template if not set + // Template-level takes precedence over top-level + if instance.Spec.NotificationsBus != nil { + if instance.Spec.Designate.Template.NotificationsBus == nil { + instance.Spec.Designate.Template.NotificationsBus = instance.Spec.NotificationsBus + } + } + helper.GetLogger().Info("Reconciling Designate", "Designate.Namespace", instance.Namespace, "Designate.Name", "designate") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), designate, func() error { // FIXME: the designate structs need some rework (images should be at the top level, not in the sub structs) diff --git a/internal/openstack/glance.go b/internal/openstack/glance.go index 8d5dcabcd..aa76888ba 100644 --- a/internal/openstack/glance.go +++ b/internal/openstack/glance.go @@ -5,6 +5,7 @@ import ( "fmt" glancev1 "github.com/openstack-k8s-operators/glance-operator/api/v1beta1" + rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1" "github.com/openstack-k8s-operators/lib-common/modules/common/condition" "github.com/openstack-k8s-operators/lib-common/modules/common/helper" "github.com/openstack-k8s-operators/lib-common/modules/common/service" @@ -70,6 +71,25 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl instance.Spec.Glance.Template = &glancev1.GlanceSpecCore{} } + // Migration and inheritance: Set NotificationsBus.Cluster with correct priority order + if instance.Spec.Glance.Template.NotificationsBus == nil || instance.Spec.Glance.Template.NotificationsBus.Cluster == "" { + // Priority 1: Migrate from service-level deprecated field (pointer type) + if instance.Spec.Glance.Template.NotificationBusInstance != nil && *instance.Spec.Glance.Template.NotificationBusInstance != "" { + if instance.Spec.Glance.Template.NotificationsBus == nil { + instance.Spec.Glance.Template.NotificationsBus = &rabbitmqv1.RabbitMqConfig{} + } + instance.Spec.Glance.Template.NotificationsBus.Cluster = *instance.Spec.Glance.Template.NotificationBusInstance + // Priority 2: Inherit from top-level NotificationsBus + } else if instance.Spec.NotificationsBus != nil && instance.Spec.NotificationsBus.Cluster != "" { + instance.Spec.Glance.Template.NotificationsBus = instance.Spec.NotificationsBus + } + // No Priority 3 default - NotificationsBus is optional + } + // Clear deprecated field after migration + if instance.Spec.Glance.Template.NotificationsBus != nil && instance.Spec.Glance.Template.NotificationsBus.Cluster != "" { + instance.Spec.Glance.Template.NotificationBusInstance = nil + } + if instance.Spec.Glance.Template.NodeSelector == nil { instance.Spec.Glance.Template.NodeSelector = &instance.Spec.NodeSelector } @@ -82,12 +102,6 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl instance.Spec.Glance.Template.TopologyRef = instance.Spec.TopologyRef } - // When no NotificationsBusInstance is referenced in the subCR (override) - // try to inject the top-level one if defined - if instance.Spec.Glance.Template.NotificationBusInstance == nil { - instance.Spec.Glance.Template.NotificationBusInstance = instance.Spec.NotificationsBusInstance - } - // When component services got created check if there is the need to create a route if err := helper.GetClient().Get(ctx, types.NamespacedName{Name: glanceName, Namespace: instance.Namespace}, glance); err != nil { if !k8s_errors.IsNotFound(err) { diff --git a/internal/openstack/heat.go b/internal/openstack/heat.go index 16d493d5b..5fe489660 100644 --- a/internal/openstack/heat.go +++ b/internal/openstack/heat.go @@ -47,6 +47,9 @@ func ReconcileHeat(ctx context.Context, instance *corev1beta1.OpenStackControlPl instance.Spec.Heat.Template = &heatv1.HeatSpecCore{} } + // Note: Migration from rabbitMqClusterName to messagingBus.cluster is handled by the webhook + // via annotation-based triggers. No direct spec mutation here to avoid GitOps conflicts. + if instance.Spec.Heat.Template.NodeSelector == nil { instance.Spec.Heat.Template.NodeSelector = &instance.Spec.NodeSelector } @@ -59,6 +62,21 @@ func ReconcileHeat(ctx context.Context, instance *corev1beta1.OpenStackControlPl instance.Spec.Heat.Template.TopologyRef = instance.Spec.TopologyRef } + // Propagate MessagingBus from top-level to template if not set + // Template-level takes precedence over top-level + if instance.Spec.MessagingBus != nil && instance.Spec.MessagingBus.Cluster != "" { + if instance.Spec.Heat.Template.MessagingBus.Cluster == "" { + instance.Spec.Heat.Template.MessagingBus = *instance.Spec.MessagingBus + } + } + + // Propagate NotificationsBus from top-level to template if not set + if instance.Spec.NotificationsBus != nil { + if instance.Spec.Heat.Template.NotificationsBus == nil { + instance.Spec.Heat.Template.NotificationsBus = instance.Spec.NotificationsBus + } + } + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Heat.Template.HeatAPI.Override.Service == nil { @@ -199,6 +217,7 @@ func ReconcileHeat(ctx context.Context, instance *corev1beta1.OpenStackControlPl instance.Spec.Heat.Template.HeatCfnAPI.TLS.API.Public.SecretName = endpointDetails.GetEndptCertSecret(service.EndpointPublic) instance.Spec.Heat.Template.HeatCfnAPI.TLS.API.Internal.SecretName = endpointDetails.GetEndptCertSecret(service.EndpointInternal) } + Log := GetLogger(ctx) Log.Info("Reconcile heat", "heat.Namespace", instance.Namespace, "heat.Name", "heat") diff --git a/internal/openstack/ironic.go b/internal/openstack/ironic.go index c922b0580..81b4fca5d 100644 --- a/internal/openstack/ironic.go +++ b/internal/openstack/ironic.go @@ -47,6 +47,10 @@ func ReconcileIronic(ctx context.Context, instance *corev1beta1.OpenStackControl instance.Spec.Ironic.Template = &ironicv1.IronicSpecCore{} } + // Note: Migration from rabbitMqClusterName to messagingBus.cluster is handled by the webhook + // via annotation-based triggers. No direct spec mutation here to avoid GitOps conflicts. + // This applies to both Ironic main template and IronicNeutronAgent. + if instance.Spec.Ironic.Template.NodeSelector == nil { instance.Spec.Ironic.Template.NodeSelector = &instance.Spec.NodeSelector } @@ -59,6 +63,22 @@ func ReconcileIronic(ctx context.Context, instance *corev1beta1.OpenStackControl instance.Spec.Ironic.Template.TopologyRef = instance.Spec.TopologyRef } + // Propagate MessagingBus from top-level to template if not set + // Template-level takes precedence over top-level + if instance.Spec.MessagingBus != nil && instance.Spec.MessagingBus.Cluster != "" { + if instance.Spec.Ironic.Template.MessagingBus.Cluster == "" { + instance.Spec.Ironic.Template.MessagingBus = *instance.Spec.MessagingBus + } + } + + // Propagate MessagingBus to IronicNeutronAgent if not set + // IronicNeutronAgent inherits from Ironic service-level if not set + if instance.Spec.Ironic.Template.MessagingBus.Cluster != "" { + if instance.Spec.Ironic.Template.IronicNeutronAgent.MessagingBus.Cluster == "" { + instance.Spec.Ironic.Template.IronicNeutronAgent.MessagingBus = instance.Spec.Ironic.Template.MessagingBus + } + } + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Ironic.Template.IronicAPI.Override.Service == nil { diff --git a/internal/openstack/keystone.go b/internal/openstack/keystone.go index b58ade1e4..a7a7d8a77 100644 --- a/internal/openstack/keystone.go +++ b/internal/openstack/keystone.go @@ -43,6 +43,9 @@ func ReconcileKeystoneAPI(ctx context.Context, instance *corev1beta1.OpenStackCo instance.Spec.Keystone.Template = &keystonev1.KeystoneAPISpecCore{} } + // Note: Migration from rabbitMqClusterName to notificationsBus.cluster is handled by the webhook + // via annotation-based triggers. No direct spec mutation here to avoid GitOps conflicts. + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Keystone.Template.Override.Service == nil { @@ -115,9 +118,21 @@ func ReconcileKeystoneAPI(ctx context.Context, instance *corev1beta1.OpenStackCo instance.Spec.Keystone.Template.TopologyRef = instance.Spec.TopologyRef } + // Propagate NotificationsBus from top-level to template if not set + // Template-level takes precedence over top-level + if instance.Spec.NotificationsBus != nil { + if instance.Spec.Keystone.Template.NotificationsBus == nil { + instance.Spec.Keystone.Template.NotificationsBus = instance.Spec.NotificationsBus + } + } + Log.Info("Reconciling KeystoneAPI", "KeystoneAPI.Namespace", instance.Namespace, "KeystoneAPI.Name", "keystone") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), keystoneAPI, func() error { instance.Spec.Keystone.Template.DeepCopyInto(&keystoneAPI.Spec.KeystoneAPISpecCore) + // Explicitly propagate NotificationsBus only if non-nil to allow webhook defaulting from rabbitMqClusterName + if instance.Spec.Keystone.Template.NotificationsBus != nil { + keystoneAPI.Spec.NotificationsBus = instance.Spec.Keystone.Template.NotificationsBus + } keystoneAPI.Spec.ContainerImage = *version.Status.ContainerImages.KeystoneAPIImage if keystoneAPI.Spec.Secret == "" { diff --git a/internal/openstack/manila.go b/internal/openstack/manila.go index d946b2f68..12c6f095b 100644 --- a/internal/openstack/manila.go +++ b/internal/openstack/manila.go @@ -45,6 +45,9 @@ func ReconcileManila(ctx context.Context, instance *corev1beta1.OpenStackControl instance.Spec.Manila.Template = &manilav1.ManilaSpecCore{} } + // Note: Migration from rabbitMqClusterName to messagingBus.cluster is handled by the webhook + // via annotation-based triggers. No direct spec mutation here to avoid GitOps conflicts. + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Manila.Template.ManilaAPI.Override.Service == nil { @@ -157,10 +160,20 @@ func ReconcileManila(ctx context.Context, instance *corev1beta1.OpenStackControl instance.Spec.Manila.Template.TopologyRef = instance.Spec.TopologyRef } - // When no NotificationsBusInstance is referenced in the subCR (override) + // Propagate MessagingBus from top-level to template if not set + // Template-level takes precedence over top-level + if instance.Spec.MessagingBus != nil && instance.Spec.MessagingBus.Cluster != "" { + if instance.Spec.Manila.Template.MessagingBus.Cluster == "" { + instance.Spec.Manila.Template.MessagingBus = *instance.Spec.MessagingBus + } + } + + // When no NotificationsBus is referenced in the subCR (override) // try to inject the top-level one if defined - if instance.Spec.Manila.Template.NotificationsBusInstance == nil { - instance.Spec.Manila.Template.NotificationsBusInstance = instance.Spec.NotificationsBusInstance + if instance.Spec.NotificationsBus != nil { + if instance.Spec.Manila.Template.NotificationsBus == nil { + instance.Spec.Manila.Template.NotificationsBus = instance.Spec.NotificationsBus + } } Log.Info("Reconciling Manila", "Manila.Namespace", instance.Namespace, "Manila.Name", "manila") diff --git a/internal/openstack/neutron.go b/internal/openstack/neutron.go index cf33dadd5..ce70ac5e7 100644 --- a/internal/openstack/neutron.go +++ b/internal/openstack/neutron.go @@ -46,6 +46,9 @@ func ReconcileNeutron(ctx context.Context, instance *corev1beta1.OpenStackContro instance.Spec.Neutron.Template = &neutronv1.NeutronAPISpecCore{} } + // Note: Migration from rabbitMqClusterName to messagingBus.cluster is handled by the webhook + // via annotation-based triggers. No direct spec mutation here to avoid GitOps conflicts. + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Neutron.Template.Override.Service == nil { @@ -194,10 +197,20 @@ func ReconcileNeutron(ctx context.Context, instance *corev1beta1.OpenStackContro instance.Spec.Neutron.Template.TopologyRef = instance.Spec.TopologyRef } - // When no NotificationsBusInstance is referenced in the subCR (override) + // Propagate MessagingBus from top-level to template if not set + // Template-level takes precedence over top-level + if instance.Spec.MessagingBus != nil && instance.Spec.MessagingBus.Cluster != "" { + if instance.Spec.Neutron.Template.MessagingBus.Cluster == "" { + instance.Spec.Neutron.Template.MessagingBus = *instance.Spec.MessagingBus + } + } + + // When no NotificationsBus is referenced in the subCR (override) // try to inject the top-level one if defined - if instance.Spec.Neutron.Template.NotificationsBusInstance == nil { - instance.Spec.Neutron.Template.NotificationsBusInstance = instance.Spec.NotificationsBusInstance + if instance.Spec.NotificationsBus != nil { + if instance.Spec.Neutron.Template.NotificationsBus == nil { + instance.Spec.Neutron.Template.NotificationsBus = instance.Spec.NotificationsBus + } } Log.Info("Reconciling NeutronAPI", "NeutronAPI.Namespace", instance.Namespace, "NeutronAPI.Name", "neutron") diff --git a/internal/openstack/nova.go b/internal/openstack/nova.go index 0837f4c75..2f1ecb3a2 100644 --- a/internal/openstack/nova.go +++ b/internal/openstack/nova.go @@ -68,14 +68,41 @@ func ReconcileNova(ctx context.Context, instance *corev1beta1.OpenStackControlPl instance.Spec.Nova.Template = &novav1.NovaSpecCore{} } + // Note: Migration from apiMessageBusInstance and cellMessageBusInstance to messagingBus.cluster + // is handled by the webhook via annotation-based triggers. No direct spec mutation here to avoid GitOps conflicts. + if instance.Spec.Nova.Template.NodeSelector == nil { instance.Spec.Nova.Template.NodeSelector = &instance.Spec.NodeSelector } - // When no NotificationsBusInstance is referenced in the subCR (override) + // When no NotificationsBus is referenced in the subCR (override) // try to inject the top-level one if defined - if instance.Spec.Nova.Template.NotificationsBusInstance == nil { - instance.Spec.Nova.Template.NotificationsBusInstance = instance.Spec.NotificationsBusInstance + if instance.Spec.NotificationsBus != nil { + if instance.Spec.Nova.Template.NotificationsBus == nil { + instance.Spec.Nova.Template.NotificationsBus = instance.Spec.NotificationsBus + } + } + + // Propagate MessagingBus from top-level to template if not set (for Nova API) + // Template-level takes precedence over top-level + if instance.Spec.MessagingBus != nil && instance.Spec.MessagingBus.Cluster != "" { + if instance.Spec.Nova.Template.MessagingBus.Cluster == "" { + instance.Spec.Nova.Template.MessagingBus = *instance.Spec.MessagingBus + } + } + + // Propagate MessagingBus to cell0 only if not set + // Cell0 is special (handles failed scheduling) and inherits from Nova API-level + // Other cells (cell1+) should be explicitly configured for isolation + if instance.Spec.Nova.Template.CellTemplates != nil { + if cell0Template, exists := instance.Spec.Nova.Template.CellTemplates["cell0"]; exists { + if instance.Spec.Nova.Template.MessagingBus.Cluster != "" { + if cell0Template.MessagingBus.Cluster == "" { + cell0Template.MessagingBus = instance.Spec.Nova.Template.MessagingBus + instance.Spec.Nova.Template.CellTemplates["cell0"] = cell0Template + } + } + } } // When there's no Topology referenced in the Service Template, inject the diff --git a/internal/openstack/octavia.go b/internal/openstack/octavia.go index 49aed0fc4..69da10764 100644 --- a/internal/openstack/octavia.go +++ b/internal/openstack/octavia.go @@ -66,6 +66,9 @@ func ReconcileOctavia(ctx context.Context, instance *corev1beta1.OpenStackContro instance.Spec.Octavia.Template = &octaviav1.OctaviaSpecCore{} } + // Note: Migration from rabbitMqClusterName to messagingBus.cluster is handled by the webhook + // via annotation-based triggers. No direct spec mutation here to avoid GitOps conflicts. + if instance.Spec.Octavia.Template.NodeSelector == nil { instance.Spec.Octavia.Template.NodeSelector = &instance.Spec.NodeSelector } @@ -78,6 +81,22 @@ func ReconcileOctavia(ctx context.Context, instance *corev1beta1.OpenStackContro instance.Spec.Octavia.Template.TopologyRef = instance.Spec.TopologyRef } + // Propagate MessagingBus from top-level to template if not set + // Template-level takes precedence over top-level + if instance.Spec.MessagingBus != nil && instance.Spec.MessagingBus.Cluster != "" { + if instance.Spec.Octavia.Template.MessagingBus.Cluster == "" { + instance.Spec.Octavia.Template.MessagingBus = *instance.Spec.MessagingBus + } + } + + // Propagate NotificationsBus from top-level to template if not set + // Template-level takes precedence over top-level + if instance.Spec.NotificationsBus != nil { + if instance.Spec.Octavia.Template.NotificationsBus == nil { + instance.Spec.Octavia.Template.NotificationsBus = instance.Spec.NotificationsBus + } + } + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Octavia.Template.OctaviaAPI.Override.Service == nil { @@ -223,6 +242,10 @@ func ReconcileOctavia(ctx context.Context, instance *corev1beta1.OpenStackContro instance.Spec.Octavia.Template.OctaviaHealthManager.DeepCopyInto(&octavia.Spec.OctaviaHealthManager.OctaviaAmphoraControllerSpecCore) instance.Spec.Octavia.Template.OctaviaWorker.DeepCopyInto(&octavia.Spec.OctaviaWorker.OctaviaAmphoraControllerSpecCore) instance.Spec.Octavia.Template.OctaviaRsyslog.DeepCopyInto(&octavia.Spec.OctaviaRsyslog.OctaviaRsyslogSpecCore) + // Explicitly propagate NotificationsBus only if non-nil to allow webhook defaulting from rabbitMqClusterName + if instance.Spec.Octavia.Template.NotificationsBus != nil { + octavia.Spec.NotificationsBus = instance.Spec.Octavia.Template.NotificationsBus + } octavia.Spec.OctaviaAPI.ContainerImage = *version.Status.ContainerImages.OctaviaAPIImage octavia.Spec.OctaviaWorker.ContainerImage = *version.Status.ContainerImages.OctaviaWorkerImage diff --git a/internal/openstack/rabbitmq_cascading_test.go b/internal/openstack/rabbitmq_cascading_test.go new file mode 100644 index 000000000..5d7c8bab2 --- /dev/null +++ b/internal/openstack/rabbitmq_cascading_test.go @@ -0,0 +1,173 @@ +/* +Copyright 2024. + +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 openstack + +import ( + "testing" + + . "github.com/onsi/gomega" //revive:disable:dot-imports + + rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1" +) + +// TestMessagingBusCascading tests that top-level MessagingBus cascades using the cascading pattern +func TestMessagingBusCascading(t *testing.T) { + g := NewWithT(t) + + // Test the cascading pattern logic + topLevelMessagingBus := &rabbitmqv1.RabbitMqConfig{ + Cluster: "rabbitmq-global", + User: "global-user", + Vhost: "global-vhost", + } + + // Test case 1: Empty cluster should cascade + t.Run("Empty cluster triggers cascading", func(_ *testing.T) { + serviceMessagingBus := rabbitmqv1.RabbitMqConfig{} + + // Simulate cascading logic + if topLevelMessagingBus != nil && serviceMessagingBus.Cluster == "" { + serviceMessagingBus = *topLevelMessagingBus + } + + g.Expect(serviceMessagingBus.Cluster).To(Equal("rabbitmq-global")) + g.Expect(serviceMessagingBus.User).To(Equal("global-user")) + g.Expect(serviceMessagingBus.Vhost).To(Equal("global-vhost")) + }) + + // Test case 2: Non-empty cluster should NOT cascade + t.Run("Non-empty cluster prevents cascading", func(_ *testing.T) { + serviceMessagingBus := rabbitmqv1.RabbitMqConfig{ + Cluster: "service-specific-rabbitmq", + User: "service-user", + Vhost: "service-vhost", + } + + // Simulate cascading logic + if topLevelMessagingBus != nil && serviceMessagingBus.Cluster == "" { + serviceMessagingBus = *topLevelMessagingBus + } + + // Should keep service-specific values + g.Expect(serviceMessagingBus.Cluster).To(Equal("service-specific-rabbitmq")) + g.Expect(serviceMessagingBus.User).To(Equal("service-user")) + g.Expect(serviceMessagingBus.Vhost).To(Equal("service-vhost")) + }) + + // Test case 3: Nil top-level should not cause cascading + t.Run("Nil top-level MessagingBus does not cascade", func(_ *testing.T) { + var nilMessagingBus *rabbitmqv1.RabbitMqConfig + serviceMessagingBus := rabbitmqv1.RabbitMqConfig{} + + // Simulate cascading logic: when top-level is nil, no cascading occurs + // In real code: if nilMessagingBus != nil && serviceMessagingBus.Cluster == "" {...} + // Here we just verify the nil case doesn't cascade + _ = nilMessagingBus + + // Should remain empty when top-level is nil + g.Expect(serviceMessagingBus.Cluster).To(Equal("")) + g.Expect(serviceMessagingBus.User).To(Equal("")) + }) +} + +// TestNotificationsBusCascading tests that top-level NotificationsBus cascades using the cascading pattern +func TestNotificationsBusCascading(t *testing.T) { + g := NewWithT(t) + + // Test the cascading pattern logic for NotificationsBus + topLevelNotificationsBus := &rabbitmqv1.RabbitMqConfig{ + Cluster: "rabbitmq-notifications", + User: "notifications-user", + Vhost: "notifications-vhost", + } + + // Test case 1: Nil service-level should cascade + t.Run("Nil service NotificationsBus triggers cascading", func(_ *testing.T) { + // Simulate cascading logic: when service-level is nil, use top-level + // In real code: if serviceNotificationsBus == nil { serviceNotificationsBus = topLevelNotificationsBus } + serviceNotificationsBus := topLevelNotificationsBus + + g.Expect(serviceNotificationsBus).ToNot(BeNil()) + g.Expect(serviceNotificationsBus.Cluster).To(Equal("rabbitmq-notifications")) + g.Expect(serviceNotificationsBus.User).To(Equal("notifications-user")) + g.Expect(serviceNotificationsBus.Vhost).To(Equal("notifications-vhost")) + }) + + // Test case 2: Non-nil service-level should NOT cascade + t.Run("Non-nil service NotificationsBus prevents cascading", func(_ *testing.T) { + serviceNotificationsBus := &rabbitmqv1.RabbitMqConfig{ + Cluster: "service-specific-notifications", + User: "service-notif-user", + Vhost: "service-notif-vhost", + } + + // Cascading logic would check: if serviceNotificationsBus == nil + // But since it's already set, no cascading occurs + + // Should keep service-specific values + g.Expect(serviceNotificationsBus).ToNot(BeNil()) + g.Expect(serviceNotificationsBus.Cluster).To(Equal("service-specific-notifications")) + g.Expect(serviceNotificationsBus.User).To(Equal("service-notif-user")) + g.Expect(serviceNotificationsBus.Vhost).To(Equal("service-notif-vhost")) + }) + + // Test case 3: Nil top-level should remain nil + t.Run("Nil top-level NotificationsBus stays nil", func(_ *testing.T) { + var topLevel *rabbitmqv1.RabbitMqConfig + + // Simulate cascading logic: when both are nil, service stays nil + // In real code: if serviceNotificationsBus == nil { serviceNotificationsBus = topLevel } + serviceNotificationsBus := topLevel + + // Should remain nil when both are nil + g.Expect(serviceNotificationsBus).To(BeNil()) + }) +} + +// TestBothMessagingAndNotificationsBusCascading tests that both MessagingBus and NotificationsBus cascade correctly +func TestBothMessagingAndNotificationsBusCascading(t *testing.T) { + g := NewWithT(t) + + topLevelMessagingBus := &rabbitmqv1.RabbitMqConfig{ + Cluster: "rabbitmq-rpc", + User: "rpc-user", + Vhost: "rpc-vhost", + } + + topLevelNotificationsBus := &rabbitmqv1.RabbitMqConfig{ + Cluster: "rabbitmq-notifications", + User: "notifications-user", + Vhost: "notifications-vhost", + } + + // Simulate a service with empty MessagingBus and nil NotificationsBus + // In real code: cascading would check conditions and assign values + // Here we directly test the cascaded results + serviceMessagingBus := *topLevelMessagingBus + serviceNotificationsBus := topLevelNotificationsBus + + // Verify MessagingBus cascaded + g.Expect(serviceMessagingBus.Cluster).To(Equal("rabbitmq-rpc")) + g.Expect(serviceMessagingBus.User).To(Equal("rpc-user")) + g.Expect(serviceMessagingBus.Vhost).To(Equal("rpc-vhost")) + + // Verify NotificationsBus cascaded + g.Expect(serviceNotificationsBus).ToNot(BeNil()) + g.Expect(serviceNotificationsBus.Cluster).To(Equal("rabbitmq-notifications")) + g.Expect(serviceNotificationsBus.User).To(Equal("notifications-user")) + g.Expect(serviceNotificationsBus.Vhost).To(Equal("notifications-vhost")) +} diff --git a/internal/openstack/swift.go b/internal/openstack/swift.go index d965214e6..bb4c68d3a 100644 --- a/internal/openstack/swift.go +++ b/internal/openstack/swift.go @@ -10,6 +10,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1" corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/api/core/v1beta1" swiftv1 "github.com/openstack-k8s-operators/swift-operator/api/v1beta1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" @@ -46,6 +47,21 @@ func ReconcileSwift(ctx context.Context, instance *corev1beta1.OpenStackControlP instance.Spec.Swift.Template = &swiftv1.SwiftSpecCore{} } + // Migration: Ensure SwiftProxy NotificationsBus.Cluster is set from deprecated RabbitMqClusterName if needed + if instance.Spec.Swift.Template.SwiftProxy.NotificationsBus == nil || instance.Spec.Swift.Template.SwiftProxy.NotificationsBus.Cluster == "" { + if instance.Spec.Swift.Template.SwiftProxy.RabbitMqClusterName != "" { + if instance.Spec.Swift.Template.SwiftProxy.NotificationsBus == nil { + instance.Spec.Swift.Template.SwiftProxy.NotificationsBus = &rabbitmqv1.RabbitMqConfig{} + } + instance.Spec.Swift.Template.SwiftProxy.NotificationsBus.Cluster = instance.Spec.Swift.Template.SwiftProxy.RabbitMqClusterName + } + // NotificationsBus.Cluster is not defaulted - it must be explicitly set if NotificationsBus is configured + } + // Clear deprecated field if new field is set + if instance.Spec.Swift.Template.SwiftProxy.NotificationsBus != nil && instance.Spec.Swift.Template.SwiftProxy.NotificationsBus.Cluster != "" { + instance.Spec.Swift.Template.SwiftProxy.RabbitMqClusterName = "" + } + if instance.Spec.Swift.Template.NodeSelector == nil { instance.Spec.Swift.Template.NodeSelector = &instance.Spec.NodeSelector } @@ -58,6 +74,14 @@ func ReconcileSwift(ctx context.Context, instance *corev1beta1.OpenStackControlP instance.Spec.Swift.Template.TopologyRef = instance.Spec.TopologyRef } + // Propagate NotificationsBus from top-level to SwiftProxy template if not set + // Template-level takes precedence over top-level + if instance.Spec.NotificationsBus != nil { + if instance.Spec.Swift.Template.SwiftProxy.NotificationsBus == nil { + instance.Spec.Swift.Template.SwiftProxy.NotificationsBus = instance.Spec.NotificationsBus + } + } + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Swift.Template.SwiftProxy.Override.Service == nil { diff --git a/internal/openstack/telemetry.go b/internal/openstack/telemetry.go index fd7a697ef..354d669b6 100644 --- a/internal/openstack/telemetry.go +++ b/internal/openstack/telemetry.go @@ -61,6 +61,10 @@ func ReconcileTelemetry(ctx context.Context, instance *corev1beta1.OpenStackCont instance.Spec.Telemetry.Template = &telemetryv1.TelemetrySpecCore{} } + // Note: Migration from rabbitMqClusterName to messagingBus.cluster (CloudKitty) and + // notificationsBus.cluster (Aodh, Ceilometer) is handled by the webhook via annotation-based triggers. + // No direct spec mutation here to avoid GitOps conflicts. + if instance.Spec.Telemetry.Template.NodeSelector == nil { instance.Spec.Telemetry.Template.NodeSelector = &instance.Spec.NodeSelector } @@ -73,6 +77,25 @@ func ReconcileTelemetry(ctx context.Context, instance *corev1beta1.OpenStackCont instance.Spec.Telemetry.Template.TopologyRef = instance.Spec.TopologyRef } + // Propagate MessagingBus from top-level to CloudKitty if not set + // Template-level takes precedence over top-level + if instance.Spec.MessagingBus != nil && instance.Spec.MessagingBus.Cluster != "" { + if instance.Spec.Telemetry.Template.CloudKitty.MessagingBus.Cluster == "" { + instance.Spec.Telemetry.Template.CloudKitty.MessagingBus = *instance.Spec.MessagingBus + } + } + + // Propagate NotificationsBus from top-level to template sub-components if not set + // Template-level takes precedence over top-level + if instance.Spec.NotificationsBus != nil { + if instance.Spec.Telemetry.Template.Ceilometer.NotificationsBus == nil { + instance.Spec.Telemetry.Template.Ceilometer.NotificationsBus = instance.Spec.NotificationsBus + } + if instance.Spec.Telemetry.Template.Autoscaling.Aodh.NotificationsBus == nil { + instance.Spec.Telemetry.Template.Autoscaling.Aodh.NotificationsBus = instance.Spec.NotificationsBus + } + } + if err := helper.GetClient().Get(ctx, types.NamespacedName{Name: "telemetry", Namespace: instance.Namespace}, telemetry); err != nil { if !k8s_errors.IsNotFound(err) { return ctrl.Result{}, err @@ -511,6 +534,14 @@ func ReconcileTelemetry(ctx context.Context, instance *corev1beta1.OpenStackCont instance.Spec.Telemetry.Template.CloudKitty.CloudKittyAPI.DeepCopyInto(&telemetry.Spec.CloudKitty.CloudKittyAPI.CloudKittyAPITemplateCore) instance.Spec.Telemetry.Template.CloudKitty.CloudKittyProc.DeepCopyInto(&telemetry.Spec.CloudKitty.CloudKittyProc.CloudKittyProcTemplateCore) + // Explicitly propagate NotificationsBus only if non-nil to allow webhook defaulting from rabbitMqClusterName + if instance.Spec.Telemetry.Template.Ceilometer.NotificationsBus != nil { + telemetry.Spec.Ceilometer.NotificationsBus = instance.Spec.Telemetry.Template.Ceilometer.NotificationsBus + } + if instance.Spec.Telemetry.Template.Autoscaling.Aodh.NotificationsBus != nil { + telemetry.Spec.Autoscaling.Aodh.NotificationsBus = instance.Spec.Telemetry.Template.Autoscaling.Aodh.NotificationsBus + } + // TODO: investigate if the following could be simplified to // telemetry.Spec..Enabled = instance.Spec.Telemetry.Template..Enabled // With current implementation we essentially create a copy of the bools and point to that, so the @@ -570,6 +601,9 @@ func ReconcileTelemetry(ctx context.Context, instance *corev1beta1.OpenStackCont if telemetry.Spec.CloudKitty.StorageClass == "" { telemetry.Spec.CloudKitty.StorageClass = instance.Spec.StorageClass } + if telemetry.Spec.CloudKitty.Secret == "" { + telemetry.Spec.CloudKitty.Secret = instance.Spec.Secret + } err := controllerutil.SetControllerReference(helper.GetBeforeObject(), telemetry, helper.GetScheme()) if err != nil { diff --git a/internal/openstack/watcher.go b/internal/openstack/watcher.go index 7298d6eb2..8ffc7bc83 100644 --- a/internal/openstack/watcher.go +++ b/internal/openstack/watcher.go @@ -43,6 +43,9 @@ func ReconcileWatcher(ctx context.Context, instance *corev1beta1.OpenStackContro instance.Spec.Watcher.Template = &watcherv1.WatcherSpecCore{} } + // Note: Migration from rabbitMqClusterName to messagingBus.cluster is handled by the webhook + // via annotation-based triggers. No direct spec mutation here to avoid GitOps conflicts. + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Watcher.Template.APIServiceTemplate.Override.Service == nil { @@ -169,15 +172,29 @@ func ReconcileWatcher(ctx context.Context, instance *corev1beta1.OpenStackContro instance.Spec.Watcher.Template.TopologyRef = instance.Spec.TopologyRef } - // When no NotificationsBusInstance is referenced in the subCR (override) - // try to inject the top-level one if defined - if instance.Spec.Watcher.Template.NotificationsBusInstance == nil { - instance.Spec.Watcher.Template.NotificationsBusInstance = instance.Spec.NotificationsBusInstance + // Propagate MessagingBus from top-level to template if not set + // Template-level takes precedence over top-level + if instance.Spec.MessagingBus != nil && instance.Spec.MessagingBus.Cluster != "" { + if instance.Spec.Watcher.Template.MessagingBus.Cluster == "" { + instance.Spec.Watcher.Template.MessagingBus = *instance.Spec.MessagingBus + } + } + + // Propagate NotificationsBus from top-level to template if not set + // Template-level takes precedence over top-level + if instance.Spec.NotificationsBus != nil { + if instance.Spec.Watcher.Template.NotificationsBus == nil { + instance.Spec.Watcher.Template.NotificationsBus = instance.Spec.NotificationsBus + } } helper.GetLogger().Info("Reconciling Watcher", "Watcher.Namespace", instance.Namespace, "Watcher.Name", "watcher") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), watcher, func() error { instance.Spec.Watcher.Template.DeepCopyInto(&watcher.Spec.WatcherSpecCore) + // Explicitly propagate NotificationsBus only if non-nil to allow webhook defaulting from rabbitMqClusterName + if instance.Spec.Watcher.Template.NotificationsBus != nil { + watcher.Spec.NotificationsBus = instance.Spec.Watcher.Template.NotificationsBus + } if version.Status.ContainerImages.WatcherAPIImage == nil || version.Status.ContainerImages.WatcherApplierImage == nil || diff --git a/test/functional/ctlplane/base_test.go b/test/functional/ctlplane/base_test.go index 75a7d23b6..529630cb1 100644 --- a/test/functional/ctlplane/base_test.go +++ b/test/functional/ctlplane/base_test.go @@ -33,11 +33,13 @@ import ( horizonv1 "github.com/openstack-k8s-operators/horizon-operator/api/v1beta1" infrav1 "github.com/openstack-k8s-operators/infra-operator/apis/network/v1beta1" rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1" + keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" "github.com/openstack-k8s-operators/lib-common/modules/common/condition" manilav1 "github.com/openstack-k8s-operators/manila-operator/api/v1beta1" mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" neutronv1 "github.com/openstack-k8s-operators/neutron-operator/api/v1beta1" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" + octaviav1 "github.com/openstack-k8s-operators/octavia-operator/api/v1beta1" openstackclientv1 "github.com/openstack-k8s-operators/openstack-operator/api/client/v1beta1" corev1 "github.com/openstack-k8s-operators/openstack-operator/api/core/v1beta1" dataplanev1 "github.com/openstack-k8s-operators/openstack-operator/api/dataplane/v1beta1" @@ -61,6 +63,7 @@ type Names struct { HorizonName types.NamespacedName HeatName types.NamespacedName NovaName types.NamespacedName + OctaviaName types.NamespacedName TelemetryName types.NamespacedName WatcherName types.NamespacedName DBName types.NamespacedName @@ -195,6 +198,10 @@ func CreateNames(openstackControlplaneName types.NamespacedName) Names { Namespace: openstackControlplaneName.Namespace, Name: "nova", }, + OctaviaName: types.NamespacedName{ + Namespace: openstackControlplaneName.Namespace, + Name: "octavia", + }, WatcherName: types.NamespacedName{ Namespace: openstackControlplaneName.Namespace, Name: "watcher", @@ -949,3 +956,21 @@ func GetWatcher(name types.NamespacedName) *watcherv1.Watcher { }, timeout, interval).Should(Succeed()) return instance } + +// GetOctavia +func GetOctavia(name types.NamespacedName) *octaviav1.Octavia { + instance := &octaviav1.Octavia{} + Eventually(func(g Gomega) { + g.Expect(k8sClient.Get(ctx, name, instance)).Should(Succeed()) + }, timeout, interval).Should(Succeed()) + return instance +} + +// GetKeystone +func GetKeystone(name types.NamespacedName) *keystonev1.KeystoneAPI { + instance := &keystonev1.KeystoneAPI{} + Eventually(func(g Gomega) { + g.Expect(k8sClient.Get(ctx, name, instance)).Should(Succeed()) + }, timeout, interval).Should(Succeed()) + return instance +} diff --git a/test/functional/ctlplane/openstackoperator_controller_test.go b/test/functional/ctlplane/openstackoperator_controller_test.go index 4d03a5fb0..f237bc269 100644 --- a/test/functional/ctlplane/openstackoperator_controller_test.go +++ b/test/functional/ctlplane/openstackoperator_controller_test.go @@ -31,6 +31,7 @@ import ( k8s_corev1 "k8s.io/api/core/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/types" @@ -155,32 +156,66 @@ var _ = Describe("OpenStackOperator controller", func() { glanceNotifSvc = Entry("the Glance service", func() ( client.Object, *string) { svc := GetGlance(names.GlanceName) - return svc, svc.Spec.NotificationBusInstance + if svc.Spec.NotificationsBus == nil { + return svc, nil + } + return svc, &svc.Spec.NotificationsBus.Cluster }) cinderNotifSvc = Entry("the Cinder service", func() ( client.Object, *string) { svc := GetCinder(names.CinderName) - return svc, svc.Spec.NotificationsBusInstance + if svc.Spec.NotificationsBus == nil { + return svc, nil + } + return svc, &svc.Spec.NotificationsBus.Cluster }) manilaNotifSvc = Entry("the Manila service", func() ( client.Object, *string) { svc := GetManila(names.ManilaName) - return svc, svc.Spec.NotificationsBusInstance + if svc.Spec.NotificationsBus == nil { + return svc, nil + } + return svc, &svc.Spec.NotificationsBus.Cluster }) neutronNotifSvc = Entry("the Neutron service", func() ( client.Object, *string) { svc := GetNeutron(names.NeutronName) - return svc, svc.Spec.NotificationsBusInstance + if svc.Spec.NotificationsBus == nil { + return svc, nil + } + return svc, &svc.Spec.NotificationsBus.Cluster }) novaNotifSvc = Entry("the Nova service", func() ( client.Object, *string) { svc := GetNova(names.NovaName) - return svc, svc.Spec.NotificationsBusInstance + if svc.Spec.NotificationsBus == nil { + return svc, nil + } + return svc, &svc.Spec.NotificationsBus.Cluster }) watcherNotifSvc = Entry("the Watcher service", func() ( client.Object, *string) { svc := GetWatcher(names.WatcherName) - return svc, svc.Spec.NotificationsBusInstance + if svc.Spec.NotificationsBus == nil { + return svc, nil + } + return svc, &svc.Spec.NotificationsBus.Cluster + }) + octaviaNotifSvc = Entry("the Octavia service", func() ( + client.Object, *string) { + svc := GetOctavia(names.OctaviaName) + if svc.Spec.NotificationsBus == nil { + return svc, nil + } + return svc, &svc.Spec.NotificationsBus.Cluster + }) + keystoneNotifSvc = Entry("the Keystone service", func() ( + client.Object, *string) { + svc := GetKeystone(names.KeystoneAPIName) + if svc.Spec.NotificationsBus == nil { + return svc, nil + } + return svc, &svc.Spec.NotificationsBus.Cluster }) ) // @@ -1205,6 +1240,7 @@ var _ = Describe("OpenStackOperator controller", func() { // create cert secrets for ovn instance DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNMetricsCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName)) spec := GetDefaultOpenStackControlPlaneSpec() spec["tls"] = GetTLSeCustomIssuerSpec() @@ -1333,6 +1369,7 @@ var _ = Describe("OpenStackOperator controller", func() { // create cert secrets for ovn instance DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNMetricsCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName)) DeferCleanup(k8sClient.Delete, ctx, @@ -2027,6 +2064,7 @@ var _ = Describe("OpenStackOperator controller", func() { // create cert secrets for ovn instance DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNMetricsCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.WatcherCertPublicRouteName)) @@ -2216,6 +2254,7 @@ var _ = Describe("OpenStackOperator controller", func() { // create cert secrets for ovn instance DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNMetricsCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.WatcherCertPublicRouteName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.WatcherCertPublicSvcName)) @@ -2692,6 +2731,7 @@ var _ = Describe("OpenStackOperator controller", func() { // create cert secrets for ovn instance DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNMetricsCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName)) DeferCleanup( @@ -2876,12 +2916,14 @@ var _ = Describe("OpenStackOperator controller", func() { ) }) - When("An OpenStackControlplane instance references a notificationsBusInstance", func() { + When("An OpenStackControlplane instance references a notificationsBus", func() { BeforeEach(func() { spec := GetDefaultOpenStackControlPlaneSpec() - // point notificationsBusInstance to the default rabbitmq instance - spec["notificationsBusInstance"] = names.RabbitMQName.Name + // point notificationsBus.cluster to the default rabbitmq instance + spec["notificationsBus"] = map[string]interface{}{ + "cluster": names.RabbitMQName.Name, + } spec["telemetry"] = map[string]interface{}{ "enabled": true, @@ -2897,6 +2939,12 @@ var _ = Describe("OpenStackOperator controller", func() { spec["watcher"] = map[string]interface{}{ "enabled": true, } + spec["octavia"] = map[string]interface{}{ + "enabled": true, + } + spec["ovn"] = map[string]interface{}{ + "enabled": true, + } // enable nova and its dependencies spec["nova"] = map[string]interface{}{ @@ -2924,7 +2972,10 @@ var _ = Describe("OpenStackOperator controller", func() { // create cert secrets for ovn instance DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNMetricsCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName)) + // create cert secret for octavia ovn client + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(types.NamespacedName{Name: "cert-octavia-ovndbs", Namespace: names.Namespace})) DeferCleanup( th.DeleteInstance, @@ -2965,11 +3016,12 @@ var _ = Describe("OpenStackOperator controller", func() { svc, notif := serviceNameFunc() OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) - // service exists and notificationsBusInstance has been propagated + // service exists and notificationsBus.cluster has been propagated Eventually(func(g Gomega) { g.Expect(OSCtlplane).Should(Not(BeNil())) g.Expect(svc).Should(Not(BeNil())) - g.Expect(notif).To(Equal(OSCtlplane.Spec.NotificationsBusInstance)) + g.Expect(OSCtlplane.Spec.NotificationsBus).ToNot(BeNil()) + g.Expect(notif).To(Equal(&OSCtlplane.Spec.NotificationsBus.Cluster)) }, timeout, interval).Should(Succeed()) }, // The entry list depends on the services that currently implement @@ -2980,6 +3032,8 @@ var _ = Describe("OpenStackOperator controller", func() { neutronNotifSvc, novaNotifSvc, watcherNotifSvc, + octaviaNotifSvc, + keystoneNotifSvc, ) DescribeTable("A service (Nova) overrides the notification value", func(serviceNameFunc func() (client.Object, *string)) { @@ -2988,7 +3042,10 @@ var _ = Describe("OpenStackOperator controller", func() { Eventually(func(g Gomega) { ctlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) - ctlplane.Spec.Nova.Template.NotificationsBusInstance = &rabbitMqOverride + if ctlplane.Spec.Nova.Template.NotificationsBus == nil { + ctlplane.Spec.Nova.Template.NotificationsBus = &rabbitmqv1.RabbitMqConfig{} + } + ctlplane.Spec.Nova.Template.NotificationsBus.Cluster = rabbitMqOverride g.Expect(k8sClient.Update(ctx, ctlplane)).To(Succeed()) }, timeout, interval).Should(Succeed()) @@ -2998,8 +3055,10 @@ var _ = Describe("OpenStackOperator controller", func() { nova := GetNova(names.NovaName) g.Expect(OSCtlplane).Should(Not(BeNil())) g.Expect(nova).Should(Not(BeNil())) - g.Expect(nova.Spec.NotificationsBusInstance).To(Equal(OSCtlplane.Spec.Nova.Template.NotificationsBusInstance)) - g.Expect(*nova.Spec.NotificationsBusInstance).To(Equal(rabbitMqOverride)) + g.Expect(nova.Spec.NotificationsBus).ToNot(BeNil()) + g.Expect(OSCtlplane.Spec.Nova.Template.NotificationsBus).ToNot(BeNil()) + g.Expect(nova.Spec.NotificationsBus.Cluster).To(Equal(OSCtlplane.Spec.Nova.Template.NotificationsBus.Cluster)) + g.Expect(nova.Spec.NotificationsBus.Cluster).To(Equal(rabbitMqOverride)) }, timeout, interval).Should(Succeed()) // The rest of the services still point to the top-level rabbit @@ -3007,27 +3066,8 @@ var _ = Describe("OpenStackOperator controller", func() { Eventually(func(g Gomega) { g.Expect(OSCtlplane).Should(Not(BeNil())) g.Expect(svc).Should(Not(BeNil())) - g.Expect(notif).To(Equal(OSCtlplane.Spec.NotificationsBusInstance)) - }, timeout, interval).Should(Succeed()) - }, - // The entry list depends on the services that currently implement - // the notificationsBusInstance interface - glanceNotifSvc, - cinderNotifSvc, - manilaNotifSvc, - neutronNotifSvc, - watcherNotifSvc, - ) - DescribeTable("An OpenStackControlplane removes the notificationsBusInstance reference", - func(serviceNameFunc func() (client.Object, *string)) { - Eventually(func(g Gomega) { - ctlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) - ctlplane.Spec.NotificationsBusInstance = nil - g.Expect(k8sClient.Update(ctx, ctlplane)).To(Succeed()) - - svc, notif := serviceNameFunc() - g.Expect(svc).Should(Not(BeNil())) - g.Expect(notif).To(BeNil()) + g.Expect(OSCtlplane.Spec.NotificationsBus).ToNot(BeNil()) + g.Expect(notif).To(Equal(&OSCtlplane.Spec.NotificationsBus.Cluster)) }, timeout, interval).Should(Succeed()) }, // The entry list depends on the services that currently implement @@ -3036,46 +3076,113 @@ var _ = Describe("OpenStackOperator controller", func() { cinderNotifSvc, manilaNotifSvc, neutronNotifSvc, - novaNotifSvc, watcherNotifSvc, ) + // NOTE: Test for "removes the notificationsBus reference" removed because + // the new template-level precedence pattern means setting top-level NotificationsBus + // to nil does not clear template-level NotificationsBus configuration. + // Template-level takes precedence over top-level. }) }) var _ = Describe("OpenStackOperator Webhook", func() { - DescribeTable("notificationsBusInstance", - func(getNotificationField func() (string, string)) { - spec := GetDefaultOpenStackControlPlaneSpec() - value, errMsg := getNotificationField() - spec["notificationsBusInstance"] = value - raw := map[string]interface{}{ - "apiVersion": "core.openstack.org/v1beta1", - "kind": "OpenStackControlPlane", - "metadata": map[string]interface{}{ - "name": "foo", - "namespace": namespace, + // Note: The migration functionality is thoroughly tested in webhook unit tests + // (api/core/v1beta1/openstackcontrolplane_webhook_test.go). + // This integration test verifies that the webhook migration works end-to-end. + It("migrates deprecated notificationsBusInstance field via webhook", func() { + // Create a minimal OpenStackControlPlane with the deprecated field + deprecatedValue := "rabbitmq" + ctlplane := &corev1.OpenStackControlPlane{ + ObjectMeta: metav1.ObjectMeta{ + Name: "migration-test-ctlplane", + Namespace: namespace, + }, + Spec: corev1.OpenStackControlPlaneSpec{ + Secret: "osp-secret", + StorageClass: "local-storage", + Rabbitmq: corev1.RabbitmqSection{ + Enabled: true, + Templates: &map[string]rabbitmqv1.RabbitMqSpecCore{ + "rabbitmq": {}, + }, }, - "spec": spec, - } - unstructuredObj := &unstructured.Unstructured{Object: raw} - _, err := controllerutil.CreateOrPatch( - th.Ctx, th.K8sClient, unstructuredObj, func() error { return nil }) - Expect(err).Should(HaveOccurred()) - var statusError *k8s_errors.StatusError - Expect(errors.As(err, &statusError)).To(BeTrue()) - Expect(statusError.ErrStatus.Details.Kind).To(Equal("OpenStackControlPlane")) - Expect(statusError.ErrStatus.Message).To( - ContainSubstring(errMsg), - ) - }, - Entry("notificationsBusInstance is wrong", func() (string, string) { - return "foo", "spec.notificationsBusInstance: Invalid value: \"foo\": notificationsBusInstance must match an existing RabbitMQ instance name" - }), - Entry("notificationsBusInstance is an empty string", func() (string, string) { - return "", "spec.notificationsBusInstance: Invalid value: \"\": notificationsBusInstance is not a valid string" - }), - ) + NotificationsBusInstance: &deprecatedValue, + }, + } + + DeferCleanup(th.DeleteInstance, ctlplane) + + // The creation should succeed - webhook migrates the deprecated field + Expect(th.K8sClient.Create(th.Ctx, ctlplane)).Should(Succeed()) + + // Verify migration occurred + Eventually(func(g Gomega) { + instance := &corev1.OpenStackControlPlane{} + g.Expect(th.K8sClient.Get(th.Ctx, client.ObjectKeyFromObject(ctlplane), instance)).To(Succeed()) + + // Deprecated field should be cleared + g.Expect(instance.Spec.NotificationsBusInstance).To(BeNil()) + + // New field should be populated + g.Expect(instance.Spec.NotificationsBus).ToNot(BeNil()) + g.Expect(instance.Spec.NotificationsBus.Cluster).To(Equal("rabbitmq")) + }, timeout, interval).Should(Succeed()) + }) + + It("migrates existing CR with deprecated field via controller annotation trigger (operator upgrade)", func() { + // Simulate operator upgrade scenario: + // 1. Create a CR with deprecated field (as if created by old operator version) + // 2. Update it to bypass the webhook Default() - simulating an existing CR in etcd + // 3. Let controller reconcile and trigger migration via annotation + + deprecatedValue := "rabbitmq" + ctlplane := &corev1.OpenStackControlPlane{ + ObjectMeta: metav1.ObjectMeta{ + Name: "upgrade-scenario-test", + Namespace: namespace, + }, + Spec: corev1.OpenStackControlPlaneSpec{ + Secret: "osp-secret", + StorageClass: "local-storage", + Rabbitmq: corev1.RabbitmqSection{ + Enabled: true, + Templates: &map[string]rabbitmqv1.RabbitMqSpecCore{ + "rabbitmq": {}, + }, + }, + // Simulate old CR that was created before migration logic existed + // NotificationsBus is nil, only deprecated field is set + NotificationsBusInstance: &deprecatedValue, + }, + } + + DeferCleanup(th.DeleteInstance, ctlplane) + + // Create the CR + Expect(th.K8sClient.Create(th.Ctx, ctlplane)).Should(Succeed()) + + // Wait for controller to reconcile and trigger migration + // The controller should detect the deprecated field and add the annotation + // The webhook should then migrate the field + Eventually(func(g Gomega) { + instance := &corev1.OpenStackControlPlane{} + g.Expect(th.K8sClient.Get(th.Ctx, client.ObjectKeyFromObject(ctlplane), instance)).To(Succeed()) + + // Migration should have occurred + g.Expect(instance.Spec.NotificationsBusInstance).To(BeNil(), + "deprecated field should be cleared after migration") + g.Expect(instance.Spec.NotificationsBus).ToNot(BeNil(), + "new field should be populated") + g.Expect(instance.Spec.NotificationsBus.Cluster).To(Equal("rabbitmq"), + "cluster should be migrated from deprecated field") + + // Annotation should be cleaned up by webhook + annotations := instance.GetAnnotations() + g.Expect(annotations).ToNot(HaveKey("openstack.org/reconcile-trigger"), + "annotation should be removed after migration") + }, timeout, interval).Should(Succeed()) + }) It("Blocks creating multiple ctlplane CRs in the same namespace", func() { spec := GetDefaultOpenStackControlPlaneSpec() @@ -3761,6 +3868,7 @@ var _ = Describe("OpenStackOperator controller nova cell deletion", func() { // create cert secrets for ovn instance DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNMetricsCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName)) // create cert secrets for memcached instance diff --git a/test/kuttl/tests/ctlplane-collapsed/01-assert-collapsed-cell.yaml b/test/kuttl/tests/ctlplane-collapsed/01-assert-collapsed-cell.yaml index 0214d9c42..5e67edc4b 100644 --- a/test/kuttl/tests/ctlplane-collapsed/01-assert-collapsed-cell.yaml +++ b/test/kuttl/tests/ctlplane-collapsed/01-assert-collapsed-cell.yaml @@ -85,7 +85,8 @@ spec: cell1: cellDatabaseAccount: nova-cell1 cellDatabaseInstance: openstack - cellMessageBusInstance: rabbitmq + messagingBus: + cluster: rabbitmq conductorServiceTemplate: replicas: 1 hasAPIAccess: true