support dedicated waap rules testing in cscli hubtest
This commit is contained in:
parent
2d01e4680f
commit
e4b92af78c
3 changed files with 161 additions and 98 deletions
|
@ -19,6 +19,9 @@ import (
|
|||
)
|
||||
|
||||
var HubTest hubtest.HubTest
|
||||
var HubWaapTests hubtest.HubTest
|
||||
var hubPtr *hubtest.HubTest
|
||||
var isWaapTest bool
|
||||
|
||||
func NewHubTestCmd() *cobra.Command {
|
||||
var hubPath string
|
||||
|
@ -33,11 +36,20 @@ func NewHubTestCmd() *cobra.Command {
|
|||
DisableAutoGenTag: true,
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
var err error
|
||||
HubTest, err = hubtest.NewHubTest(hubPath, crowdsecPath, cscliPath)
|
||||
HubTest, err = hubtest.NewHubTest(hubPath, crowdsecPath, cscliPath, false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to load hubtest: %+v", err)
|
||||
}
|
||||
|
||||
HubWaapTests, err = hubtest.NewHubTest(hubPath, crowdsecPath, cscliPath, true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to load waap specific hubtest: %+v", err)
|
||||
}
|
||||
/*commands will use the hubPtr, will point to the default hubTest object, or the one dedicated to WAAP tests*/
|
||||
hubPtr = &HubTest
|
||||
if isWaapTest {
|
||||
hubPtr = &HubWaapTests
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -45,6 +57,7 @@ func NewHubTestCmd() *cobra.Command {
|
|||
cmdHubTest.PersistentFlags().StringVar(&hubPath, "hub", ".", "Path to hub folder")
|
||||
cmdHubTest.PersistentFlags().StringVar(&crowdsecPath, "crowdsec", "crowdsec", "Path to crowdsec")
|
||||
cmdHubTest.PersistentFlags().StringVar(&cscliPath, "cscli", "cscli", "Path to cscli")
|
||||
cmdHubTest.PersistentFlags().BoolVar(&isWaapTest, "waap", false, "Command relates to WAAP tests")
|
||||
|
||||
cmdHubTest.AddCommand(NewHubTestCreateCmd())
|
||||
cmdHubTest.AddCommand(NewHubTestRunCmd())
|
||||
|
@ -76,7 +89,7 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
|
|||
DisableAutoGenTag: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
testName := args[0]
|
||||
testPath := filepath.Join(HubTest.HubTestPath, testName)
|
||||
testPath := filepath.Join(hubPtr.HubTestPath, testName)
|
||||
if _, err := os.Stat(testPath); os.IsExist(err) {
|
||||
return fmt.Errorf("test '%s' already exists in '%s', exiting", testName, testPath)
|
||||
}
|
||||
|
@ -89,53 +102,76 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
|
|||
return fmt.Errorf("unable to create folder '%s': %+v", testPath, err)
|
||||
}
|
||||
|
||||
// create empty log file
|
||||
logFileName := fmt.Sprintf("%s.log", testName)
|
||||
logFilePath := filepath.Join(testPath, logFileName)
|
||||
logFile, err := os.Create(logFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logFile.Close()
|
||||
|
||||
// create empty parser assertion file
|
||||
parserAssertFilePath := filepath.Join(testPath, hubtest.ParserAssertFileName)
|
||||
parserAssertFile, err := os.Create(parserAssertFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
parserAssertFile.Close()
|
||||
|
||||
// create empty scenario assertion file
|
||||
scenarioAssertFilePath := filepath.Join(testPath, hubtest.ScenarioAssertFileName)
|
||||
scenarioAssertFile, err := os.Create(scenarioAssertFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
scenarioAssertFile.Close()
|
||||
|
||||
parsers = append(parsers, "crowdsecurity/syslog-logs")
|
||||
parsers = append(parsers, "crowdsecurity/dateparse-enrich")
|
||||
|
||||
if len(scenarios) == 0 {
|
||||
scenarios = append(scenarios, "")
|
||||
}
|
||||
|
||||
if len(postoverflows) == 0 {
|
||||
postoverflows = append(postoverflows, "")
|
||||
}
|
||||
|
||||
configFileData := &hubtest.HubTestItemConfig{
|
||||
Parsers: parsers,
|
||||
Scenarios: scenarios,
|
||||
PostOverflows: postoverflows,
|
||||
LogFile: logFileName,
|
||||
LogType: logType,
|
||||
IgnoreParsers: ignoreParsers,
|
||||
Labels: labels,
|
||||
}
|
||||
|
||||
configFilePath := filepath.Join(testPath, "config.yaml")
|
||||
|
||||
configFileData := &hubtest.HubTestItemConfig{}
|
||||
if logType == "waap" {
|
||||
//create empty nuclei template file
|
||||
nucleiFileName := fmt.Sprintf("%s.yaml", testName)
|
||||
nucleiFilePath := filepath.Join(testPath, nucleiFileName)
|
||||
nucleiFile, err := os.Create(nucleiFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nucleiFile.Close()
|
||||
configFileData.WaapRules = []string{"your_rule_here.yaml"}
|
||||
configFileData.NucleiTemplate = nucleiFileName
|
||||
fmt.Println()
|
||||
fmt.Printf(" Test name : %s\n", testName)
|
||||
fmt.Printf(" Test path : %s\n", testPath)
|
||||
fmt.Printf(" Nuclei Template : %s\n", nucleiFileName)
|
||||
} else {
|
||||
// create empty log file
|
||||
logFileName := fmt.Sprintf("%s.log", testName)
|
||||
logFilePath := filepath.Join(testPath, logFileName)
|
||||
logFile, err := os.Create(logFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logFile.Close()
|
||||
|
||||
// create empty parser assertion file
|
||||
parserAssertFilePath := filepath.Join(testPath, hubtest.ParserAssertFileName)
|
||||
parserAssertFile, err := os.Create(parserAssertFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
parserAssertFile.Close()
|
||||
// create empty scenario assertion file
|
||||
scenarioAssertFilePath := filepath.Join(testPath, hubtest.ScenarioAssertFileName)
|
||||
scenarioAssertFile, err := os.Create(scenarioAssertFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
scenarioAssertFile.Close()
|
||||
|
||||
parsers = append(parsers, "crowdsecurity/syslog-logs")
|
||||
parsers = append(parsers, "crowdsecurity/dateparse-enrich")
|
||||
|
||||
if len(scenarios) == 0 {
|
||||
scenarios = append(scenarios, "")
|
||||
}
|
||||
|
||||
if len(postoverflows) == 0 {
|
||||
postoverflows = append(postoverflows, "")
|
||||
}
|
||||
configFileData.Parsers = parsers
|
||||
configFileData.Scenarios = scenarios
|
||||
configFileData.PostOverflows = postoverflows
|
||||
configFileData.LogFile = logFileName
|
||||
configFileData.LogType = logType
|
||||
configFileData.IgnoreParsers = ignoreParsers
|
||||
configFileData.Labels = labels
|
||||
fmt.Println()
|
||||
fmt.Printf(" Test name : %s\n", testName)
|
||||
fmt.Printf(" Test path : %s\n", testPath)
|
||||
fmt.Printf(" Log file : %s (please fill it with logs)\n", logFilePath)
|
||||
fmt.Printf(" Parser assertion file : %s (please fill it with assertion)\n", parserAssertFilePath)
|
||||
fmt.Printf(" Scenario assertion file : %s (please fill it with assertion)\n", scenarioAssertFilePath)
|
||||
fmt.Printf(" Configuration File : %s (please fill it with parsers, scenarios...)\n", configFilePath)
|
||||
|
||||
}
|
||||
|
||||
fd, err := os.Create(configFilePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("open: %s", err)
|
||||
|
@ -151,14 +187,6 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
|
|||
if err := fd.Close(); err != nil {
|
||||
return fmt.Errorf("close: %s", err)
|
||||
}
|
||||
fmt.Println()
|
||||
fmt.Printf(" Test name : %s\n", testName)
|
||||
fmt.Printf(" Test path : %s\n", testPath)
|
||||
fmt.Printf(" Log file : %s (please fill it with logs)\n", logFilePath)
|
||||
fmt.Printf(" Parser assertion file : %s (please fill it with assertion)\n", parserAssertFilePath)
|
||||
fmt.Printf(" Scenario assertion file : %s (please fill it with assertion)\n", scenarioAssertFilePath)
|
||||
fmt.Printf(" Configuration File : %s (please fill it with parsers, scenarios...)\n", configFilePath)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -188,12 +216,12 @@ func NewHubTestRunCmd() *cobra.Command {
|
|||
}
|
||||
|
||||
if runAll {
|
||||
if err := HubTest.LoadAllTests(); err != nil {
|
||||
if err := hubPtr.LoadAllTests(); err != nil {
|
||||
return fmt.Errorf("unable to load all tests: %+v", err)
|
||||
}
|
||||
} else {
|
||||
for _, testName := range args {
|
||||
_, err := HubTest.LoadTestItem(testName)
|
||||
_, err := hubPtr.LoadTestItem(testName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to load test '%s': %s", testName, err)
|
||||
}
|
||||
|
@ -202,8 +230,7 @@ func NewHubTestRunCmd() *cobra.Command {
|
|||
|
||||
// set timezone to avoid DST issues
|
||||
os.Setenv("TZ", "UTC")
|
||||
|
||||
for _, test := range HubTest.Tests {
|
||||
for _, test := range hubPtr.Tests {
|
||||
if csConfig.Cscli.Output == "human" {
|
||||
log.Infof("Running test '%s'", test.Name)
|
||||
}
|
||||
|
@ -218,8 +245,8 @@ func NewHubTestRunCmd() *cobra.Command {
|
|||
PersistentPostRunE: func(cmd *cobra.Command, args []string) error {
|
||||
success := true
|
||||
testResult := make(map[string]bool)
|
||||
for _, test := range HubTest.Tests {
|
||||
if test.AutoGen {
|
||||
for _, test := range hubPtr.Tests {
|
||||
if test.AutoGen && !isWaapTest {
|
||||
if test.ParserAssert.AutoGenAssert {
|
||||
log.Warningf("Assert file '%s' is empty, generating assertion:", test.ParserAssert.File)
|
||||
fmt.Println()
|
||||
|
@ -341,7 +368,7 @@ func NewHubTestCleanCmd() *cobra.Command {
|
|||
DisableAutoGenTag: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
for _, testName := range args {
|
||||
test, err := HubTest.LoadTestItem(testName)
|
||||
test, err := hubPtr.LoadTestItem(testName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to load test '%s': %s", testName, err)
|
||||
}
|
||||
|
@ -364,17 +391,23 @@ func NewHubTestInfoCmd() *cobra.Command {
|
|||
Args: cobra.MinimumNArgs(1),
|
||||
DisableAutoGenTag: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
for _, testName := range args {
|
||||
test, err := HubTest.LoadTestItem(testName)
|
||||
test, err := hubPtr.LoadTestItem(testName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to load test '%s': %s", testName, err)
|
||||
}
|
||||
fmt.Println()
|
||||
fmt.Printf(" Test name : %s\n", test.Name)
|
||||
fmt.Printf(" Test path : %s\n", test.Path)
|
||||
fmt.Printf(" Log file : %s\n", filepath.Join(test.Path, test.Config.LogFile))
|
||||
fmt.Printf(" Parser assertion file : %s\n", filepath.Join(test.Path, hubtest.ParserAssertFileName))
|
||||
fmt.Printf(" Scenario assertion file : %s\n", filepath.Join(test.Path, hubtest.ScenarioAssertFileName))
|
||||
if isWaapTest {
|
||||
fmt.Printf(" Nuclei Template : %s\n", test.Config.NucleiTemplate)
|
||||
fmt.Printf(" Waap Rules : %s\n", strings.Join(test.Config.WaapRules, ", "))
|
||||
} else {
|
||||
fmt.Printf(" Log file : %s\n", filepath.Join(test.Path, test.Config.LogFile))
|
||||
fmt.Printf(" Parser assertion file : %s\n", filepath.Join(test.Path, hubtest.ParserAssertFileName))
|
||||
fmt.Printf(" Scenario assertion file : %s\n", filepath.Join(test.Path, hubtest.ScenarioAssertFileName))
|
||||
}
|
||||
fmt.Printf(" Configuration File : %s\n", filepath.Join(test.Path, "config.yaml"))
|
||||
}
|
||||
|
||||
|
@ -391,15 +424,15 @@ func NewHubTestListCmd() *cobra.Command {
|
|||
Short: "list",
|
||||
DisableAutoGenTag: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := HubTest.LoadAllTests(); err != nil {
|
||||
if err := hubPtr.LoadAllTests(); err != nil {
|
||||
return fmt.Errorf("unable to load all tests: %s", err)
|
||||
}
|
||||
|
||||
switch csConfig.Cscli.Output {
|
||||
case "human":
|
||||
hubTestListTable(color.Output, HubTest.Tests)
|
||||
hubTestListTable(color.Output, hubPtr.Tests)
|
||||
case "json":
|
||||
j, err := json.MarshalIndent(HubTest.Tests, " ", " ")
|
||||
j, err := json.MarshalIndent(hubPtr.Tests, " ", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -425,6 +458,7 @@ func NewHubTestCoverageCmd() *cobra.Command {
|
|||
Short: "coverage",
|
||||
DisableAutoGenTag: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
//for this one we explictely don't do for Waap
|
||||
if err := HubTest.LoadAllTests(); err != nil {
|
||||
return fmt.Errorf("unable to load all tests: %+v", err)
|
||||
}
|
||||
|
@ -529,7 +563,7 @@ func NewHubTestEvalCmd() *cobra.Command {
|
|||
DisableAutoGenTag: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
for _, testName := range args {
|
||||
test, err := HubTest.LoadTestItem(testName)
|
||||
test, err := hubPtr.LoadTestItem(testName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't load test: %+v", err)
|
||||
}
|
||||
|
|
|
@ -14,7 +14,8 @@ type HubTest struct {
|
|||
CrowdSecPath string
|
||||
CscliPath string
|
||||
HubPath string
|
||||
HubTestPath string
|
||||
HubTestPath string //generic parser/scenario tests .tests
|
||||
HubWaapTestPath string //dir specific to waap tests .waap-tests
|
||||
HubIndexFile string
|
||||
TemplateConfigPath string
|
||||
TemplateProfilePath string
|
||||
|
@ -33,7 +34,7 @@ const (
|
|||
templateWaapProfilePath = "template_waap-profile.yaml"
|
||||
)
|
||||
|
||||
func NewHubTest(hubPath string, crowdsecPath string, cscliPath string) (HubTest, error) {
|
||||
func NewHubTest(hubPath string, crowdsecPath string, cscliPath string, isWaapTest bool) (HubTest, error) {
|
||||
hubPath, err := filepath.Abs(hubPath)
|
||||
if err != nil {
|
||||
return HubTest{}, fmt.Errorf("can't get absolute path of hub: %+v", err)
|
||||
|
@ -43,9 +44,6 @@ func NewHubTest(hubPath string, crowdsecPath string, cscliPath string) (HubTest,
|
|||
if _, err = os.Stat(hubPath); os.IsNotExist(err) {
|
||||
return HubTest{}, fmt.Errorf("path to hub '%s' doesn't exist, can't run", hubPath)
|
||||
}
|
||||
|
||||
HubTestPath := filepath.Join(hubPath, "./.tests/")
|
||||
|
||||
// we can't use hubtest without crowdsec binary
|
||||
if _, err = exec.LookPath(crowdsecPath); err != nil {
|
||||
if _, err = os.Stat(crowdsecPath); os.IsNotExist(err) {
|
||||
|
@ -60,6 +58,39 @@ func NewHubTest(hubPath string, crowdsecPath string, cscliPath string) (HubTest,
|
|||
}
|
||||
}
|
||||
|
||||
if isWaapTest {
|
||||
HubTestPath := filepath.Join(hubPath, "./.waap-tests/")
|
||||
hubIndexFile := filepath.Join(hubPath, ".index.json")
|
||||
|
||||
local := &csconfig.LocalHubCfg{
|
||||
HubDir: hubPath,
|
||||
HubIndexFile: hubIndexFile,
|
||||
InstallDir: HubTestPath,
|
||||
InstallDataDir: HubTestPath,
|
||||
}
|
||||
|
||||
hub, err := cwhub.NewHub(local, nil, false)
|
||||
if err != nil {
|
||||
return HubTest{}, fmt.Errorf("unable to load hub: %s", err)
|
||||
}
|
||||
|
||||
return HubTest{
|
||||
CrowdSecPath: crowdsecPath,
|
||||
CscliPath: cscliPath,
|
||||
HubPath: hubPath,
|
||||
HubTestPath: HubTestPath,
|
||||
HubIndexFile: hubIndexFile,
|
||||
TemplateConfigPath: filepath.Join(HubTestPath, templateConfigFile),
|
||||
TemplateProfilePath: filepath.Join(HubTestPath, templateProfileFile),
|
||||
TemplateSimulationPath: filepath.Join(HubTestPath, templateSimulationFile),
|
||||
TemplateWaapProfilePath: filepath.Join(HubTestPath, templateWaapProfilePath),
|
||||
TemplateAcquisPath: filepath.Join(HubTestPath, templateAcquisFile),
|
||||
HubIndex: hub,
|
||||
}, nil
|
||||
}
|
||||
|
||||
HubTestPath := filepath.Join(hubPath, "./.tests/")
|
||||
|
||||
hubIndexFile := filepath.Join(hubPath, ".index.json")
|
||||
|
||||
local := &csconfig.LocalHubCfg{
|
||||
|
@ -75,17 +106,15 @@ func NewHubTest(hubPath string, crowdsecPath string, cscliPath string) (HubTest,
|
|||
}
|
||||
|
||||
return HubTest{
|
||||
CrowdSecPath: crowdsecPath,
|
||||
CscliPath: cscliPath,
|
||||
HubPath: hubPath,
|
||||
HubTestPath: HubTestPath,
|
||||
HubIndexFile: hubIndexFile,
|
||||
TemplateConfigPath: filepath.Join(HubTestPath, templateConfigFile),
|
||||
TemplateProfilePath: filepath.Join(HubTestPath, templateProfileFile),
|
||||
TemplateSimulationPath: filepath.Join(HubTestPath, templateSimulationFile),
|
||||
TemplateWaapProfilePath: filepath.Join(HubTestPath, templateWaapProfilePath),
|
||||
TemplateAcquisPath: filepath.Join(HubTestPath, templateAcquisFile),
|
||||
HubIndex: hub,
|
||||
CrowdSecPath: crowdsecPath,
|
||||
CscliPath: cscliPath,
|
||||
HubPath: hubPath,
|
||||
HubTestPath: HubTestPath,
|
||||
HubIndexFile: hubIndexFile,
|
||||
TemplateConfigPath: filepath.Join(HubTestPath, templateConfigFile),
|
||||
TemplateProfilePath: filepath.Join(HubTestPath, templateProfileFile),
|
||||
TemplateSimulationPath: filepath.Join(HubTestPath, templateSimulationFile),
|
||||
HubIndex: hub,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -19,17 +19,17 @@ import (
|
|||
)
|
||||
|
||||
type HubTestItemConfig struct {
|
||||
Parsers []string `yaml:"parsers"`
|
||||
Scenarios []string `yaml:"scenarios"`
|
||||
PostOverflows []string `yaml:"postoverflows"`
|
||||
WaapRules []string `yaml:"waap-rules"`
|
||||
NucleiTemplate string `yaml:"nuclei_template"`
|
||||
ExpectedNucleiFailure bool `yaml:"expect_failure"`
|
||||
LogFile string `yaml:"log_file"`
|
||||
LogType string `yaml:"log_type"`
|
||||
Labels map[string]string `yaml:"labels"`
|
||||
IgnoreParsers bool `yaml:"ignore_parsers"` // if we test a scenario, we don't want to assert on Parser
|
||||
OverrideStatics []parser.ExtraField `yaml:"override_statics"` //Allow to override statics. Executed before s00
|
||||
Parsers []string `yaml:"parsers,omitempty"`
|
||||
Scenarios []string `yaml:"scenarios,omitempty"`
|
||||
PostOverflows []string `yaml:"postoverflows,omitempty"`
|
||||
WaapRules []string `yaml:"waap-rules,omitempty"`
|
||||
NucleiTemplate string `yaml:"nuclei_template,omitempty"`
|
||||
ExpectedNucleiFailure bool `yaml:"expect_failure,omitempty"`
|
||||
LogFile string `yaml:"log_file,omitempty"`
|
||||
LogType string `yaml:"log_type,omitempty"`
|
||||
Labels map[string]string `yaml:"labels,omitempty"`
|
||||
IgnoreParsers bool `yaml:"ignore_parsers,omitempty"` // if we test a scenario, we don't want to assert on Parser
|
||||
OverrideStatics []parser.ExtraField `yaml:"override_statics,omitempty"` //Allow to override statics. Executed before s00
|
||||
}
|
||||
|
||||
type HubTestItem struct {
|
||||
|
|
Loading…
Reference in a new issue