Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Traceectl to Tracee #4396

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 150 additions & 0 deletions cmd/traceectl/cmd/event.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package cmd

//TODO:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

import (
"context"

pb "github.com/aquasecurity/tracee/api/v1beta1"
"github.com/aquasecurity/tracee/cmd/traceectl/pkg/client"
"github.com/aquasecurity/tracee/cmd/traceectl/pkg/cmd/formatter"
"github.com/aquasecurity/tracee/cmd/traceectl/pkg/cmd/printer"
"github.com/spf13/cobra"
)

var eventFormatFlag string
var eventOutputFlag string

var eventCmd = &cobra.Command{
Use: "event [command]",
Short: "Event management for tracee",
Long: `Event Management for tracee
Let you enable and disable events in tracee.
Get descriptions of events and run them.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Get descriptions of events and run them.
Get descriptions of events.

`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
cmd.PrintErrln("Error: no event names provided. Please specify at least one event to enable.")
return
}
},
}

func init() {
eventCmd.AddCommand(listEventCmd)
eventCmd.AddCommand(describeEventCmd)
eventCmd.AddCommand(enableEventCmd)
eventCmd.AddCommand(disableEventCmd)

listEventCmd.Flags().StringVarP(&eventFormatFlag, "format", "f", formatter.FormatTable, "Output format (json|table|template) ")
listEventCmd.Flags().StringVarP(&eventOutputFlag, "output", "o", "stdout", "Output destination ")

describeEventCmd.Flags().StringVarP(&eventFormatFlag, "format", "f", formatter.FormatTable, "Output format (json|table|template) ")
describeEventCmd.Flags().StringVarP(&eventOutputFlag, "output", "o", "stdout", "Output destination ")
Comment on lines +39 to +43
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Output can be made global instead of per command

}

var listEventCmd = &cobra.Command{
Use: "list",
Short: "list events",
Long: `Lists all available event definitions (built-in and plugin-defined), providing a brief summary of each.`,
Args: cobra.MaximumNArgs(0),
Run: func(cmd *cobra.Command, args []string) {
listEvents(cmd, args)
},
}
var describeEventCmd = &cobra.Command{
Use: "describe <event_name>",
Short: "describe event",
Long: `Retrieves the detailed definition of a specific event, including its fields, types, and other metadata.`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
getEventDescriptions(cmd, args)
},
}
var enableEventCmd = &cobra.Command{
Use: "enable <event_name>",
Short: "enable event",
Long: `Enables capturing of a specific event type.`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
enableEvents(cmd, args[0])
},
}
var disableEventCmd = &cobra.Command{
Use: "disable <event_name>",
Short: "disable event",
Long: `Disables capturing of a specific event type.`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
disableEvents(cmd, args[0])
},
}

func listEvents(cmd *cobra.Command, args []string) {
var traceeClient client.ServiceClient
if err := traceeClient.NewServiceClient(serverInfo); err != nil {
cmd.PrintErrln("Error creating client: ", err)
return
}
defer traceeClient.CloseConnection()
response, err := traceeClient.GetEventDefinitions(context.Background(), &pb.GetEventDefinitionsRequest{EventNames: args})
if err != nil {
cmd.PrintErrln("Error getting event definitions: ", err)
return

}
format, err := formatter.New(eventFormatFlag, eventOutputFlag, cmd)
if err != nil {
cmd.PrintErrln("Error creating formatter: ", err)
return
}
printer.ListEvents(format, args, response)
}
func getEventDescriptions(cmd *cobra.Command, args []string) {
var traceeClient client.ServiceClient
if err := traceeClient.NewServiceClient(serverInfo); err != nil {
cmd.PrintErrln("Error creating client: ", err)
return
}
defer traceeClient.CloseConnection()
response, err := traceeClient.GetEventDefinitions(context.Background(), &pb.GetEventDefinitionsRequest{EventNames: args})
if err != nil {
cmd.PrintErrln("Error getting event definitions: ", err)
return

}
format, err := formatter.New(eventFormatFlag, eventOutputFlag, cmd)
if err != nil {
cmd.PrintErrln("Error creating formatter: ", err)
return
}
printer.DescribeEvent(format, args, response)
}
func enableEvents(cmd *cobra.Command, eventName string) {
var traceeClient client.ServiceClient
if err := traceeClient.NewServiceClient(serverInfo); err != nil {
cmd.PrintErrln("Error creating client: ", err)
return
}
_, err := traceeClient.EnableEvent(context.Background(), &pb.EnableEventRequest{Name: eventName})
if err != nil {
cmd.PrintErrln("Error enabling event:", err)
return
}
cmd.Printf("Enabled event: %s\n", eventName)
}

