diff --git a/test/e2e/auth/audit.go b/test/e2e/auth/audit.go index 0bf6b9e197a..1d6b8ae8598 100644 --- a/test/e2e/auth/audit.go +++ b/test/e2e/auth/audit.go @@ -79,6 +79,16 @@ var _ = SIGDescribe("Advanced Audit", func() { anonymousClient, err := clientset.NewForConfig(config) framework.ExpectNoError(err) + By("Creating a kubernetes client that impersonates an authorized user") + config, err = framework.LoadConfig() + framework.ExpectNoError(err) + config.Impersonate = restclient.ImpersonationConfig{ + UserName: "superman", + Groups: []string{"system:masters"}, + } + impersonatedClient, err := clientset.NewForConfig(config) + framework.ExpectNoError(err) + testCases := []struct { action func() events []utils.AuditEvent @@ -668,6 +678,30 @@ var _ = SIGDescribe("Advanced Audit", func() { }, }, }, + // List pods as impersonated user. + { + func() { + _, err = impersonatedClient.CoreV1().Pods(namespace).List(metav1.ListOptions{}) + framework.ExpectNoError(err, "failed to list pods") + }, + []utils.AuditEvent{ + { + Level: auditinternal.LevelRequest, + Stage: auditinternal.StageResponseComplete, + RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/pods", namespace), + Verb: "list", + Code: 200, + User: auditTestUser, + ImpersonatedUser: "superman", + ImpersonatedGroups: "system:masters", + Resource: "pods", + Namespace: namespace, + RequestObject: false, + ResponseObject: false, + AuthorizeDecision: "allow", + }, + }, + }, } // test authorizer annotations, RBAC is required. @@ -684,17 +718,19 @@ var _ = SIGDescribe("Advanced Audit", func() { }, []utils.AuditEvent{ { - Level: auditinternal.LevelRequest, - Stage: auditinternal.StageResponseComplete, - RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/pods/another-audit-pod", namespace), - Verb: "get", - Code: 403, - User: auditTestUser, - Resource: "pods", - Namespace: namespace, - RequestObject: false, - ResponseObject: false, - AuthorizeDecision: "forbid", + Level: auditinternal.LevelRequest, + Stage: auditinternal.StageResponseComplete, + RequestURI: fmt.Sprintf("/api/v1/namespaces/%s/pods/another-audit-pod", namespace), + Verb: "get", + Code: 403, + User: auditTestUser, + ImpersonatedUser: "system:anonymous", + ImpersonatedGroups: "system:unauthenticated", + Resource: "pods", + Namespace: namespace, + RequestObject: false, + ResponseObject: false, + AuthorizeDecision: "forbid", }, }, }, diff --git a/test/utils/audit.go b/test/utils/audit.go index e4cd1b07722..c78cb2719a2 100644 --- a/test/utils/audit.go +++ b/test/utils/audit.go @@ -20,6 +20,8 @@ import ( "bufio" "fmt" "io" + "sort" + "strings" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -28,17 +30,19 @@ import ( ) type AuditEvent struct { - Level auditinternal.Level - Stage auditinternal.Stage - RequestURI string - Verb string - Code int32 - User string - Resource string - Namespace string - RequestObject bool - ResponseObject bool - AuthorizeDecision string + Level auditinternal.Level + Stage auditinternal.Stage + RequestURI string + Verb string + Code int32 + User string + ImpersonatedUser string + ImpersonatedGroups string + Resource string + Namespace string + RequestObject bool + ResponseObject bool + AuthorizeDecision string } // Search the audit log for the expected audit lines. @@ -101,6 +105,11 @@ func parseAuditLine(line string, version schema.GroupVersion) (AuditEvent, error if e.RequestObject != nil { event.RequestObject = true } + if e.ImpersonatedUser != nil { + event.ImpersonatedUser = e.ImpersonatedUser.Username + sort.Strings(e.ImpersonatedUser.Groups) + event.ImpersonatedGroups = strings.Join(e.ImpersonatedUser.Groups, ",") + } event.AuthorizeDecision = e.Annotations["authorization.k8s.io/decision"] return event, nil }