11package derive
22
33import (
4- "fmt"
5-
64 "github.com/aquasecurity/tracee/pkg/events"
75 "github.com/aquasecurity/tracee/types/trace"
86)
97
10- // Use as static variable for testability reasons
11- var getEventDefFunc = events .Definitions .Get
8+ // deriveFunction is a function prototype for a function that receives an event as
9+ // argument and may produce a new event if relevant.
10+ // It returns a derived or empty event, depending on successful derivation,
11+ // and an error if one occurred.
12+ type deriveFunction func (trace.Event ) ([]trace.Event , []error )
13+
14+ // Table defines a table between events and events they can be derived into corresponding to a deriveFunction
15+ // The Enabled flag is used in order to skip derivation of unneeded events.
16+ type Table map [events.ID ]map [events.ID ]struct {
17+ DeriveFunction deriveFunction
18+ Enabled bool
19+ }
1220
13- // eventSkeleton is a struct for the necessary information from an event definition to create the derived event
14- type eventSkeleton struct {
21+ // DeriveEvent takes a trace.Event and checks if it can derive additional events from it as defined by a derivationTable.
22+ func DeriveEvent (event trace.Event , derivationTable Table ) ([]trace.Event , []error ) {
23+ derivatives := []trace.Event {}
24+ errors := []error {}
25+ deriveFns := derivationTable [events .ID (event .EventID )]
26+ for id , deriveFn := range deriveFns {
27+ if deriveFn .Enabled {
28+ derivative , errs := deriveFn .DeriveFunction (event )
29+ for _ , err := range errs {
30+ errors = append (errors , deriveError (id , err ))
31+ }
32+ derivatives = append (derivatives , derivative ... )
33+ }
34+ }
35+
36+ return derivatives , errors
37+ }
38+
39+ // deriveBase is a struct for the necessary information from an event definition to create a derived event
40+ type deriveBase struct {
1541 Name string
1642 ID int
1743 Params []trace.ArgMeta
1844}
1945
20- // deriveArgsFunction is the main logic of the derived event .
21- // It checks the event and produce the arguments of the derived event.
22- // If no event is derived, then the returned args should equal ` nil` .
46+ // deriveArgsFunction defines the logic of deriving an Event .
47+ // It checks the base event and produces arguments for the derived event.
48+ // If an event can't be derived, the returned arguments should be nil.
2349type deriveArgsFunction func (event trace.Event ) ([]interface {}, error )
2450
25- // singleEventDeriveFunc create an events.DeriveFunction to generate a single derive trace.Event.
26- // The event will be created using the original event information, the ID given and the arguments given.
27- // The order of the arguments given will match the order in the event definition, so make sure the order match
28- // the order of the params in the events.event struct of the event under events.Definitions .
29- // If the arguments given is nil, than no event will be derived.
30- func singleEventDeriveFunc (id events.ID , deriveArgsFunc deriveArgsFunction ) events. DeriveFunction {
31- skeleton := makeEventSkeleton (id )
51+ // deriveSingleEvent create an deriveFunction which generates a single derive trace.Event.
52+ // The event will be created using the original event information, the ID given and resulting
53+ // arguments from the function.
54+ // The arguments will be inserted in order, so they should match the resulting definition argument order .
55+ // If the returned arguments are nil - no event will be derived.
56+ func deriveSingleEvent (id events.ID , deriveArgs deriveArgsFunction ) deriveFunction {
57+ skeleton := makeDeriveBase (id )
3258 return func (event trace.Event ) ([]trace.Event , []error ) {
33- args , err := deriveArgsFunc (event )
59+ args , err := deriveArgs (event )
3460 if err != nil {
3561 return nil , []error {err }
3662 }
3763 if args == nil {
3864 return []trace.Event {}, nil
3965 }
40- de , err := newEvent (& event , skeleton , args )
66+ de , err := buildDerivedEvent (& event , skeleton , args )
4167 if err != nil {
4268 return []trace.Event {}, []error {err }
4369 }
4470 return []trace.Event {de }, nil
4571 }
4672}
4773
48- // newEvent create a new derived event from given event values, adjusted by the derived event skeleton meta-data.
74+ // buildDerivedEvent create a new derived event from given event values, adjusted by the derived event skeleton meta-data.
4975// This method enables using the context of the base event, but with the new arguments and meta-data of the derived one.
50- func newEvent (baseEvent * trace.Event , skeleton eventSkeleton , argsValues []interface {}) (trace.Event , error ) {
76+ func buildDerivedEvent (baseEvent * trace.Event , skeleton deriveBase , argsValues []interface {}) (trace.Event , error ) {
5177 if len (skeleton .Params ) != len (argsValues ) {
52- return trace.Event {}, fmt . Errorf ( "error while building derived event '%s' - expected %d arguments but given %d" , skeleton .Name , len (skeleton .Params ), len (argsValues ))
78+ return trace.Event {}, unexpectedArgCountError ( skeleton .Name , len (skeleton .Params ), len (argsValues ))
5379 }
5480 de := * baseEvent
5581 de .EventID = skeleton .ID
@@ -64,9 +90,12 @@ func newEvent(baseEvent *trace.Event, skeleton eventSkeleton, argsValues []inter
6490 return de , nil
6591}
6692
67- func makeEventSkeleton (eventID events.ID ) eventSkeleton {
68- def := getEventDefFunc (eventID )
69- return eventSkeleton {
93+ // store as static variable for mocking in tests
94+ var getEventDefinition = events .Definitions .Get
95+
96+ func makeDeriveBase (eventID events.ID ) deriveBase {
97+ def := getEventDefinition (eventID )
98+ return deriveBase {
7099 Name : def .Name ,
71100 ID : int (eventID ),
72101 Params : def .Params ,
0 commit comments