func disableEvents(cmd *cobra.Command, eventName string) {
var traceeClient client.ServiceClient
if err := traceeClient.NewServiceClient(serverInfo); err != nil {
cmd.PrintErrln("Error creating client: ", err)
return
}
_, err := traceeClient.DisableEvent(context.Background(), &pb.DisableEventRequest{Name: eventName})
if err != nil {
cmd.PrintErrln("Error disabling event:", err)
return
}
cmd.Printf("Disabled event: %s\n", eventName)

}
64 changes: 64 additions & 0 deletions cmd/traceectl/cmd/event_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package cmd

import (
"fmt"
"testing"

"github.com/aquasecurity/tracee/cmd/traceectl/pkg/cmd/test"
)

func TestEvent(t *testing.T) {
eventTests := []test.TestCase{
{
TestName: "event",
OutputSlice: []string{"event"},
ExpectedPrinter: nil,
ExpectedError: fmt.Errorf("requires at least 1 arg(s), only received 0"),
},
{
TestName: "events list",
OutputSlice: []string{"event", "list", "--format", "json"},
ExpectedPrinter: "",
ExpectedError: nil,
},
{
TestName: "No events describe",
OutputSlice: []string{"event", "describe", "--format", "json"},
ExpectedPrinter: nil,
ExpectedError: fmt.Errorf("accepts 1 arg(s), received 0"),
},
{
TestName: "describe <event_test1>",
OutputSlice: []string{"event", "describe", "event_test1", "--format", "json"},
ExpectedPrinter: "event_test1",
ExpectedError: nil,
},
{
TestName: "No events enable",
OutputSlice: []string{"event", "enable"},
ExpectedPrinter: nil,
ExpectedError: fmt.Errorf("accepts 1 arg(s), received 0"),
},
{
TestName: "enable event",
OutputSlice: []string{"event", "enable", "event"},
ExpectedPrinter: "Enabled event: event",
ExpectedError: nil,
},
{
TestName: "No disable events",
OutputSlice: []string{"event", "disable"},
ExpectedPrinter: nil,
ExpectedError: fmt.Errorf("accepts 1 arg(s), received 0"),
},
{
TestName: "disable event",
OutputSlice: []string{"event", "disable", "event"},
ExpectedPrinter: "Disabled event: event",
ExpectedError: nil,
},
}
for _, testCase := range eventTests {
t.Run(testCase.TestName, func(t *testing.T) { test.TestCommand(t, testCase, rootCmd) })
}
}
106 changes: 106 additions & 0 deletions cmd/traceectl/cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package cmd

import (
"context"
"os"

pb "github.com/aquasecurity/tracee/api/v1beta1"
"github.com/aquasecurity/tracee/cmd/traceectl/pkg/client"

"github.com/spf13/cobra"
)

var formatFlag string
var outputFlag string
var serverFlag string
var (
serverInfo client.ServerInfo = client.ServerInfo{
ConnectionType: client.PROTOCOL_UNIX,
ADDR: client.SOCKET,
}

rootCmd = &cobra.Command{
Use: "traceectl [flags] [command]",
Short: "TraceeCtl is a CLI tool for tracee",
Long: "TraceeCtl is the client for the tracee API server.",
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
},
}
)

func init() {
rootCmd.AddCommand(streamCmd)
rootCmd.AddCommand(eventCmd)
rootCmd.AddCommand(metricsCmd)
rootCmd.AddCommand(versionCmd)

rootCmd.PersistentFlags().StringVar(&serverInfo.ADDR, "server", client.SOCKET, `Server connection path or address.
for unix socket <socket_path> (default: /tmp/tracee.sock)
for tcp <IP:Port>`)

}

