44 "context"
55 _ "embed"
66 "fmt"
7+ "strings"
78
89 instancehav1beta1 "github.com/openstack-k8s-operators/infra-operator/apis/instanceha/v1beta1"
910 rabbitmqv1beta1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1"
@@ -109,6 +110,37 @@ func (r *Reconciler) addProxySidecar(
109110 // Add proxy sidecar container
110111 podSpec .Containers = append (podSpec .Containers , r .buildProxySidecarContainer (instance ))
111112
113+ // Update RabbitMQ container's readiness probe and ports to match backend configuration
114+ // The RabbitMQ cluster operator sets a probe on port 5671 and exposes ports by default,
115+ // but with the proxy enabled, RabbitMQ only listens on localhost:5673
116+ for i , container := range podSpec .Containers {
117+ if container .Name == "rabbitmq" {
118+ // Override the readiness probe to check the backend port
119+ podSpec .Containers [i ].ReadinessProbe = & corev1.Probe {
120+ ProbeHandler : corev1.ProbeHandler {
121+ TCPSocket : & corev1.TCPSocketAction {
122+ Host : "127.0.0.1" ,
123+ Port : intstr .FromInt32 (int32 (rabbitmqBackendPort )),
124+ },
125+ },
126+ InitialDelaySeconds : 10 ,
127+ TimeoutSeconds : 5 ,
128+ PeriodSeconds : 10 ,
129+ SuccessThreshold : 1 ,
130+ FailureThreshold : 3 ,
131+ }
132+
133+ // Note: We don't override container ports here because:
134+ // 1. Ports are just metadata declarations, not actual network configuration
135+ // 2. What RabbitMQ actually listens on is controlled by our listener config
136+ // 3. Overriding ports can cause conflicts with cluster operator defaults
137+
138+ Log .Info ("Updated RabbitMQ container readiness probe for proxy mode" ,
139+ "readinessProbePort" , rabbitmqBackendPort )
140+ break
141+ }
142+ }
143+
112144 // Add volume for proxy script
113145 if podSpec .Volumes == nil {
114146 podSpec .Volumes = []corev1.Volume {}
@@ -137,6 +169,10 @@ func (r *Reconciler) addProxySidecar(
137169 })
138170 }
139171
172+ // Note: rabbitmq-tls volume is automatically added by the cluster operator when
173+ // cluster.Spec.TLS.SecretName is set (which we keep for inter-node TLS).
174+ // The proxy container will mount this volume via buildProxySidecarContainer().
175+
140176 // Add rabbitmq-tls-ca volume if CA is in a separate secret
141177 if instance .Spec .TLS .CaSecretName != "" && instance .Spec .TLS .CaSecretName != instance .Spec .TLS .SecretName {
142178 caVolumeExists := false
@@ -317,10 +353,23 @@ func (r *Reconciler) removeProxySidecar(cluster *rabbitmqv2.RabbitmqCluster) {
317353 }
318354 podSpec .Containers = newContainers
319355
320- // Remove proxy-script volume
356+ // Restore RabbitMQ container's readiness probe to default
357+ // When proxy is removed, RabbitMQ listens on standard ports again
358+ // Setting probe to nil allows the cluster operator to restore its default
359+ if removed {
360+ for i , container := range podSpec .Containers {
361+ if container .Name == "rabbitmq" {
362+ podSpec .Containers [i ].ReadinessProbe = nil
363+ Log .Info ("Restored RabbitMQ container readiness probe to default" )
364+ break
365+ }
366+ }
367+ }
368+
369+ // Remove proxy-script and rabbitmq-tls-ca volumes
321370 newVolumes := []corev1.Volume {}
322371 for _ , vol := range podSpec .Volumes {
323- if vol .Name != "proxy-script" {
372+ if vol .Name != "proxy-script" && vol . Name != "rabbitmq-tls-ca" {
324373 newVolumes = append (newVolumes , vol )
325374 }
326375 }
@@ -396,6 +445,8 @@ func (r *Reconciler) configureRabbitMQBackendPort(
396445 instance * rabbitmqv1beta1.RabbitMq ,
397446 cluster * rabbitmqv2.RabbitmqCluster ,
398447) {
448+ Log := r .GetLogger (context .Background ())
449+
399450 // Determine proxy listen port based on TLS configuration
400451 listenPort := proxyListenPortPlain
401452 tlsStatus := "without TLS"
@@ -404,22 +455,29 @@ func (r *Reconciler) configureRabbitMQBackendPort(
404455 tlsStatus = "with TLS"
405456 }
406457
407- // Configure RabbitMQ to listen on localhost:5673 without TLS
408- // The proxy will handle TLS termination (if enabled) on 0.0.0.0:5671 or 0.0.0.0:5672
409- additionalConfig := fmt .Sprintf (`
410- # Proxy sidecar configuration
411- # RabbitMQ listens on localhost:%d without TLS (proxy handles encryption)
412- # External clients connect to proxy on port %d %s
413- # Disable all default listeners to prevent bypassing the proxy and port conflicts
414- listeners.tcp = none
415- listeners.ssl = none
416- listeners.tcp.1 = 127.0.0.1:%d
417- ` , rabbitmqBackendPort , listenPort , tlsStatus , rabbitmqBackendPort )
418-
419- // Append to existing additional config if any
420- if cluster .Spec .Rabbitmq .AdditionalConfig != "" {
421- cluster .Spec .Rabbitmq .AdditionalConfig += "\n " + additionalConfig
422- } else {
423- cluster .Spec .Rabbitmq .AdditionalConfig = additionalConfig
458+ // Inject listener configuration into existing AdvancedConfig
459+ // The cluster operator already sets up AdvancedConfig with TLS settings
460+ // We need to add tcp_listeners and ssl_listeners to the {rabbit, [...]} section
461+ advancedConfig := cluster .Spec .Rabbitmq .AdvancedConfig
462+ if advancedConfig != "" {
463+ // Find the {rabbit, [ section and inject our listener config after ssl_options
464+ // We look for the closing ]} of ssl_options and insert our listeners there
465+ listenerSettings := fmt .Sprintf (`,
466+ {tcp_listeners, [{"127.0.0.1", %d}]},
467+ {ssl_listeners, []}` , rabbitmqBackendPort )
468+
469+ // Insert after the ssl_options section closes
470+ // Pattern: find "]}↵]}" which closes ssl_options and rabbit section
471+ advancedConfig = strings .Replace (advancedConfig ,
472+ "]}\n ]}," , // End of ssl_options within rabbit section
473+ "]}" + listenerSettings + "\n ]}," , // Add our listeners
474+ 1 )
475+
476+ cluster .Spec .Rabbitmq .AdvancedConfig = advancedConfig
424477 }
478+
479+ Log .Info ("Configured RabbitMQ backend listener for proxy mode" ,
480+ "backendPort" , rabbitmqBackendPort ,
481+ "proxyPort" , listenPort ,
482+ "tlsStatus" , tlsStatus )
425483}
0 commit comments