Skip to content

Commit

Permalink
tetra: Add CEL filter to the CLI
Browse files Browse the repository at this point in the history
Add the ability to filter events using CEL expressions, for example:

  # tetra getevents --cel-expression "process_exec.process.binary == '/bin/sh'"

Signed-off-by: Kevin Conner <[email protected]>
  • Loading branch information
knrc committed Dec 6, 2024
1 parent 93fb03c commit 4d81dac
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 1 deletion.
5 changes: 5 additions & 0 deletions cmd/tetra/getevents/getevents.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type Opts struct {
StackTraces bool
ImaHash bool
PolicyNames []string
CelExpression []string
}

var Options Opts
Expand Down Expand Up @@ -85,6 +86,9 @@ var GetFilter = func() *tetragon.Filter {
if len(Options.PolicyNames) > 0 {
filter.PolicyNames = Options.PolicyNames
}
if len(Options.CelExpression) > 0 {
filter.CelExpression = Options.CelExpression
}

return &filter
}
Expand Down Expand Up @@ -222,5 +226,6 @@ redirection of events to the stdin. Examples:
flags.BoolVar(&Options.StackTraces, "stack-traces", true, "Include stack traces in compact output")
flags.BoolVar(&Options.ImaHash, "ima-hash", true, "Include ima hashes in compact output")
flags.StringSliceVar(&Options.PolicyNames, "policy-names", nil, "Get events by tracing policy names")
flags.StringSliceVar(&Options.CelExpression, "cel-expression", nil, "Get events satisfying the CEL expression")
return &cmd
}
21 changes: 21 additions & 0 deletions cmd/tetra/getevents/getevents_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,25 @@ func Test_GetEvents_FilterFields(t *testing.T) {
assert.NotEmpty(t, res.GetProcessExec().Parent)
}
})

t.Run("FilterCelExpression", func(t *testing.T) {
testutils.MockPipedFile(t, testutils.RepoRootPath("testdata/events.json"))
cmd := New()
cmd.SetArgs([]string{"--cel-expression", "process_exec.process.pod.pod_labels['class'] == 'deathstar'"})
output := testutils.RedirectStdoutExecuteCmd(t, cmd)
// remove last trailing newline for splitting
output = bytes.TrimSpace(output)
lines := bytes.Split(output, []byte("\n"))
assert.Equal(t, 2, len(lines))
for _, line := range lines {
var res tetragon.GetEventsResponse
err := json.Unmarshal(line, &res)
if err != nil {
t.Fatal(err)
}
class, ok := res.GetProcessExec().Process.Pod.PodLabels["class"]
assert.True(t, ok, "Class label should be present")
assert.Equal(t, class, "deathstar")
}
})
}
2 changes: 2 additions & 0 deletions pkg/filters/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
hubbleFilters "github.com/cilium/cilium/pkg/hubble/filters"
"github.com/cilium/tetragon/api/v1/tetragon"
"github.com/cilium/tetragon/api/v1/tetragon/codegen/helpers"
"github.com/sirupsen/logrus"
)

// ParseFilterList parses a list of process filters in JSON format into protobuf messages.
Expand Down Expand Up @@ -95,6 +96,7 @@ var Filters = []OnBuildFilter{
&PodRegexFilter{},
&PolicyNamesFilter{},
&CapsFilter{},
NewCELExpressionFilter(logrus.New()),
}

func GetProcess(event *v1.Event) *tetragon.Process {
Expand Down
4 changes: 3 additions & 1 deletion pkg/filters/filters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ func TestParseFilterList(t *testing.T) {
{"pid_set":[1]}
{"event_set":["PROCESS_EXEC", "PROCESS_EXIT", "PROCESS_KPROBE", "PROCESS_TRACEPOINT"]}
{"arguments_regex":["^--version$","^-a -b -c$"]}
{"capabilities": {"effective": {"all": ["CAP_BPF", "CAP_SYS_ADMIN"]}}}`
{"capabilities": {"effective": {"all": ["CAP_BPF", "CAP_SYS_ADMIN"]}}}
{"cel_expression": ["process_exec.process.bad_field_name == 'curl'"]}`
filterProto, err := ParseFilterList(f, true)
assert.NoError(t, err)
if diff := cmp.Diff(
Expand All @@ -50,6 +51,7 @@ func TestParseFilterList(t *testing.T) {
All: []tetragon.CapabilitiesType{tetragon.CapabilitiesType_CAP_BPF, tetragon.CapabilitiesType_CAP_SYS_ADMIN},
},
}},
{CelExpression: []string{"process_exec.process.bad_field_name == 'curl'"}},
},
filterProto,
cmpopts.IgnoreUnexported(tetragon.Filter{}),
Expand Down

0 comments on commit 4d81dac

Please sign in to comment.