var metricsCmd = &cobra.Command{
Use: "metrics [--output <format>]",
Short: "Display Tracee metrics",
Long: "Retrieves metrics about Tracee's performance and resource usage.",
Run: func(cmd *cobra.Command, args []string) {
displayMetrics(cmd, args)
},
}

var versionCmd = &cobra.Command{
Use: "version",
Short: "Display the version of tracee",
Long: "This is the version of tracee application you connected to",
Run: func(cmd *cobra.Command, args []string) {
displayVersion(cmd, args)
},
}

func Execute() {
if err := rootCmd.Execute(); err != nil {
os.Exit(1)
}
}

func displayMetrics(cmd *cobra.Command, _ []string) {
var traceeClient client.DiagnosticClient
if err := traceeClient.NewDiagnosticClient(serverInfo); err != nil {
cmd.PrintErrln("Error creating client: ", err)
return
}
defer traceeClient.CloseConnection()
response, err := traceeClient.GetMetrics(context.Background(), &pb.GetMetricsRequest{})
if err != nil {
cmd.PrintErrln("Error getting metrics: ", err)
return
}
cmd.Println("EventCount:", response.EventCount)
cmd.Println("EventsFiltered:", response.EventsFiltered)
cmd.Println("NetCapCount:", response.NetCapCount)
cmd.Println("BPFLogsCount:", response.BPFLogsCount)
cmd.Println("ErrorCount:", response.ErrorCount)
cmd.Println("LostEvCount:", response.LostEvCount)
cmd.Println("LostWrCount:", response.LostWrCount)
cmd.Println("LostNtCapCount:", response.LostNtCapCount)
cmd.Println("LostBPFLogsCount:", response.LostBPFLogsCount)
}

func displayVersion(cmd *cobra.Command, _ []string) {
var traceeClient client.ServiceClient
if err := traceeClient.NewServiceClient(serverInfo); err != nil {
cmd.PrintErrln("Error creating client: ", err)
return
}
defer traceeClient.CloseConnection()
response, err := traceeClient.GetVersion(context.Background(), &pb.GetVersionRequest{})

if err != nil {
cmd.PrintErrln("Error getting version: ", err)
return
} else {
cmd.Println("Version: ", response.Version)
}
}
53 changes: 53 additions & 0 deletions cmd/traceectl/cmd/stream.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package cmd

import (
pb "github.com/aquasecurity/tracee/api/v1beta1"
"github.com/aquasecurity/tracee/cmd/traceectl/pkg/client"
"github.com/aquasecurity/tracee/cmd/traceectl/pkg/cmd/formatter"
"github.com/aquasecurity/tracee/cmd/traceectl/pkg/cmd/printer"

"github.com/spf13/cobra"
)

var streamFormatFlag string
var streamOutputFlag string
var streamCmd = &cobra.Command{
Use: "stream [policies...]",
Short: "Stream events from tracee",
Long: `Stream Management:

`,
Run: func(cmd *cobra.Command, args []string) {
stream(cmd, args)
},
}

func init() {

streamCmd.Flags().StringVarP(&streamFormatFlag, "format", "f", formatter.FormatJSON, "Output format (json|table|template)")
streamCmd.Flags().StringVarP(&streamOutputFlag, "output", "o", "stdout", "Output destination ")
}

func stream(cmd *cobra.Command, args []string) {

var traceeClient client.ServiceClient
err := traceeClient.NewServiceClient(serverInfo)
if err != nil {
cmd.PrintErrln("Error creating client: ", err)
return
}
defer traceeClient.CloseConnection()
req := &pb.StreamEventsRequest{Policies: args}
stream, err := traceeClient.StreamEvents(cmd.Context(), req)
if err != nil {
cmd.PrintErrln("Error calling Stream: ", err)
return
}
format, err := formatter.New(streamFormatFlag, streamOutputFlag, cmd)
if err != nil {
cmd.PrintErrln("Error creating formatter: ", err)
return
}
printer.StreamEvents(format, args, stream)

}
Loading