Skip to content

K8SPG-901: allow running without pgbouncer#1443

Merged
hors merged 20 commits into
mainfrom
K8SPG-901
Feb 18, 2026
Merged

K8SPG-901: allow running without pgbouncer#1443
hors merged 20 commits into
mainfrom
K8SPG-901

Conversation

@mayankshah1607
Copy link
Copy Markdown
Member

@mayankshah1607 mayankshah1607 commented Feb 16, 2026

CHANGE DESCRIPTION

Problem:
Operator does not allow running a cluster without PG bouncer. Specifying nil for .spec.proxy or .spec.proxy.pgbouncer still results in the default pgbouncer settings being applied.

Cause:
Operator adds default pgbouncer settings when set to nil.

Solution:
Honor nil setting for .spec.proxy, and apply pgbouncer defaults only when .spec.proxy is not nil

CHECKLIST

Jira

  • Is the Jira ticket created and referenced properly?
  • Does the Jira ticket have the proper statuses for documentation (Needs Doc) and QA (Needs QA)?
  • Does the Jira ticket link to the proper milestone (Fix Version field)?

Tests

  • Is an E2E test/test case added for the new feature/change?
  • Are unit tests added where appropriate?

Config/Logging/Testability

  • Are all needed new/changed options added to default YAML files?
  • Are all needed new/changed options added to the Helm Chart?
  • Did we add proper logging messages for operator actions?
  • Did we ensure compatibility with the previous version or cluster upgrade process?
  • Does the change support oldest and newest supported PG version?
  • Does the change support oldest and newest supported Kubernetes version?

Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Copilot AI review requested due to automatic review settings February 16, 2026 13:54
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enables running the Percona PostgreSQL Operator without PGBouncer by making the Proxy specification optional. Previously, the operator always initialized Proxy and PGBouncer objects even when not configured. Now, clusters can run with direct connections to PostgreSQL pods instead of routing through PGBouncer.

Changes:

  • Modified the Default() method to only initialize PGBouncer when Proxy is configured
  • Updated getHost() to return the pod service FQDN when Proxy/PGBouncer is not configured
  • Added nil check for Proxy before accessing PGBouncer.EnvFrom (partially - bug found)

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go Modified Default() to conditionally initialize PGBouncer only when Proxy is non-nil
percona/controller/pgcluster/status.go Updated getHost() to fallback to ClusterPodService when Proxy/PGBouncer is nil, improving service name handling
percona/controller/pgcluster/controller.go Added partial nil check for Proxy before accessing PGBouncer.EnvFrom (missing PGBouncer check)

Comment thread percona/controller/pgcluster/controller.go Outdated
Comment thread pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go Outdated
mayankshah1607 and others added 2 commits February 16, 2026 19:28
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Copilot AI review requested due to automatic review settings February 16, 2026 15:22
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread percona/controller/pgcluster/controller.go Outdated
Comment thread percona/controller/pgcluster/status.go Outdated
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Copilot AI review requested due to automatic review settings February 17, 2026 07:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Comment thread percona/controller/pgcluster/controller.go Outdated
Comment thread percona/controller/pgcluster/controller.go Outdated
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Copilot AI review requested due to automatic review settings February 17, 2026 08:53
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Copilot AI review requested due to automatic review settings February 17, 2026 09:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Copilot AI review requested due to automatic review settings February 17, 2026 09:29
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings February 18, 2026 12:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.


// If proxy is not configured, use the primary service as host.
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 on lines +388 to 419
"handles nil proxy": {
expectedPerconaPGCluster: &PerconaPGCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "test-cluster",
Namespace: "test-namespace",
},
Spec: PerconaPGClusterSpec{
CRVersion: "2.9.0",
PostgresVersion: 15,
Proxy: nil,
InstanceSets: PGInstanceSets{
{
Name: "instance1",
Replicas: &[]int32{1}[0],
DataVolumeClaimSpec: corev1.PersistentVolumeClaimSpec{
AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce},
},
},
},
Backups: Backups{
PGBackRest: PGBackRestArchive{
Repos: []crunchyv1beta1.PGBackRestRepo{
{Name: "repo1"},
},
},
},
},
},
assertClusterFunc: func(t *testing.T, actual *crunchyv1beta1.PostgresCluster, _ *PerconaPGCluster) {
assert.Nil(t, actual.Spec.Proxy)
},
},
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: The test suite covers Proxy: nil but does not cover the newly-supported case where Proxy is non-nil while Proxy.PGBouncer is nil (e.g. YAML proxy: {} or pgBouncer: null).
  2. Why it matters: That is a realistic user configuration for disabling pgBouncer, and it would have caught the current ToCrunchy nil-dereference risk.
  3. Fix: Add a ToCrunchy table entry that sets Spec.Proxy = &PGProxySpec{PGBouncer:nil} (or an empty PGProxySpec{}) and assert actual.Spec.Proxy == nil (and no panic/error).

Copilot generated this review using guidance from repository custom instructions.
}

func (p *PGProxySpec) ToCrunchy(version string) *crunchyv1beta1.PostgresProxySpec {
if p == 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: PGProxySpec.ToCrunchy will panic when .spec.proxy is present but .spec.proxy.pgBouncer is nil, because it later dereferences p.PGBouncer without a nil guard.
  2. Why it matters: With this PR, Default() can leave Proxy non-nil while PGBouncer is nil (e.g. proxy: {}), making this crash reachable during PerconaPGCluster.ToCrunchy.
  3. Fix: In ToCrunchy, treat p == nil || p.PGBouncer == nil as “proxy disabled” and return nil (or otherwise guard the dereference) before calling into p.PGBouncer.
Suggested change
if p == nil {
if p == nil || p.PGBouncer == nil {

Copilot uses AI. Check for mistakes.
@hors hors merged commit 308e961 into main Feb 18, 2026
21 of 22 checks passed
@hors hors deleted the K8SPG-901 branch February 18, 2026 12:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants