Skip to content

Commit

Permalink
cscli refact: extract table wrapper to own package (#3105)
Browse files Browse the repository at this point in the history
* cscli refact: extract table wrapper to own package

* lint
  • Loading branch information
mmetc authored Jul 4, 2024
1 parent 9cebcf9 commit 90e3299
Show file tree
Hide file tree
Showing 22 changed files with 218 additions and 200 deletions.
14 changes: 9 additions & 5 deletions cmd/crowdsec-cli/alerts.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

"github.com/crowdsecurity/go-cs-lib/maptools"

"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/cstable"
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
Expand Down Expand Up @@ -54,7 +55,8 @@ func DecisionsFromAlert(alert *models.Alert) string {
}

func (cli *cliAlerts) alertsToTable(alerts *models.GetAlertsResponse, printMachine bool) error {
switch cli.cfg().Cscli.Output {
cfg := cli.cfg()
switch cfg.Cscli.Output {
case "raw":
csvwriter := csv.NewWriter(os.Stdout)
header := []string{"id", "scope", "value", "reason", "country", "as", "decisions", "created_at"}
Expand Down Expand Up @@ -104,7 +106,7 @@ func (cli *cliAlerts) alertsToTable(alerts *models.GetAlertsResponse, printMachi
return nil
}

alertsTable(color.Output, alerts, printMachine)
alertsTable(color.Output, cfg.Cscli.Color, alerts, printMachine)
}

return nil
Expand Down Expand Up @@ -138,15 +140,17 @@ func (cli *cliAlerts) displayOneAlert(alert *models.Alert, withDetail bool) erro
return err
}

alertDecisionsTable(color.Output, alert)
cfg := cli.cfg()

alertDecisionsTable(color.Output, cfg.Cscli.Color, alert)

if len(alert.Meta) > 0 {
fmt.Printf("\n - Context :\n")
sort.Slice(alert.Meta, func(i, j int) bool {
return alert.Meta[i].Key < alert.Meta[j].Key
})

table := newTable(color.Output)
table := cstable.New(color.Output, cfg.Cscli.Color)
table.SetRowLines(false)
table.SetHeaders("Key", "Value")

Expand All @@ -171,7 +175,7 @@ func (cli *cliAlerts) displayOneAlert(alert *models.Alert, withDetail bool) erro
fmt.Printf("\n - Events :\n")

for _, event := range alert.Events {
alertEventTable(color.Output, event)
alertEventTable(color.Output, cfg.Cscli.Color, event)
}
}

Expand Down
13 changes: 7 additions & 6 deletions cmd/crowdsec-cli/alerts_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import (

log "github.com/sirupsen/logrus"

"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/cstable"
"github.com/crowdsecurity/crowdsec/pkg/models"
)

func alertsTable(out io.Writer, alerts *models.GetAlertsResponse, printMachine bool) {
t := newTable(out)
func alertsTable(out io.Writer, wantColor string, alerts *models.GetAlertsResponse, printMachine bool) {
t := cstable.New(out, wantColor)
t.SetRowLines(false)

header := []string{"ID", "value", "reason", "country", "as", "decisions", "created_at"}
Expand Down Expand Up @@ -51,9 +52,9 @@ func alertsTable(out io.Writer, alerts *models.GetAlertsResponse, printMachine b
t.Render()
}

func alertDecisionsTable(out io.Writer, alert *models.Alert) {
func alertDecisionsTable(out io.Writer, wantColor string, alert *models.Alert) {
foundActive := false
t := newTable(out)
t := cstable.New(out, wantColor)
t.SetRowLines(false)
t.SetHeaders("ID", "scope:value", "action", "expiration", "created_at")

Expand Down Expand Up @@ -90,10 +91,10 @@ func alertDecisionsTable(out io.Writer, alert *models.Alert) {
}
}

func alertEventTable(out io.Writer, event *models.Event) {
func alertEventTable(out io.Writer, wantColor string, event *models.Event) {
fmt.Fprintf(out, "\n- Date: %s\n", *event.Timestamp)

t := newTable(out)
t := cstable.New(out, wantColor)
t.SetHeaders("Key", "Value")
sort.Slice(event.Meta, func(i, j int) bool {
return event.Meta[i].Key < event.Meta[j].Key
Expand Down
5 changes: 3 additions & 2 deletions cmd/crowdsec-cli/bouncers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"

"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/cstable"
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
middlewares "github.com/crowdsecurity/crowdsec/pkg/apiserver/middlewares/v1"
"github.com/crowdsecurity/crowdsec/pkg/database"
Expand Down Expand Up @@ -90,7 +91,7 @@ Note: This command requires database direct access, so is intended to be run on
}

func (cli *cliBouncers) listHuman(out io.Writer, bouncers ent.Bouncers) {
t := newLightTable(out).Writer
t := cstable.NewLight(out, cli.cfg().Cscli.Color).Writer
t.AppendHeader(table.Row{"Name", "IP Address", "Valid", "Last API pull", "Type", "Version", "Auth Type"})

for _, b := range bouncers {
Expand Down Expand Up @@ -411,7 +412,7 @@ cscli bouncers prune -d 45m --force`,
}

func (cli *cliBouncers) inspectHuman(out io.Writer, bouncer *ent.Bouncer) {
t := newTable(out).Writer
t := cstable.NewLight(out, cli.cfg().Cscli.Color).Writer

t.SetTitle("Bouncer: " + bouncer.Name)

Expand Down
2 changes: 1 addition & 1 deletion cmd/crowdsec-cli/console.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ func (cli *cliConsole) newStatusCmd() *cobra.Command {
consoleCfg := cfg.API.Server.ConsoleConfig
switch cfg.Cscli.Output {
case "human":
cmdConsoleStatusTable(color.Output, *consoleCfg)
cmdConsoleStatusTable(color.Output, cfg.Cscli.Color, *consoleCfg)
case "json":
out := map[string](*bool){
csconfig.SEND_MANUAL_SCENARIOS: consoleCfg.ShareManualDecisions,
Expand Down
10 changes: 6 additions & 4 deletions cmd/crowdsec-cli/console_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ package main
import (
"io"

"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/table"
"github.com/jedib0t/go-pretty/v6/text"

"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/cstable"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/emoji"
)

func cmdConsoleStatusTable(out io.Writer, consoleCfg csconfig.ConsoleConfig) {
t := newTable(out)
func cmdConsoleStatusTable(out io.Writer, wantColor string, consoleCfg csconfig.ConsoleConfig) {
t := cstable.New(out, wantColor)
t.SetRowLines(false)

t.SetHeaders("Option Name", "Activated", "Description")
t.SetHeaderAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft)
t.SetHeaderAlignment(text.AlignLeft, text.AlignLeft, text.AlignLeft)

for _, option := range csconfig.CONSOLE_CONFIGS {
activated := emoji.CrossMark
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,64 @@
package main
package cstable

// transisional file to keep (minimal) backwards compatibility with the old table
// we can migrate the code to the new dependency later, it can already use the Writer interface

import (
"fmt"
"io"
"os"

"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
isatty "github.com/mattn/go-isatty"
)

func RenderTitle(out io.Writer, title string) {
if out == nil {
panic("renderTableTitle: out is nil")
}

if title == "" {
return
}

fmt.Fprintln(out, title)
}

func shouldWeColorize(wantColor string) bool {
switch wantColor {
case "yes":
return true
case "no":
return false
default:
return isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd())
}
}

type Table struct {
Writer table.Writer
output io.Writer
align []text.Align
alignHeader []text.Align
}

func newTable(out io.Writer) *Table {
func New(out io.Writer, wantColor string) *Table {
if out == nil {
panic("newTable: out is nil")
}

t := table.NewWriter()

// colorize output, use unicode box characters
fancy := shouldWeColorize()
fancy := shouldWeColorize(wantColor)

color := table.ColorOptions{}
colorOptions := table.ColorOptions{}

if fancy {
color.Header = text.Colors{text.Italic}
color.Border = text.Colors{text.FgHiBlack}
color.Separator = text.Colors{text.FgHiBlack}
colorOptions.Header = text.Colors{text.Italic}
colorOptions.Border = text.Colors{text.FgHiBlack}
colorOptions.Separator = text.Colors{text.FgHiBlack}
}

// no upper/lower case transformations
Expand All @@ -46,7 +71,7 @@ func newTable(out io.Writer) *Table {

style := table.Style{
Box: box,
Color: color,
Color: colorOptions,
Format: format,
HTML: table.DefaultHTMLOptions,
Options: table.OptionsDefault,
Expand All @@ -63,8 +88,8 @@ func newTable(out io.Writer) *Table {
}
}

func newLightTable(output io.Writer) *Table {
t := newTable(output)
func NewLight(output io.Writer, wantColor string) *Table {
t := New(output, wantColor)
s := t.Writer.Style()
s.Box.Left = ""
s.Box.LeftSeparator = ""
Expand Down Expand Up @@ -100,6 +125,7 @@ func (t *Table) setColumnConfigs() {
WidthMaxEnforcer: text.WrapSoft,
})
}

t.Writer.SetColumnConfigs(configs)
}

Expand Down
3 changes: 2 additions & 1 deletion cmd/crowdsec-cli/decisions_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import (
"io"
"strconv"

"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/cstable"
"github.com/crowdsecurity/crowdsec/pkg/models"
)

func (cli *cliDecisions) decisionsTable(out io.Writer, alerts *models.GetAlertsResponse, printMachine bool) {
t := newTable(out)
t := cstable.New(out, cli.cfg().Cscli.Color)
t.SetRowLines(false)

header := []string{"ID", "Source", "Scope:Value", "Reason", "Action", "Country", "AS", "Events", "expiration", "Alert ID"}
Expand Down
2 changes: 1 addition & 1 deletion cmd/crowdsec-cli/hub.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (cli *cliHub) list(all bool) error {
}
}

err = listItems(color.Output, cwhub.ItemTypes, items, true, cfg.Cscli.Output)
err = listItems(color.Output, cfg.Cscli.Color, cwhub.ItemTypes, items, true, cfg.Cscli.Output)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 90e3299

Please sign in to comment.