Skip to content

Commit 42659a0

Browse files
committed
Set fsGroup on pgBouncer pods
When we looked into logging validation, we found that pgBouncer wasn't being created with an fsGroup setting. This PR updates that.
1 parent a618814 commit 42659a0

File tree

4 files changed

+100
-1
lines changed

4 files changed

+100
-1
lines changed

internal/controller/postgrescluster/pgbouncer.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,13 @@ func (r *Reconciler) generatePGBouncerDeployment(
462462
// Do not add environment variables describing services in this namespace.
463463
deploy.Spec.Template.Spec.EnableServiceLinks = initialize.Bool(false)
464464

465-
deploy.Spec.Template.Spec.SecurityContext = initialize.PodSecurityContext()
465+
fsGroup := 2
466+
if initialize.FromPointer(cluster.Spec.OpenShift) {
467+
fsGroup = 0
468+
}
469+
deploy.Spec.Template.Spec.SecurityContext = util.PodSecurityContext(int64(fsGroup),
470+
cluster.Spec.SupplementalGroups,
471+
)
466472

467473
// set the image pull secrets, if any exist
468474
deploy.Spec.Template.Spec.ImagePullSecrets = cluster.Spec.ImagePullSecrets

internal/controller/postgrescluster/pgbouncer_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,7 @@ containers: null
478478
enableServiceLinks: false
479479
restartPolicy: Always
480480
securityContext:
481+
fsGroup: 2
481482
fsGroupChangePolicy: OnRootMismatch
482483
shareProcessNamespace: true
483484
topologySpreadConstraints:

internal/util/pod_security.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright 2017 - 2025 Crunchy Data Solutions, Inc.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
package util
6+
7+
import (
8+
corev1 "k8s.io/api/core/v1"
9+
10+
"github.com/crunchydata/postgres-operator/internal/initialize"
11+
)
12+
13+
// PodSecurityContext returns a v1.PodSecurityContext for cluster that can write
14+
// to PersistentVolumes.
15+
// This func sets the supplmental groups and fsGgroup if present.
16+
// fsGroup should not be present in OpenShift environments
17+
func PodSecurityContext(fsgroup int64, supplementalGroups []int64) *corev1.PodSecurityContext {
18+
psc := initialize.PodSecurityContext()
19+
20+
// Use the specified supplementary groups except for root. The CRD has
21+
// similar validation, but we should never emit a PodSpec with that group.
22+
// - https://docs.k8s.io/concepts/security/pod-security-standards/
23+
for i := range supplementalGroups {
24+
if gid := supplementalGroups[i]; gid > 0 {
25+
psc.SupplementalGroups = append(psc.SupplementalGroups, gid)
26+
}
27+
}
28+
29+
// OpenShift assigns a filesystem group based on a SecurityContextConstraint.
30+
// Otherwise, set a filesystem group so PostgreSQL can write to files
31+
// regardless of the UID or GID of a container.
32+
// - https://cloud.redhat.com/blog/a-guide-to-openshift-and-uids
33+
// - https://docs.k8s.io/tasks/configure-pod-container/security-context/
34+
// - https://docs.openshift.com/container-platform/4.8/authentication/managing-security-context-constraints.html
35+
if fsgroup > 0 {
36+
psc.FSGroup = initialize.Int64(fsgroup)
37+
}
38+
39+
return psc
40+
}

internal/util/pod_security_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2017 - 2025 Crunchy Data Solutions, Inc.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
package util
6+
7+
import (
8+
"testing"
9+
10+
"gotest.tools/v3/assert"
11+
12+
"github.com/crunchydata/postgres-operator/internal/testing/cmp"
13+
)
14+
15+
func TestPodSecurityContext(t *testing.T) {
16+
t.Run("Non-Openshift", func(t *testing.T) {
17+
assert.Assert(t, cmp.MarshalMatches(PodSecurityContext(2, []int64{}), `
18+
fsGroup: 2
19+
fsGroupChangePolicy: OnRootMismatch
20+
`))
21+
22+
supplementalGroups := []int64{3, 4}
23+
assert.Assert(t, cmp.MarshalMatches(PodSecurityContext(26, supplementalGroups), `
24+
fsGroup: 26
25+
fsGroupChangePolicy: OnRootMismatch
26+
supplementalGroups:
27+
- 3
28+
- 4
29+
`))
30+
})
31+
32+
t.Run("OpenShift", func(t *testing.T) {
33+
assert.Assert(t, cmp.MarshalMatches(PodSecurityContext(0, []int64{}),
34+
`fsGroupChangePolicy: OnRootMismatch`))
35+
36+
supplementalGroups := []int64{3, 4}
37+
assert.Assert(t, cmp.MarshalMatches(PodSecurityContext(0, supplementalGroups), `
38+
fsGroupChangePolicy: OnRootMismatch
39+
supplementalGroups:
40+
- 3
41+
- 4
42+
`))
43+
})
44+
45+
t.Run("NoRootGID", func(t *testing.T) {
46+
supplementalGroups := []int64{999, 0, 100, 0}
47+
assert.DeepEqual(t, []int64{999, 100}, PodSecurityContext(2, supplementalGroups).SupplementalGroups)
48+
49+
supplementalGroups = []int64{0}
50+
assert.Assert(t, PodSecurityContext(2, supplementalGroups).SupplementalGroups == nil)
51+
})
52+
}

0 commit comments

Comments
 (0)