Skip to content

Commit 8de7015

Browse files
Merge pull request #133765 from cfryanr/feature-readable-audit-event
restore public func `AuditEventFrom` which was deleted by #129472 Kubernetes-commit: 0f660b5eb498ab876180f991e46586f01067bdc6
2 parents 7fe26a9 + 7abb35c commit 8de7015

File tree

4 files changed

+180
-6
lines changed

4 files changed

+180
-6
lines changed

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ require (
4949
gopkg.in/evanphx/json-patch.v4 v4.13.0
5050
gopkg.in/go-jose/go-jose.v2 v2.6.3
5151
gopkg.in/natefinch/lumberjack.v2 v2.2.1
52-
k8s.io/api v0.0.0-20250929192326-dd80a46c1286
52+
k8s.io/api v0.0.0-20250930152327-c397f90a55bd
5353
k8s.io/apimachinery v0.0.0-20250929164018-5674a461e8a9
5454
k8s.io/client-go v0.0.0-20250929192726-5eac01c2bb55
55-
k8s.io/component-base v0.0.0-20250919034137-4453c3be72a8
55+
k8s.io/component-base v0.0.0-20250930153136-66f123b5ac6a
5656
k8s.io/klog/v2 v2.130.1
5757
k8s.io/kms v0.0.0-20250918004306-2fba1b2102ee
5858
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -295,14 +295,14 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYs
295295
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
296296
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
297297
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
298-
k8s.io/api v0.0.0-20250929192326-dd80a46c1286 h1:2gTEsSU/0HEVWl2v7cttEyNNqDxBU0/6owog7vkVhlw=
299-
k8s.io/api v0.0.0-20250929192326-dd80a46c1286/go.mod h1:zc2Bftemdv4WGe3gh/TWTwdUt5ERkIycxBrRQmuOjtc=
298+
k8s.io/api v0.0.0-20250930152327-c397f90a55bd h1:Cg2aqUh0jZZC7BD38J3K2Z6TAvKepgIvsO+e621Gz6M=
299+
k8s.io/api v0.0.0-20250930152327-c397f90a55bd/go.mod h1:zc2Bftemdv4WGe3gh/TWTwdUt5ERkIycxBrRQmuOjtc=
300300
k8s.io/apimachinery v0.0.0-20250929164018-5674a461e8a9 h1:tvHk/t27eNXdAUvzZ2Fz+BvoUpfB+tTnvmWR/ET1s2Q=
301301
k8s.io/apimachinery v0.0.0-20250929164018-5674a461e8a9/go.mod h1:1YSL0XujdSTcnuHOR73D16EdW+d49JOdd8TXjCo6Dhc=
302302
k8s.io/client-go v0.0.0-20250929192726-5eac01c2bb55 h1:VJDMZBpwiO8tLGelK/I8Ya3GTpJh2BHik2Xm2BNIuFo=
303303
k8s.io/client-go v0.0.0-20250929192726-5eac01c2bb55/go.mod h1:QU7JGxRCfyhP6ZIE+A+7BhoAnJolaWuH6Dh3NTpH8Sk=
304-
k8s.io/component-base v0.0.0-20250919034137-4453c3be72a8 h1:6ori9Hm1g6OqXGZa9ihRpScRfwRnVwf0PpqzTu2KCl0=
305-
k8s.io/component-base v0.0.0-20250919034137-4453c3be72a8/go.mod h1:k2hnvURL10Hd0tc/Tn7RZprCv4tlRGtDqYD3GSRo/NE=
304+
k8s.io/component-base v0.0.0-20250930153136-66f123b5ac6a h1:40tugOkDa2yxeCGR35eJOeNdHIXQt/610okoFxb6Zt0=
305+
k8s.io/component-base v0.0.0-20250930153136-66f123b5ac6a/go.mod h1:W22InbHsMbwfSRy9wR+2tl0soSSJFMELYq+qdLu9ysc=
306306
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
307307
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
308308
k8s.io/kms v0.0.0-20250918004306-2fba1b2102ee h1:dCR1mK59u+fkeNCgDWwcOBbPZ4lrO4qVyDM8xIOkGOI=

pkg/audit/context.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,25 @@ func (ac *AuditContext) LogRequestPatch(patch []byte) {
178178
})
179179
}
180180

