Skip to content

Commit ffbc3ba

Browse files
authored
Add mutating webhook to set fsGroupChangePolicy field (#582)
* Add mutating webhook to set fsGroupChangePolicy field * Added decoder, debug logging * Fix path * Add missing name * Fix typo * Add sample podAnnotator * Try defaulter * Do webhook registration earlier * Add webhook server configuration annotations * Test cert-dir annotation * Remove webhook-server annotation * Fix typo * Logging * Add webhook server * Naming * Formatting * Try different registration * Move registration after start * Try registering FsGroupPolicySetter again * Move registration back up again * ... * use port 9443 again * Update annotation * Add scheme * Fix setting FSGroupChangePolicy * Remove samples * Make webhook configurable * Remove useless check * Since fsGroup is set by default, also enable webhook by default * Move code * Remove webhook.Options (we're using the default port anyway)
1 parent c7ed72e commit ffbc3ba

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

main.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,23 @@ import (
1717
"github.com/metal-stack/v"
1818
coreosv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
1919
zalando "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1"
20+
appsv1 "k8s.io/api/apps/v1"
2021
"k8s.io/apimachinery/pkg/runtime"
2122
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
2223
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
2324
"k8s.io/client-go/tools/clientcmd"
2425
ctrl "sigs.k8s.io/controller-runtime"
2526
"sigs.k8s.io/controller-runtime/pkg/log/zap"
2627
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
28+
"sigs.k8s.io/controller-runtime/pkg/webhook"
29+
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
2730

2831
databasev1 "github.com/fi-ts/postgreslet/api/v1"
2932
"github.com/fi-ts/postgreslet/controllers"
3033
"github.com/fi-ts/postgreslet/pkg/etcdmanager"
3134
"github.com/fi-ts/postgreslet/pkg/lbmanager"
3235
"github.com/fi-ts/postgreslet/pkg/operatormanager"
36+
"github.com/fi-ts/postgreslet/pkg/webhooks"
3337
firewall "github.com/metal-stack/firewall-controller/api/v1"
3438
"github.com/spf13/viper"
3539
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
@@ -84,6 +88,7 @@ const (
8488
tlsClusterIssuerFlg = "tls-cluster-issuer"
8589
tlsSubDomainFlg = "tls-sub-domain"
8690
enablePatroniFailsafeModeFlg = "enable-patroni-failsafe-mode"
91+
enableFsGroupChangePolicyWebhookFlg = "enable-fsgroup-change-policy-webhook"
8792
)
8893

8994
var (
@@ -98,6 +103,7 @@ func init() {
98103
_ = firewall.AddToScheme(scheme)
99104
_ = zalando.AddToScheme(scheme)
100105
_ = coreosv1.AddToScheme(scheme)
106+
_ = appsv1.AddToScheme(scheme)
101107
// +kubebuilder:scaffold:scheme
102108
_ = cmapi.AddToScheme(scheme)
103109
}
@@ -143,6 +149,7 @@ func main() {
143149
enableBootstrapStandbyFromS3 bool
144150
enableSuperUserForDBO bool
145151
enablePatroniFailsafeMode bool
152+
enableFsGroupChangePolicyWebhook bool
146153

147154
portRangeStart int
148155
portRangeSize int
@@ -305,6 +312,9 @@ func main() {
305312
viper.SetDefault(enablePatroniFailsafeModeFlg, true)
306313
enablePatroniFailsafeMode = viper.GetBool(enablePatroniFailsafeModeFlg)
307314

315+
viper.SetDefault(enableFsGroupChangePolicyWebhookFlg, true)
316+
enableFsGroupChangePolicyWebhook = viper.GetBool(enableFsGroupChangePolicyWebhookFlg)
317+
308318
ctrl.Log.Info("flag",
309319
metricsAddrSvcMgrFlg, metricsAddrSvcMgr,
310320
metricsAddrCtrlMgrFlg, metricsAddrCtrlMgr,
@@ -349,6 +359,7 @@ func main() {
349359
tlsClusterIssuerFlg, tlsClusterIssuer,
350360
tlsSubDomainFlg, tlsSubDomain,
351361
enablePatroniFailsafeModeFlg, enablePatroniFailsafeMode,
362+
enableFsGroupChangePolicyWebhookFlg, enableFsGroupChangePolicyWebhook,
352363
)
353364

354365
svcClusterConf := ctrl.GetConfigOrDie()
@@ -486,6 +497,19 @@ func main() {
486497
}
487498
// +kubebuilder:scaffold:builder
488499

500+
if enableFsGroupChangePolicyWebhook {
501+
svcClusterMgr.GetWebhookServer().Register(
502+
"/mutate-apps-v1-statefulset",
503+
&webhook.Admission{
504+
Handler: &webhooks.FsGroupChangePolicySetter{
505+
SvcClient: svcClusterMgr.GetClient(),
506+
Decoder: admission.NewDecoder(svcClusterMgr.GetScheme()),
507+
Log: ctrl.Log.WithName("webhooks").WithName("FsGroupChangePolicySetter"),
508+
},
509+
},
510+
)
511+
}
512+
489513
ctx := context.Background()
490514

491515
// update all existing operators to the current version
@@ -506,4 +530,5 @@ func main() {
506530
setupLog.Error(err, "problem running control plane cluster manager")
507531
os.Exit(1)
508532
}
533+
509534
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package webhooks
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"net/http"
7+
8+
"github.com/go-logr/logr"
9+
appsv1 "k8s.io/api/apps/v1"
10+
v1 "k8s.io/api/core/v1"
11+
"sigs.k8s.io/controller-runtime/pkg/client"
12+
13+
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
14+
)
15+
16+
// +kubebuilder:webhook:path=/mutate-apps-v1-statefulset,mutating=true,failurePolicy=ignore,groups=apps,resources=statefulsets,verbs=create;update,versions=v1,name=fsgroupchangepolicy.postgres.fits.cloud
17+
18+
// FsGroupChangePolicySetter Adds securityContext.fsGroupChangePolicy=OnRootMismatch when the securityContext.fsGroup field is set
19+
type FsGroupChangePolicySetter struct {
20+
SvcClient client.Client
21+
Decoder *admission.Decoder
22+
Log logr.Logger
23+
}
24+
25+
func (a *FsGroupChangePolicySetter) Handle(ctx context.Context, req admission.Request) admission.Response {
26+
log := a.Log.WithValues("name", req.Name, "ns", req.Namespace)
27+
log.V(1).Info("handling admission request")
28+
29+
sts := &appsv1.StatefulSet{}
30+
err := a.Decoder.Decode(req, sts)
31+
if err != nil {
32+
log.Error(err, "failed to decode request")
33+
return admission.Errored(http.StatusBadRequest, err)
34+
}
35+
36+
// when the fsGroup field is set, also set the fsGroupChangePolicy to OnRootMismatch
37+
if sts.Spec.Template.Spec.SecurityContext != nil && sts.Spec.Template.Spec.SecurityContext.FSGroup != nil {
38+
p := v1.FSGroupChangeOnRootMismatch
39+
sts.Spec.Template.Spec.SecurityContext.FSGroupChangePolicy = &p
40+
log.V(1).Info("Mutating StatefulSet", "sts", sts)
41+
}
42+
43+
marshaledSts, err := json.Marshal(sts)
44+
if err != nil {
45+
log.Error(err, "failed to marshal response")
46+
return admission.Errored(http.StatusInternalServerError, err)
47+
}
48+
49+
log.V(1).Info("done")
50+
return admission.PatchResponseFromRaw(req.Object.Raw, marshaledSts)
51+
}

0 commit comments

Comments
 (0)