Skip to content

Commit

Permalink
ps syncer: add a controller for run-level 0 namespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
stlaz committed Aug 3, 2023
1 parent 8501bc8 commit 33b7970
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 10 deletions.
23 changes: 13 additions & 10 deletions pkg/cmd/controller/config.go
@@ -1,17 +1,20 @@
package controller

var ControllerInitializers = map[string]InitFunc{
"openshift.io/namespace-security-allocation": RunNamespaceSecurityAllocationController,
"openshift.io/resourcequota": RunResourceQuotaManager,
"openshift.io/cluster-quota-reconciliation": RunClusterQuotaReconciliationController,
"openshift.io/cluster-csr-approver": RunCSRApproverController,
"openshift.io/podsecurity-admission-label-syncer": runPodSecurityAdmissionLabelSynchronizationController,
"openshift.io/namespace-security-allocation": RunNamespaceSecurityAllocationController,
"openshift.io/resourcequota": RunResourceQuotaManager,
"openshift.io/cluster-quota-reconciliation": RunClusterQuotaReconciliationController,
"openshift.io/cluster-csr-approver": RunCSRApproverController,
"openshift.io/podsecurity-admission-label-syncer": runPodSecurityAdmissionLabelSynchronizationController,
"openshift.io/privileged-namespaces-psa-label-syncer": runPrivilegedNamespacesPSALabelSyncer,
}

const (
infraClusterQuotaReconciliationControllerServiceAccountName = "cluster-quota-reconciliation-controller"
infraClusterCSRApproverControllerServiceAccountName = "cluster-csr-approver-controller"
infraNamespaceSecurityAllocationControllerServiceAccountName = "namespace-security-allocation-controller"
podSecurityAdmissionLabelSyncerControllerServiceAccountName = "podsecurity-admission-label-syncer-controller"
defaultOpenShiftInfraNamespace = "openshift-infra"
infraClusterQuotaReconciliationControllerServiceAccountName = "cluster-quota-reconciliation-controller"
infraClusterCSRApproverControllerServiceAccountName = "cluster-csr-approver-controller"
infraNamespaceSecurityAllocationControllerServiceAccountName = "namespace-security-allocation-controller"
podSecurityAdmissionLabelSyncerControllerServiceAccountName = "podsecurity-admission-label-syncer-controller"
privilegedNamespacesPodSecurityAdmissionLabelSyncerServiceAccountName = "privileged-namespaces-psa-label-syncer"

defaultOpenShiftInfraNamespace = "openshift-infra"
)
17 changes: 17 additions & 0 deletions pkg/cmd/controller/psalabelsyncer.go
Expand Up @@ -51,3 +51,20 @@ func runPodSecurityAdmissionLabelSynchronizationController(ctx context.Context,

return true, nil
}

func runPrivilegedNamespacesPSALabelSyncer(ctx context.Context, controllerCtx *EnhancedControllerContext) (bool, error) {
kubeClient, err := controllerCtx.ClientBuilder.Client(privilegedNamespacesPodSecurityAdmissionLabelSyncerServiceAccountName)
if err != nil {
return true, err
}

controller := psalabelsyncer.NewPrivilegedNamespacesPSALabelSyncer(
kubeClient.CoreV1().Namespaces(),
controllerCtx.KubernetesInformers.Core().V1().Namespaces(),
controllerCtx.EventRecorder.ForComponent("privileged-namespaces-psa-label-syncer"),
)

go controller.Run(ctx, 1)

return true, nil
}
72 changes: 72 additions & 0 deletions pkg/psalabelsyncer/privileged_namespaces_controller.go
@@ -0,0 +1,72 @@
package psalabelsyncer

import (
"context"
"fmt"
"time"

v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1apply "k8s.io/client-go/applyconfigurations/core/v1"
corev1informers "k8s.io/client-go/informers/core/v1"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
corev1listers "k8s.io/client-go/listers/core/v1"
psapi "k8s.io/pod-security-admission/api"

"github.com/openshift/library-go/pkg/controller/factory"
"github.com/openshift/library-go/pkg/operator/events"
)

const privilegedControllerName = "privileged-namespaces-psa-label-syncer"

type privilegedNamespacesPSALabelSyncer struct {
nsClient corev1client.NamespaceInterface
nsLister corev1listers.NamespaceLister
}

func NewPrivilegedNamespacesPSALabelSyncer(
namespaceClient corev1client.NamespaceInterface,
namespaceInformer corev1informers.NamespaceInformer,
eventRecorder events.Recorder,
) factory.Controller {
c := &privilegedNamespacesPSALabelSyncer{
nsClient: namespaceClient,
nsLister: namespaceInformer.Lister(),
}

return factory.New().
WithSync(c.sync).
WithFilteredEventsInformersQueueKeyFunc(
factory.ObjectNameToKey,
factory.NamesFilter("default", "kube-system", "kube-public"),
namespaceInformer.Informer(),
).
ResyncEvery(1*time.Hour).
ToController(
privilegedControllerName,
eventRecorder.WithComponentSuffix(privilegedControllerName),
)
}

func (c *privilegedNamespacesPSALabelSyncer) sync(ctx context.Context, controllerCtx factory.SyncContext) error {
qKey := controllerCtx.QueueKey()
ns, err := c.nsLister.Get(qKey)
if err != nil {
return fmt.Errorf("failed to retrieve ns %q: %w", qKey, err)
}

if ns.Labels[psapi.EnforceLevelLabel] == "privileged" &&
ns.Labels[psapi.WarnLevelLabel] == "privileged" &&
ns.Labels[psapi.AuditLevelLabel] == "privileged" {
return nil
}

nsApplyConfig := corev1apply.Namespace(ns.Name).WithLabels(map[string]string{
psapi.EnforceLevelLabel: "privileged",
psapi.WarnLevelLabel: "privileged",
psapi.AuditLevelLabel: "privileged",
})

_, err = c.nsClient.Apply(ctx, nsApplyConfig, v1.ApplyOptions{FieldManager: privilegedControllerName, Force: true})

return err
}

0 comments on commit 33b7970

Please sign in to comment.