mirror of https://github.com/k3s-io/k3s
Audit test utils fix (#74276)
* changes audit e2e event version scheme; adds internal audit to common audit scheme; removes unneeded comments * add more detail to audit missing events in e2e/integration tests * adds version priority to audit scheme; updates commentpull/564/head
parent
9e53b85d28
commit
9e4f8d6fae
|
@ -23,6 +23,7 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
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/v1"
|
||||||
"k8s.io/apiserver/pkg/apis/audit/v1alpha1"
|
"k8s.io/apiserver/pkg/apis/audit/v1alpha1"
|
||||||
"k8s.io/apiserver/pkg/apis/audit/v1beta1"
|
"k8s.io/apiserver/pkg/apis/audit/v1beta1"
|
||||||
|
@ -36,4 +37,6 @@ func init() {
|
||||||
utilruntime.Must(v1.AddToScheme(Scheme))
|
utilruntime.Must(v1.AddToScheme(Scheme))
|
||||||
utilruntime.Must(v1alpha1.AddToScheme(Scheme))
|
utilruntime.Must(v1alpha1.AddToScheme(Scheme))
|
||||||
utilruntime.Must(v1beta1.AddToScheme(Scheme))
|
utilruntime.Must(v1beta1.AddToScheme(Scheme))
|
||||||
|
utilruntime.Must(auditinternal.AddToScheme(Scheme))
|
||||||
|
utilruntime.Must(Scheme.SetVersionPriority(v1.SchemeGroupVersion, v1beta1.SchemeGroupVersion, v1alpha1.SchemeGroupVersion))
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ go_library(
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_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/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: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/apiserver/pkg/authentication/serviceaccount:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes: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",
|
"//staging/src/k8s.io/client-go/kubernetes/typed/certificates/v1beta1:go_default_library",
|
||||||
|
|
|
@ -31,7 +31,7 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
auditinternal "k8s.io/apiserver/pkg/apis/audit"
|
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"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
@ -734,13 +734,13 @@ func expectEvents(f *framework.Framework, expectedEvents []utils.AuditEvent) {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
missing, err := utils.CheckAuditLines(stream, expectedEvents, v1beta1.SchemeGroupVersion)
|
missingReport, err := utils.CheckAuditLines(stream, expectedEvents, v1.SchemeGroupVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
framework.Logf("Failed to observe audit events: %v", err)
|
framework.Logf("Failed to observe audit events: %v", err)
|
||||||
} else if len(missing) > 0 {
|
} else if len(missingReport.MissingEvents) > 0 {
|
||||||
framework.Logf("Events %#v not found!", missing)
|
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)
|
framework.ExpectNoError(err, "after %v failed to observe audit events", pollingTimeout)
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,12 +214,12 @@ func testAudit(t *testing.T, version string) {
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
missing, err := utils.CheckAuditLines(stream, expectedEvents, versions[version])
|
missingReport, err := utils.CheckAuditLines(stream, expectedEvents, versions[version])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
if len(missing) > 0 {
|
if len(missingReport.MissingEvents) > 0 {
|
||||||
t.Errorf("Failed to match all expected events, events %#v not found!", missing)
|
t.Errorf(missingReport.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,23 +48,54 @@ type AuditEvent struct {
|
||||||
AuthorizeDecision string
|
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.
|
// 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) (missingReport *MissingEventsReport, err error) {
|
||||||
func CheckAuditLines(stream io.Reader, expected []AuditEvent, version schema.GroupVersion) (missing []AuditEvent, err error) {
|
|
||||||
expectations := buildEventExpectations(expected)
|
expectations := buildEventExpectations(expected)
|
||||||
|
|
||||||
scanner := bufio.NewScanner(stream)
|
scanner := bufio.NewScanner(stream)
|
||||||
for scanner.Scan() {
|
|
||||||
|
missingReport = &MissingEventsReport{
|
||||||
|
MissingEvents: expected,
|
||||||
|
}
|
||||||
|
|
||||||
|
var i int
|
||||||
|
for i = 0; scanner.Scan(); i++ {
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
|
|
||||||
e := &auditinternal.Event{}
|
e := &auditinternal.Event{}
|
||||||
decoder := audit.Codecs.UniversalDecoder(version)
|
decoder := audit.Codecs.UniversalDecoder(version)
|
||||||
if err := runtime.DecodeInto(decoder, []byte(line), e); err != nil {
|
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)
|
event, err := testEventFromInternal(e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return expected, err
|
return missingReport, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the event was expected, mark it as found.
|
// 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 {
|
if err := scanner.Err(); err != nil {
|
||||||
return expected, err
|
return missingReport, err
|
||||||
}
|
}
|
||||||
|
|
||||||
missing = findMissing(expectations)
|
missingEvents := findMissing(expectations)
|
||||||
return missing, nil
|
missingReport.MissingEvents = missingEvents
|
||||||
|
missingReport.NumEventsChecked = i
|
||||||
|
return missingReport, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckAuditList searches an audit event list for the expected audit events.
|
// 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) {
|
func CheckAuditList(el auditinternal.EventList, expected []AuditEvent) (missing []AuditEvent, err error) {
|
||||||
expectations := buildEventExpectations(expected)
|
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
|
// 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) {
|
func testEventFromInternal(e *auditinternal.Event) (AuditEvent, error) {
|
||||||
event := AuditEvent{
|
event := AuditEvent{
|
||||||
Level: e.Level,
|
Level: e.Level,
|
||||||
|
|
Loading…
Reference in New Issue