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"
|
||||
|
||||
"github.com/aquasecurity/table"
|
||||
"github.com/enescakir/emoji"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/database/ent"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
for _, b := range bouncers {
|
||||
var revoked string
|
||||
if !b.Revoked {
|
||||
revoked = emoji.CheckMark.String()
|
||||
} else {
|
||||
revoked = emoji.Prohibited.String()
|
||||
revoked := emoji.CheckMark
|
||||
if b.Revoked {
|
||||
revoked = emoji.Prohibited
|
||||
}
|
||||
|
||||
t.AddRow(b.Name, b.IPAddress, revoked, b.LastPull.Format(time.RFC3339), b.Type, b.Version, b.AuthType)
|
||||
|
|
|
@ -4,9 +4,9 @@ import (
|
|||
"io"
|
||||
|
||||
"github.com/aquasecurity/table"
|
||||
"github.com/enescakir/emoji"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
for _, option := range csconfig.CONSOLE_CONFIGS {
|
||||
activated := string(emoji.CrossMark)
|
||||
activated := emoji.CrossMark
|
||||
|
||||
switch option {
|
||||
case csconfig.SEND_CUSTOM_SCENARIOS:
|
||||
if *consoleCfg.ShareCustomScenarios {
|
||||
activated = string(emoji.CheckMarkButton)
|
||||
activated = emoji.CheckMarkButton
|
||||
}
|
||||
case csconfig.SEND_MANUAL_SCENARIOS:
|
||||
if *consoleCfg.ShareManualDecisions {
|
||||
activated = string(emoji.CheckMarkButton)
|
||||
activated = emoji.CheckMarkButton
|
||||
}
|
||||
case csconfig.SEND_TAINTED_SCENARIOS:
|
||||
if *consoleCfg.ShareTaintedScenarios {
|
||||
activated = string(emoji.CheckMarkButton)
|
||||
activated = emoji.CheckMarkButton
|
||||
}
|
||||
case csconfig.SEND_CONTEXT:
|
||||
if *consoleCfg.ShareContext {
|
||||
activated = string(emoji.CheckMarkButton)
|
||||
activated = emoji.CheckMarkButton
|
||||
}
|
||||
case csconfig.CONSOLE_MANAGEMENT:
|
||||
if *consoleCfg.ConsoleManagement {
|
||||
activated = string(emoji.CheckMarkButton)
|
||||
activated = emoji.CheckMarkButton
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,13 +11,13 @@ import (
|
|||
"text/template"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/enescakir/emoji"
|
||||
"github.com/fatih/color"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/dumps"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/hubtest"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"io"
|
||||
|
||||
"github.com/aquasecurity/table"
|
||||
"github.com/enescakir/emoji"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/hubtest"
|
||||
)
|
||||
|
||||
|
@ -17,9 +17,9 @@ func hubTestResultTable(out io.Writer, testResult map[string]bool) {
|
|||
t.SetAlignment(table.AlignLeft)
|
||||
|
||||
for testName, success := range testResult {
|
||||
status := emoji.CheckMarkButton.String()
|
||||
status := emoji.CheckMarkButton
|
||||
if !success {
|
||||
status = emoji.CrossMark.String()
|
||||
status = emoji.CrossMark
|
||||
}
|
||||
|
||||
t.AddRow(testName, status)
|
||||
|
@ -50,11 +50,12 @@ func hubTestParserCoverageTable(out io.Writer, coverage []hubtest.Coverage) {
|
|||
parserTested := 0
|
||||
|
||||
for _, test := range coverage {
|
||||
status := emoji.RedCircle.String()
|
||||
status := emoji.RedCircle
|
||||
if test.TestsCount > 0 {
|
||||
status = emoji.GreenCircle.String()
|
||||
status = emoji.GreenCircle
|
||||
parserTested++
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
for _, test := range coverage {
|
||||
status := emoji.RedCircle.String()
|
||||
status := emoji.RedCircle
|
||||
if test.TestsCount > 0 {
|
||||
status = emoji.GreenCircle.String()
|
||||
status = emoji.GreenCircle
|
||||
parserTested++
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
for _, test := range coverage {
|
||||
status := emoji.RedCircle.String()
|
||||
status := emoji.RedCircle
|
||||
if test.TestsCount > 0 {
|
||||
status = emoji.GreenCircle.String()
|
||||
status = emoji.GreenCircle
|
||||
parserTested++
|
||||
}
|
||||
|
||||
t.AddRow(test.Name, status, fmt.Sprintf("%d times (across %d tests)", test.TestsCount, len(test.PresentIn)))
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/aquasecurity/table"
|
||||
"github.com/enescakir/emoji"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/database/ent"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
for _, m := range machines {
|
||||
var validated string
|
||||
validated := emoji.Prohibited
|
||||
if m.IsValidated {
|
||||
validated = emoji.CheckMark.String()
|
||||
} else {
|
||||
validated = emoji.Prohibited.String()
|
||||
validated = emoji.CheckMark
|
||||
}
|
||||
|
||||
hb, active := getLastHeartbeat(m)
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/aquasecurity/table"
|
||||
"github.com/enescakir/emoji"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||
)
|
||||
|
||||
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.SetHeaderAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
||||
t.SetAlignment(table.AlignLeft, table.AlignLeft, table.AlignLeft, table.AlignLeft)
|
||||
|
||||
keys := make([]string, 0, len(ncfgs))
|
||||
for k := range ncfgs {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
sort.Slice(keys, func(i, j int) bool {
|
||||
return len(ncfgs[keys[i]].Profiles) > len(ncfgs[keys[j]].Profiles)
|
||||
})
|
||||
|
||||
for _, k := range keys {
|
||||
b := ncfgs[k]
|
||||
profilesList := []string{}
|
||||
|
||||
for _, p := range b.Profiles {
|
||||
profilesList = append(profilesList, p.Name)
|
||||
}
|
||||
active := emoji.CheckMark.String()
|
||||
|
||||
active := emoji.CheckMark
|
||||
if len(profilesList) == 0 {
|
||||
active = emoji.Prohibited.String()
|
||||
active = emoji.Prohibited
|
||||
}
|
||||
|
||||
t.AddRow(active, b.Config.Name, b.Config.Type, strings.Join(profilesList, ", "))
|
||||
}
|
||||
|
||||
t.Render()
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ import (
|
|||
"strconv"
|
||||
|
||||
"github.com/aquasecurity/table"
|
||||
"github.com/enescakir/emoji"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||
)
|
||||
|
||||
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())
|
||||
t.AddRow(item.Name, status, item.State.LocalVersion, item.State.LocalPath)
|
||||
}
|
||||
|
||||
renderTableTitle(out, title)
|
||||
t.Render()
|
||||
}
|
||||
|
@ -42,6 +43,7 @@ func scenarioMetricsTable(out io.Writer, itemName string, metrics map[string]int
|
|||
if metrics["instantiation"] == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
t := newTable(out)
|
||||
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["unparsed"]),
|
||||
)
|
||||
|
||||
showTable = true
|
||||
}
|
||||
}
|
||||
|
|
3
go.mod
3
go.mod
|
@ -33,7 +33,6 @@ require (
|
|||
github.com/dghubble/sling v1.3.0
|
||||
github.com/docker/docker v24.0.7+incompatible
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/enescakir/emoji v1.0.0
|
||||
github.com/fatih/color v1.15.0
|
||||
github.com/fsnotify/fsnotify v1.6.0
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
|
@ -92,7 +91,6 @@ require (
|
|||
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gotest.tools/v3 v3.5.0
|
||||
k8s.io/apiserver v0.28.4
|
||||
)
|
||||
|
||||
|
@ -210,6 +208,7 @@ require (
|
|||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // 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/apimachinery v0.28.4 // 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.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
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.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||
|
|
|
@ -2,6 +2,7 @@ package loki_test
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -13,19 +14,17 @@ import (
|
|||
"testing"
|
||||
"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/crowdsec/pkg/acquisition/modules/loki"
|
||||
"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) {
|
||||
|
||||
log.Infof("Test 'TestConfigure'")
|
||||
|
||||
tests := []struct {
|
||||
|
@ -127,22 +126,26 @@ query: >
|
|||
subLogger := log.WithFields(log.Fields{
|
||||
"type": "loki",
|
||||
})
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.testName, func(t *testing.T) {
|
||||
lokiSource := loki.LokiSource{}
|
||||
err := lokiSource.Configure([]byte(test.config), subLogger)
|
||||
cstest.AssertErrorContains(t, err, test.expectedErr)
|
||||
|
||||
if test.password != "" {
|
||||
p := lokiSource.Config.Auth.Password
|
||||
if test.password != p {
|
||||
t.Fatalf("Password mismatch : %s != %s", test.password, p)
|
||||
}
|
||||
}
|
||||
|
||||
if test.waitForReady != 0 {
|
||||
if lokiSource.Config.WaitForReady != test.waitForReady {
|
||||
t.Fatalf("Wrong WaitForReady %v != %v", lokiSource.Config.WaitForReady, test.waitForReady)
|
||||
}
|
||||
}
|
||||
|
||||
if test.delayFor != 0 {
|
||||
if 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) {
|
||||
log.Infof("Test 'TestConfigureDSN'")
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
dsn string
|
||||
|
@ -218,7 +222,9 @@ func TestConfigureDSN(t *testing.T) {
|
|||
"type": "loki",
|
||||
"name": test.name,
|
||||
})
|
||||
|
||||
t.Logf("Test : %s", test.name)
|
||||
|
||||
lokiSource := &loki.LokiSource{}
|
||||
err := lokiSource.ConfigureByDSN(test.dsn, map[string]string{"type": "testtype"}, subLogger, "")
|
||||
cstest.AssertErrorContains(t, err, test.expectedErr)
|
||||
|
@ -234,17 +240,20 @@ func TestConfigureDSN(t *testing.T) {
|
|||
t.Fatalf("Password mismatch : %s != %s", test.password, p)
|
||||
}
|
||||
}
|
||||
|
||||
if test.scheme != "" {
|
||||
url, _ := url.Parse(lokiSource.Config.URL)
|
||||
if test.scheme != url.Scheme {
|
||||
t.Fatalf("Schema mismatch : %s != %s", test.scheme, url.Scheme)
|
||||
}
|
||||
}
|
||||
|
||||
if test.waitForReady != 0 {
|
||||
if lokiSource.Config.WaitForReady != test.waitForReady {
|
||||
t.Fatalf("Wrong WaitForReady %v != %v", lokiSource.Config.WaitForReady, test.waitForReady)
|
||||
}
|
||||
}
|
||||
|
||||
if test.delayFor != 0 {
|
||||
if 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),
|
||||
}
|
||||
}
|
||||
|
||||
buff, err := json.Marshal(streams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, "http://127.0.0.1:3100/loki/api/v1/push", bytes.NewBuffer(buff))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("X-Scope-OrgID", "1234")
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusNoContent {
|
||||
b, _ := io.ReadAll(resp.Body)
|
||||
logger.Error(string(b))
|
||||
|
||||
return fmt.Errorf("Bad post status %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
logger.Info(n, " Events sent")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -300,9 +318,11 @@ func TestOneShotAcquisition(t *testing.T) {
|
|||
if runtime.GOOS == "windows" {
|
||||
t.Skip("Skipping test on windows")
|
||||
}
|
||||
|
||||
log.SetOutput(os.Stdout)
|
||||
log.SetLevel(log.InfoLevel)
|
||||
log.Info("Test 'TestStreamingAcquisition'")
|
||||
|
||||
title := time.Now().String() // Loki will be messy, with a lot of stuff, lets use a unique key
|
||||
tests := []struct {
|
||||
config string
|
||||
|
@ -327,6 +347,7 @@ since: 1h
|
|||
})
|
||||
lokiSource := loki.LokiSource{}
|
||||
err := lokiSource.Configure([]byte(ts.config), subLogger)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error : %s", err)
|
||||
}
|
||||
|
@ -338,19 +359,23 @@ since: 1h
|
|||
|
||||
out := make(chan types.Event)
|
||||
read := 0
|
||||
|
||||
go func() {
|
||||
for {
|
||||
<-out
|
||||
|
||||
read++
|
||||
}
|
||||
}()
|
||||
|
||||
lokiTomb := tomb.Tomb{}
|
||||
|
||||
err = lokiSource.OneShotAcquisition(out, &lokiTomb)
|
||||
if err != nil {
|
||||
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" {
|
||||
t.Skip("Skipping test on windows")
|
||||
}
|
||||
|
||||
log.SetOutput(os.Stdout)
|
||||
log.SetLevel(log.InfoLevel)
|
||||
log.Info("Test 'TestStreamingAcquisition'")
|
||||
|
||||
title := time.Now().String()
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -396,6 +423,7 @@ query: >
|
|||
expectedLines: 20,
|
||||
},
|
||||
}
|
||||
|
||||
for _, ts := range tests {
|
||||
t.Run(ts.name, func(t *testing.T) {
|
||||
logger := log.New()
|
||||
|
@ -407,10 +435,12 @@ query: >
|
|||
out := make(chan types.Event)
|
||||
lokiTomb := tomb.Tomb{}
|
||||
lokiSource := loki.LokiSource{}
|
||||
|
||||
err := lokiSource.Configure([]byte(ts.config), subLogger)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error : %s", err)
|
||||
}
|
||||
|
||||
err = lokiSource.StreamingAcquisition(out, &lokiTomb)
|
||||
cstest.AssertErrorContains(t, err, ts.streamErr)
|
||||
|
||||
|
@ -418,22 +448,26 @@ query: >
|
|||
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{}
|
||||
readCtx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
count := 0
|
||||
|
||||
readTomb.Go(func() error {
|
||||
defer cancel()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-readCtx.Done():
|
||||
return readCtx.Err()
|
||||
case evt := <-out:
|
||||
count++
|
||||
|
||||
if !strings.HasSuffix(evt.Line.Raw, title) {
|
||||
return fmt.Errorf("Incorrect suffix : %s", evt.Line.Raw)
|
||||
}
|
||||
|
||||
if count == ts.expectedLines {
|
||||
return nil
|
||||
}
|
||||
|
@ -447,20 +481,23 @@ query: >
|
|||
}
|
||||
|
||||
err = readTomb.Wait()
|
||||
|
||||
cancel()
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error : %s", err)
|
||||
}
|
||||
assert.Equal(t, count, ts.expectedLines)
|
||||
|
||||
assert.Equal(t, ts.expectedLines, count)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestStopStreaming(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("Skipping test on windows")
|
||||
}
|
||||
|
||||
config := `
|
||||
mode: tail
|
||||
source: loki
|
||||
|
@ -476,24 +513,30 @@ query: >
|
|||
})
|
||||
title := time.Now().String()
|
||||
lokiSource := loki.LokiSource{}
|
||||
|
||||
err := lokiSource.Configure([]byte(config), subLogger)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error : %s", err)
|
||||
}
|
||||
|
||||
out := make(chan types.Event)
|
||||
|
||||
lokiTomb := &tomb.Tomb{}
|
||||
|
||||
err = lokiSource.StreamingAcquisition(out, lokiTomb)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error : %s", err)
|
||||
}
|
||||
|
||||
time.Sleep(time.Second * 2)
|
||||
|
||||
err = feedLoki(subLogger, 1, title)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error : %s", err)
|
||||
}
|
||||
|
||||
lokiTomb.Kill(nil)
|
||||
|
||||
err = lokiTomb.Wait()
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error : %s", err)
|
||||
|
@ -519,5 +562,6 @@ func (l *LogValue) MarshalJSON() ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return []byte(fmt.Sprintf(`["%d",%s]`, l.Time.UnixNano(), string(line))), nil
|
||||
}
|
||||
|
|
|
@ -7,7 +7,8 @@ import (
|
|||
"slices"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/enescakir/emoji"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/emoji"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -84,7 +85,7 @@ func (s *ItemState) Text() string {
|
|||
}
|
||||
|
||||
// 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 {
|
||||
case s.IsLocal():
|
||||
return emoji.House
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
"os"
|
||||
"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.
|
||||
|
@ -60,6 +60,7 @@ func (i *Item) Upgrade(force bool) (bool, error) {
|
|||
// TODO: use a better way to communicate this
|
||||
fmt.Printf("updated %s\n", i.Name)
|
||||
i.hub.logger.Infof("%v %s: updated", emoji.Package, i.Name)
|
||||
|
||||
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.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
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package dumps
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
@ -8,13 +9,15 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||
"github.com/crowdsecurity/go-cs-lib/maptools"
|
||||
"github.com/enescakir/emoji"
|
||||
"github.com/fatih/color"
|
||||
diff "github.com/r3labs/diff/v2"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"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 {
|
||||
|
@ -56,7 +59,7 @@ func LoadParserDump(filepath string) (*ParserResults, error) {
|
|||
|
||||
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-- {
|
||||
if len(pdump[stages[i]]) != 0 {
|
||||
lastStage = stages[i]
|
||||
|
@ -73,7 +76,7 @@ func LoadParserDump(filepath string) (*ParserResults, error) {
|
|||
sort.Strings(parsers)
|
||||
|
||||
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]
|
||||
|
@ -90,14 +93,15 @@ func LoadParserDump(filepath string) (*ParserResults, error) {
|
|||
}
|
||||
|
||||
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)
|
||||
assoc := make(map[time.Time]string, 0)
|
||||
parser_order := make(map[string][]string)
|
||||
|
||||
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))
|
||||
|
||||
for pname, parser := range parsers {
|
||||
if len(parser) > 0 {
|
||||
parser_order[stage][parser[0].Idx-1] = pname
|
||||
|
@ -128,14 +132,14 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
|
|||
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 {
|
||||
state[evt.Line.Time] = make(map[string]map[string]ParserResult)
|
||||
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
|
||||
//we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
|
||||
// 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
|
||||
if _, ok := state[evt.Line.Time]["buckets"]; !ok {
|
||||
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()
|
||||
green := color.New(color.FgGreen).SprintFunc()
|
||||
whitelistReason := ""
|
||||
//get each line
|
||||
// get each line
|
||||
for tstamp, rawstr := range assoc {
|
||||
if opts.SkipOk {
|
||||
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]))
|
||||
|
||||
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
|
||||
//we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
|
||||
// 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
|
||||
if k == "buckets" {
|
||||
continue
|
||||
}
|
||||
|
@ -216,6 +220,7 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
|
|||
whitelistReason = parsers[parser].Evt.WhitelistReason
|
||||
}
|
||||
}
|
||||
|
||||
updated++
|
||||
case "delete":
|
||||
deleted++
|
||||
|
@ -277,7 +282,7 @@ func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpO
|
|||
sep = "├"
|
||||
}
|
||||
|
||||
//did the event enter the bucket pour phase ?
|
||||
// did the event enter the bucket pour phase ?
|
||||
if _, ok := state[tstamp]["buckets"]["OK"]; ok {
|
||||
fmt.Printf("\t%s-------- parser success %s\n", sep, emoji.GreenCircle)
|
||||
} 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)
|
||||
}
|
||||
|
||||
//now print bucket info
|
||||
// now print bucket info
|
||||
if len(state[tstamp]["buckets"]) > 0 {
|
||||
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"]))
|
||||
|
||||
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
|
||||
//we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
|
||||
// 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
|
||||
if k == "OK" {
|
||||
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…
Reference in a new issue