diff --git a/cmd/traceectl/pkg/cmd/formatter/JSONFormatter.go b/cmd/traceectl/pkg/cmd/formatter/JSONFormatter.go deleted file mode 100644 index da04a61068bb..000000000000 --- a/cmd/traceectl/pkg/cmd/formatter/JSONFormatter.go +++ /dev/null @@ -1,17 +0,0 @@ -package formatter - -import ( - pb "github.com/aquasecurity/tracee/api/v1beta1" -) - -func (f *Formatter) PrintStreamJSON(event *pb.Event) { - f.CMD.Printf("%s", event.String()) -} - -func (f *Formatter) PrintEventListJSON(list *pb.GetEventDefinitionsResponse) { - f.CMD.Printf("%s", list.String()) -} - -func (f *Formatter) PrintEventDescriptionJSON(description *pb.GetEventDefinitionsResponse) { - f.CMD.Printf("%s", description.String()) -} diff --git a/cmd/traceectl/pkg/cmd/formatter/TableFormatter.go b/cmd/traceectl/pkg/cmd/formatter/TableFormatter.go deleted file mode 100644 index 53b787b34580..000000000000 --- a/cmd/traceectl/pkg/cmd/formatter/TableFormatter.go +++ /dev/null @@ -1,128 +0,0 @@ -package formatter - -import ( - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/aquasecurity/table" - pb "github.com/aquasecurity/tracee/api/v1beta1" - "github.com/spf13/cobra" -) - -func (f *Formatter) PrintSteamTableHeaders() { - f.CMD.Printf("%-15s %-25s %-15s %-15s %s\n", - "TIME", - "EVENT NAME", - "POLICIES", - "PID", - "DATA", - ) -} -func (f *Formatter) PrintStreamTableRow(event *pb.Event) { - timestamp := event.Timestamp.AsTime().Format("15:04:05.000") - - f.CMD.Printf("%-15s %-25s %-15s %-15s %s\n", - timestamp, - event.Name, - strings.Join(event.Policies.Matched, ","), - fmt.Sprintf("%d", event.Context.Process.Pid.Value), - getEventData(event.Data), - ) - -} -func getEventData(data []*pb.EventValue) string { - var result []string - for _, ev := range data { - result = append(result, getEventName(ev)+getEventValue(ev)) - } - return strings.Join(result, ", ") -} -func getEventName(ev *pb.EventValue) string { - return strings.ToUpper(ev.Name[0:1]) + ev.Name[1:] + ": " -} -func getEventValue(ev *pb.EventValue) string { - switch v := ev.Value.(type) { - case *pb.EventValue_Int32: - return fmt.Sprintf("%d", v.Int32) - case *pb.EventValue_Int64: - return fmt.Sprintf("%d", v.Int64) - case *pb.EventValue_UInt32: - return fmt.Sprintf("%d", v.UInt32) - case *pb.EventValue_UInt64: - return fmt.Sprintf("%d", v.UInt64) - case *pb.EventValue_Str: - return v.Str - case *pb.EventValue_Bytes: - return fmt.Sprintf("%x", v.Bytes) - case *pb.EventValue_Bool: - return fmt.Sprintf("%t", v.Bool) - case *pb.EventValue_StrArray: - return strings.Join(v.StrArray.Value, ", ") - case *pb.EventValue_Int32Array: - return fmt.Sprintf("%v", v.Int32Array.Value) - case *pb.EventValue_UInt64Array: - return fmt.Sprintf("%v", v.UInt64Array.Value) - default: - return "unknown" - } -} - -func (f *Formatter) PrintEventListTable(response *pb.GetEventDefinitionsResponse) *table.Table { - tbl := createTable(f) - tbl.SetHeaders("ID", "Name", "Version", "Tags") - for _, event := range response.Definitions { - tbl.AddRow( - fmt.Sprintf("%d", event.Id), - event.Name, - fmt.Sprintf("%d.%d.%d", event.Version.Major, event.Version.Minor, event.Version.Patch), - strings.Join(event.Tags, ", "), - ) - - } - return tbl -} - -func (f *Formatter) PrintEventDescriptionTable(response *pb.GetEventDefinitionsResponse) *table.Table { - tbl := createTable(f) - tbl.SetHeaders("ID", "Name", "Version", "Tags", "Description") - for _, event := range response.Definitions { - tbl.AddRow( - fmt.Sprintf("%d", event.Id), - event.Name, - fmt.Sprintf("%d.%d.%d", event.Version.Major, event.Version.Minor, event.Version.Patch), - strings.Join(event.Tags, ", "), - event.Description, - ) - - } - return tbl -} - -func createTable(f *Formatter) *table.Table { - if (f.Output != "") && (f.Output != "stdout") { - if f.Output == "" || strings.TrimSpace(f.Output) == "" { - fmt.Errorf("Output file path is empty or invalid") - return nil - } - dir := filepath.Dir(f.Output) - if err := os.MkdirAll(dir, 0755); err != nil { - fmt.Errorf("failed to create directories for output file: %v", err) - return nil - } - file, err := os.Create(f.Output) - if err != nil { - fmt.Errorf("failed to open output file: %v", err) - return nil - } - tbl := table.New(file) - f.CMD.PersistentPostRun = func(cmd *cobra.Command, args []string) { - file.Close() - } - return tbl - } else { - return table.New(os.Stdout) - } - -} diff --git a/cmd/traceectl/pkg/cmd/formatter/formatter.go b/cmd/traceectl/pkg/cmd/formatter/formatter.go index 72b41d51ba61..dcd4541cf671 100644 --- a/cmd/traceectl/pkg/cmd/formatter/formatter.go +++ b/cmd/traceectl/pkg/cmd/formatter/formatter.go @@ -2,9 +2,6 @@ package formatter import ( "fmt" - "os" - "path/filepath" - "strings" "github.com/spf13/cobra" ) @@ -12,57 +9,34 @@ import ( const ( FormatJSON = "json" FormatTable = "table" - FormatGoTpl = "gotemplate" ) -var SupportedFormats = []string{FormatJSON, FormatTable, FormatGoTpl} +var SupportedFormats = []string{FormatJSON, FormatTable} type Formatter struct { - Format string - Output string - CMD *cobra.Command + format string + cmd *cobra.Command + paddings map[int][]int } -func New(format string, output string, cmd *cobra.Command) (*Formatter, error) { - if !containsFormat(format) { +func NewFormatter(format string, cmd *cobra.Command) (*Formatter, error) { + switch format { + case FormatJSON: + return &Formatter{ + format: format, + cmd: cmd, + }, nil + case FormatTable: + //add padding for table + return &Formatter{ + format: format, + cmd: cmd, + paddings: map[int][]int{ + 4: {20, 15, 15, 20}, // Padding for 4 columns + 5: {15, 10, 20, 15, 10}, // Padding for 5 columns + }, + }, nil + default: return nil, fmt.Errorf("format %s is not supported", format) } - if err := initOutput(cmd, output); err != nil { - return nil, err - } - return &Formatter{ - Format: format, - Output: output, - CMD: cmd, - }, nil -} -func containsFormat(format string) bool { - for _, f := range SupportedFormats { - if f == format { - return true - } - } - return false -} -func initOutput(cmd *cobra.Command, output string) error { - if (output != "") && (output != "stdout") { - if output == "" || strings.TrimSpace(output) == "" { - return fmt.Errorf("output file path is empty or invalid") - } - dir := filepath.Dir(output) - if err := os.MkdirAll(dir, 0755); err != nil { - return fmt.Errorf("failed to create directories for output file: %v", err) - } - file, err := os.Create(output) - if err != nil { - return fmt.Errorf("failed to open output file: %v", err) - } - - cmd.SetOut(file) - cmd.SetErr(file) - cmd.PersistentPostRun = func(cmd *cobra.Command, args []string) { - file.Close() - } - } - return nil } diff --git a/cmd/traceectl/pkg/cmd/formatter/tableFormat.go b/cmd/traceectl/pkg/cmd/formatter/tableFormat.go new file mode 100644 index 000000000000..ef04c88efc1f --- /dev/null +++ b/cmd/traceectl/pkg/cmd/formatter/tableFormat.go @@ -0,0 +1,47 @@ +package formatter + +// PrintTableHeaders prints table headers with padding based on their length. +func (f *Formatter) PrintTableHeaders(headers []string) { + switch len(headers) { + case 4: + f.cmd.Printf("%-20s %-15s %-15s %-20s\n", + headers[0], + headers[1], + headers[2], + headers[3], + ) + case 5: + f.cmd.Printf("%-15s %-10s %-20s %-15s %-10s\n", + headers[0], + headers[1], + headers[2], + headers[3], + headers[4], + ) + default: + f.cmd.Println("Error: Unsupported number of headers.") + } +} + +// PrintTableRow prints a single row with padding matching the header format. +func (f *Formatter) PrintTableRow(row []string) { + switch len(row) { + case 4: + f.cmd.Printf("%-20s %-15s %-15s %-20s\n", + row[0], + row[1], + row[2], + row[3], + ) + case 5: + f.cmd.Printf("%-15s %-10s %-20s %-15s %-10s\n", + row[0], + row[1], + row[2], + row[3], + row[4], + ) + default: + f.cmd.Println("Error: Unsupported number of columns in row.") + } +}