Skip to content

Commit

Permalink
Add logging for the projected token mount webhook (#5520)
Browse files Browse the repository at this point in the history
  • Loading branch information
rfranzke committed Mar 4, 2022
1 parent b867bdf commit a599e5b
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 3 deletions.
9 changes: 8 additions & 1 deletion pkg/resourcemanager/webhook/projectedtokenmount/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package projectedtokenmount
import (
"github.com/spf13/pflag"
"sigs.k8s.io/controller-runtime/pkg/cluster"
runtimelog "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/webhook"
)
Expand Down Expand Up @@ -44,7 +45,13 @@ type WebhookConfig struct {
// AddToManagerWithOptions adds the webhook to a Manager with the given config.
func AddToManagerWithOptions(mgr manager.Manager, conf WebhookConfig) error {
server := mgr.GetWebhookServer()
server.Register(WebhookPath, &webhook.Admission{Handler: NewHandler(conf.TargetCluster.GetCache(), conf.ExpirationSeconds)})
server.Register(WebhookPath, &webhook.Admission{
Handler: NewHandler(
runtimelog.Log.WithName("webhook").WithName(HandlerName),
conf.TargetCluster.GetCache(),
conf.ExpirationSeconds,
),
})
return nil
}

Expand Down
14 changes: 13 additions & 1 deletion pkg/resourcemanager/webhook/projectedtokenmount/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/gardener/gardener/pkg/resourcemanager/controller/rootcapublisher"
kutil "github.com/gardener/gardener/pkg/utils/kubernetes"

"github.com/go-logr/logr"
admissionv1 "k8s.io/api/admission/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/utils/pointer"
Expand All @@ -33,14 +34,16 @@ import (
)

type handler struct {
logger logr.Logger
targetClient client.Reader
decoder *admission.Decoder
expirationSeconds int64
}

// NewHandler returns a new handler.
func NewHandler(targetClient client.Reader, expirationSeconds int64) admission.Handler {
func NewHandler(logger logr.Logger, targetClient client.Reader, expirationSeconds int64) admission.Handler {
return &handler{
logger: logger,
targetClient: targetClient,
expirationSeconds: expirationSeconds,
}
Expand All @@ -61,32 +64,40 @@ func (h *handler) Handle(ctx context.Context, req admission.Request) admission.R
return admission.Errored(http.StatusUnprocessableEntity, err)
}

log := h.logger.WithValues("pod", client.ObjectKeyFromObject(pod))

if len(pod.Spec.ServiceAccountName) == 0 || pod.Spec.ServiceAccountName == "default" {
log.Info("Pod's service account name is empty or defaulted, nothing to be done", "serviceAccountName", pod.Spec.ServiceAccountName)
return admission.Allowed("service account not specified or defaulted")
}

serviceAccount := &corev1.ServiceAccount{}
// We use `req.Namespace` instead of `pod.Namespace` due to https://github.com/kubernetes/kubernetes/issues/88282.
if err := h.targetClient.Get(ctx, kutil.Key(req.Namespace, pod.Spec.ServiceAccountName), serviceAccount); err != nil {
log.Error(err, "Error getting service account", "serviceAccountName", pod.Spec.ServiceAccountName)
return admission.Errored(http.StatusInternalServerError, err)
}

if serviceAccount.AutomountServiceAccountToken == nil || *serviceAccount.AutomountServiceAccountToken {
log.Info("Pod's service account does not set .spec.automountServiceAccountToken=false, nothing to be done")
return admission.Allowed("auto-mounting service account token is not disabled on ServiceAccount level")
}

if pod.Spec.AutomountServiceAccountToken != nil && !*pod.Spec.AutomountServiceAccountToken {
log.Info("Pod explicitly disables auto-mount by setting .spec.automountServiceAccountToken to false, nothing to be done")
return admission.Allowed("Pod explicitly disables a service account token mount")
}

for _, volume := range pod.Spec.Volumes {
if strings.HasPrefix(volume.Name, serviceAccountVolumeNamePrefix) {
log.Info("Pod already has a service account volume mount, nothing to be done")
return admission.Allowed("pod already has service account volume mount")
}
}

expirationSeconds, err := tokenExpirationSeconds(pod.Annotations, h.expirationSeconds)
if err != nil {
log.Error(err, "Error getting the token expiration seconds")
return admission.Errored(http.StatusUnprocessableEntity, err)
}

Expand Down Expand Up @@ -115,6 +126,7 @@ func (h *handler) Handle(ctx context.Context, req admission.Request) admission.R
return admission.Errored(http.StatusInternalServerError, err)
}

log.Info("Pod meets requirements for auto-mounting the projected token")
return admission.PatchResponseFromRaw(req.Object.Raw, marshaledPod)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

. "github.com/gardener/gardener/pkg/resourcemanager/webhook/projectedtokenmount"

"github.com/go-logr/logr"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"gomodules.xyz/jsonpatch/v2"
Expand All @@ -32,6 +33,7 @@ import (
"k8s.io/utils/pointer"
"sigs.k8s.io/controller-runtime/pkg/client"
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
logzap "sigs.k8s.io/controller-runtime/pkg/log/zap"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)

Expand All @@ -40,6 +42,7 @@ var _ = Describe("Handler", func() {
ctx = context.TODO()
err error

logger logr.Logger
decoder *admission.Decoder
encoder runtime.Encoder
fakeClient client.Client
Expand All @@ -57,13 +60,15 @@ var _ = Describe("Handler", func() {
)

BeforeEach(func() {
logger = logzap.New(logzap.WriteTo(GinkgoWriter))

decoder, err = admission.NewDecoder(kubernetesscheme.Scheme)
Expect(err).NotTo(HaveOccurred())
encoder = &json.Serializer{}

fakeClient = fakeclient.NewClientBuilder().WithScheme(kubernetesscheme.Scheme).Build()

handler = NewHandler(fakeClient, expirationSeconds)
handler = NewHandler(logger, fakeClient, expirationSeconds)
Expect(admission.InjectDecoderInto(decoder, handler)).To(BeTrue())

request = admission.Request{
Expand Down

0 comments on commit a599e5b

Please sign in to comment.