diff --git a/deploy/crds/eventlogger.bakito.ch_eventloggers_crd.yaml b/deploy/crds/eventlogger.bakito.ch_eventloggers_crd.yaml index 6a449a6..f744af2 100644 --- a/deploy/crds/eventlogger.bakito.ch_eventloggers_crd.yaml +++ b/deploy/crds/eventlogger.bakito.ch_eventloggers_crd.yaml @@ -12,6 +12,97 @@ spec: scope: Namespaced subresources: status: {} + validation: + openAPIV3Schema: + description: EventLogger is the Schema for the eventloggers API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: EventLoggerSpec defines the desired state of EventLogger + properties: + eventTypes: + description: EventTypes the event types to log. If empty all events + are logged. + items: + type: string + minItems: 0 + type: array + uniqueItems: true + kinds: + description: Kinds the kinds to logg the events for + items: + description: Kind defines a kind to loge events for + properties: + eventTypes: + description: EventTypes the event types to log. If empty events + are logged as defined in spec. + items: + type: string + minItems: 0 + type: array + uniqueItems: true + matchingPatterns: + description: MatchingPatterns optional regex pattern that must + be contained in the message to be logged + items: + description: MatchingPattern defines a message matching pattern + properties: + pattern: + description: Pattern the match regex pattern + minLength: 3 + type: string + skip: + description: Skip skip the entry if matched + type: boolean + required: + - pattern + type: object + minItems: 0 + type: array + uniqueItems: true + name: + minLength: 3 + type: string + required: + - name + type: object + minItems: 1 + type: array + uniqueItems: true + required: + - kinds + type: object + status: + description: EventLoggerStatus defines the observed state of EventLogger + properties: + error: + description: Error + type: string + lastProcessed: + description: LastProcessed the timestamp the cr was last processed + type: string + operatorVersion: + description: OperatorVersion the version of the operator that processed + the cr + type: string + required: + - lastProcessed + - operatorVersion + type: object + required: + - spec + type: object version: v1 versions: - name: v1 diff --git a/pkg/apis/eventlogger/v1/eventlogger_types.go b/pkg/apis/eventlogger/v1/eventlogger_types.go index a9e38e5..f632aa8 100644 --- a/pkg/apis/eventlogger/v1/eventlogger_types.go +++ b/pkg/apis/eventlogger/v1/eventlogger_types.go @@ -38,6 +38,9 @@ type Kind struct { // +kubebuilder:validation:UniqueItems=true // +listType=set MatchingPatterns []string `json:"matchingPatterns,omitempty"` + + // SkipOnMatch skip the entry if matched + SkipOnMatch *bool `json:"skip,omitempty"` } // EventLoggerStatus defines the observed state of EventLogger diff --git a/pkg/apis/eventlogger/v1/zz_generated.deepcopy.go b/pkg/apis/eventlogger/v1/zz_generated.deepcopy.go index d7c85e4..c22eae7 100644 --- a/pkg/apis/eventlogger/v1/zz_generated.deepcopy.go +++ b/pkg/apis/eventlogger/v1/zz_generated.deepcopy.go @@ -126,6 +126,11 @@ func (in *Kind) DeepCopyInto(out *Kind) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.SkipOnMatch != nil { + in, out := &in.SkipOnMatch, &out.SkipOnMatch + *out = new(bool) + **out = **in + } return } diff --git a/pkg/apis/eventlogger/v1/zz_generated.openapi.go b/pkg/apis/eventlogger/v1/zz_generated.openapi.go index c2f921b..48c7979 100644 --- a/pkg/apis/eventlogger/v1/zz_generated.openapi.go +++ b/pkg/apis/eventlogger/v1/zz_generated.openapi.go @@ -11,10 +11,11 @@ import ( func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ - "./pkg/apis/eventlogger/v1.EventLogger": schema_pkg_apis_eventlogger_v1_EventLogger(ref), - "./pkg/apis/eventlogger/v1.EventLoggerSpec": schema_pkg_apis_eventlogger_v1_EventLoggerSpec(ref), - "./pkg/apis/eventlogger/v1.EventLoggerStatus": schema_pkg_apis_eventlogger_v1_EventLoggerStatus(ref), - "./pkg/apis/eventlogger/v1.Kind": schema_pkg_apis_eventlogger_v1_Kind(ref), + "github.com/bakito/k8s-event-logger-operator/pkg/apis/eventlogger/v1.EventLogger": schema_pkg_apis_eventlogger_v1_EventLogger(ref), + "github.com/bakito/k8s-event-logger-operator/pkg/apis/eventlogger/v1.EventLoggerSpec": schema_pkg_apis_eventlogger_v1_EventLoggerSpec(ref), + "github.com/bakito/k8s-event-logger-operator/pkg/apis/eventlogger/v1.EventLoggerStatus": schema_pkg_apis_eventlogger_v1_EventLoggerStatus(ref), + "github.com/bakito/k8s-event-logger-operator/pkg/apis/eventlogger/v1.Kind": schema_pkg_apis_eventlogger_v1_Kind(ref), + "github.com/bakito/k8s-event-logger-operator/pkg/apis/eventlogger/v1.MatchingPattern": schema_pkg_apis_eventlogger_v1_MatchingPattern(ref), } } @@ -46,12 +47,12 @@ func schema_pkg_apis_eventlogger_v1_EventLogger(ref common.ReferenceCallback) co }, "spec": { SchemaProps: spec.SchemaProps{ - Ref: ref("./pkg/apis/eventlogger/v1.EventLoggerSpec"), + Ref: ref("github.com/bakito/k8s-event-logger-operator/pkg/apis/eventlogger/v1.EventLoggerSpec"), }, }, "status": { SchemaProps: spec.SchemaProps{ - Ref: ref("./pkg/apis/eventlogger/v1.EventLoggerStatus"), + Ref: ref("github.com/bakito/k8s-event-logger-operator/pkg/apis/eventlogger/v1.EventLoggerStatus"), }, }, }, @@ -59,7 +60,7 @@ func schema_pkg_apis_eventlogger_v1_EventLogger(ref common.ReferenceCallback) co }, }, Dependencies: []string{ - "./pkg/apis/eventlogger/v1.EventLoggerSpec", "./pkg/apis/eventlogger/v1.EventLoggerStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + "github.com/bakito/k8s-event-logger-operator/pkg/apis/eventlogger/v1.EventLoggerSpec", "github.com/bakito/k8s-event-logger-operator/pkg/apis/eventlogger/v1.EventLoggerStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, } } @@ -82,7 +83,7 @@ func schema_pkg_apis_eventlogger_v1_EventLoggerSpec(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Ref: ref("./pkg/apis/eventlogger/v1.Kind"), + Ref: ref("github.com/bakito/k8s-event-logger-operator/pkg/apis/eventlogger/v1.Kind"), }, }, }, @@ -112,7 +113,7 @@ func schema_pkg_apis_eventlogger_v1_EventLoggerSpec(ref common.ReferenceCallback }, }, Dependencies: []string{ - "./pkg/apis/eventlogger/v1.Kind"}, + "github.com/bakito/k8s-event-logger-operator/pkg/apis/eventlogger/v1.Kind"}, } } @@ -195,8 +196,7 @@ func schema_pkg_apis_eventlogger_v1_Kind(ref common.ReferenceCallback) common.Op Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", + Ref: ref("github.com/bakito/k8s-event-logger-operator/pkg/apis/eventlogger/v1.MatchingPattern"), }, }, }, @@ -206,5 +206,35 @@ func schema_pkg_apis_eventlogger_v1_Kind(ref common.ReferenceCallback) common.Op Required: []string{"name"}, }, }, + Dependencies: []string{ + "github.com/bakito/k8s-event-logger-operator/pkg/apis/eventlogger/v1.MatchingPattern"}, + } +} + +func schema_pkg_apis_eventlogger_v1_MatchingPattern(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "MatchingPattern defines a message matching pattern", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "pattern": { + SchemaProps: spec.SchemaProps{ + Description: "Pattern the match regex pattern", + Type: []string{"string"}, + Format: "", + }, + }, + "skip": { + SchemaProps: spec.SchemaProps{ + Description: "Skip skip the entry if matched", + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + Required: []string{"pattern"}, + }, + }, } } diff --git a/pkg/controller/event/event_controller.go b/pkg/controller/event/event_controller.go index d7e3870..5b95938 100644 --- a/pkg/controller/event/event_controller.go +++ b/pkg/controller/event/event_controller.go @@ -43,17 +43,30 @@ type loggingPredicate struct { predicate.Funcs lastVersion string - kinds map[string]*eventloggerv1.Kind + kinds map[string]*filter } func (p *loggingPredicate) init(config *eventloggerv1.EventLoggerSpec) { - // TODO pre init regex pattern - p.kinds = make(map[string]*eventloggerv1.Kind) + p.kinds = make(map[string]*filter) for _, k := range config.Kinds { kp := &k - p.kinds[k.Name] = kp + p.kinds[k.Name] = &filter{ + matchingPatterns: []*regexp.Regexp{}, + } if kp.EventTypes == nil { - kp.EventTypes = config.EventTypes + p.kinds[k.Name].eventTypes = config.EventTypes + } else { + p.kinds[k.Name].eventTypes = kp.EventTypes + } + + if k.MatchingPatterns != nil { + if k.SkipOnMatch != nil && *k.SkipOnMatch { + p.kinds[k.Name].skipOnMatch = true + } + for _, mp := range k.MatchingPatterns { + + p.kinds[k.Name].matchingPatterns = append(p.kinds[k.Name].matchingPatterns, regexp.MustCompile(mp)) + } } } } @@ -95,29 +108,28 @@ func (p loggingPredicate) logEvent(mo metav1.Object, e runtime.Object) bool { } func (p *loggingPredicate) shouldLog(e *corev1.Event) bool { - k, ok := p.kinds[e.InvolvedObject.Kind] + f, ok := p.kinds[e.InvolvedObject.Kind] if !ok { return false } - if !p.contains(k.EventTypes, e.Type) { + if !p.contains(f.eventTypes, e.Type) { return false } - return p.matches(k.MatchingPatterns, e.Message) + return p.matches(f.matchingPatterns, f.skipOnMatch, e.Message) } -func (p *loggingPredicate) matches(list []string, val string) bool { - if len(list) == 0 { +func (p *loggingPredicate) matches(patterns []*regexp.Regexp, skipOnMatch bool, val string) bool { + if len(patterns) == 0 { return true } - for _, v := range list { - var p = regexp.MustCompile(v) + for _, p := range patterns { if p.MatchString(val) { - return true + return !skipOnMatch } } - return false + return skipOnMatch } func (p *loggingPredicate) contains(list []string, val string) bool { @@ -131,3 +143,9 @@ func (p *loggingPredicate) contains(list []string, val string) bool { } return false } + +type filter struct { + eventTypes []string + matchingPatterns []*regexp.Regexp + skipOnMatch bool +} diff --git a/pkg/controller/event/event_controller_test.go b/pkg/controller/event/event_controller_test.go index 154173b..500f2dc 100644 --- a/pkg/controller/event/event_controller_test.go +++ b/pkg/controller/event/event_controller_test.go @@ -1,6 +1,7 @@ package event import ( + "regexp" "testing" v1 "github.com/bakito/k8s-event-logger-operator/pkg/apis/eventlogger/v1" @@ -11,9 +12,9 @@ import ( func Test_matches(t *testing.T) { lp := &loggingPredicate{} - Assert(t, lp.matches([]string{"abc", "xyz"}, "abc")) - Assert(t, lp.matches([]string{"abc", "xyz"}, "^abc$")) - Assert(t, !lp.matches([]string{"abc", "xyz"}, "^ab$")) + Assert(t, lp.matches([]*regexp.Regexp{regexp.MustCompile("abc")}, false, "abc")) + Assert(t, lp.matches([]*regexp.Regexp{regexp.MustCompile("^abc$")}, false, "abc")) + Assert(t, !lp.matches([]*regexp.Regexp{regexp.MustCompile("^ab$")}, false, "abc")) } func Test_contains(t *testing.T) {