Skip to content

Commit 2493b39

Browse files
committed
Rework logger and pass *Request pointer in webhook/authentication
Signed-off-by: Vince Prignano <[email protected]>
1 parent 0d4b81e commit 2493b39

File tree

7 files changed

+57
-39
lines changed

7 files changed

+57
-39
lines changed

examples/tokenreview/tokenreview.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ type authenticator struct {
2929
}
3030

3131
// authenticator admits a request by the token.
32-
func (a *authenticator) Handle(ctx context.Context, req authentication.Request) authentication.Response {
32+
func (a *authenticator) Handle(ctx context.Context, req *authentication.Request) authentication.Response {
3333
if req.Spec.Token == "invalid" {
3434
return authentication.Unauthenticated("invalid is an invalid token", v1.UserInfo{})
3535
}

pkg/webhook/admission/webhook_test.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import (
3131
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3232
machinerytypes "k8s.io/apimachinery/pkg/types"
3333

34-
internallog "sigs.k8s.io/controller-runtime/pkg/internal/log"
3534
logf "sigs.k8s.io/controller-runtime/pkg/log"
3635
"sigs.k8s.io/controller-runtime/pkg/log/zap"
3736
)
@@ -59,7 +58,6 @@ var _ = Describe("Admission Webhooks", func() {
5958
}
6059
webhook := &Webhook{
6160
Handler: handler,
62-
log: internallog.RuntimeLog.WithName("webhook"),
6361
}
6462

6563
return webhook
@@ -109,7 +107,6 @@ var _ = Describe("Admission Webhooks", func() {
109107
},
110108
}
111109
}),
112-
log: internallog.RuntimeLog.WithName("webhook"),
113110
}
114111

