diff --git a/staging/src/k8s.io/apiserver/pkg/audit/scheme.go b/staging/src/k8s.io/apiserver/pkg/audit/scheme.go index d72e394ec0..031759ec75 100644 --- a/staging/src/k8s.io/apiserver/pkg/audit/scheme.go +++ b/staging/src/k8s.io/apiserver/pkg/audit/scheme.go @@ -23,6 +23,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" + auditinternal "k8s.io/apiserver/pkg/apis/audit" "k8s.io/apiserver/pkg/apis/audit/v1" "k8s.io/apiserver/pkg/apis/audit/v1alpha1" "k8s.io/apiserver/pkg/apis/audit/v1beta1" @@ -36,4 +37,6 @@ func init() { utilruntime.Must(v1.AddToScheme(Scheme)) utilruntime.Must(v1alpha1.AddToScheme(Scheme)) utilruntime.Must(v1beta1.AddToScheme(Scheme)) + utilruntime.Must(auditinternal.AddToScheme(Scheme)) + utilruntime.Must(Scheme.SetVersionPriority(v1.SchemeGroupVersion, v1beta1.SchemeGroupVersion, v1alpha1.SchemeGroupVersion)) } diff --git a/test/e2e/auth/BUILD b/test/e2e/auth/BUILD index 68514b9e21..e8b93c2865 100644 --- a/test/e2e/auth/BUILD +++ b/test/e2e/auth/BUILD @@ -43,7 +43,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apiserver/pkg/apis/audit:go_default_library", - "//staging/src/k8s.io/apiserver/pkg/apis/audit/v1beta1:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/apis/audit/v1:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/serviceaccount:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/typed/certificates/v1beta1:go_default_library", diff --git a/test/e2e/auth/audit.go b/test/e2e/auth/audit.go index d6b07adfcd..3e1fb97a35 100644 --- a/test/e2e/auth/audit.go +++ b/test/e2e/auth/audit.go @@ -31,7 +31,7 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" auditinternal "k8s.io/apiserver/pkg/apis/audit" - "k8s.io/apiserver/pkg/apis/audit/v1beta1" + "k8s.io/apiserver/pkg/apis/audit/v1" clientset "k8s.io/client-go/kubernetes" restclient "k8s.io/client-go/rest" "k8s.io/kubernetes/test/e2e/framework" @@ -734,13 +734,13 @@ func expectEvents(f *framework.Framework, expectedEvents []utils.AuditEvent) { return false, err } defer stream.Close() - missing, err := utils.CheckAuditLines(stream, expectedEvents, v1beta1.SchemeGroupVersion) + missingReport, err := utils.CheckAuditLines(stream, expectedEvents, v1.SchemeGroupVersion) if err != nil { framework.Logf("Failed to observe audit events: %v", err) - } else if len(missing) > 0 { - framework.Logf("Events %#v not found!", missing) + } else if len(missingReport.MissingEvents) > 0 { + framework.Logf(missingReport.String()) } - return len(missing) == 0, nil + return len(missingReport.MissingEvents) == 0, nil }) framework.ExpectNoError(err, "after %v failed to observe audit events", pollingTimeout) } diff --git a/test/integration/master/audit_test.go b/test/integration/master/audit_test.go index e9ffff1c66..1b7662c357 100644 --- a/test/integration/master/audit_test.go +++ b/test/integration/master/audit_test.go @@ -214,12 +214,12 @@ func testAudit(t *testing.T, version string) { t.Fatalf("Unexpected error: %v", err) } defer stream.Close() - missing, err := utils.CheckAuditLines(stream, expectedEvents, versions[version]) + missingReport, err := utils.CheckAuditLines(stream, expectedEvents, versions[version]) if err != nil { t.Fatalf("Unexpected error: %v", err) } - if len(missing) > 0 { - t.Errorf("Failed to match all expected events, events %#v not found!", missing) + if len(missingReport.MissingEvents) > 0 { + t.Errorf(missingReport.String()) } } diff --git a/test/utils/audit.go b/test/utils/audit.go index 028829c794..3a9feea9c1 100644 --- a/test/utils/audit.go +++ b/test/utils/audit.go @@ -48,23 +48,54 @@ type AuditEvent struct { AuthorizeDecision string } +// MissingEventsReport provides an analysis if any events are missing +type MissingEventsReport struct { + FirstEventChecked *auditinternal.Event + LastEventChecked *auditinternal.Event + NumEventsChecked int + MissingEvents []AuditEvent +} + +// String returns a human readable string representation of the report +func (m *MissingEventsReport) String() string { + return fmt.Sprintf(`missing %d events + +- first event checked: %#v + +- last event checked: %#v + +- number of events checked: %d + +- missing events: %#v`, len(m.MissingEvents), m.FirstEventChecked, m.LastEventChecked, m.NumEventsChecked, m.MissingEvents) +} + // CheckAuditLines searches the audit log for the expected audit lines. -// if includeID is true the event ids will also be verified -func CheckAuditLines(stream io.Reader, expected []AuditEvent, version schema.GroupVersion) (missing []AuditEvent, err error) { +func CheckAuditLines(stream io.Reader, expected []AuditEvent, version schema.GroupVersion) (missingReport *MissingEventsReport, err error) { expectations := buildEventExpectations(expected) scanner := bufio.NewScanner(stream) - for scanner.Scan() { + + missingReport = &MissingEventsReport{ + MissingEvents: expected, + } + + var i int + for i = 0; scanner.Scan(); i++ { line := scanner.Text() + e := &auditinternal.Event{} decoder := audit.Codecs.UniversalDecoder(version) if err := runtime.DecodeInto(decoder, []byte(line), e); err != nil { - return expected, fmt.Errorf("failed decoding buf: %s, apiVersion: %s", line, version) + return missingReport, fmt.Errorf("failed decoding buf: %s, apiVersion: %s", line, version) } + if i == 0 { + missingReport.FirstEventChecked = e + } + missingReport.LastEventChecked = e event, err := testEventFromInternal(e) if err != nil { - return expected, err + return missingReport, err } // If the event was expected, mark it as found. @@ -73,15 +104,16 @@ func CheckAuditLines(stream io.Reader, expected []AuditEvent, version schema.Gro } } if err := scanner.Err(); err != nil { - return expected, err + return missingReport, err } - missing = findMissing(expectations) - return missing, nil + missingEvents := findMissing(expectations) + missingReport.MissingEvents = missingEvents + missingReport.NumEventsChecked = i + return missingReport, nil } // CheckAuditList searches an audit event list for the expected audit events. -// if includeID is true the event ids will also be verified func CheckAuditList(el auditinternal.EventList, expected []AuditEvent) (missing []AuditEvent, err error) { expectations := buildEventExpectations(expected) @@ -133,7 +165,6 @@ func buildEventExpectations(expected []AuditEvent) map[AuditEvent]bool { } // testEventFromInternal takes an internal audit event and returns a test event -// if includeID is true the event id will be included func testEventFromInternal(e *auditinternal.Event) (AuditEvent, error) { event := AuditEvent{ Level: e.Level,