181+
// GetEventUser returns a copy of the User associated with the audit Event.
182+
func (ac *AuditContext) GetEventUser() authnv1.UserInfo {
183+
var val *authnv1.UserInfo
184+
ac.visitEvent(func(ev *auditinternal.Event) {
185+
val = ev.User.DeepCopy()
186+
})
187+
return *val
188+
}
189+
190+
// GetEventImpersonatedUser returns a copy of the ImpersonatedUser associated with the audit Event,
191+
// or returns nil when there is no ImpersonatedUser.
192+
func (ac *AuditContext) GetEventImpersonatedUser() *authnv1.UserInfo {
193+
var val *authnv1.UserInfo
194+
ac.visitEvent(func(ev *auditinternal.Event) {
195+
val = ev.ImpersonatedUser.DeepCopy()
196+
})
197+
return val
198+
}
199+
181200
func (ac *AuditContext) GetEventAnnotation(key string) (string, bool) {
182201
var val string
183202
var ok bool

pkg/audit/context_test.go

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ import (
2222
"sync"
2323
"testing"
2424

25+
authnv1 "k8s.io/api/authentication/v1"
2526
auditinternal "k8s.io/apiserver/pkg/apis/audit"
2627

2728
"github.com/stretchr/testify/assert"
29+
"github.com/stretchr/testify/require"
2830
)
2931

3032
func TestEnabled(t *testing.T) {
@@ -175,6 +177,159 @@ func TestAuditAnnotationsWithAuditLoggingSetup(t *testing.T) {
175177
assert.Equal(t, expected, actual)
176178
}
177179

180+
func TestGetEventUser(t *testing.T) {
181+
tests := []struct {
182+
name string
183+
auditEventUser authnv1.UserInfo
184+
wantUser authnv1.UserInfo
185+
}{
186+
{
187+
name: "fields with zero values are returned as fields with zero values",
188+
auditEventUser: authnv1.UserInfo{},
189+
wantUser: authnv1.UserInfo{},
190+
},
191+
{
192+
name: "fields with non-zero values are returned as copies",
193+
auditEventUser: authnv1.UserInfo{
194+
Username: "test-user",
195+
UID: "test-uid",
196+
Groups: []string{"test-group1", "test-group2"},
197+
Extra: map[string]authnv1.ExtraValue{
198+
"test-extra1": {"test-extra1-val1", "test-extra1-val2"},
199+
"test-extra2": {"test-extra2-val1", "test-extra2-val2"},
200+
},
201+
},
202+
wantUser: authnv1.UserInfo{
203+
Username: "test-user",
204+
UID: "test-uid",
205+
Groups: []string{"test-group1", "test-group2"},
206+
Extra: map[string]authnv1.ExtraValue{
207+
"test-extra1": {"test-extra1-val1", "test-extra1-val2"},
208+
"test-extra2": {"test-extra2-val1", "test-extra2-val2"},
209+
},
210+
},
211+
},
212+
}
213+
for _, test := range tests {
214+
t.Run(test.name, func(t *testing.T) {
215+
ac := AuditContext{event: auditinternal.Event{User: test.auditEventUser}}
216+
got := ac.GetEventUser()
217+
require.Equal(t, test.wantUser, got)
218+
})
219+
}
220+
221+
t.Run("mutating the returned groups does not change the audit event's User's groups", func(t *testing.T) {
222+
ac := AuditContext{
223+
event: auditinternal.Event{
224+
User: authnv1.UserInfo{
225+
Groups: []string{"test-group1", "test-group2"},
226+
},
227+
},
228+
}
229+
got := ac.GetEventUser()
230+
require.Equal(t, []string{"test-group1", "test-group2"}, got.Groups)
231+
got.Groups[0] = "mutated group"
232+
require.Equal(t, []string{"mutated group", "test-group2"}, got.Groups)
233+
// The event's groups are not changed.
234+
require.Equal(t, []string{"test-group1", "test-group2"}, ac.event.User.Groups)
235+
})
236+
237+
t.Run("mutating the returned extras does not change the audit event's User's extras", func(t *testing.T) {
238+
ac := AuditContext{
239+
event: auditinternal.Event{
240+
User: authnv1.UserInfo{
241+
Extra: map[string]authnv1.ExtraValue{"test-extra": {"test-extra-val"}},
242+
},
243+
},
244+
}
245+
got := ac.GetEventUser()
246+
require.Equal(t, map[string]authnv1.ExtraValue{"test-extra": {"test-extra-val"}}, got.Extra)
247+
got.Extra["test-extra"] = authnv1.ExtraValue{"mutated value"}
248+
require.Equal(t, map[string]authnv1.ExtraValue{"test-extra": {"mutated value"}}, got.Extra)
249+
// The event's extras are not changed.
250+
require.Equal(t, map[string]authnv1.ExtraValue{"test-extra": {"test-extra-val"}}, ac.event.User.Extra)
251+
})
252+
}
253+
254+
func TestGetEventImpersonatedUser(t *testing.T) {
255+
tests := []struct {
256+
name string
257+
auditEventImpersonatedUser *authnv1.UserInfo
258+
wantUser *authnv1.UserInfo
259+
}{
260+
{
261+
name: "nil ImpersonatedUser returns nil",
262+
auditEventImpersonatedUser: nil,
263+
wantUser: nil,
264+
},
265+
{
266+
name: "fields with zero values are returned as fields with zero values",
267+
auditEventImpersonatedUser: &authnv1.UserInfo{},
268+
wantUser: &authnv1.UserInfo{},
269+
},
270+
{
271+
name: "fields with non-zero values are returned as copies",
272+
auditEventImpersonatedUser: &authnv1.UserInfo{
273+
Username: "test-user",
274+
UID: "test-uid",
275+
Groups: []string{"test-group1", "test-group2"},
276+
Extra: map[string]authnv1.ExtraValue{
277+
"test-extra1": {"test-extra1-val1", "test-extra1-val2"},
278+
"test-extra2": {"test-extra2-val1", "test-extra2-val2"},
279+
},
280+
},
281+
wantUser: &authnv1.UserInfo{
282+
Username: "test-user",
283+
UID: "test-uid",
284+
Groups: []string{"test-group1", "test-group2"},
285+
Extra: map[string]authnv1.ExtraValue{
286+
"test-extra1": {"test-extra1-val1", "test-extra1-val2"},
287+
"test-extra2": {"test-extra2-val1", "test-extra2-val2"},
288+
},
289+
},
290+
},
291+
}
292+
for _, test := range tests {
293+
t.Run(test.name, func(t *testing.T) {
294+
ac := AuditContext{event: auditinternal.Event{ImpersonatedUser: test.auditEventImpersonatedUser}}
295+
got := ac.GetEventImpersonatedUser()
296+
require.Equal(t, test.wantUser, got)
297+
})
298+
}
299+
300+
t.Run("mutating the returned groups does not change the audit event's ImpersonatedUser's groups", func(t *testing.T) {
301+
ac := AuditContext{
302+
event: auditinternal.Event{
303+
ImpersonatedUser: &authnv1.UserInfo{
304+
Groups: []string{"test-group1", "test-group2"},
305+
},
306+
},
307+
}
308+
got := ac.GetEventImpersonatedUser()
309+
require.Equal(t, []string{"test-group1", "test-group2"}, got.Groups)
310+
got.Groups[0] = "mutated group"
311+
require.Equal(t, []string{"mutated group", "test-group2"}, got.Groups)
312+
// The event's groups are not changed.
313+
require.Equal(t, []string{"test-group1", "test-group2"}, ac.event.ImpersonatedUser.Groups)
314+
})
315+
316+
t.Run("mutating the returned extras does not change the audit event's ImpersonatedUser's extras", func(t *testing.T) {
317+
ac := AuditContext{
318+
event: auditinternal.Event{
319+
ImpersonatedUser: &authnv1.UserInfo{
320+
Extra: map[string]authnv1.ExtraValue{"test-extra": {"test-extra-val"}},
321+
},
322+
},
323+
}
324+
got := ac.GetEventImpersonatedUser()
325+
require.Equal(t, map[string]authnv1.ExtraValue{"test-extra": {"test-extra-val"}}, got.Extra)
326+
got.Extra["test-extra"] = authnv1.ExtraValue{"mutated value"}
327+
require.Equal(t, map[string]authnv1.ExtraValue{"test-extra": {"mutated value"}}, got.Extra)
328+
// The event's extras are not changed.
329+
require.Equal(t, map[string]authnv1.ExtraValue{"test-extra": {"test-extra-val"}}, ac.event.ImpersonatedUser.Extra)
330+
})
331+
}
332+
178333
func withAuditContextAndLevel(ctx context.Context, t *testing.T, l auditinternal.Level) context.Context {
179334
ctx = WithAuditContext(ctx)
180335
if err := AuditContextFrom(ctx).Init(RequestAuditConfig{Level: l}, nil); err != nil {

0 commit comments

Comments
 (0)