115112
By("invoking the webhook")
@@ -126,7 +123,6 @@ var _ = Describe("Admission Webhooks", func() {
126123
Handler: HandlerFunc(func(ctx context.Context, req Request) Response {
127124
return Patched("", jsonpatch.Operation{Operation: "add", Path: "/a", Value: 2}, jsonpatch.Operation{Operation: "replace", Path: "/b", Value: 4})
128125
}),
129-
log: internallog.RuntimeLog.WithName("webhook"),
130126
}
131127

132128
By("invoking the webhook")
@@ -213,7 +209,6 @@ var _ = Describe("Admission Webhooks", func() {
213209
webhook := &Webhook{
214210
Handler: handler,
215211
RecoverPanic: true,
216-
log: internallog.RuntimeLog.WithName("webhook"),
217212
}
218213

219214
return webhook
@@ -240,7 +235,6 @@ var _ = Describe("Admission Webhooks", func() {
240235
}
241236
webhook := &Webhook{
242237
Handler: handler,
243-
log: internallog.RuntimeLog.WithName("webhook"),
244238
}
245239

246240
return webhook

pkg/webhook/authentication/doc.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,3 @@ methods to implement authentication webhook handlers.
2121
See examples/tokenreview/ for an example of authentication webhooks.
2222
*/
2323
package authentication
24-
25-
import (
26-
logf "sigs.k8s.io/controller-runtime/pkg/internal/log"
27-
)
28-
29-
var log = logf.RuntimeLog.WithName("authentication")

pkg/webhook/authentication/http.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,15 @@ func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) {
5252
var reviewResponse Response
5353
if r.Body == nil {
5454
err = errors.New("request body is empty")
55-
log.Error(err, "bad request")
55+
wh.getLogger(nil).Error(err, "bad request")
5656
reviewResponse = Errored(err)
5757
wh.writeResponse(w, reviewResponse)
5858
return
5959
}
6060

6161
defer r.Body.Close()
6262
if body, err = io.ReadAll(r.Body); err != nil {
63-
log.Error(err, "unable to read the body from the incoming request")
63+
wh.getLogger(nil).Error(err, "unable to read the body from the incoming request")
6464
reviewResponse = Errored(err)
6565
wh.writeResponse(w, reviewResponse)
6666
return
@@ -69,7 +69,7 @@ func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) {
6969
// verify the content type is accurate
7070
if contentType := r.Header.Get("Content-Type"); contentType != "application/json" {
7171
err = fmt.Errorf("contentType=%s, expected application/json", contentType)
72-
log.Error(err, "unable to process a request with an unknown content type", "content type", contentType)
72+
wh.getLogger(nil).Error(err, "unable to process a request with an unknown content type", "content type", contentType)
7373
reviewResponse = Errored(err)
7474
wh.writeResponse(w, reviewResponse)
7575
return
@@ -82,23 +82,23 @@ func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) {
8282
// unregistered type to the v1 GVK, the decoder will coerce a v1beta1 TokenReview to authenticationv1.
8383
// The actual TokenReview GVK will be used to write a typed response in case the
8484
// webhook config permits multiple versions, otherwise this response will fail.
85-
req := Request{}
85+
req := new(Request)
8686
ar := unversionedTokenReview{}
8787
// avoid an extra copy
8888
ar.TokenReview = &req.TokenReview
8989
ar.SetGroupVersionKind(authenticationv1.SchemeGroupVersion.WithKind("TokenReview"))
9090
_, actualTokRevGVK, err := authenticationCodecs.UniversalDeserializer().Decode(body, nil, &ar)
9191
if err != nil {
92-
log.Error(err, "unable to decode the request")
92+
wh.getLogger(req).Error(err, "unable to decode the request")
9393
reviewResponse = Errored(err)
9494
wh.writeResponse(w, reviewResponse)
9595
return
9696
}
97-
log.V(1).Info("received request", "UID", req.UID, "kind", req.Kind)
97+
wh.getLogger(req).V(1).Info("received request", "UID", req.UID, "kind", req.Kind)
9898

9999
if req.Spec.Token == "" {
100100
err = errors.New("token is empty")
101-
log.Error(err, "bad request")
101+
wh.getLogger(req).Error(err, "bad request")
102102
reviewResponse = Errored(err)
103103
wh.writeResponse(w, reviewResponse)
104104
return
@@ -131,12 +131,12 @@ func (wh *Webhook) writeResponseTyped(w io.Writer, response Response, tokRevGVK
131131
// writeTokenResponse writes ar to w.
132132
func (wh *Webhook) writeTokenResponse(w io.Writer, ar authenticationv1.TokenReview) {
133133
if err := json.NewEncoder(w).Encode(ar); err != nil {
134-
log.Error(err, "unable to encode the response")
134+
wh.getLogger(nil).Error(err, "unable to encode the response")
135135
wh.writeResponse(w, Errored(err))
136136
}
137137
res := ar
138-
if log.V(1).Enabled() {
139-
log.V(1).Info("wrote response", "UID", res.UID, "authenticated", res.Status.Authenticated)
138+
if wh.getLogger(nil).V(1).Enabled() {
139+
wh.getLogger(nil).V(1).Info("wrote response", "UID", res.UID, "authenticated", res.Status.Authenticated)
140140
}
141141
}
142142

pkg/webhook/authentication/http_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ var _ = Describe("Authentication Webhooks", func() {
138138
const value = "from-ctx"
139139
webhook := &Webhook{
140140
Handler: &fakeHandler{
141-
fn: func(ctx context.Context, req Request) Response {
141+
fn: func(ctx context.Context, req *Request) Response {
142142
<-ctx.Done()
143143
return Authenticated(ctx.Value(key).(string), authenticationv1.UserInfo{})
144144
},
@@ -164,7 +164,7 @@ var _ = Describe("Authentication Webhooks", func() {
164164
const key ctxkey = 1
165165
webhook := &Webhook{
166166
Handler: &fakeHandler{
167-
fn: func(ctx context.Context, req Request) Response {
167+
fn: func(ctx context.Context, req *Request) Response {
168168
return Authenticated(ctx.Value(key).(string), authenticationv1.UserInfo{})
169169
},
170170
},
@@ -192,10 +192,10 @@ func (nopCloser) Close() error { return nil }
192192

193193
type fakeHandler struct {
194194
invoked bool
195-
fn func(context.Context, Request) Response
195+
fn func(context.Context, *Request) Response
196196
}
197197

198-
func (h *fakeHandler) Handle(ctx context.Context, req Request) Response {
198+
func (h *fakeHandler) Handle(ctx context.Context, req *Request) Response {
199199
h.invoked = true
200200
if h.fn != nil {
201201
return h.fn(ctx, req)

pkg/webhook/authentication/webhook.go

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,13 @@ import (
2020
"context"
2121
"errors"
2222
"net/http"
23+
"sync"
2324

25+
"github.com/go-logr/logr"
2426
authenticationv1 "k8s.io/api/authentication/v1"
27+
"k8s.io/klog/v2"
28+
29+
logf "sigs.k8s.io/controller-runtime/pkg/log"
2530
)
2631

2732
var (
@@ -46,7 +51,7 @@ type Response struct {
4651

4752
// Complete populates any fields that are yet to be set in
4853
// the underlying TokenResponse, It mutates the response.
49-
func (r *Response) Complete(req Request) error {
54+
func (r *Response) Complete(req *Request) error {
5055
r.UID = req.UID
5156

5257
return nil
@@ -58,16 +63,16 @@ type Handler interface {
5863
//
5964
// The supplied context is extracted from the received http.Request, allowing wrapping
6065
// http.Handlers to inject values into and control cancelation of downstream request processing.
61-
Handle(context.Context, Request) Response
66+
Handle(context.Context, *Request) Response
6267
}
6368

6469
// HandlerFunc implements Handler interface using a single function.
65-
type HandlerFunc func(context.Context, Request) Response
70+
type HandlerFunc func(context.Context, *Request) Response
6671

6772
var _ Handler = HandlerFunc(nil)
6873

6974
// Handle process the TokenReview by invoking the underlying function.
70-
func (f HandlerFunc) Handle(ctx context.Context, req Request) Response {
75+
func (f HandlerFunc) Handle(ctx context.Context, req *Request) Response {
7176
return f(ctx, req)
7277
}
7378

@@ -81,15 +86,40 @@ type Webhook struct {
8186
// add any additional information such as passing the request path or
8287
// headers thus allowing you to read them from within the handler
8388
WithContextFunc func(context.Context, *http.Request) context.Context
89+
90+
setupLogOnce sync.Once
91+
log logr.Logger
8492
}
8593

8694
// Handle processes TokenReview.
87-
func (wh *Webhook) Handle(ctx context.Context, req Request) Response {
95+
func (wh *Webhook) Handle(ctx context.Context, req *Request) Response {
8896
resp := wh.Handler.Handle(ctx, req)
8997
if err := resp.Complete(req); err != nil {
90-
log.Error(err, "unable to encode response")
98+
wh.getLogger(req).Error(err, "unable to encode response")
9199
return Errored(errUnableToEncodeResponse)
92100
}
93101

94102
return resp
95103
}
104+
105+
// getLogger constructs a logger from the injected log and LogConstructor.
106+
func (wh *Webhook) getLogger(req *Request) logr.Logger {
107+
wh.setupLogOnce.Do(func() {
108+
if wh.log.GetSink() == nil {
109+
wh.log = logf.Log.WithName("authentication")
110+
}
111+
})
112+
113+
return logConstructor(wh.log, req)
114+
}
115+
116+
// logConstructor adds some commonly interesting fields to the given logger.
117+
func logConstructor(base logr.Logger, req *Request) logr.Logger {
118+
if req != nil {
119+
return base.WithValues("object", klog.KRef(req.Namespace, req.Name),
120+
"namespace", req.Namespace, "name", req.Name,
121+
"user", req.Status.User.Username,
122+
)
123+
}
124+
return base
125+
}

pkg/webhook/authentication/webhook_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import (
3030
var _ = Describe("Authentication Webhooks", func() {
3131
allowHandler := func() *Webhook {
3232
handler := &fakeHandler{
33-
fn: func(ctx context.Context, req Request) Response {
33+
fn: func(ctx context.Context, req *Request) Response {
3434
return Response{
3535
TokenReview: authenticationv1.TokenReview{
3636
Status: authenticationv1.TokenReviewStatus{
@@ -52,7 +52,7 @@ var _ = Describe("Authentication Webhooks", func() {
5252
webhook := allowHandler()
5353

5454
By("invoking the webhook")
55-
resp := webhook.Handle(context.Background(), Request{})
55+
resp := webhook.Handle(context.Background(), &Request{})
5656

5757
By("checking that it allowed the request")
5858
Expect(resp.Status.Authenticated).To(BeTrue())
@@ -63,7 +63,7 @@ var _ = Describe("Authentication Webhooks", func() {
6363
webhook := allowHandler()
6464

6565
By("invoking the webhook")
66-
resp := webhook.Handle(context.Background(), Request{TokenReview: authenticationv1.TokenReview{ObjectMeta: metav1.ObjectMeta{UID: "foobar"}}})
66+
resp := webhook.Handle(context.Background(), &Request{TokenReview: authenticationv1.TokenReview{ObjectMeta: metav1.ObjectMeta{UID: "foobar"}}})
6767

6868
By("checking that the response share's the request's UID")
6969
Expect(resp.UID).To(Equal(machinerytypes.UID("foobar")))
@@ -74,7 +74,7 @@ var _ = Describe("Authentication Webhooks", func() {
7474
webhook := allowHandler()
7575

7676
By("invoking the webhook")
77-
resp := webhook.Handle(context.Background(), Request{})
77+
resp := webhook.Handle(context.Background(), &Request{})
7878

7979
By("checking that the response share's the request's UID")
8080
Expect(resp.Status).To(Equal(authenticationv1.TokenReviewStatus{Authenticated: true}))
@@ -83,7 +83,7 @@ var _ = Describe("Authentication Webhooks", func() {
8383
It("shouldn't overwrite the status on a response", func() {
8484
By("setting up a webhook that sets a status")
8585
webhook := &Webhook{
86-
Handler: HandlerFunc(func(ctx context.Context, req Request) Response {
86+
Handler: HandlerFunc(func(ctx context.Context, req *Request) Response {
8787
return Response{
8888
TokenReview: authenticationv1.TokenReview{
8989
Status: authenticationv1.TokenReviewStatus{
@@ -96,7 +96,7 @@ var _ = Describe("Authentication Webhooks", func() {
9696
}
9797

9898
By("invoking the webhook")
99-
resp := webhook.Handle(context.Background(), Request{})
99+
resp := webhook.Handle(context.Background(), &Request{})
100100

101101
By("checking that the message is intact")
102102
Expect(resp.Status).NotTo(BeNil())

0 commit comments

Comments
 (0)