Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion percona/controller/pgcluster/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ func (r *PGClusterReconciler) reconcileEnvFromSecrets(ctx context.Context, cr *v
m[&set.EnvFrom] = set.Metadata
}

if len(cr.Spec.Proxy.PGBouncer.EnvFrom) > 0 {
if cr.Spec.Proxy != nil && len(cr.Spec.Proxy.PGBouncer.EnvFrom) > 0 {
Comment thread
mayankshah1607 marked this conversation as resolved.
Outdated
Comment thread
mayankshah1607 marked this conversation as resolved.
Outdated
if cr.Spec.Proxy.PGBouncer.Metadata == nil {
cr.Spec.Proxy.PGBouncer.Metadata = new(v1beta1.Metadata)
}
Expand Down
22 changes: 20 additions & 2 deletions percona/controller/pgcluster/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package pgcluster

import (
"context"
"fmt"

"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
Expand All @@ -11,16 +12,33 @@ import (
"k8s.io/client-go/util/retry"

"github.com/percona/percona-postgresql-operator/v2/internal/controller/postgrescluster"
"github.com/percona/percona-postgresql-operator/v2/internal/naming"
pNaming "github.com/percona/percona-postgresql-operator/v2/percona/naming"
v2 "github.com/percona/percona-postgresql-operator/v2/pkg/apis/pgv2.percona.com/v2"
"github.com/percona/percona-postgresql-operator/v2/pkg/apis/postgres-operator.crunchydata.com/v1beta1"
)

func (r *PGClusterReconciler) getHost(ctx context.Context, cr *v2.PerconaPGCluster) (string, error) {
svcName := cr.Name + "-pgbouncer"
postgresCluster := &v1beta1.PostgresCluster{
ObjectMeta: metav1.ObjectMeta{
Name: cr.Name,
Namespace: cr.Namespace,
},
}

svcFQDN := func(svcName, ns string) string {
return fmt.Sprintf("%s.%s.svc", svcName, ns)
}

// If proxy is not configured, use the primary service
if cr.Spec.Proxy == nil || cr.Spec.Proxy.PGBouncer == nil {
return svcFQDN(naming.ClusterPrimaryService(postgresCluster).Name, postgresCluster.Namespace), nil
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Problem: When proxy/pgBouncer is not configured, getHost always returns the in-cluster primary Service FQDN, ignoring whether the primary Service is exposed as a LoadBalancer.
  2. Why it matters: .status.host is printed as the user-facing “Endpoint”; without pgBouncer, users exposing Postgres via .spec.expose.type=LoadBalancer will still see an internal-only DNS name.
  3. Fix: Mirror the existing LoadBalancer logic for the primary Service when proxy is nil: if .spec.expose is LoadBalancer, fetch the primary Service and prefer its ingress hostname/IP; otherwise return the Service FQDN.
Suggested change
return svcFQDN(naming.ClusterPrimaryService(postgresCluster).Name, postgresCluster.Namespace), nil
svcName := naming.ClusterPrimaryService(postgresCluster).Name
// If the primary is exposed via LoadBalancer, prefer its external hostname/IP.
if cr.Spec.Expose != nil && cr.Spec.Expose.Type == string(corev1.ServiceTypeLoadBalancer) {
svc := &corev1.Service{}
err := r.Client.Get(ctx, types.NamespacedName{Namespace: cr.Namespace, Name: svcName}, svc)
if err != nil {
return "", errors.Wrapf(err, "get %s service", svcName)
}
var host string
for _, i := range svc.Status.LoadBalancer.Ingress {
if len(i.Hostname) > 0 {
host = i.Hostname
} else if len(i.IP) > 0 {
host = i.IP
}
}
if host != "" {
return host, nil
}
}
return svcFQDN(svcName, postgresCluster.Namespace), nil

Copilot uses AI. Check for mistakes.
}
Comment thread
mayankshah1607 marked this conversation as resolved.
Outdated

// PGBouncer is not exposed, use the service name
svcName := naming.ClusterPGBouncer(postgresCluster).Name
if cr.Spec.Proxy.PGBouncer.ServiceExpose == nil || cr.Spec.Proxy.PGBouncer.ServiceExpose.Type != string(corev1.ServiceTypeLoadBalancer) {
return svcName + "." + cr.Namespace + ".svc", nil
return svcFQDN(svcName, postgresCluster.Namespace), nil
}

svc := &corev1.Service{}
Expand Down
24 changes: 11 additions & 13 deletions pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,21 +212,19 @@ func (cr *PerconaPGCluster) Default() {
cr.Spec.InstanceSets[i].Metadata.Labels[LabelOperatorVersion] = cr.Spec.CRVersion
}

if cr.Spec.Proxy == nil {
cr.Spec.Proxy = new(PGProxySpec)
}

if cr.Spec.Proxy.PGBouncer == nil {
cr.Spec.Proxy.PGBouncer = new(PGBouncerSpec)
}
if cr.Spec.Proxy != nil {
if cr.Spec.Proxy.PGBouncer == nil {
cr.Spec.Proxy.PGBouncer = new(PGBouncerSpec)
}

if cr.Spec.Proxy.PGBouncer.Metadata == nil {
cr.Spec.Proxy.PGBouncer.Metadata = new(crunchyv1beta1.Metadata)
}
if cr.Spec.Proxy.PGBouncer.Metadata.Labels == nil {
cr.Spec.Proxy.PGBouncer.Metadata.Labels = make(map[string]string)
if cr.Spec.Proxy.PGBouncer.Metadata == nil {
cr.Spec.Proxy.PGBouncer.Metadata = new(crunchyv1beta1.Metadata)
}
if cr.Spec.Proxy.PGBouncer.Metadata.Labels == nil {
cr.Spec.Proxy.PGBouncer.Metadata.Labels = make(map[string]string)
}
cr.Spec.Proxy.PGBouncer.Metadata.Labels[LabelOperatorVersion] = cr.Spec.CRVersion
}
Comment thread
mayankshah1607 marked this conversation as resolved.
Outdated
cr.Spec.Proxy.PGBouncer.Metadata.Labels[LabelOperatorVersion] = cr.Spec.CRVersion

t := true
f := false
Expand Down
Loading