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  }