mirror of
https://github.com/crowdsecurity/crowdsec.git
synced 2025-05-12 04:45:52 +02:00
remove dependencies on enescakir/emoji, gotest.tools (#2837)
* wrap emoji package in pkg/emoji * remove dependency on enescakir/emoji * remove dependency on gotest.tools * lint (whitespace)
This commit is contained in:
parent
4bf640c6e8
commit
a23fe06d68
14 changed files with 140 additions and 67 deletions
|
@ -5,9 +5,9 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aquasecurity/table"
|
"github.com/aquasecurity/table"
|
||||||
"github.com/enescakir/emoji"
|
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/database/ent"
|
"github.com/crowdsecurity/crowdsec/pkg/database/ent"
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getBouncersTable(out io.Writer, bouncers []*ent.Bouncer) {
|
func getBouncersTable(out io.Writer, bouncers []*ent.Bouncer) {
|
||||||
|
@ -17,11 +17,9 @@ func getBouncersTable(out io.Writer, bouncers []*ent.Bouncer) {
|
||||||
t.SetAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
t.SetAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
||||||
|
|
||||||
for _, b := range bouncers {
|
for _, b := range bouncers {
|
||||||
var revoked string
|
revoked := emoji.CheckMark
|
||||||
if !b.Revoked {
|
if b.Revoked {
|
||||||
revoked = emoji.CheckMark.String()
|
revoked = emoji.Prohibited
|
||||||
} else {
|
|
||||||
revoked = emoji.Prohibited.String()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t.AddRow(b.Name, b.IPAddress, revoked, b.LastPull.Format(time.RFC3339), b.Type, b.Version, b.AuthType)
|
t.AddRow(b.Name, b.IPAddress, revoked, b.LastPull.Format(time.RFC3339), b.Type, b.Version, b.AuthType)
|
||||||
|
|
|
@ -4,9 +4,9 @@ import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/aquasecurity/table"
|
"github.com/aquasecurity/table"
|
||||||
"github.com/enescakir/emoji"
|
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||||
)
|
)
|
||||||
|
|
||||||
func cmdConsoleStatusTable(out io.Writer, consoleCfg csconfig.ConsoleConfig) {
|
func cmdConsoleStatusTable(out io.Writer, consoleCfg csconfig.ConsoleConfig) {
|
||||||
|
@ -17,28 +17,28 @@ func cmdConsoleStatusTable(out io.Writer, consoleCfg csconfig.ConsoleConfig) {
|
||||||
t.SetHeaderAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
t.SetHeaderAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
||||||
|
|
||||||
for _, option := range csconfig.CONSOLE_CONFIGS {
|
for _, option := range csconfig.CONSOLE_CONFIGS {
|
||||||
activated := string(emoji.CrossMark)
|
activated := emoji.CrossMark
|
||||||
|
|
||||||
switch option {
|
switch option {
|
||||||
case csconfig.SEND_CUSTOM_SCENARIOS:
|
case csconfig.SEND_CUSTOM_SCENARIOS:
|
||||||
if *consoleCfg.ShareCustomScenarios {
|
if *consoleCfg.ShareCustomScenarios {
|
||||||
activated = string(emoji.CheckMarkButton)
|
activated = emoji.CheckMarkButton
|
||||||
}
|
}
|
||||||
case csconfig.SEND_MANUAL_SCENARIOS:
|
case csconfig.SEND_MANUAL_SCENARIOS:
|
||||||
if *consoleCfg.ShareManualDecisions {
|
if *consoleCfg.ShareManualDecisions {
|
||||||
activated = string(emoji.CheckMarkButton)
|
activated = emoji.CheckMarkButton
|
||||||
}
|
}
|
||||||
case csconfig.SEND_TAINTED_SCENARIOS:
|
case csconfig.SEND_TAINTED_SCENARIOS:
|
||||||
if *consoleCfg.ShareTaintedScenarios {
|
if *consoleCfg.ShareTaintedScenarios {
|
||||||
activated = string(emoji.CheckMarkButton)
|
activated = emoji.CheckMarkButton
|
||||||
}
|
}
|
||||||
case csconfig.SEND_CONTEXT:
|
case csconfig.SEND_CONTEXT:
|
||||||
if *consoleCfg.ShareContext {
|
if *consoleCfg.ShareContext {
|
||||||
activated = string(emoji.CheckMarkButton)
|
activated = emoji.CheckMarkButton
|
||||||
}
|
}
|
||||||
case csconfig.CONSOLE_MANAGEMENT:
|
case csconfig.CONSOLE_MANAGEMENT:
|
||||||
if *consoleCfg.ConsoleManagement {
|
if *consoleCfg.ConsoleManagement {
|
||||||
activated = string(emoji.CheckMarkButton)
|
activated = emoji.CheckMarkButton
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,13 +11,13 @@ import (
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/enescakir/emoji"
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/dumps"
|
"github.com/crowdsecurity/crowdsec/pkg/dumps"
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/hubtest"
|
"github.com/crowdsecurity/crowdsec/pkg/hubtest"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/aquasecurity/table"
|
"github.com/aquasecurity/table"
|
||||||
"github.com/enescakir/emoji"
|
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/hubtest"
|
"github.com/crowdsecurity/crowdsec/pkg/hubtest"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,9 +17,9 @@ func hubTestResultTable(out io.Writer, testResult map[string]bool) {
|
||||||
t.SetAlignment(table.AlignLeft)
|
t.SetAlignment(table.AlignLeft)
|
||||||
|
|
||||||
for testName, success := range testResult {
|
for testName, success := range testResult {
|
||||||
status := emoji.CheckMarkButton.String()
|
status := emoji.CheckMarkButton
|
||||||
if !success {
|
if !success {
|
||||||
status = emoji.CrossMark.String()
|
status = emoji.CrossMark
|
||||||
}
|
}
|
||||||
|
|
||||||
t.AddRow(testName, status)
|
t.AddRow(testName, status)
|
||||||
|
@ -50,11 +50,12 @@ func hubTestParserCoverageTable(out io.Writer, coverage []hubtest.Coverage) {
|
||||||
parserTested := 0
|
parserTested := 0
|
||||||
|
|
||||||
for _, test := range coverage {
|
for _, test := range coverage {
|
||||||
status := emoji.RedCircle.String()
|
status := emoji.RedCircle
|
||||||
if test.TestsCount > 0 {
|
if test.TestsCount > 0 {
|
||||||
status = emoji.GreenCircle.String()
|
status = emoji.GreenCircle
|
||||||
parserTested++
|
parserTested++
|
||||||
}
|
}
|
||||||
|
|
||||||
t.AddRow(test.Name, status, fmt.Sprintf("%d times (across %d tests)", test.TestsCount, len(test.PresentIn)))
|
t.AddRow(test.Name, status, fmt.Sprintf("%d times (across %d tests)", test.TestsCount, len(test.PresentIn)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,11 +71,12 @@ func hubTestAppsecRuleCoverageTable(out io.Writer, coverage []hubtest.Coverage)
|
||||||
parserTested := 0
|
parserTested := 0
|
||||||
|
|
||||||
for _, test := range coverage {
|
for _, test := range coverage {
|
||||||
status := emoji.RedCircle.String()
|
status := emoji.RedCircle
|
||||||
if test.TestsCount > 0 {
|
if test.TestsCount > 0 {
|
||||||
status = emoji.GreenCircle.String()
|
status = emoji.GreenCircle
|
||||||
parserTested++
|
parserTested++
|
||||||
}
|
}
|
||||||
|
|
||||||
t.AddRow(test.Name, status, fmt.Sprintf("%d times (across %d tests)", test.TestsCount, len(test.PresentIn)))
|
t.AddRow(test.Name, status, fmt.Sprintf("%d times (across %d tests)", test.TestsCount, len(test.PresentIn)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,11 +92,12 @@ func hubTestScenarioCoverageTable(out io.Writer, coverage []hubtest.Coverage) {
|
||||||
parserTested := 0
|
parserTested := 0
|
||||||
|
|
||||||
for _, test := range coverage {
|
for _, test := range coverage {
|
||||||
status := emoji.RedCircle.String()
|
status := emoji.RedCircle
|
||||||
if test.TestsCount > 0 {
|
if test.TestsCount > 0 {
|
||||||
status = emoji.GreenCircle.String()
|
status = emoji.GreenCircle
|
||||||
parserTested++
|
parserTested++
|
||||||
}
|
}
|
||||||
|
|
||||||
t.AddRow(test.Name, status, fmt.Sprintf("%d times (across %d tests)", test.TestsCount, len(test.PresentIn)))
|
t.AddRow(test.Name, status, fmt.Sprintf("%d times (across %d tests)", test.TestsCount, len(test.PresentIn)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,9 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aquasecurity/table"
|
"github.com/aquasecurity/table"
|
||||||
"github.com/enescakir/emoji"
|
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/database/ent"
|
"github.com/crowdsecurity/crowdsec/pkg/database/ent"
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getAgentsTable(out io.Writer, machines []*ent.Machine) {
|
func getAgentsTable(out io.Writer, machines []*ent.Machine) {
|
||||||
|
@ -17,17 +17,16 @@ func getAgentsTable(out io.Writer, machines []*ent.Machine) {
|
||||||
t.SetAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
t.SetAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
||||||
|
|
||||||
for _, m := range machines {
|
for _, m := range machines {
|
||||||
var validated string
|
validated := emoji.Prohibited
|
||||||
if m.IsValidated {
|
if m.IsValidated {
|
||||||
validated = emoji.CheckMark.String()
|
validated = emoji.CheckMark
|
||||||
} else {
|
|
||||||
validated = emoji.Prohibited.String()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hb, active := getLastHeartbeat(m)
|
hb, active := getLastHeartbeat(m)
|
||||||
if !active {
|
if !active {
|
||||||
hb = emoji.Warning.String() + " " + hb
|
hb = emoji.Warning + " " + hb
|
||||||
}
|
}
|
||||||
|
|
||||||
t.AddRow(m.MachineId, m.IpAddress, m.UpdatedAt.Format(time.RFC3339), validated, m.Version, m.AuthType, hb)
|
t.AddRow(m.MachineId, m.IpAddress, m.UpdatedAt.Format(time.RFC3339), validated, m.Version, m.AuthType, hb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/aquasecurity/table"
|
"github.com/aquasecurity/table"
|
||||||
"github.com/enescakir/emoji"
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||||
)
|
)
|
||||||
|
|
||||||
func notificationListTable(out io.Writer, ncfgs map[string]NotificationsCfg) {
|
func notificationListTable(out io.Writer, ncfgs map[string]NotificationsCfg) {
|
||||||
|
@ -14,24 +15,31 @@ func notificationListTable(out io.Writer, ncfgs map[string]NotificationsCfg) {
|
||||||
t.SetHeaders("Active", "Name", "Type", "Profile name")
|
t.SetHeaders("Active", "Name", "Type", "Profile name")
|
||||||
t.SetHeaderAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
t.SetHeaderAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
||||||
t.SetAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
t.SetAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
||||||
|
|
||||||
keys := make([]string, 0, len(ncfgs))
|
keys := make([]string, 0, len(ncfgs))
|
||||||
for k := range ncfgs {
|
for k := range ncfgs {
|
||||||
keys = append(keys, k)
|
keys = append(keys, k)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Slice(keys, func(i, j int) bool {
|
sort.Slice(keys, func(i, j int) bool {
|
||||||
return len(ncfgs[keys[i]].Profiles) > len(ncfgs[keys[j]].Profiles)
|
return len(ncfgs[keys[i]].Profiles) > len(ncfgs[keys[j]].Profiles)
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
b := ncfgs[k]
|
b := ncfgs[k]
|
||||||
profilesList := []string{}
|
profilesList := []string{}
|
||||||
|
|
||||||
for _, p := range b.Profiles {
|
for _, p := range b.Profiles {
|
||||||
profilesList = append(profilesList, p.Name)
|
profilesList = append(profilesList, p.Name)
|
||||||
}
|
}
|
||||||
active := emoji.CheckMark.String()
|
|
||||||
|
active := emoji.CheckMark
|
||||||
if len(profilesList) == 0 {
|
if len(profilesList) == 0 {
|
||||||
active = emoji.Prohibited.String()
|
active = emoji.Prohibited
|
||||||
}
|
}
|
||||||
|
|
||||||
t.AddRow(active, b.Config.Name, b.Config.Type, strings.Join(profilesList, ", "))
|
t.AddRow(active, b.Config.Name, b.Config.Type, strings.Join(profilesList, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Render()
|
t.Render()
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/aquasecurity/table"
|
"github.com/aquasecurity/table"
|
||||||
"github.com/enescakir/emoji"
|
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||||
)
|
)
|
||||||
|
|
||||||
func listHubItemTable(out io.Writer, title string, items []*cwhub.Item) {
|
func listHubItemTable(out io.Writer, title string, items []*cwhub.Item) {
|
||||||
|
@ -21,6 +21,7 @@ func listHubItemTable(out io.Writer, title string, items []*cwhub.Item) {
|
||||||
status := fmt.Sprintf("%v %s", item.State.Emoji(), item.State.Text())
|
status := fmt.Sprintf("%v %s", item.State.Emoji(), item.State.Text())
|
||||||
t.AddRow(item.Name, status, item.State.LocalVersion, item.State.LocalPath)
|
t.AddRow(item.Name, status, item.State.LocalVersion, item.State.LocalPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTableTitle(out, title)
|
renderTableTitle(out, title)
|
||||||
t.Render()
|
t.Render()
|
||||||
}
|
}
|
||||||
|
@ -42,6 +43,7 @@ func scenarioMetricsTable(out io.Writer, itemName string, metrics map[string]int
|
||||||
if metrics["instantiation"] == 0 {
|
if metrics["instantiation"] == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
t := newTable(out)
|
t := newTable(out)
|
||||||
t.SetHeaders("Current Count", "Overflows", "Instantiated", "Poured", "Expired")
|
t.SetHeaders("Current Count", "Overflows", "Instantiated", "Poured", "Expired")
|
||||||
|
|
||||||
|
@ -72,6 +74,7 @@ func parserMetricsTable(out io.Writer, itemName string, metrics map[string]map[s
|
||||||
strconv.Itoa(stats["parsed"]),
|
strconv.Itoa(stats["parsed"]),
|
||||||
strconv.Itoa(stats["unparsed"]),
|
strconv.Itoa(stats["unparsed"]),
|
||||||
)
|
)
|
||||||
|
|
||||||
showTable = true
|
showTable = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
3
go.mod
3
go.mod
|
@ -33,7 +33,6 @@ require (
|
||||||
github.com/dghubble/sling v1.3.0
|
github.com/dghubble/sling v1.3.0
|
||||||
github.com/docker/docker v24.0.7+incompatible
|
github.com/docker/docker v24.0.7+incompatible
|
||||||
github.com/docker/go-connections v0.4.0
|
github.com/docker/go-connections v0.4.0
|
||||||
github.com/enescakir/emoji v1.0.0
|
|
||||||
github.com/fatih/color v1.15.0
|
github.com/fatih/color v1.15.0
|
||||||
github.com/fsnotify/fsnotify v1.6.0
|
github.com/fsnotify/fsnotify v1.6.0
|
||||||
github.com/gin-gonic/gin v1.9.1
|
github.com/gin-gonic/gin v1.9.1
|
||||||
|
@ -92,7 +91,6 @@ require (
|
||||||
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637
|
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
gotest.tools/v3 v3.5.0
|
|
||||||
k8s.io/apiserver v0.28.4
|
k8s.io/apiserver v0.28.4
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -210,6 +208,7 @@ require (
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||||
|
gotest.tools/v3 v3.5.0 // indirect
|
||||||
k8s.io/api v0.28.4 // indirect
|
k8s.io/api v0.28.4 // indirect
|
||||||
k8s.io/apimachinery v0.28.4 // indirect
|
k8s.io/apimachinery v0.28.4 // indirect
|
||||||
k8s.io/klog/v2 v2.100.1 // indirect
|
k8s.io/klog/v2 v2.100.1 // indirect
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -124,8 +124,6 @@ github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
|
||||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
github.com/enescakir/emoji v1.0.0 h1:W+HsNql8swfCQFtioDGDHCHri8nudlK1n5p2rHCJoog=
|
|
||||||
github.com/enescakir/emoji v1.0.0/go.mod h1:Bt1EKuLnKDTYpLALApstIkAjdDrS/8IAgTkKp+WKFD0=
|
|
||||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||||
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||||
|
|
|
@ -2,6 +2,7 @@ package loki_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -13,19 +14,17 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"context"
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
tomb "gopkg.in/tomb.v2"
|
||||||
|
|
||||||
"github.com/crowdsecurity/go-cs-lib/cstest"
|
"github.com/crowdsecurity/go-cs-lib/cstest"
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/loki"
|
"github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/loki"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
tomb "gopkg.in/tomb.v2"
|
|
||||||
"gotest.tools/v3/assert"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestConfiguration(t *testing.T) {
|
func TestConfiguration(t *testing.T) {
|
||||||
|
|
||||||
log.Infof("Test 'TestConfigure'")
|
log.Infof("Test 'TestConfigure'")
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -127,22 +126,26 @@ query: >
|
||||||
subLogger := log.WithFields(log.Fields{
|
subLogger := log.WithFields(log.Fields{
|
||||||
"type": "loki",
|
"type": "loki",
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.testName, func(t *testing.T) {
|
t.Run(test.testName, func(t *testing.T) {
|
||||||
lokiSource := loki.LokiSource{}
|
lokiSource := loki.LokiSource{}
|
||||||
err := lokiSource.Configure([]byte(test.config), subLogger)
|
err := lokiSource.Configure([]byte(test.config), subLogger)
|
||||||
cstest.AssertErrorContains(t, err, test.expectedErr)
|
cstest.AssertErrorContains(t, err, test.expectedErr)
|
||||||
|
|
||||||
if test.password != "" {
|
if test.password != "" {
|
||||||
p := lokiSource.Config.Auth.Password
|
p := lokiSource.Config.Auth.Password
|
||||||
if test.password != p {
|
if test.password != p {
|
||||||
t.Fatalf("Password mismatch : %s != %s", test.password, p)
|
t.Fatalf("Password mismatch : %s != %s", test.password, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if test.waitForReady != 0 {
|
if test.waitForReady != 0 {
|
||||||
if lokiSource.Config.WaitForReady != test.waitForReady {
|
if lokiSource.Config.WaitForReady != test.waitForReady {
|
||||||
t.Fatalf("Wrong WaitForReady %v != %v", lokiSource.Config.WaitForReady, test.waitForReady)
|
t.Fatalf("Wrong WaitForReady %v != %v", lokiSource.Config.WaitForReady, test.waitForReady)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if test.delayFor != 0 {
|
if test.delayFor != 0 {
|
||||||
if lokiSource.Config.DelayFor != test.delayFor {
|
if lokiSource.Config.DelayFor != test.delayFor {
|
||||||
t.Fatalf("Wrong DelayFor %v != %v", lokiSource.Config.DelayFor, test.delayFor)
|
t.Fatalf("Wrong DelayFor %v != %v", lokiSource.Config.DelayFor, test.delayFor)
|
||||||
|
@ -154,6 +157,7 @@ query: >
|
||||||
|
|
||||||
func TestConfigureDSN(t *testing.T) {
|
func TestConfigureDSN(t *testing.T) {
|
||||||
log.Infof("Test 'TestConfigureDSN'")
|
log.Infof("Test 'TestConfigureDSN'")
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
dsn string
|
dsn string
|
||||||
|
@ -218,7 +222,9 @@ func TestConfigureDSN(t *testing.T) {
|
||||||
"type": "loki",
|
"type": "loki",
|
||||||
"name": test.name,
|
"name": test.name,
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Logf("Test : %s", test.name)
|
t.Logf("Test : %s", test.name)
|
||||||
|
|
||||||
lokiSource := &loki.LokiSource{}
|
lokiSource := &loki.LokiSource{}
|
||||||
err := lokiSource.ConfigureByDSN(test.dsn, map[string]string{"type": "testtype"}, subLogger, "")
|
err := lokiSource.ConfigureByDSN(test.dsn, map[string]string{"type": "testtype"}, subLogger, "")
|
||||||
cstest.AssertErrorContains(t, err, test.expectedErr)
|
cstest.AssertErrorContains(t, err, test.expectedErr)
|
||||||
|
@ -234,17 +240,20 @@ func TestConfigureDSN(t *testing.T) {
|
||||||
t.Fatalf("Password mismatch : %s != %s", test.password, p)
|
t.Fatalf("Password mismatch : %s != %s", test.password, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if test.scheme != "" {
|
if test.scheme != "" {
|
||||||
url, _ := url.Parse(lokiSource.Config.URL)
|
url, _ := url.Parse(lokiSource.Config.URL)
|
||||||
if test.scheme != url.Scheme {
|
if test.scheme != url.Scheme {
|
||||||
t.Fatalf("Schema mismatch : %s != %s", test.scheme, url.Scheme)
|
t.Fatalf("Schema mismatch : %s != %s", test.scheme, url.Scheme)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if test.waitForReady != 0 {
|
if test.waitForReady != 0 {
|
||||||
if lokiSource.Config.WaitForReady != test.waitForReady {
|
if lokiSource.Config.WaitForReady != test.waitForReady {
|
||||||
t.Fatalf("Wrong WaitForReady %v != %v", lokiSource.Config.WaitForReady, test.waitForReady)
|
t.Fatalf("Wrong WaitForReady %v != %v", lokiSource.Config.WaitForReady, test.waitForReady)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if test.delayFor != 0 {
|
if test.delayFor != 0 {
|
||||||
if lokiSource.Config.DelayFor != test.delayFor {
|
if lokiSource.Config.DelayFor != test.delayFor {
|
||||||
t.Fatalf("Wrong DelayFor %v != %v", lokiSource.Config.DelayFor, test.delayFor)
|
t.Fatalf("Wrong DelayFor %v != %v", lokiSource.Config.DelayFor, test.delayFor)
|
||||||
|
@ -272,27 +281,36 @@ func feedLoki(logger *log.Entry, n int, title string) error {
|
||||||
Line: fmt.Sprintf("Log line #%d %v", i, title),
|
Line: fmt.Sprintf("Log line #%d %v", i, title),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buff, err := json.Marshal(streams)
|
buff, err := json.Marshal(streams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, "http://127.0.0.1:3100/loki/api/v1/push", bytes.NewBuffer(buff))
|
req, err := http.NewRequest(http.MethodPost, "http://127.0.0.1:3100/loki/api/v1/push", bytes.NewBuffer(buff))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
req.Header.Set("X-Scope-OrgID", "1234")
|
req.Header.Set("X-Scope-OrgID", "1234")
|
||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusNoContent {
|
if resp.StatusCode != http.StatusNoContent {
|
||||||
b, _ := io.ReadAll(resp.Body)
|
b, _ := io.ReadAll(resp.Body)
|
||||||
logger.Error(string(b))
|
logger.Error(string(b))
|
||||||
|
|
||||||
return fmt.Errorf("Bad post status %d", resp.StatusCode)
|
return fmt.Errorf("Bad post status %d", resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info(n, " Events sent")
|
logger.Info(n, " Events sent")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,9 +318,11 @@ func TestOneShotAcquisition(t *testing.T) {
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
t.Skip("Skipping test on windows")
|
t.Skip("Skipping test on windows")
|
||||||
}
|
}
|
||||||
|
|
||||||
log.SetOutput(os.Stdout)
|
log.SetOutput(os.Stdout)
|
||||||
log.SetLevel(log.InfoLevel)
|
log.SetLevel(log.InfoLevel)
|
||||||
log.Info("Test 'TestStreamingAcquisition'")
|
log.Info("Test 'TestStreamingAcquisition'")
|
||||||
|
|
||||||
title := time.Now().String() // Loki will be messy, with a lot of stuff, lets use a unique key
|
title := time.Now().String() // Loki will be messy, with a lot of stuff, lets use a unique key
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
config string
|
config string
|
||||||
|
@ -327,6 +347,7 @@ since: 1h
|
||||||
})
|
})
|
||||||
lokiSource := loki.LokiSource{}
|
lokiSource := loki.LokiSource{}
|
||||||
err := lokiSource.Configure([]byte(ts.config), subLogger)
|
err := lokiSource.Configure([]byte(ts.config), subLogger)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error : %s", err)
|
t.Fatalf("Unexpected error : %s", err)
|
||||||
}
|
}
|
||||||
|
@ -338,19 +359,23 @@ since: 1h
|
||||||
|
|
||||||
out := make(chan types.Event)
|
out := make(chan types.Event)
|
||||||
read := 0
|
read := 0
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
<-out
|
<-out
|
||||||
|
|
||||||
read++
|
read++
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
lokiTomb := tomb.Tomb{}
|
lokiTomb := tomb.Tomb{}
|
||||||
|
|
||||||
err = lokiSource.OneShotAcquisition(out, &lokiTomb)
|
err = lokiSource.OneShotAcquisition(out, &lokiTomb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error : %s", err)
|
t.Fatalf("Unexpected error : %s", err)
|
||||||
}
|
}
|
||||||
assert.Equal(t, 20, read)
|
|
||||||
|
|
||||||
|
assert.Equal(t, 20, read)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,9 +383,11 @@ func TestStreamingAcquisition(t *testing.T) {
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
t.Skip("Skipping test on windows")
|
t.Skip("Skipping test on windows")
|
||||||
}
|
}
|
||||||
|
|
||||||
log.SetOutput(os.Stdout)
|
log.SetOutput(os.Stdout)
|
||||||
log.SetLevel(log.InfoLevel)
|
log.SetLevel(log.InfoLevel)
|
||||||
log.Info("Test 'TestStreamingAcquisition'")
|
log.Info("Test 'TestStreamingAcquisition'")
|
||||||
|
|
||||||
title := time.Now().String()
|
title := time.Now().String()
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -396,6 +423,7 @@ query: >
|
||||||
expectedLines: 20,
|
expectedLines: 20,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ts := range tests {
|
for _, ts := range tests {
|
||||||
t.Run(ts.name, func(t *testing.T) {
|
t.Run(ts.name, func(t *testing.T) {
|
||||||
logger := log.New()
|
logger := log.New()
|
||||||
|
@ -407,10 +435,12 @@ query: >
|
||||||
out := make(chan types.Event)
|
out := make(chan types.Event)
|
||||||
lokiTomb := tomb.Tomb{}
|
lokiTomb := tomb.Tomb{}
|
||||||
lokiSource := loki.LokiSource{}
|
lokiSource := loki.LokiSource{}
|
||||||
|
|
||||||
err := lokiSource.Configure([]byte(ts.config), subLogger)
|
err := lokiSource.Configure([]byte(ts.config), subLogger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error : %s", err)
|
t.Fatalf("Unexpected error : %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = lokiSource.StreamingAcquisition(out, &lokiTomb)
|
err = lokiSource.StreamingAcquisition(out, &lokiTomb)
|
||||||
cstest.AssertErrorContains(t, err, ts.streamErr)
|
cstest.AssertErrorContains(t, err, ts.streamErr)
|
||||||
|
|
||||||
|
@ -418,22 +448,26 @@ query: >
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(time.Second * 2) //We need to give time to start reading from the WS
|
time.Sleep(time.Second * 2) // We need to give time to start reading from the WS
|
||||||
|
|
||||||
readTomb := tomb.Tomb{}
|
readTomb := tomb.Tomb{}
|
||||||
readCtx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
readCtx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||||
count := 0
|
count := 0
|
||||||
|
|
||||||
readTomb.Go(func() error {
|
readTomb.Go(func() error {
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-readCtx.Done():
|
case <-readCtx.Done():
|
||||||
return readCtx.Err()
|
return readCtx.Err()
|
||||||
case evt := <-out:
|
case evt := <-out:
|
||||||
count++
|
count++
|
||||||
|
|
||||||
if !strings.HasSuffix(evt.Line.Raw, title) {
|
if !strings.HasSuffix(evt.Line.Raw, title) {
|
||||||
return fmt.Errorf("Incorrect suffix : %s", evt.Line.Raw)
|
return fmt.Errorf("Incorrect suffix : %s", evt.Line.Raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
if count == ts.expectedLines {
|
if count == ts.expectedLines {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -447,20 +481,23 @@ query: >
|
||||||
}
|
}
|
||||||
|
|
||||||
err = readTomb.Wait()
|
err = readTomb.Wait()
|
||||||
|
|
||||||
cancel()
|
cancel()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error : %s", err)
|
t.Fatalf("Unexpected error : %s", err)
|
||||||
}
|
}
|
||||||
assert.Equal(t, count, ts.expectedLines)
|
|
||||||
|
assert.Equal(t, ts.expectedLines, count)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStopStreaming(t *testing.T) {
|
func TestStopStreaming(t *testing.T) {
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
t.Skip("Skipping test on windows")
|
t.Skip("Skipping test on windows")
|
||||||
}
|
}
|
||||||
|
|
||||||
config := `
|
config := `
|
||||||
mode: tail
|
mode: tail
|
||||||
source: loki
|
source: loki
|
||||||
|
@ -476,24 +513,30 @@ query: >
|
||||||
})
|
})
|
||||||
title := time.Now().String()
|
title := time.Now().String()
|
||||||
lokiSource := loki.LokiSource{}
|
lokiSource := loki.LokiSource{}
|
||||||
|
|
||||||
err := lokiSource.Configure([]byte(config), subLogger)
|
err := lokiSource.Configure([]byte(config), subLogger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error : %s", err)
|
t.Fatalf("Unexpected error : %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
out := make(chan types.Event)
|
out := make(chan types.Event)
|
||||||
|
|
||||||
lokiTomb := &tomb.Tomb{}
|
lokiTomb := &tomb.Tomb{}
|
||||||
|
|
||||||
err = lokiSource.StreamingAcquisition(out, lokiTomb)
|
err = lokiSource.StreamingAcquisition(out, lokiTomb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error : %s", err)
|
t.Fatalf("Unexpected error : %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(time.Second * 2)
|
time.Sleep(time.Second * 2)
|
||||||
|
|
||||||
err = feedLoki(subLogger, 1, title)
|
err = feedLoki(subLogger, 1, title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error : %s", err)
|
t.Fatalf("Unexpected error : %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
lokiTomb.Kill(nil)
|
lokiTomb.Kill(nil)
|
||||||
|
|
||||||
err = lokiTomb.Wait()
|
err = lokiTomb.Wait()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error : %s", err)
|
t.Fatalf("Unexpected error : %s", err)
|
||||||
|
@ -519,5 +562,6 @@ func (l *LogValue) MarshalJSON() ([]byte, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return []byte(fmt.Sprintf(`["%d",%s]`, l.Time.UnixNano(), string(line))), nil
|
return []byte(fmt.Sprintf(`["%d",%s]`, l.Time.UnixNano(), string(line))), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,8 @@ import (
|
||||||
"slices"
|
"slices"
|
||||||
|
|
||||||
"github.com/Masterminds/semver/v3"
|
"github.com/Masterminds/semver/v3"
|
||||||
"github.com/enescakir/emoji"
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -84,7 +85,7 @@ func (s *ItemState) Text() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emoji returns the status of the item as an emoji (eg. emoji.Warning).
|
// Emoji returns the status of the item as an emoji (eg. emoji.Warning).
|
||||||
func (s *ItemState) Emoji() emoji.Emoji {
|
func (s *ItemState) Emoji() string {
|
||||||
switch {
|
switch {
|
||||||
case s.IsLocal():
|
case s.IsLocal():
|
||||||
return emoji.House
|
return emoji.House
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/enescakir/emoji"
|
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Upgrade downloads and applies the last version of the item from the hub.
|
// Upgrade downloads and applies the last version of the item from the hub.
|
||||||
|
@ -60,6 +60,7 @@ func (i *Item) Upgrade(force bool) (bool, error) {
|
||||||
// TODO: use a better way to communicate this
|
// TODO: use a better way to communicate this
|
||||||
fmt.Printf("updated %s\n", i.Name)
|
fmt.Printf("updated %s\n", i.Name)
|
||||||
i.hub.logger.Infof("%v %s: updated", emoji.Package, i.Name)
|
i.hub.logger.Infof("%v %s: updated", emoji.Package, i.Name)
|
||||||
|
|
||||||
updated = true
|
updated = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +152,7 @@ func (i *Item) FetchLatest() ([]byte, string, error) {
|
||||||
i.hub.logger.Errorf("Downloaded version doesn't match index, please 'hub update'")
|
i.hub.logger.Errorf("Downloaded version doesn't match index, please 'hub update'")
|
||||||
i.hub.logger.Debugf("got %s, expected %s", meow, i.Versions[i.Version].Digest)
|
i.hub.logger.Debugf("got %s, expected %s", meow, i.Versions[i.Version].Digest)
|
||||||
|
|
||||||
return nil, "", fmt.Errorf("invalid download hash")
|
return nil, "", errors.New("invalid download hash")
|
||||||
}
|
}
|
||||||
|
|
||||||
return body, url, nil
|
return body, url, nil
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package dumps
|
package dumps
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -8,13 +9,15 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
|
||||||
"github.com/crowdsecurity/go-cs-lib/maptools"
|
|
||||||
"github.com/enescakir/emoji"
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
diff "github.com/r3labs/diff/v2"
|
diff "github.com/r3labs/diff/v2"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/go-cs-lib/maptools"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ParserResult struct {
|
type ParserResult struct {
|
||||||
|
@ -56,7 +59,7 @@ func LoadParserDump(filepath string) (*ParserResults, error) {
|
||||||
|
|
||||||
var lastStage string
|
var lastStage string
|
||||||
|
|
||||||
//Loop over stages to find last successful one with at least one parser
|
// Loop over stages to find last successful one with at least one parser
|
||||||
for i := len(stages) - 2; i >= 0; i-- {
|
for i := len(stages) - 2; i >= 0; i-- {
|
||||||
if len(pdump[stages[i]]) != 0 {
|
if len(pdump[stages[i]]) != 0 {
|
||||||
lastStage = stages[i]
|
lastStage = stages[i]
|
||||||
|
@ -73,7 +76,7 @@ func LoadParserDump(filepath string) (*ParserResults, error) {
|
||||||
sort.Strings(parsers)
|
sort.Strings(parsers)
|
||||||
|
|
||||||
if len(parsers) == 0 {
|
if len(parsers) == 0 {
|
||||||
return nil, fmt.Errorf("no parser found. Please install the appropriate parser and retry")
|
return nil, errors.New("no parser found. Please install the appropriate parser and retry")
|
||||||
}
|
}
|
||||||
|
|
||||||
lastParser := parsers[len(parsers)-1]
|
lastParser := parsers[len(parsers)-1]
|
||||||
|
@ -90,14 +93,15 @@ func LoadParserDump(filepath string) (*ParserResults, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpOpts) {
|
func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpOpts) {
|
||||||
//note : we can use line -> time as the unique identifier (of acquisition)
|
// note : we can use line -> time as the unique identifier (of acquisition)
|
||||||
state := make(map[time.Time]map[string]map[string]ParserResult)
|
state := make(map[time.Time]map[string]map[string]ParserResult)
|
||||||
assoc := make(map[time.Time]string, 0)
|
assoc := make(map[time.Time]string, 0)
|
||||||
parser_order := make(map[string][]string)
|
parser_order := make(map[string][]string)
|
||||||
|
|
||||||
for stage, parsers := range parserResults {
|
for stage, parsers := range parserResults {
|
||||||
//let's process parsers in the order according to idx
|
// let's process parsers in the order according to idx
|
||||||
parser_order[stage] = make([]string, len(parsers))
|
parser_order[stage] = make([]string, len(parsers))
|
||||||
|
|
||||||
for pname, parser := range parsers {
|
for pname, parser := range parsers {
|
||||||
if len(parser) > 0 {
|
if len(parser) > 0 {
|
||||||
parser_order[stage][parser[0].Idx-1] = pname
|
parser_order[stage][parser[0].Idx-1] = pname
|
||||||
|
@ -128,14 +132,14 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
//it might be bucket overflow being reprocessed, skip this
|
// it might be bucket overflow being reprocessed, skip this
|
||||||
if _, ok := state[evt.Line.Time]; !ok {
|
if _, ok := state[evt.Line.Time]; !ok {
|
||||||
state[evt.Line.Time] = make(map[string]map[string]ParserResult)
|
state[evt.Line.Time] = make(map[string]map[string]ParserResult)
|
||||||
assoc[evt.Line.Time] = evt.Line.Raw
|
assoc[evt.Line.Time] = evt.Line.Raw
|
||||||
}
|
}
|
||||||
|
|
||||||
//there is a trick : to know if an event successfully exit the parsers, we check if it reached the pour() phase
|
// there is a trick : to know if an event successfully exit the parsers, we check if it reached the pour() phase
|
||||||
//we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
|
// we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
|
||||||
if _, ok := state[evt.Line.Time]["buckets"]; !ok {
|
if _, ok := state[evt.Line.Time]["buckets"]; !ok {
|
||||||
state[evt.Line.Time]["buckets"] = make(map[string]ParserResult)
|
state[evt.Line.Time]["buckets"] = make(map[string]ParserResult)
|
||||||
}
|
}
|
||||||
|
@ -148,7 +152,7 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
|
||||||
red := color.New(color.FgRed).SprintFunc()
|
red := color.New(color.FgRed).SprintFunc()
|
||||||
green := color.New(color.FgGreen).SprintFunc()
|
green := color.New(color.FgGreen).SprintFunc()
|
||||||
whitelistReason := ""
|
whitelistReason := ""
|
||||||
//get each line
|
// get each line
|
||||||
for tstamp, rawstr := range assoc {
|
for tstamp, rawstr := range assoc {
|
||||||
if opts.SkipOk {
|
if opts.SkipOk {
|
||||||
if _, ok := state[tstamp]["buckets"]["OK"]; ok {
|
if _, ok := state[tstamp]["buckets"]["OK"]; ok {
|
||||||
|
@ -161,8 +165,8 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
|
||||||
skeys := make([]string, 0, len(state[tstamp]))
|
skeys := make([]string, 0, len(state[tstamp]))
|
||||||
|
|
||||||
for k := range state[tstamp] {
|
for k := range state[tstamp] {
|
||||||
//there is a trick : to know if an event successfully exit the parsers, we check if it reached the pour() phase
|
// there is a trick : to know if an event successfully exit the parsers, we check if it reached the pour() phase
|
||||||
//we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
|
// we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
|
||||||
if k == "buckets" {
|
if k == "buckets" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -216,6 +220,7 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
|
||||||
whitelistReason = parsers[parser].Evt.WhitelistReason
|
whitelistReason = parsers[parser].Evt.WhitelistReason
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updated++
|
updated++
|
||||||
case "delete":
|
case "delete":
|
||||||
deleted++
|
deleted++
|
||||||
|
@ -277,7 +282,7 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
|
||||||
sep = "├"
|
sep = "├"
|
||||||
}
|
}
|
||||||
|
|
||||||
//did the event enter the bucket pour phase ?
|
// did the event enter the bucket pour phase ?
|
||||||
if _, ok := state[tstamp]["buckets"]["OK"]; ok {
|
if _, ok := state[tstamp]["buckets"]["OK"]; ok {
|
||||||
fmt.Printf("\t%s-------- parser success %s\n", sep, emoji.GreenCircle)
|
fmt.Printf("\t%s-------- parser success %s\n", sep, emoji.GreenCircle)
|
||||||
} else if whitelistReason != "" {
|
} else if whitelistReason != "" {
|
||||||
|
@ -286,7 +291,7 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
|
||||||
fmt.Printf("\t%s-------- parser failure %s\n", sep, emoji.RedCircle)
|
fmt.Printf("\t%s-------- parser failure %s\n", sep, emoji.RedCircle)
|
||||||
}
|
}
|
||||||
|
|
||||||
//now print bucket info
|
// now print bucket info
|
||||||
if len(state[tstamp]["buckets"]) > 0 {
|
if len(state[tstamp]["buckets"]) > 0 {
|
||||||
fmt.Printf("\t├ Scenarios\n")
|
fmt.Printf("\t├ Scenarios\n")
|
||||||
}
|
}
|
||||||
|
@ -294,8 +299,8 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
|
||||||
bnames := make([]string, 0, len(state[tstamp]["buckets"]))
|
bnames := make([]string, 0, len(state[tstamp]["buckets"]))
|
||||||
|
|
||||||
for k := range state[tstamp]["buckets"] {
|
for k := range state[tstamp]["buckets"] {
|
||||||
//there is a trick : to know if an event successfully exit the parsers, we check if it reached the pour() phase
|
// there is a trick : to know if an event successfully exit the parsers, we check if it reached the pour() phase
|
||||||
//we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
|
// we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
|
||||||
if k == "OK" {
|
if k == "OK" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
14
pkg/emoji/emoji.go
Normal file
14
pkg/emoji/emoji.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package emoji
|
||||||
|
|
||||||
|
const (
|
||||||
|
CheckMarkButton = "\u2705" // ✅
|
||||||
|
CheckMark = "\u2714\ufe0f" // ✔️
|
||||||
|
CrossMark = "\u274c" // ❌
|
||||||
|
GreenCircle = "\U0001f7e2" // 🟢
|
||||||
|
House = "\U0001f3e0" // 🏠
|
||||||
|
Package = "\U0001f4e6" // 📦
|
||||||
|
Prohibited = "\U0001f6ab" // 🚫
|
||||||
|
QuestionMark = "\u2753" // ❓
|
||||||
|
RedCircle = "\U0001f534" // 🔴
|
||||||
|
Warning = "\u26a0\ufe0f" // ⚠️
|
||||||
|
)
|
Loading…
Add table
Add a link
Reference in a new issue