CI: add a CI to test parsers (#67)
This commit is contained in:
parent
c37f020da3
commit
64c5fa7360
7 changed files with 115 additions and 39 deletions
48
.github/workflows/hub-ci.yml
vendored
Normal file
48
.github/workflows/hub-ci.yml
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
name: Hub-CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Hub Parser/Scenario tests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Go 1.13
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: 1.13
|
||||
id: go
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
- name: Build release
|
||||
run: make release
|
||||
- name: clone and build hub CI tool
|
||||
run: |
|
||||
git clone https://github.com/crowdsecurity/hub-tests.git
|
||||
cd hub-tests
|
||||
make
|
||||
- name: Create crowdsec test env with all parsers from the release
|
||||
run: |
|
||||
cd crowdsec-pull
|
||||
./test_env.sh
|
||||
cd tests
|
||||
for i in `./cscli -c dev.yaml list parsers -a -o json | jq -r ".[].name" ` ; do
|
||||
./cscli -c dev.yaml install parser $i ;
|
||||
done
|
||||
- name: Setup hub ci in crowdsec
|
||||
working-directory: ./crowdsec-pull/tests/
|
||||
run: |
|
||||
cp -R ../../hub-tests/tests .
|
||||
cp ../../hub-tests/main .
|
||||
- name: Run the HUB CI
|
||||
working-directory: ./crowdsec-pull/tests/
|
||||
run: |
|
||||
for i in `find ./tests -mindepth 1 -maxdepth 1 -type d` ; do
|
||||
echo "::group::Test-${i}" ;
|
||||
./main $i || (echo "::error file=${i}::Failed test for ${i}" ; diff ${i}"/results.yaml" ${i}"/results.yaml.fail") ;
|
||||
echo "::endgroup::" ;
|
||||
done ;
|
|
@ -12,6 +12,7 @@
|
|||
<img src="https://github.com/crowdsecurity/crowdsec/workflows/build-binary-package/badge.svg">
|
||||
<img src="https://goreportcard.com/badge/github.com/crowdsecurity/crowdsec">
|
||||
<img src="https://img.shields.io/github/license/crowdsecurity/crowdsec">
|
||||
<img src="https://github.com/crowdsecurity/crowdsec/workflows/Hub-CI/badge.svg">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/acquisition"
|
||||
)
|
||||
|
||||
func loadAcquisition() (*acquisition.FileAcquisCtx, error) {
|
||||
var acquisitionCTX *acquisition.FileAcquisCtx
|
||||
var err error
|
||||
/*Init the acqusition : from cli or from acquis.yaml file*/
|
||||
if cConfig.SingleFile != "" {
|
||||
var input acquisition.FileCtx
|
||||
input.Filename = cConfig.SingleFile
|
||||
input.Mode = acquisition.CATMODE
|
||||
input.Labels = make(map[string]string)
|
||||
input.Labels["type"] = cConfig.SingleFileLabel
|
||||
acquisitionCTX, err = acquisition.InitReaderFromFileCtx([]acquisition.FileCtx{input})
|
||||
} else { /* Init file reader if we tail */
|
||||
acquisitionCTX, err = acquisition.InitReader(cConfig.AcquisitionFile)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to start file acquisition, bailout %v", err)
|
||||
}
|
||||
if acquisitionCTX == nil {
|
||||
return nil, fmt.Errorf("no inputs to process")
|
||||
}
|
||||
if cConfig.Profiling {
|
||||
acquisitionCTX.Profiling = true
|
||||
}
|
||||
|
||||
return acquisitionCTX, nil
|
||||
}
|
|
@ -294,7 +294,7 @@ func main() {
|
|||
log.Warningf("Starting processing data")
|
||||
|
||||
//Init the acqusition : from cli or from acquis.yaml file
|
||||
acquisitionCTX, err = loadAcquisition()
|
||||
acquisitionCTX, err = acquisition.LoadAcquisitionConfig(cConfig)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to start acquisition : %s", err)
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
leaky "github.com/crowdsecurity/crowdsec/pkg/leakybucket"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||
|
||||
|
@ -66,6 +67,33 @@ var ReaderHits = prometheus.NewCounterVec(
|
|||
[]string{"source"},
|
||||
)
|
||||
|
||||
func LoadAcquisitionConfig(cConfig *csconfig.CrowdSec) (*FileAcquisCtx, error) {
|
||||
var acquisitionCTX *FileAcquisCtx
|
||||
var err error
|
||||
/*Init the acqusition : from cli or from acquis.yaml file*/
|
||||
if cConfig.SingleFile != "" {
|
||||
var input FileCtx
|
||||
input.Filename = cConfig.SingleFile
|
||||
input.Mode = CATMODE
|
||||
input.Labels = make(map[string]string)
|
||||
input.Labels["type"] = cConfig.SingleFileLabel
|
||||
acquisitionCTX, err = InitReaderFromFileCtx([]FileCtx{input})
|
||||
} else { /* Init file reader if we tail */
|
||||
acquisitionCTX, err = InitReader(cConfig.AcquisitionFile)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to start file acquisition, bailout %v", err)
|
||||
}
|
||||
if acquisitionCTX == nil {
|
||||
return nil, fmt.Errorf("no inputs to process")
|
||||
}
|
||||
if cConfig.Profiling {
|
||||
acquisitionCTX.Profiling = true
|
||||
}
|
||||
|
||||
return acquisitionCTX, nil
|
||||
}
|
||||
|
||||
func InitReader(cfg string) (*FileAcquisCtx, error) {
|
||||
var files []FileCtx
|
||||
|
||||
|
|
|
@ -227,6 +227,9 @@ func stageidx(stage string, stages []string) int {
|
|||
return -1
|
||||
}
|
||||
|
||||
var ParseDump bool
|
||||
var StageParseCache map[string]map[string]types.Event
|
||||
|
||||
func /*(u types.UnixParser)*/ Parse(ctx UnixParserCtx, xp types.Event, nodes []Node) (types.Event, error) {
|
||||
var event types.Event = xp
|
||||
|
||||
|
@ -250,7 +253,14 @@ func /*(u types.UnixParser)*/ Parse(ctx UnixParserCtx, xp types.Event, nodes []N
|
|||
log.Tracef("INPUT '%s'", event.Line.Raw)
|
||||
}
|
||||
|
||||
if ParseDump {
|
||||
StageParseCache = make(map[string]map[string]types.Event)
|
||||
}
|
||||
|
||||
for _, stage := range ctx.Stages {
|
||||
if ParseDump {
|
||||
StageParseCache[stage] = make(map[string]types.Event)
|
||||
}
|
||||
/* if the node is forward in stages, seek to its stage */
|
||||
/* this is for example used by testing system to inject logs in post-syslog-parsing phase*/
|
||||
if stageidx(event.Stage, ctx.Stages) > stageidx(stage, ctx.Stages) {
|
||||
|
@ -267,14 +277,14 @@ func /*(u types.UnixParser)*/ Parse(ctx UnixParserCtx, xp types.Event, nodes []N
|
|||
|
||||
isStageOK := false
|
||||
for idx, node := range nodes {
|
||||
clog := log.WithFields(log.Fields{
|
||||
"node-name": node.rn,
|
||||
"stage": event.Stage,
|
||||
})
|
||||
//Only process current stage's nodes
|
||||
if event.Stage != node.Stage {
|
||||
continue
|
||||
}
|
||||
clog := log.WithFields(log.Fields{
|
||||
"node-name": node.rn,
|
||||
"stage": event.Stage,
|
||||
})
|
||||
clog.Tracef("Processing node %d/%d -> %s", idx, len(nodes), node.rn)
|
||||
if ctx.Profiling {
|
||||
node.Profiling = true
|
||||
|
@ -286,6 +296,13 @@ func /*(u types.UnixParser)*/ Parse(ctx UnixParserCtx, xp types.Event, nodes []N
|
|||
clog.Tracef("node (%s) ret : %v", node.rn, ret)
|
||||
if ret {
|
||||
isStageOK = true
|
||||
if ParseDump {
|
||||
evtcopy := types.Event{}
|
||||
if err := types.Clone(&event, &evtcopy); err != nil {
|
||||
log.Fatalf("while cloning Event in parser : %s", err)
|
||||
}
|
||||
StageParseCache[stage][node.Name] = evtcopy
|
||||
}
|
||||
}
|
||||
if ret && node.OnSuccess == "next_stage" {
|
||||
clog.Debugf("node successful, stop end stage %s", stage)
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
|
@ -93,3 +95,17 @@ func ConfigureLogger(clog *log.Logger) error {
|
|||
clog.SetLevel(logLevel)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Clone(a, b interface{}) error {
|
||||
|
||||
buff := new(bytes.Buffer)
|
||||
enc := gob.NewEncoder(buff)
|
||||
dec := gob.NewDecoder(buff)
|
||||
if err := enc.Encode(a); err != nil {
|
||||
return fmt.Errorf("failed cloning %T", a)
|
||||
}
|
||||
if err := dec.Decode(b); err != nil {
|
||||
return fmt.Errorf("failed cloning %T", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue