Skip to content

Commit 313bc06

Browse files
Merge pull request #1675 from stlaz/scc-reconcile
OCPBUGS-33522: add a controller that reconciles SCCs' volumes
2 parents b352992 + 4ea21e0 commit 313bc06

34 files changed

+2870
-1
lines changed

bindata/assets/config/config-overrides.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,3 @@ serviceAccountPublicKeyFiles:
1717
# The following path contains the public keys needed to verify bound sa
1818
# tokens. This is only supported post-bootstrap.
1919
- /etc/kubernetes/static-pod-resources/configmaps/bound-sa-token-signing-certs
20-
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package sccreconcilecontroller
2+
3+
import (
4+
"context"
5+
6+
securityv1client "github.com/openshift/client-go/security/clientset/versioned/typed/security/v1"
7+
securityv1informers "github.com/openshift/client-go/security/informers/externalversions/security/v1"
8+
securityv1listers "github.com/openshift/client-go/security/listers/security/v1"
9+
"github.com/openshift/library-go/pkg/controller/factory"
10+
"github.com/openshift/library-go/pkg/operator/events"
11+
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
"k8s.io/apimachinery/pkg/util/sets"
13+
)
14+
15+
type sccReconcileController struct {
16+
sccClient securityv1client.SecurityV1Interface
17+
sccLister securityv1listers.SecurityContextConstraintsLister
18+
}
19+
20+
var createOnlySCCs = []string{
21+
"anyuid",
22+
"hostaccess",
23+
"hostmount-anyuid",
24+
"hostnetwork",
25+
"nonroot",
26+
"restricted",
27+
}
28+
29+
// NewSCCReconcileController reconciles the "ephemeral" and "csi" volumes into
30+
// otherwise "create-only" reconciled SCCs to make these volumes available to
31+
// regular users in upgraded clusters.
32+
//
33+
// TODO:(consider): In the past we tried to reconcile the original (non-v2) SCCs with CVO
34+
// but that backfired badly as people still used the original SCC permission model
35+
// directly writing to SCC's "users" and "groups" fields as compared to
36+
// the newer RBAC approach.
37+
// Consider using this controller to reconcile all the fields BUT "users" and "groups"
38+
// for these older SCCs.
39+
func NewSCCReconcileController(
40+
sccClient securityv1client.SecurityV1Interface,
41+
sccInformer securityv1informers.SecurityContextConstraintsInformer,
42+
recorder events.Recorder,
43+
) (factory.Controller, error) {
44+
c := &sccReconcileController{
45+
sccClient: sccClient,
46+
sccLister: sccInformer.Lister(),
47+
}
48+
49+
return factory.New().
50+
WithSync(c.sync).
51+
WithFilteredEventsInformersQueueKeyFunc(
52+
factory.ObjectNameToKey,
53+
factory.NamesFilter(createOnlySCCs...),
54+
sccInformer.Informer(),
55+
).
56+
ToController("SCCReconcileController", recorder.WithComponentSuffix("scc-reconcile-controller")), nil
57+
}
58+
59+
func (c *sccReconcileController) sync(ctx context.Context, controllerContext factory.SyncContext) error {
60+
sccName := controllerContext.QueueKey()
61+
scc, err := c.sccLister.Get(sccName)
62+
if err != nil {
63+
return err
64+
}
65+
66+
volumeSet := sets.New(scc.Volumes...)
67+
if volumeSet.Has("ephemeral") && volumeSet.Has("csi") {
68+
return nil
69+
}
70+
71+
volumeSet.Insert("ephemeral", "csi")
72+
sccCopy := scc.DeepCopy()
73+
sccCopy.Volumes = volumeSet.UnsortedList()
74+
75+
_, err = c.sccClient.SecurityContextConstraints().Update(ctx, sccCopy, v1.UpdateOptions{})
76+
return err
77+
}

pkg/operator/starter.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import (
1515
operatorv1client "github.com/openshift/client-go/operator/clientset/versioned"
1616
operatorv1informers "github.com/openshift/client-go/operator/informers/externalversions"
1717
operatorcontrolplaneclient "github.com/openshift/client-go/operatorcontrolplane/clientset/versioned"
18+
securityclient "github.com/openshift/client-go/security/clientset/versioned"
19+
securityvnformers "github.com/openshift/client-go/security/informers/externalversions"
1820
"github.com/openshift/cluster-kube-apiserver-operator/bindata"
1921
"github.com/openshift/cluster-kube-apiserver-operator/pkg/operator/boundsatokensignercontroller"
2022
"github.com/openshift/cluster-kube-apiserver-operator/pkg/operator/certrotationcontroller"
@@ -28,6 +30,7 @@ import (
2830
"github.com/openshift/cluster-kube-apiserver-operator/pkg/operator/operatorclient"
2931
"github.com/openshift/cluster-kube-apiserver-operator/pkg/operator/podsecurityreadinesscontroller"
3032
"github.com/openshift/cluster-kube-apiserver-operator/pkg/operator/resourcesynccontroller"
33+
"github.com/openshift/cluster-kube-apiserver-operator/pkg/operator/sccreconcilecontroller"
3134
"github.com/openshift/cluster-kube-apiserver-operator/pkg/operator/serviceaccountissuercontroller"
3235
"github.com/openshift/cluster-kube-apiserver-operator/pkg/operator/startupmonitorreadiness"
3336
"github.com/openshift/cluster-kube-apiserver-operator/pkg/operator/targetconfigcontroller"
@@ -84,6 +87,10 @@ func RunOperator(ctx context.Context, controllerContext *controllercmd.Controlle
8487
if err != nil {
8588
return err
8689
}
90+
securityClient, err := securityclient.NewForConfig(controllerContext.KubeConfig)
91+
if err != nil {
92+
return err
93+
}
8794
operatorcontrolplaneClient, err := operatorcontrolplaneclient.NewForConfig(controllerContext.KubeConfig)
8895
if err != nil {
8996
return err
@@ -113,6 +120,8 @@ func RunOperator(ctx context.Context, controllerContext *controllercmd.Controlle
113120
return err
114121
}
115122

123+
securityInformers := securityvnformers.NewSharedInformerFactory(securityClient, 10*time.Minute)
124+
116125
desiredVersion := status.VersionForOperatorFromEnv()
117126
missingVersion := "0.0.1-snapshot"
118127

@@ -427,6 +436,12 @@ func RunOperator(ctx context.Context, controllerContext *controllercmd.Controlle
427436
controllerContext.EventRecorder,
428437
)
429438

439+
sccReconcileController, err := sccreconcilecontroller.NewSCCReconcileController(
440+
securityClient.SecurityV1(),
441+
securityInformers.Security().V1().SecurityContextConstraints(),
442+
controllerContext.EventRecorder,
443+
)
444+
430445
podSecurityReadinessController, err := podsecurityreadinesscontroller.NewPodSecurityReadinessController(
431446
controllerContext.ProtoKubeConfig,
432447
operatorClient,
@@ -448,6 +463,7 @@ func RunOperator(ctx context.Context, controllerContext *controllercmd.Controlle
448463
migrationInformer.Start(ctx.Done())
449464
apiextensionsInformers.Start(ctx.Done())
450465
operatorInformers.Start(ctx.Done())
466+
securityInformers.Start(ctx.Done())
451467

452468
go staticPodControllers.Start(ctx)
453469
go resourceSyncController.Run(ctx, 1)
@@ -470,6 +486,7 @@ func RunOperator(ctx context.Context, controllerContext *controllercmd.Controlle
470486
go webhookSupportabilityController.Run(ctx, 1)
471487
go serviceAccountIssuerController.Run(ctx, 1)
472488
go podSecurityReadinessController.Run(ctx, 1)
489+
go sccReconcileController.Run(ctx, 1)
473490

474491
<-ctx.Done()
475492
return nil

0 commit comments

Comments
 (0)