refact cscli (globals) (#2854)
* cscli capi: avoid globals, extract methods * cscli config restore: avoid global * cscli hubtest: avoid global * lint (whitespace, wrapped errors)
This commit is contained in:
parent
0df8f54fbb
commit
e34af358d7
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"slices"
|
"slices"
|
||||||
|
@ -58,13 +59,16 @@ Note: This command requires database direct access, so is intended to be run on
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
PersistentPreRunE: func(_ *cobra.Command, _ []string) error {
|
PersistentPreRunE: func(_ *cobra.Command, _ []string) error {
|
||||||
var err error
|
var err error
|
||||||
if err = require.LAPI(cli.cfg()); err != nil {
|
|
||||||
|
cfg := cli.cfg()
|
||||||
|
|
||||||
|
if err = require.LAPI(cfg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cli.db, err = database.NewClient(cli.cfg().DbConfig)
|
cli.db, err = database.NewClient(cfg.DbConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't connect to the database: %s", err)
|
return fmt.Errorf("can't connect to the database: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -84,7 +88,7 @@ func (cli *cliBouncers) list() error {
|
||||||
|
|
||||||
bouncers, err := cli.db.ListBouncers()
|
bouncers, err := cli.db.ListBouncers()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to list bouncers: %s", err)
|
return fmt.Errorf("unable to list bouncers: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch cli.cfg().Cscli.Output {
|
switch cli.cfg().Cscli.Output {
|
||||||
|
@ -146,13 +150,13 @@ func (cli *cliBouncers) add(bouncerName string, key string) error {
|
||||||
if key == "" {
|
if key == "" {
|
||||||
key, err = middlewares.GenerateAPIKey(keyLength)
|
key, err = middlewares.GenerateAPIKey(keyLength)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to generate api key: %s", err)
|
return fmt.Errorf("unable to generate api key: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = cli.db.CreateBouncer(bouncerName, "", middlewares.HashSHA512(key), types.ApiKeyAuthType)
|
_, err = cli.db.CreateBouncer(bouncerName, "", middlewares.HashSHA512(key), types.ApiKeyAuthType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to create bouncer: %s", err)
|
return fmt.Errorf("unable to create bouncer: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch cli.cfg().Cscli.Output {
|
switch cli.cfg().Cscli.Output {
|
||||||
|
@ -165,7 +169,7 @@ func (cli *cliBouncers) add(bouncerName string, key string) error {
|
||||||
case "json":
|
case "json":
|
||||||
j, err := json.Marshal(key)
|
j, err := json.Marshal(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to marshal api key")
|
return errors.New("unable to marshal api key")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Print(string(j))
|
fmt.Print(string(j))
|
||||||
|
@ -191,7 +195,7 @@ cscli bouncers add MyBouncerName --key <random-key>`,
|
||||||
|
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
flags.StringP("length", "l", "", "length of the api key")
|
flags.StringP("length", "l", "", "length of the api key")
|
||||||
flags.MarkDeprecated("length", "use --key instead")
|
_ = flags.MarkDeprecated("length", "use --key instead")
|
||||||
flags.StringVarP(&key, "key", "k", "", "api key for the bouncer")
|
flags.StringVarP(&key, "key", "k", "", "api key for the bouncer")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
@ -218,7 +222,7 @@ func (cli *cliBouncers) delete(bouncers []string) error {
|
||||||
for _, bouncerID := range bouncers {
|
for _, bouncerID := range bouncers {
|
||||||
err := cli.db.DeleteBouncer(bouncerID)
|
err := cli.db.DeleteBouncer(bouncerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to delete bouncer '%s': %s", bouncerID, err)
|
return fmt.Errorf("unable to delete bouncer '%s': %w", bouncerID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("bouncer '%s' deleted successfully", bouncerID)
|
log.Infof("bouncer '%s' deleted successfully", bouncerID)
|
||||||
|
@ -280,7 +284,7 @@ func (cli *cliBouncers) prune(duration time.Duration, force bool) error {
|
||||||
|
|
||||||
deleted, err := cli.db.BulkDeleteBouncers(bouncers)
|
deleted, err := cli.db.BulkDeleteBouncers(bouncers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to prune bouncers: %s", err)
|
return fmt.Errorf("unable to prune bouncers: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Successfully deleted %d bouncers\n", deleted)
|
fmt.Fprintf(os.Stderr, "Successfully deleted %d bouncers\n", deleted)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
@ -26,24 +27,29 @@ const (
|
||||||
CAPIURLPrefix = "v3"
|
CAPIURLPrefix = "v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type cliCapi struct{}
|
type cliCapi struct {
|
||||||
|
cfg configGetter
|
||||||
func NewCLICapi() *cliCapi {
|
|
||||||
return &cliCapi{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli cliCapi) NewCommand() *cobra.Command {
|
func NewCLICapi(cfg configGetter) *cliCapi {
|
||||||
var cmd = &cobra.Command{
|
return &cliCapi{
|
||||||
|
cfg: cfg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cli *cliCapi) NewCommand() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
Use: "capi [action]",
|
Use: "capi [action]",
|
||||||
Short: "Manage interaction with Central API (CAPI)",
|
Short: "Manage interaction with Central API (CAPI)",
|
||||||
Args: cobra.MinimumNArgs(1),
|
Args: cobra.MinimumNArgs(1),
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
PersistentPreRunE: func(_ *cobra.Command, _ []string) error {
|
PersistentPreRunE: func(_ *cobra.Command, _ []string) error {
|
||||||
if err := require.LAPI(csConfig); err != nil {
|
cfg := cli.cfg()
|
||||||
|
if err := require.LAPI(cfg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := require.CAPI(csConfig); err != nil {
|
if err := require.CAPI(cfg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,34 +57,27 @@ func (cli cliCapi) NewCommand() *cobra.Command {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.AddCommand(cli.NewRegisterCmd())
|
cmd.AddCommand(cli.newRegisterCmd())
|
||||||
cmd.AddCommand(cli.NewStatusCmd())
|
cmd.AddCommand(cli.newStatusCmd())
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli cliCapi) NewRegisterCmd() *cobra.Command {
|
func (cli *cliCapi) register(capiUserPrefix string, outputFile string) error {
|
||||||
var (
|
cfg := cli.cfg()
|
||||||
capiUserPrefix string
|
|
||||||
outputFile string
|
|
||||||
)
|
|
||||||
|
|
||||||
var cmd = &cobra.Command{
|
|
||||||
Use: "register",
|
|
||||||
Short: "Register to Central API (CAPI)",
|
|
||||||
Args: cobra.MinimumNArgs(0),
|
|
||||||
DisableAutoGenTag: true,
|
|
||||||
RunE: func(_ *cobra.Command, _ []string) error {
|
|
||||||
var err error
|
|
||||||
capiUser, err := generateID(capiUserPrefix)
|
capiUser, err := generateID(capiUserPrefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to generate machine id: %s", err)
|
return fmt.Errorf("unable to generate machine id: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
password := strfmt.Password(generatePassword(passwordLength))
|
password := strfmt.Password(generatePassword(passwordLength))
|
||||||
|
|
||||||
apiurl, err := url.Parse(types.CAPIBaseURL)
|
apiurl, err := url.Parse(types.CAPIBaseURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to parse api url %s: %w", types.CAPIBaseURL, err)
|
return fmt.Errorf("unable to parse api url %s: %w", types.CAPIBaseURL, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = apiclient.RegisterClient(&apiclient.Config{
|
_, err = apiclient.RegisterClient(&apiclient.Config{
|
||||||
MachineID: capiUser,
|
MachineID: capiUser,
|
||||||
Password: password,
|
Password: password,
|
||||||
|
@ -90,32 +89,38 @@ func (cli cliCapi) NewRegisterCmd() *cobra.Command {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("api client register ('%s'): %w", types.CAPIBaseURL, err)
|
return fmt.Errorf("api client register ('%s'): %w", types.CAPIBaseURL, err)
|
||||||
}
|
}
|
||||||
log.Printf("Successfully registered to Central API (CAPI)")
|
|
||||||
|
log.Infof("Successfully registered to Central API (CAPI)")
|
||||||
|
|
||||||
var dumpFile string
|
var dumpFile string
|
||||||
|
|
||||||
if outputFile != "" {
|
switch {
|
||||||
|
case outputFile != "":
|
||||||
dumpFile = outputFile
|
dumpFile = outputFile
|
||||||
} else if csConfig.API.Server.OnlineClient.CredentialsFilePath != "" {
|
case cfg.API.Server.OnlineClient.CredentialsFilePath != "":
|
||||||
dumpFile = csConfig.API.Server.OnlineClient.CredentialsFilePath
|
dumpFile = cfg.API.Server.OnlineClient.CredentialsFilePath
|
||||||
} else {
|
default:
|
||||||
dumpFile = ""
|
dumpFile = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
apiCfg := csconfig.ApiCredentialsCfg{
|
apiCfg := csconfig.ApiCredentialsCfg{
|
||||||
Login: capiUser,
|
Login: capiUser,
|
||||||
Password: password.String(),
|
Password: password.String(),
|
||||||
URL: types.CAPIBaseURL,
|
URL: types.CAPIBaseURL,
|
||||||
}
|
}
|
||||||
|
|
||||||
apiConfigDump, err := yaml.Marshal(apiCfg)
|
apiConfigDump, err := yaml.Marshal(apiCfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to marshal api credentials: %w", err)
|
return fmt.Errorf("unable to marshal api credentials: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if dumpFile != "" {
|
if dumpFile != "" {
|
||||||
err = os.WriteFile(dumpFile, apiConfigDump, 0o600)
|
err = os.WriteFile(dumpFile, apiConfigDump, 0o600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("write api credentials in '%s' failed: %w", dumpFile, err)
|
return fmt.Errorf("write api credentials in '%s' failed: %w", dumpFile, err)
|
||||||
}
|
}
|
||||||
log.Printf("Central API credentials written to '%s'", dumpFile)
|
|
||||||
|
log.Infof("Central API credentials written to '%s'", dumpFile)
|
||||||
} else {
|
} else {
|
||||||
fmt.Println(string(apiConfigDump))
|
fmt.Println(string(apiConfigDump))
|
||||||
}
|
}
|
||||||
|
@ -123,6 +128,21 @@ func (cli cliCapi) NewRegisterCmd() *cobra.Command {
|
||||||
log.Warning(ReloadMessage())
|
log.Warning(ReloadMessage())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cli *cliCapi) newRegisterCmd() *cobra.Command {
|
||||||
|
var (
|
||||||
|
capiUserPrefix string
|
||||||
|
outputFile string
|
||||||
|
)
|
||||||
|
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "register",
|
||||||
|
Short: "Register to Central API (CAPI)",
|
||||||
|
Args: cobra.MinimumNArgs(0),
|
||||||
|
DisableAutoGenTag: true,
|
||||||
|
RunE: func(_ *cobra.Command, _ []string) error {
|
||||||
|
return cli.register(capiUserPrefix, outputFile)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,25 +156,21 @@ func (cli cliCapi) NewRegisterCmd() *cobra.Command {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli cliCapi) NewStatusCmd() *cobra.Command {
|
func (cli *cliCapi) status() error {
|
||||||
cmd := &cobra.Command{
|
cfg := cli.cfg()
|
||||||
Use: "status",
|
|
||||||
Short: "Check status with the Central API (CAPI)",
|
if err := require.CAPIRegistered(cfg); err != nil {
|
||||||
Args: cobra.MinimumNArgs(0),
|
|
||||||
DisableAutoGenTag: true,
|
|
||||||
RunE: func(_ *cobra.Command, _ []string) error {
|
|
||||||
if err := require.CAPIRegistered(csConfig); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
password := strfmt.Password(csConfig.API.Server.OnlineClient.Credentials.Password)
|
password := strfmt.Password(cfg.API.Server.OnlineClient.Credentials.Password)
|
||||||
|
|
||||||
apiurl, err := url.Parse(csConfig.API.Server.OnlineClient.Credentials.URL)
|
apiurl, err := url.Parse(cfg.API.Server.OnlineClient.Credentials.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("parsing api url ('%s'): %w", csConfig.API.Server.OnlineClient.Credentials.URL, err)
|
return fmt.Errorf("parsing api url ('%s'): %w", cfg.API.Server.OnlineClient.Credentials.URL, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
hub, err := require.Hub(csConfig, nil, nil)
|
hub, err := require.Hub(cfg, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -165,7 +181,7 @@ func (cli cliCapi) NewStatusCmd() *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(scenarios) == 0 {
|
if len(scenarios) == 0 {
|
||||||
return fmt.Errorf("no scenarios installed, abort")
|
return errors.New("no scenarios installed, abort")
|
||||||
}
|
}
|
||||||
|
|
||||||
Client, err = apiclient.NewDefaultClient(apiurl, CAPIURLPrefix, fmt.Sprintf("crowdsec/%s", version.String()), nil)
|
Client, err = apiclient.NewDefaultClient(apiurl, CAPIURLPrefix, fmt.Sprintf("crowdsec/%s", version.String()), nil)
|
||||||
|
@ -174,21 +190,32 @@ func (cli cliCapi) NewStatusCmd() *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
t := models.WatcherAuthRequest{
|
t := models.WatcherAuthRequest{
|
||||||
MachineID: &csConfig.API.Server.OnlineClient.Credentials.Login,
|
MachineID: &cfg.API.Server.OnlineClient.Credentials.Login,
|
||||||
Password: &password,
|
Password: &password,
|
||||||
Scenarios: scenarios,
|
Scenarios: scenarios,
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("Loaded credentials from %s", csConfig.API.Server.OnlineClient.CredentialsFilePath)
|
log.Infof("Loaded credentials from %s", cfg.API.Server.OnlineClient.CredentialsFilePath)
|
||||||
log.Infof("Trying to authenticate with username %s on %s", csConfig.API.Server.OnlineClient.Credentials.Login, apiurl)
|
log.Infof("Trying to authenticate with username %s on %s", cfg.API.Server.OnlineClient.Credentials.Login, apiurl)
|
||||||
|
|
||||||
_, _, err = Client.Auth.AuthenticateWatcher(context.Background(), t)
|
_, _, err = Client.Auth.AuthenticateWatcher(context.Background(), t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to authenticate to Central API (CAPI): %w", err)
|
return fmt.Errorf("failed to authenticate to Central API (CAPI): %w", err)
|
||||||
}
|
}
|
||||||
log.Infof("You can successfully interact with Central API (CAPI)")
|
|
||||||
|
log.Info("You can successfully interact with Central API (CAPI)")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cli *cliCapi) newStatusCmd() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "status",
|
||||||
|
Short: "Check status with the Central API (CAPI)",
|
||||||
|
Args: cobra.MinimumNArgs(0),
|
||||||
|
DisableAutoGenTag: true,
|
||||||
|
RunE: func(_ *cobra.Command, _ []string) error {
|
||||||
|
return cli.status()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (cli *cliConfig) restoreHub(dirPath string) error {
|
func (cli *cliConfig) restoreHub(dirPath string) error {
|
||||||
hub, err := require.Hub(csConfig, require.RemoteHub(csConfig), nil)
|
cfg := cli.cfg()
|
||||||
|
|
||||||
|
hub, err := require.Hub(cfg, require.RemoteHub(cfg), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -71,7 +73,7 @@ func (cli *cliConfig) restoreHub(dirPath string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
stage := file.Name()
|
stage := file.Name()
|
||||||
stagedir := fmt.Sprintf("%s/%s/%s/", csConfig.ConfigPaths.ConfigDir, itype, stage)
|
stagedir := fmt.Sprintf("%s/%s/%s/", cfg.ConfigPaths.ConfigDir, itype, stage)
|
||||||
log.Debugf("Found stage %s in %s, target directory : %s", stage, itype, stagedir)
|
log.Debugf("Found stage %s in %s, target directory : %s", stage, itype, stagedir)
|
||||||
|
|
||||||
if err = os.MkdirAll(stagedir, os.ModePerm); err != nil {
|
if err = os.MkdirAll(stagedir, os.ModePerm); err != nil {
|
||||||
|
@ -99,7 +101,7 @@ func (cli *cliConfig) restoreHub(dirPath string) error {
|
||||||
} else {
|
} else {
|
||||||
log.Infof("Going to restore local/tainted [%s]", file.Name())
|
log.Infof("Going to restore local/tainted [%s]", file.Name())
|
||||||
sourceFile := fmt.Sprintf("%s/%s", itemDirectory, file.Name())
|
sourceFile := fmt.Sprintf("%s/%s", itemDirectory, file.Name())
|
||||||
destinationFile := fmt.Sprintf("%s/%s/%s", csConfig.ConfigPaths.ConfigDir, itype, file.Name())
|
destinationFile := fmt.Sprintf("%s/%s/%s", cfg.ConfigPaths.ConfigDir, itype, file.Name())
|
||||||
|
|
||||||
if err = CopyFile(sourceFile, destinationFile); err != nil {
|
if err = CopyFile(sourceFile, destinationFile); err != nil {
|
||||||
return fmt.Errorf("failed copy %s %s to %s: %w", itype, sourceFile, destinationFile, err)
|
return fmt.Errorf("failed copy %s %s to %s: %w", itype, sourceFile, destinationFile, err)
|
||||||
|
@ -127,17 +129,19 @@ func (cli *cliConfig) restoreHub(dirPath string) error {
|
||||||
func (cli *cliConfig) restore(dirPath string) error {
|
func (cli *cliConfig) restore(dirPath string) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
cfg := cli.cfg()
|
||||||
|
|
||||||
backupMain := fmt.Sprintf("%s/config.yaml", dirPath)
|
backupMain := fmt.Sprintf("%s/config.yaml", dirPath)
|
||||||
if _, err = os.Stat(backupMain); err == nil {
|
if _, err = os.Stat(backupMain); err == nil {
|
||||||
if csConfig.ConfigPaths != nil && csConfig.ConfigPaths.ConfigDir != "" {
|
if cfg.ConfigPaths != nil && cfg.ConfigPaths.ConfigDir != "" {
|
||||||
if err = CopyFile(backupMain, fmt.Sprintf("%s/config.yaml", csConfig.ConfigPaths.ConfigDir)); err != nil {
|
if err = CopyFile(backupMain, fmt.Sprintf("%s/config.yaml", cfg.ConfigPaths.ConfigDir)); err != nil {
|
||||||
return fmt.Errorf("failed copy %s to %s: %w", backupMain, csConfig.ConfigPaths.ConfigDir, err)
|
return fmt.Errorf("failed copy %s to %s: %w", backupMain, cfg.ConfigPaths.ConfigDir, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we have config.yaml, we should regenerate config struct to have rights paths etc
|
// Now we have config.yaml, we should regenerate config struct to have rights paths etc
|
||||||
ConfigFilePath = fmt.Sprintf("%s/config.yaml", csConfig.ConfigPaths.ConfigDir)
|
ConfigFilePath = fmt.Sprintf("%s/config.yaml", cfg.ConfigPaths.ConfigDir)
|
||||||
|
|
||||||
log.Debug("Reloading configuration")
|
log.Debug("Reloading configuration")
|
||||||
|
|
||||||
|
@ -146,38 +150,40 @@ func (cli *cliConfig) restore(dirPath string) error {
|
||||||
return fmt.Errorf("failed to reload configuration: %w", err)
|
return fmt.Errorf("failed to reload configuration: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg = cli.cfg()
|
||||||
|
|
||||||
backupCAPICreds := fmt.Sprintf("%s/online_api_credentials.yaml", dirPath)
|
backupCAPICreds := fmt.Sprintf("%s/online_api_credentials.yaml", dirPath)
|
||||||
if _, err = os.Stat(backupCAPICreds); err == nil {
|
if _, err = os.Stat(backupCAPICreds); err == nil {
|
||||||
if err = CopyFile(backupCAPICreds, csConfig.API.Server.OnlineClient.CredentialsFilePath); err != nil {
|
if err = CopyFile(backupCAPICreds, cfg.API.Server.OnlineClient.CredentialsFilePath); err != nil {
|
||||||
return fmt.Errorf("failed copy %s to %s: %w", backupCAPICreds, csConfig.API.Server.OnlineClient.CredentialsFilePath, err)
|
return fmt.Errorf("failed copy %s to %s: %w", backupCAPICreds, cfg.API.Server.OnlineClient.CredentialsFilePath, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backupLAPICreds := fmt.Sprintf("%s/local_api_credentials.yaml", dirPath)
|
backupLAPICreds := fmt.Sprintf("%s/local_api_credentials.yaml", dirPath)
|
||||||
if _, err = os.Stat(backupLAPICreds); err == nil {
|
if _, err = os.Stat(backupLAPICreds); err == nil {
|
||||||
if err = CopyFile(backupLAPICreds, csConfig.API.Client.CredentialsFilePath); err != nil {
|
if err = CopyFile(backupLAPICreds, cfg.API.Client.CredentialsFilePath); err != nil {
|
||||||
return fmt.Errorf("failed copy %s to %s: %w", backupLAPICreds, csConfig.API.Client.CredentialsFilePath, err)
|
return fmt.Errorf("failed copy %s to %s: %w", backupLAPICreds, cfg.API.Client.CredentialsFilePath, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backupProfiles := fmt.Sprintf("%s/profiles.yaml", dirPath)
|
backupProfiles := fmt.Sprintf("%s/profiles.yaml", dirPath)
|
||||||
if _, err = os.Stat(backupProfiles); err == nil {
|
if _, err = os.Stat(backupProfiles); err == nil {
|
||||||
if err = CopyFile(backupProfiles, csConfig.API.Server.ProfilesPath); err != nil {
|
if err = CopyFile(backupProfiles, cfg.API.Server.ProfilesPath); err != nil {
|
||||||
return fmt.Errorf("failed copy %s to %s: %w", backupProfiles, csConfig.API.Server.ProfilesPath, err)
|
return fmt.Errorf("failed copy %s to %s: %w", backupProfiles, cfg.API.Server.ProfilesPath, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backupSimulation := fmt.Sprintf("%s/simulation.yaml", dirPath)
|
backupSimulation := fmt.Sprintf("%s/simulation.yaml", dirPath)
|
||||||
if _, err = os.Stat(backupSimulation); err == nil {
|
if _, err = os.Stat(backupSimulation); err == nil {
|
||||||
if err = CopyFile(backupSimulation, csConfig.ConfigPaths.SimulationFilePath); err != nil {
|
if err = CopyFile(backupSimulation, cfg.ConfigPaths.SimulationFilePath); err != nil {
|
||||||
return fmt.Errorf("failed copy %s to %s: %w", backupSimulation, csConfig.ConfigPaths.SimulationFilePath, err)
|
return fmt.Errorf("failed copy %s to %s: %w", backupSimulation, cfg.ConfigPaths.SimulationFilePath, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if there is a acquisition dir, restore its content*/
|
/*if there is a acquisition dir, restore its content*/
|
||||||
if csConfig.Crowdsec.AcquisitionDirPath != "" {
|
if cfg.Crowdsec.AcquisitionDirPath != "" {
|
||||||
if err = os.MkdirAll(csConfig.Crowdsec.AcquisitionDirPath, 0o700); err != nil {
|
if err = os.MkdirAll(cfg.Crowdsec.AcquisitionDirPath, 0o700); err != nil {
|
||||||
return fmt.Errorf("error while creating %s: %w", csConfig.Crowdsec.AcquisitionDirPath, err)
|
return fmt.Errorf("error while creating %s: %w", cfg.Crowdsec.AcquisitionDirPath, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,8 +192,8 @@ func (cli *cliConfig) restore(dirPath string) error {
|
||||||
if _, err = os.Stat(backupAcquisition); err == nil {
|
if _, err = os.Stat(backupAcquisition); err == nil {
|
||||||
log.Debugf("restoring backup'ed %s", backupAcquisition)
|
log.Debugf("restoring backup'ed %s", backupAcquisition)
|
||||||
|
|
||||||
if err = CopyFile(backupAcquisition, csConfig.Crowdsec.AcquisitionFilePath); err != nil {
|
if err = CopyFile(backupAcquisition, cfg.Crowdsec.AcquisitionFilePath); err != nil {
|
||||||
return fmt.Errorf("failed copy %s to %s: %w", backupAcquisition, csConfig.Crowdsec.AcquisitionFilePath, err)
|
return fmt.Errorf("failed copy %s to %s: %w", backupAcquisition, cfg.Crowdsec.AcquisitionFilePath, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +201,7 @@ func (cli *cliConfig) restore(dirPath string) error {
|
||||||
acquisBackupDir := filepath.Join(dirPath, "acquis", "*.yaml")
|
acquisBackupDir := filepath.Join(dirPath, "acquis", "*.yaml")
|
||||||
if acquisFiles, err := filepath.Glob(acquisBackupDir); err == nil {
|
if acquisFiles, err := filepath.Glob(acquisBackupDir); err == nil {
|
||||||
for _, acquisFile := range acquisFiles {
|
for _, acquisFile := range acquisFiles {
|
||||||
targetFname, err := filepath.Abs(csConfig.Crowdsec.AcquisitionDirPath + "/" + filepath.Base(acquisFile))
|
targetFname, err := filepath.Abs(cfg.Crowdsec.AcquisitionDirPath + "/" + filepath.Base(acquisFile))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("while saving %s to %s: %w", acquisFile, targetFname, err)
|
return fmt.Errorf("while saving %s to %s: %w", acquisFile, targetFname, err)
|
||||||
}
|
}
|
||||||
|
@ -208,12 +214,12 @@ func (cli *cliConfig) restore(dirPath string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if csConfig.Crowdsec != nil && len(csConfig.Crowdsec.AcquisitionFiles) > 0 {
|
if cfg.Crowdsec != nil && len(cfg.Crowdsec.AcquisitionFiles) > 0 {
|
||||||
for _, acquisFile := range csConfig.Crowdsec.AcquisitionFiles {
|
for _, acquisFile := range cfg.Crowdsec.AcquisitionFiles {
|
||||||
log.Infof("backup filepath from dir -> %s", acquisFile)
|
log.Infof("backup filepath from dir -> %s", acquisFile)
|
||||||
|
|
||||||
// if it was the default one, it has already been backed up
|
// if it was the default one, it has already been backed up
|
||||||
if csConfig.Crowdsec.AcquisitionFilePath == acquisFile {
|
if cfg.Crowdsec.AcquisitionFilePath == acquisFile {
|
||||||
log.Infof("skip this one")
|
log.Infof("skip this one")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
|
@ -20,21 +21,29 @@ import (
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/hubtest"
|
"github.com/crowdsecurity/crowdsec/pkg/hubtest"
|
||||||
)
|
)
|
||||||
|
|
||||||
var HubTest hubtest.HubTest
|
var (
|
||||||
var HubAppsecTests hubtest.HubTest
|
HubTest hubtest.HubTest
|
||||||
var hubPtr *hubtest.HubTest
|
HubAppsecTests hubtest.HubTest
|
||||||
var isAppsecTest bool
|
hubPtr *hubtest.HubTest
|
||||||
|
isAppsecTest bool
|
||||||
|
)
|
||||||
|
|
||||||
type cliHubTest struct{}
|
type cliHubTest struct {
|
||||||
|
cfg configGetter
|
||||||
func NewCLIHubTest() *cliHubTest {
|
|
||||||
return &cliHubTest{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli cliHubTest) NewCommand() *cobra.Command {
|
func NewCLIHubTest(cfg configGetter) *cliHubTest {
|
||||||
var hubPath string
|
return &cliHubTest{
|
||||||
var crowdsecPath string
|
cfg: cfg,
|
||||||
var cscliPath string
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cli *cliHubTest) NewCommand() *cobra.Command {
|
||||||
|
var (
|
||||||
|
hubPath string
|
||||||
|
crowdsecPath string
|
||||||
|
cscliPath string
|
||||||
|
)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "hubtest",
|
Use: "hubtest",
|
||||||
|
@ -53,11 +62,13 @@ func (cli cliHubTest) NewCommand() *cobra.Command {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to load appsec specific hubtest: %+v", err)
|
return fmt.Errorf("unable to load appsec specific hubtest: %+v", err)
|
||||||
}
|
}
|
||||||
/*commands will use the hubPtr, will point to the default hubTest object, or the one dedicated to appsec tests*/
|
|
||||||
|
// commands will use the hubPtr, will point to the default hubTest object, or the one dedicated to appsec tests
|
||||||
hubPtr = &HubTest
|
hubPtr = &HubTest
|
||||||
if isAppsecTest {
|
if isAppsecTest {
|
||||||
hubPtr = &HubAppsecTests
|
hubPtr = &HubAppsecTests
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -79,13 +90,16 @@ func (cli cliHubTest) NewCommand() *cobra.Command {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli cliHubTest) NewCreateCmd() *cobra.Command {
|
func (cli *cliHubTest) NewCreateCmd() *cobra.Command {
|
||||||
|
var (
|
||||||
|
ignoreParsers bool
|
||||||
|
labels map[string]string
|
||||||
|
logType string
|
||||||
|
)
|
||||||
|
|
||||||
parsers := []string{}
|
parsers := []string{}
|
||||||
postoverflows := []string{}
|
postoverflows := []string{}
|
||||||
scenarios := []string{}
|
scenarios := []string{}
|
||||||
var ignoreParsers bool
|
|
||||||
var labels map[string]string
|
|
||||||
var logType string
|
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "create",
|
Use: "create",
|
||||||
|
@ -107,7 +121,7 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
|
||||||
}
|
}
|
||||||
|
|
||||||
if logType == "" {
|
if logType == "" {
|
||||||
return fmt.Errorf("please provide a type (--type) for the test")
|
return errors.New("please provide a type (--type) for the test")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.MkdirAll(testPath, os.ModePerm); err != nil {
|
if err := os.MkdirAll(testPath, os.ModePerm); err != nil {
|
||||||
|
@ -118,7 +132,7 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
|
||||||
|
|
||||||
configFileData := &hubtest.HubTestItemConfig{}
|
configFileData := &hubtest.HubTestItemConfig{}
|
||||||
if logType == "appsec" {
|
if logType == "appsec" {
|
||||||
//create empty nuclei template file
|
// create empty nuclei template file
|
||||||
nucleiFileName := fmt.Sprintf("%s.yaml", testName)
|
nucleiFileName := fmt.Sprintf("%s.yaml", testName)
|
||||||
nucleiFilePath := filepath.Join(testPath, nucleiFileName)
|
nucleiFilePath := filepath.Join(testPath, nucleiFileName)
|
||||||
nucleiFile, err := os.OpenFile(nucleiFilePath, os.O_RDWR|os.O_CREATE, 0755)
|
nucleiFile, err := os.OpenFile(nucleiFilePath, os.O_RDWR|os.O_CREATE, 0755)
|
||||||
|
@ -128,7 +142,7 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
|
||||||
|
|
||||||
ntpl := template.Must(template.New("nuclei").Parse(hubtest.TemplateNucleiFile))
|
ntpl := template.Must(template.New("nuclei").Parse(hubtest.TemplateNucleiFile))
|
||||||
if ntpl == nil {
|
if ntpl == nil {
|
||||||
return fmt.Errorf("unable to parse nuclei template")
|
return errors.New("unable to parse nuclei template")
|
||||||
}
|
}
|
||||||
ntpl.ExecuteTemplate(nucleiFile, "nuclei", struct{ TestName string }{TestName: testName})
|
ntpl.ExecuteTemplate(nucleiFile, "nuclei", struct{ TestName string }{TestName: testName})
|
||||||
nucleiFile.Close()
|
nucleiFile.Close()
|
||||||
|
@ -188,24 +202,24 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
|
||||||
fmt.Printf(" Parser assertion file : %s (please fill it with assertion)\n", parserAssertFilePath)
|
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(" Scenario assertion file : %s (please fill it with assertion)\n", scenarioAssertFilePath)
|
||||||
fmt.Printf(" Configuration File : %s (please fill it with parsers, scenarios...)\n", configFilePath)
|
fmt.Printf(" Configuration File : %s (please fill it with parsers, scenarios...)\n", configFilePath)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fd, err := os.Create(configFilePath)
|
fd, err := os.Create(configFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("open: %s", err)
|
return fmt.Errorf("open: %w", err)
|
||||||
}
|
}
|
||||||
data, err := yaml.Marshal(configFileData)
|
data, err := yaml.Marshal(configFileData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("marshal: %s", err)
|
return fmt.Errorf("marshal: %w", err)
|
||||||
}
|
}
|
||||||
_, err = fd.Write(data)
|
_, err = fd.Write(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("write: %s", err)
|
return fmt.Errorf("write: %w", err)
|
||||||
}
|
}
|
||||||
if err := fd.Close(); err != nil {
|
if err := fd.Close(); err != nil {
|
||||||
return fmt.Errorf("close: %s", err)
|
return fmt.Errorf("close: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -219,20 +233,25 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli cliHubTest) NewRunCmd() *cobra.Command {
|
func (cli *cliHubTest) NewRunCmd() *cobra.Command {
|
||||||
var noClean bool
|
var (
|
||||||
var runAll bool
|
noClean bool
|
||||||
var forceClean bool
|
runAll bool
|
||||||
var NucleiTargetHost string
|
forceClean bool
|
||||||
var AppSecHost string
|
NucleiTargetHost string
|
||||||
var cmd = &cobra.Command{
|
AppSecHost string
|
||||||
|
)
|
||||||
|
|
||||||
|
cmd := &cobra.Command{
|
||||||
Use: "run",
|
Use: "run",
|
||||||
Short: "run [test_name]",
|
Short: "run [test_name]",
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
cfg := cli.cfg()
|
||||||
|
|
||||||
if !runAll && len(args) == 0 {
|
if !runAll && len(args) == 0 {
|
||||||
printHelp(cmd)
|
printHelp(cmd)
|
||||||
return fmt.Errorf("please provide test to run or --all flag")
|
return errors.New("please provide test to run or --all flag")
|
||||||
}
|
}
|
||||||
hubPtr.NucleiTargetHost = NucleiTargetHost
|
hubPtr.NucleiTargetHost = NucleiTargetHost
|
||||||
hubPtr.AppSecHost = AppSecHost
|
hubPtr.AppSecHost = AppSecHost
|
||||||
|
@ -244,7 +263,7 @@ func (cli cliHubTest) NewRunCmd() *cobra.Command {
|
||||||
for _, testName := range args {
|
for _, testName := range args {
|
||||||
_, err := hubPtr.LoadTestItem(testName)
|
_, err := hubPtr.LoadTestItem(testName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to load test '%s': %s", testName, err)
|
return fmt.Errorf("unable to load test '%s': %w", testName, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,7 +271,7 @@ func (cli cliHubTest) NewRunCmd() *cobra.Command {
|
||||||
// set timezone to avoid DST issues
|
// set timezone to avoid DST issues
|
||||||
os.Setenv("TZ", "UTC")
|
os.Setenv("TZ", "UTC")
|
||||||
for _, test := range hubPtr.Tests {
|
for _, test := range hubPtr.Tests {
|
||||||
if csConfig.Cscli.Output == "human" {
|
if cfg.Cscli.Output == "human" {
|
||||||
log.Infof("Running test '%s'", test.Name)
|
log.Infof("Running test '%s'", test.Name)
|
||||||
}
|
}
|
||||||
err := test.Run()
|
err := test.Run()
|
||||||
|
@ -264,6 +283,8 @@ func (cli cliHubTest) NewRunCmd() *cobra.Command {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
PersistentPostRunE: func(_ *cobra.Command, _ []string) error {
|
PersistentPostRunE: func(_ *cobra.Command, _ []string) error {
|
||||||
|
cfg := cli.cfg()
|
||||||
|
|
||||||
success := true
|
success := true
|
||||||
testResult := make(map[string]bool)
|
testResult := make(map[string]bool)
|
||||||
for _, test := range hubPtr.Tests {
|
for _, test := range hubPtr.Tests {
|
||||||
|
@ -280,7 +301,7 @@ func (cli cliHubTest) NewRunCmd() *cobra.Command {
|
||||||
}
|
}
|
||||||
if !noClean {
|
if !noClean {
|
||||||
if err := test.Clean(); err != nil {
|
if err := test.Clean(); err != nil {
|
||||||
return fmt.Errorf("unable to clean test '%s' env: %s", test.Name, err)
|
return fmt.Errorf("unable to clean test '%s' env: %w", test.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Printf("\nPlease fill your assert file(s) for test '%s', exiting\n", test.Name)
|
fmt.Printf("\nPlease fill your assert file(s) for test '%s', exiting\n", test.Name)
|
||||||
|
@ -288,18 +309,18 @@ func (cli cliHubTest) NewRunCmd() *cobra.Command {
|
||||||
}
|
}
|
||||||
testResult[test.Name] = test.Success
|
testResult[test.Name] = test.Success
|
||||||
if test.Success {
|
if test.Success {
|
||||||
if csConfig.Cscli.Output == "human" {
|
if cfg.Cscli.Output == "human" {
|
||||||
log.Infof("Test '%s' passed successfully (%d assertions)\n", test.Name, test.ParserAssert.NbAssert+test.ScenarioAssert.NbAssert)
|
log.Infof("Test '%s' passed successfully (%d assertions)\n", test.Name, test.ParserAssert.NbAssert+test.ScenarioAssert.NbAssert)
|
||||||
}
|
}
|
||||||
if !noClean {
|
if !noClean {
|
||||||
if err := test.Clean(); err != nil {
|
if err := test.Clean(); err != nil {
|
||||||
return fmt.Errorf("unable to clean test '%s' env: %s", test.Name, err)
|
return fmt.Errorf("unable to clean test '%s' env: %w", test.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
success = false
|
success = false
|
||||||
cleanTestEnv := false
|
cleanTestEnv := false
|
||||||
if csConfig.Cscli.Output == "human" {
|
if cfg.Cscli.Output == "human" {
|
||||||
if len(test.ParserAssert.Fails) > 0 {
|
if len(test.ParserAssert.Fails) > 0 {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
log.Errorf("Parser test '%s' failed (%d errors)\n", test.Name, len(test.ParserAssert.Fails))
|
log.Errorf("Parser test '%s' failed (%d errors)\n", test.Name, len(test.ParserAssert.Fails))
|
||||||
|
@ -330,20 +351,20 @@ func (cli cliHubTest) NewRunCmd() *cobra.Command {
|
||||||
Default: true,
|
Default: true,
|
||||||
}
|
}
|
||||||
if err := survey.AskOne(prompt, &cleanTestEnv); err != nil {
|
if err := survey.AskOne(prompt, &cleanTestEnv); err != nil {
|
||||||
return fmt.Errorf("unable to ask to remove runtime folder: %s", err)
|
return fmt.Errorf("unable to ask to remove runtime folder: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cleanTestEnv || forceClean {
|
if cleanTestEnv || forceClean {
|
||||||
if err := test.Clean(); err != nil {
|
if err := test.Clean(); err != nil {
|
||||||
return fmt.Errorf("unable to clean test '%s' env: %s", test.Name, err)
|
return fmt.Errorf("unable to clean test '%s' env: %w", test.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch csConfig.Cscli.Output {
|
switch cfg.Cscli.Output {
|
||||||
case "human":
|
case "human":
|
||||||
hubTestResultTable(color.Output, testResult)
|
hubTestResultTable(color.Output, testResult)
|
||||||
case "json":
|
case "json":
|
||||||
|
@ -359,11 +380,11 @@ func (cli cliHubTest) NewRunCmd() *cobra.Command {
|
||||||
}
|
}
|
||||||
jsonStr, err := json.Marshal(jsonResult)
|
jsonStr, err := json.Marshal(jsonResult)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to json test result: %s", err)
|
return fmt.Errorf("unable to json test result: %w", err)
|
||||||
}
|
}
|
||||||
fmt.Println(string(jsonStr))
|
fmt.Println(string(jsonStr))
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("only human/json output modes are supported")
|
return errors.New("only human/json output modes are supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !success {
|
if !success {
|
||||||
|
@ -383,7 +404,7 @@ func (cli cliHubTest) NewRunCmd() *cobra.Command {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli cliHubTest) NewCleanCmd() *cobra.Command {
|
func (cli *cliHubTest) NewCleanCmd() *cobra.Command {
|
||||||
var cmd = &cobra.Command{
|
var cmd = &cobra.Command{
|
||||||
Use: "clean",
|
Use: "clean",
|
||||||
Short: "clean [test_name]",
|
Short: "clean [test_name]",
|
||||||
|
@ -393,10 +414,10 @@ func (cli cliHubTest) NewCleanCmd() *cobra.Command {
|
||||||
for _, testName := range args {
|
for _, testName := range args {
|
||||||
test, err := hubPtr.LoadTestItem(testName)
|
test, err := hubPtr.LoadTestItem(testName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to load test '%s': %s", testName, err)
|
return fmt.Errorf("unable to load test '%s': %w", testName, err)
|
||||||
}
|
}
|
||||||
if err := test.Clean(); err != nil {
|
if err := test.Clean(); err != nil {
|
||||||
return fmt.Errorf("unable to clean test '%s' env: %s", test.Name, err)
|
return fmt.Errorf("unable to clean test '%s' env: %w", test.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,7 +428,7 @@ func (cli cliHubTest) NewCleanCmd() *cobra.Command {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli cliHubTest) NewInfoCmd() *cobra.Command {
|
func (cli *cliHubTest) NewInfoCmd() *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "info",
|
Use: "info",
|
||||||
Short: "info [test_name]",
|
Short: "info [test_name]",
|
||||||
|
@ -417,7 +438,7 @@ func (cli cliHubTest) NewInfoCmd() *cobra.Command {
|
||||||
for _, testName := range args {
|
for _, testName := range args {
|
||||||
test, err := hubPtr.LoadTestItem(testName)
|
test, err := hubPtr.LoadTestItem(testName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to load test '%s': %s", testName, err)
|
return fmt.Errorf("unable to load test '%s': %w", testName, err)
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Printf(" Test name : %s\n", test.Name)
|
fmt.Printf(" Test name : %s\n", test.Name)
|
||||||
|
@ -440,17 +461,19 @@ func (cli cliHubTest) NewInfoCmd() *cobra.Command {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli cliHubTest) NewListCmd() *cobra.Command {
|
func (cli *cliHubTest) NewListCmd() *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Short: "list",
|
Short: "list",
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(_ *cobra.Command, _ []string) error {
|
RunE: func(_ *cobra.Command, _ []string) error {
|
||||||
|
cfg := cli.cfg()
|
||||||
|
|
||||||
if err := hubPtr.LoadAllTests(); err != nil {
|
if err := hubPtr.LoadAllTests(); err != nil {
|
||||||
return fmt.Errorf("unable to load all tests: %s", err)
|
return fmt.Errorf("unable to load all tests: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch csConfig.Cscli.Output {
|
switch cfg.Cscli.Output {
|
||||||
case "human":
|
case "human":
|
||||||
hubTestListTable(color.Output, hubPtr.Tests)
|
hubTestListTable(color.Output, hubPtr.Tests)
|
||||||
case "json":
|
case "json":
|
||||||
|
@ -460,7 +483,7 @@ func (cli cliHubTest) NewListCmd() *cobra.Command {
|
||||||
}
|
}
|
||||||
fmt.Println(string(j))
|
fmt.Println(string(j))
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("only human/json output modes are supported")
|
return errors.New("only human/json output modes are supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -470,18 +493,22 @@ func (cli cliHubTest) NewListCmd() *cobra.Command {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli cliHubTest) NewCoverageCmd() *cobra.Command {
|
func (cli *cliHubTest) NewCoverageCmd() *cobra.Command {
|
||||||
var showParserCov bool
|
var (
|
||||||
var showScenarioCov bool
|
showParserCov bool
|
||||||
var showOnlyPercent bool
|
showScenarioCov bool
|
||||||
var showAppsecCov bool
|
showOnlyPercent bool
|
||||||
|
showAppsecCov bool
|
||||||
|
)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "coverage",
|
Use: "coverage",
|
||||||
Short: "coverage",
|
Short: "coverage",
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(_ *cobra.Command, _ []string) error {
|
RunE: func(_ *cobra.Command, _ []string) error {
|
||||||
//for this one we explicitly don't do for appsec
|
cfg := cli.cfg()
|
||||||
|
|
||||||
|
// for this one we explicitly don't do for appsec
|
||||||
if err := HubTest.LoadAllTests(); err != nil {
|
if err := HubTest.LoadAllTests(); err != nil {
|
||||||
return fmt.Errorf("unable to load all tests: %+v", err)
|
return fmt.Errorf("unable to load all tests: %+v", err)
|
||||||
}
|
}
|
||||||
|
@ -499,7 +526,7 @@ func (cli cliHubTest) NewCoverageCmd() *cobra.Command {
|
||||||
if showParserCov || showAll {
|
if showParserCov || showAll {
|
||||||
parserCoverage, err = HubTest.GetParsersCoverage()
|
parserCoverage, err = HubTest.GetParsersCoverage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("while getting parser coverage: %s", err)
|
return fmt.Errorf("while getting parser coverage: %w", err)
|
||||||
}
|
}
|
||||||
parserTested := 0
|
parserTested := 0
|
||||||
for _, test := range parserCoverage {
|
for _, test := range parserCoverage {
|
||||||
|
@ -513,7 +540,7 @@ func (cli cliHubTest) NewCoverageCmd() *cobra.Command {
|
||||||
if showScenarioCov || showAll {
|
if showScenarioCov || showAll {
|
||||||
scenarioCoverage, err = HubTest.GetScenariosCoverage()
|
scenarioCoverage, err = HubTest.GetScenariosCoverage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("while getting scenario coverage: %s", err)
|
return fmt.Errorf("while getting scenario coverage: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
scenarioTested := 0
|
scenarioTested := 0
|
||||||
|
@ -529,7 +556,7 @@ func (cli cliHubTest) NewCoverageCmd() *cobra.Command {
|
||||||
if showAppsecCov || showAll {
|
if showAppsecCov || showAll {
|
||||||
appsecRuleCoverage, err = HubTest.GetAppsecCoverage()
|
appsecRuleCoverage, err = HubTest.GetAppsecCoverage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("while getting scenario coverage: %s", err)
|
return fmt.Errorf("while getting scenario coverage: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
appsecRuleTested := 0
|
appsecRuleTested := 0
|
||||||
|
@ -542,19 +569,20 @@ func (cli cliHubTest) NewCoverageCmd() *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
if showOnlyPercent {
|
if showOnlyPercent {
|
||||||
if showAll {
|
switch {
|
||||||
|
case showAll:
|
||||||
fmt.Printf("parsers=%d%%\nscenarios=%d%%\nappsec_rules=%d%%", parserCoveragePercent, scenarioCoveragePercent, appsecRuleCoveragePercent)
|
fmt.Printf("parsers=%d%%\nscenarios=%d%%\nappsec_rules=%d%%", parserCoveragePercent, scenarioCoveragePercent, appsecRuleCoveragePercent)
|
||||||
} else if showParserCov {
|
case showParserCov:
|
||||||
fmt.Printf("parsers=%d%%", parserCoveragePercent)
|
fmt.Printf("parsers=%d%%", parserCoveragePercent)
|
||||||
} else if showScenarioCov {
|
case showScenarioCov:
|
||||||
fmt.Printf("scenarios=%d%%", scenarioCoveragePercent)
|
fmt.Printf("scenarios=%d%%", scenarioCoveragePercent)
|
||||||
} else if showAppsecCov {
|
case showAppsecCov:
|
||||||
fmt.Printf("appsec_rules=%d%%", appsecRuleCoveragePercent)
|
fmt.Printf("appsec_rules=%d%%", appsecRuleCoveragePercent)
|
||||||
}
|
}
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch csConfig.Cscli.Output {
|
switch cfg.Cscli.Output {
|
||||||
case "human":
|
case "human":
|
||||||
if showParserCov || showAll {
|
if showParserCov || showAll {
|
||||||
hubTestParserCoverageTable(color.Output, parserCoverage)
|
hubTestParserCoverageTable(color.Output, parserCoverage)
|
||||||
|
@ -595,7 +623,7 @@ func (cli cliHubTest) NewCoverageCmd() *cobra.Command {
|
||||||
}
|
}
|
||||||
fmt.Printf("%s", dump)
|
fmt.Printf("%s", dump)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("only human/json output modes are supported")
|
return errors.New("only human/json output modes are supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -610,7 +638,7 @@ func (cli cliHubTest) NewCoverageCmd() *cobra.Command {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli cliHubTest) NewEvalCmd() *cobra.Command {
|
func (cli *cliHubTest) NewEvalCmd() *cobra.Command {
|
||||||
var evalExpression string
|
var evalExpression string
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
|
@ -647,7 +675,7 @@ func (cli cliHubTest) NewEvalCmd() *cobra.Command {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli cliHubTest) NewExplainCmd() *cobra.Command {
|
func (cli *cliHubTest) NewExplainCmd() *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "explain",
|
Use: "explain",
|
||||||
Short: "explain [test_name]",
|
Short: "explain [test_name]",
|
||||||
|
@ -666,7 +694,7 @@ func (cli cliHubTest) NewExplainCmd() *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = test.ParserAssert.LoadTest(test.ParserResultFile); err != nil {
|
if err = test.ParserAssert.LoadTest(test.ParserResultFile); err != nil {
|
||||||
return fmt.Errorf("unable to load parser result after run: %s", err)
|
return fmt.Errorf("unable to load parser result after run: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,7 +705,7 @@ func (cli cliHubTest) NewExplainCmd() *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = test.ScenarioAssert.LoadTest(test.ScenarioResultFile, test.BucketPourResultFile); err != nil {
|
if err = test.ScenarioAssert.LoadTest(test.ScenarioResultFile, test.BucketPourResultFile); err != nil {
|
||||||
return fmt.Errorf("unable to load scenario result after run: %s", err)
|
return fmt.Errorf("unable to load scenario result after run: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
opts := dumps.DumpOpts{}
|
opts := dumps.DumpOpts{}
|
||||||
|
|
|
@ -240,12 +240,12 @@ It is meant to allow you to manage bans, parsers/scenarios/etc, api and generall
|
||||||
cmd.AddCommand(NewCLISimulation(cli.cfg).NewCommand())
|
cmd.AddCommand(NewCLISimulation(cli.cfg).NewCommand())
|
||||||
cmd.AddCommand(NewCLIBouncers(cli.cfg).NewCommand())
|
cmd.AddCommand(NewCLIBouncers(cli.cfg).NewCommand())
|
||||||
cmd.AddCommand(NewCLIMachines(cli.cfg).NewCommand())
|
cmd.AddCommand(NewCLIMachines(cli.cfg).NewCommand())
|
||||||
cmd.AddCommand(NewCLICapi().NewCommand())
|
cmd.AddCommand(NewCLICapi(cli.cfg).NewCommand())
|
||||||
cmd.AddCommand(NewCLILapi(cli.cfg).NewCommand())
|
cmd.AddCommand(NewCLILapi(cli.cfg).NewCommand())
|
||||||
cmd.AddCommand(NewCompletionCmd())
|
cmd.AddCommand(NewCompletionCmd())
|
||||||
cmd.AddCommand(NewCLIConsole(cli.cfg).NewCommand())
|
cmd.AddCommand(NewCLIConsole(cli.cfg).NewCommand())
|
||||||
cmd.AddCommand(NewCLIExplain(cli.cfg).NewCommand())
|
cmd.AddCommand(NewCLIExplain(cli.cfg).NewCommand())
|
||||||
cmd.AddCommand(NewCLIHubTest().NewCommand())
|
cmd.AddCommand(NewCLIHubTest(cli.cfg).NewCommand())
|
||||||
cmd.AddCommand(NewCLINotifications(cli.cfg).NewCommand())
|
cmd.AddCommand(NewCLINotifications(cli.cfg).NewCommand())
|
||||||
cmd.AddCommand(NewCLISupport().NewCommand())
|
cmd.AddCommand(NewCLISupport().NewCommand())
|
||||||
cmd.AddCommand(NewCLIPapi(cli.cfg).NewCommand())
|
cmd.AddCommand(NewCLIPapi(cli.cfg).NewCommand())
|
||||||
|
|
Loading…
Reference in a new issue