k8s.io/apiserver@v0.31.1/plugin/pkg/audit/log/backend_test.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package log 18 19 import ( 20 "bytes" 21 "reflect" 22 "regexp" 23 "testing" 24 "time" 25 26 "github.com/google/uuid" 27 28 authnv1 "k8s.io/api/authentication/v1" 29 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 30 "k8s.io/apimachinery/pkg/runtime" 31 "k8s.io/apimachinery/pkg/runtime/schema" 32 "k8s.io/apimachinery/pkg/types" 33 auditinternal "k8s.io/apiserver/pkg/apis/audit" 34 "k8s.io/apiserver/pkg/apis/audit/install" 35 auditv1 "k8s.io/apiserver/pkg/apis/audit/v1" 36 "k8s.io/apiserver/pkg/audit" 37 ) 38 39 func init() { 40 install.Install(audit.Scheme) 41 } 42 43 func TestLogEventsLegacy(t *testing.T) { 44 for _, test := range []struct { 45 event *auditinternal.Event 46 expected string 47 }{ 48 { 49 &auditinternal.Event{ 50 AuditID: types.UID(uuid.New().String()), 51 }, 52 `[\d\:\-\.\+TZ]+ AUDIT: id="[\w-]+" stage="" ip="<unknown>" method="" user="<none>" groups="<none>" as="<self>" asgroups="<lookup>" user-agent="" namespace="<none>" uri="" response="<deferred>"`, 53 }, 54 { 55 &auditinternal.Event{ 56 ResponseStatus: &metav1.Status{ 57 Code: 200, 58 }, 59 RequestURI: "/apis/rbac.authorization.k8s.io/v1/roles", 60 SourceIPs: []string{ 61 "127.0.0.1", 62 }, 63 RequestReceivedTimestamp: metav1.NewMicroTime(time.Now()), 64 AuditID: types.UID(uuid.New().String()), 65 Stage: auditinternal.StageRequestReceived, 66 Verb: "get", 67 User: authnv1.UserInfo{ 68 Username: "admin", 69 Groups: []string{ 70 "system:masters", 71 "system:authenticated", 72 }, 73 }, 74 UserAgent: "kube-admin", 75 ObjectRef: &auditinternal.ObjectReference{ 76 Namespace: "default", 77 }, 78 }, 79 `[\d\:\-\.\+TZ]+ AUDIT: id="[\w-]+" stage="RequestReceived" ip="127.0.0.1" method="get" user="admin" groups="\\"system:masters\\",\\"system:authenticated\\"" as="<self>" asgroups="<lookup>" user-agent="kube-admin" namespace="default" uri="/apis/rbac.authorization.k8s.io/v1/roles" response="200"`, 80 }, 81 { 82 &auditinternal.Event{ 83 AuditID: types.UID(uuid.New().String()), 84 Level: auditinternal.LevelMetadata, 85 ObjectRef: &auditinternal.ObjectReference{ 86 Resource: "foo", 87 APIVersion: "v1", 88 Subresource: "bar", 89 }, 90 }, 91 `[\d\:\-\.\+TZ]+ AUDIT: id="[\w-]+" stage="" ip="<unknown>" method="" user="<none>" groups="<none>" as="<self>" asgroups="<lookup>" user-agent="" namespace="<none>" uri="" response="<deferred>"`, 92 }, 93 } { 94 var buf bytes.Buffer 95 backend := NewBackend(&buf, FormatLegacy, auditv1.SchemeGroupVersion) 96 backend.ProcessEvents(test.event) 97 match, err := regexp.MatchString(test.expected, buf.String()) 98 if err != nil { 99 t.Errorf("Unexpected error matching line %v", err) 100 continue 101 } 102 if !match { 103 t.Errorf("Unexpected line of audit: %s", buf.String()) 104 } 105 } 106 } 107 108 func TestLogEventsJson(t *testing.T) { 109 for _, event := range []*auditinternal.Event{ 110 { 111 AuditID: types.UID(uuid.New().String()), 112 }, 113 { 114 ResponseStatus: &metav1.Status{ 115 Code: 200, 116 }, 117 RequestURI: "/apis/rbac.authorization.k8s.io/v1/roles", 118 SourceIPs: []string{ 119 "127.0.0.1", 120 }, 121 RequestReceivedTimestamp: metav1.NewMicroTime(time.Now().Truncate(time.Microsecond)), 122 StageTimestamp: metav1.NewMicroTime(time.Now().Truncate(time.Microsecond)), 123 AuditID: types.UID(uuid.New().String()), 124 Stage: auditinternal.StageRequestReceived, 125 Verb: "get", 126 User: authnv1.UserInfo{ 127 Username: "admin", 128 Groups: []string{ 129 "system:masters", 130 "system:authenticated", 131 }, 132 }, 133 ObjectRef: &auditinternal.ObjectReference{ 134 Namespace: "default", 135 }, 136 }, 137 { 138 AuditID: types.UID(uuid.New().String()), 139 Level: auditinternal.LevelMetadata, 140 ObjectRef: &auditinternal.ObjectReference{ 141 Resource: "foo", 142 APIVersion: "v1", 143 Subresource: "bar", 144 }, 145 }, 146 } { 147 versions := []schema.GroupVersion{auditv1.SchemeGroupVersion} 148 for _, version := range versions { 149 var buf bytes.Buffer 150 backend := NewBackend(&buf, FormatJson, version) 151 backend.ProcessEvents(event) 152 // decode events back and compare with the original one. 153 result := &auditinternal.Event{} 154 decoder := audit.Codecs.UniversalDecoder(version) 155 if err := runtime.DecodeInto(decoder, buf.Bytes(), result); err != nil { 156 t.Errorf("failed decoding buf: %s, apiVersion: %s", buf.String(), version) 157 continue 158 } 159 if !reflect.DeepEqual(event, result) { 160 t.Errorf("The result event should be the same with the original one, \noriginal: \n%#v\n result: \n%#v, apiVersion: %s", event, result, version) 161 } 162 } 163 } 164 }