mirror of
https://github.com/crowdsecurity/crowdsec.git
synced 2025-05-11 12:25:53 +02:00
Check cscli preconditions with crowdsec-cli/require package (#2388)
This commit is contained in:
parent
a01ce18b98
commit
5cb7013575
21 changed files with 260 additions and 105 deletions
|
@ -25,6 +25,8 @@ import (
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/database"
|
"github.com/crowdsecurity/crowdsec/pkg/database"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/models"
|
"github.com/crowdsecurity/crowdsec/pkg/models"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func DecisionsFromAlert(alert *models.Alert) string {
|
func DecisionsFromAlert(alert *models.Alert) string {
|
||||||
|
@ -525,8 +527,8 @@ func NewAlertsFlushCmd() *cobra.Command {
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
if err := csConfig.LoadAPIServer(); err != nil || csConfig.DisableAPI {
|
if err := require.LAPI(csConfig); err != nil {
|
||||||
return fmt.Errorf("local API is disabled, please run this command on the local API machine")
|
return err
|
||||||
}
|
}
|
||||||
dbClient, err = database.NewClient(csConfig.DbConfig)
|
dbClient, err = database.NewClient(csConfig.DbConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -16,6 +16,8 @@ import (
|
||||||
middlewares "github.com/crowdsecurity/crowdsec/pkg/apiserver/middlewares/v1"
|
middlewares "github.com/crowdsecurity/crowdsec/pkg/apiserver/middlewares/v1"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/database"
|
"github.com/crowdsecurity/crowdsec/pkg/database"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getBouncers(out io.Writer, dbClient *database.Client) error {
|
func getBouncers(out io.Writer, dbClient *database.Client) error {
|
||||||
|
@ -200,9 +202,10 @@ Note: This command requires database direct access, so is intended to be run on
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
if err := csConfig.LoadAPIServer(); err != nil || csConfig.DisableAPI {
|
if err = require.LAPI(csConfig); err != nil {
|
||||||
return fmt.Errorf("local API is disabled, please run this command on the local API machine")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
dbClient, err = database.NewClient(csConfig.DbConfig)
|
dbClient, err = database.NewClient(csConfig.DbConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to create new database client: %s", err)
|
return fmt.Errorf("unable to create new database client: %s", err)
|
||||||
|
|
|
@ -19,6 +19,8 @@ import (
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/fflag"
|
"github.com/crowdsecurity/crowdsec/pkg/fflag"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/models"
|
"github.com/crowdsecurity/crowdsec/pkg/models"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
const CAPIBaseURL string = "https://api.crowdsec.net/"
|
const CAPIBaseURL string = "https://api.crowdsec.net/"
|
||||||
|
@ -31,14 +33,12 @@ func NewCapiCmd() *cobra.Command {
|
||||||
Args: cobra.MinimumNArgs(1),
|
Args: cobra.MinimumNArgs(1),
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := csConfig.LoadAPIServer(); err != nil {
|
if err := require.LAPI(csConfig); err != nil {
|
||||||
return fmt.Errorf("local API is disabled, please run this command on the local API machine: %w", err)
|
return err
|
||||||
}
|
}
|
||||||
if csConfig.DisableAPI {
|
|
||||||
return nil
|
if err := require.CAPI(csConfig); err != nil {
|
||||||
}
|
return err
|
||||||
if csConfig.API.Server.OnlineClient == nil {
|
|
||||||
log.Fatalf("no configuration for Central API in '%s'", *csConfig.FilePath)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -134,10 +134,6 @@ func NewCapiStatusCmd() *cobra.Command {
|
||||||
Args: cobra.MinimumNArgs(0),
|
Args: cobra.MinimumNArgs(0),
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
var err error
|
|
||||||
if csConfig.API.Server == nil {
|
|
||||||
log.Fatal("There is no configuration on 'api.server:'")
|
|
||||||
}
|
|
||||||
if csConfig.API.Server.OnlineClient == nil {
|
if csConfig.API.Server.OnlineClient == nil {
|
||||||
log.Fatalf("Please provide credentials for the Central API (CAPI) in '%s'", csConfig.API.Server.OnlineClient.CredentialsFilePath)
|
log.Fatalf("Please provide credentials for the Central API (CAPI) in '%s'", csConfig.API.Server.OnlineClient.CredentialsFilePath)
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ var configShowTemplate = `Global:
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
{{- if .Crowdsec }}
|
{{- if .Crowdsec }}
|
||||||
Crowdsec:
|
Crowdsec{{if and .Crowdsec.Enable (not (ValueBool .Crowdsec.Enable))}} (disabled){{end}}:
|
||||||
- Acquisition File : {{.Crowdsec.AcquisitionFilePath}}
|
- Acquisition File : {{.Crowdsec.AcquisitionFilePath}}
|
||||||
- Parsers routines : {{.Crowdsec.ParserRoutinesCount}}
|
- Parsers routines : {{.Crowdsec.ParserRoutinesCount}}
|
||||||
{{- if .Crowdsec.AcquisitionDirPath }}
|
{{- if .Crowdsec.AcquisitionDirPath }}
|
||||||
|
@ -97,7 +97,7 @@ API Client:
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
{{- if .API.Server }}
|
{{- if .API.Server }}
|
||||||
Local API Server:
|
Local API Server{{if and .API.Server.Enable (not (ValueBool .API.Server.Enable))}} (disabled){{end}}:
|
||||||
- Listen URL : {{.API.Server.ListenURI}}
|
- Listen URL : {{.API.Server.ListenURI}}
|
||||||
- Profile File : {{.API.Server.ProfilesPath}}
|
- Profile File : {{.API.Server.ProfilesPath}}
|
||||||
|
|
||||||
|
@ -194,7 +194,15 @@ func runConfigShow(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
switch csConfig.Cscli.Output {
|
switch csConfig.Cscli.Output {
|
||||||
case "human":
|
case "human":
|
||||||
tmp, err := template.New("config").Parse(configShowTemplate)
|
// The tests on .Enable look funny because the option has a true default which has
|
||||||
|
// not been set yet (we don't really load the LAPI) and go templates don't dereference
|
||||||
|
// pointers in boolean tests. Prefix notation is the cherry on top.
|
||||||
|
funcs := template.FuncMap{
|
||||||
|
// can't use generics here
|
||||||
|
"ValueBool": func(b *bool) bool { return b!=nil && *b },
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp, err := template.New("config").Funcs(funcs).Parse(configShowTemplate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
@ -24,6 +22,8 @@ import (
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/fflag"
|
"github.com/crowdsecurity/crowdsec/pkg/fflag"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewConsoleCmd() *cobra.Command {
|
func NewConsoleCmd() *cobra.Command {
|
||||||
|
@ -33,24 +33,14 @@ func NewConsoleCmd() *cobra.Command {
|
||||||
Args: cobra.MinimumNArgs(1),
|
Args: cobra.MinimumNArgs(1),
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := csConfig.LoadAPIServer(); err != nil || csConfig.DisableAPI {
|
if err := require.LAPI(csConfig); err != nil {
|
||||||
var fdErr *fs.PathError
|
return err
|
||||||
if errors.As(err, &fdErr) {
|
|
||||||
log.Fatalf("Unable to load Local API : %s", fdErr)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Unable to load required Local API Configuration : %s", err)
|
|
||||||
}
|
|
||||||
log.Fatal("Local API is disabled, please run this command on the local API machine")
|
|
||||||
}
|
}
|
||||||
if csConfig.DisableAPI {
|
if err := require.CAPI(csConfig); err != nil {
|
||||||
log.Fatal("Local API is disabled, please run this command on the local API machine")
|
return err
|
||||||
}
|
}
|
||||||
if csConfig.API.Server.OnlineClient == nil {
|
if err := require.Enrolled(csConfig); err != nil {
|
||||||
log.Fatalf("No configuration for Central API (CAPI) in '%s'", *csConfig.FilePath)
|
return err
|
||||||
}
|
|
||||||
if csConfig.API.Server.OnlineClient.Credentials == nil {
|
|
||||||
log.Fatal("You must configure Central API (CAPI) with `cscli capi register` before accessing console features.")
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
|
|
@ -17,6 +17,8 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/metabase"
|
"github.com/crowdsecurity/crowdsec/pkg/metabase"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -54,23 +56,23 @@ cscli dashboard start
|
||||||
cscli dashboard stop
|
cscli dashboard stop
|
||||||
cscli dashboard remove
|
cscli dashboard remove
|
||||||
`,
|
`,
|
||||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := metabase.TestAvailability(); err != nil {
|
if err := require.LAPI(csConfig); err != nil {
|
||||||
log.Fatalf("%s", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := csConfig.LoadAPIServer(); err != nil || csConfig.DisableAPI {
|
if err := metabase.TestAvailability(); err != nil {
|
||||||
log.Fatal("Local API is disabled, please run this command on the local API machine")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
metabaseConfigFolderPath := filepath.Join(csConfig.ConfigPaths.ConfigDir, metabaseConfigFolder)
|
metabaseConfigFolderPath := filepath.Join(csConfig.ConfigPaths.ConfigDir, metabaseConfigFolder)
|
||||||
metabaseConfigPath = filepath.Join(metabaseConfigFolderPath, metabaseConfigFile)
|
metabaseConfigPath = filepath.Join(metabaseConfigFolderPath, metabaseConfigFile)
|
||||||
if err := os.MkdirAll(metabaseConfigFolderPath, os.ModePerm); err != nil {
|
if err := os.MkdirAll(metabaseConfigFolderPath, os.ModePerm); err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
if err := csConfig.LoadDBConfig(); err != nil {
|
|
||||||
log.Errorf("This command requires direct database access (must be run on the local API machine)")
|
if err := require.DB(csConfig); err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -84,6 +86,7 @@ cscli dashboard remove
|
||||||
metabaseContainerID = oldContainerID
|
metabaseContainerID = oldContainerID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,8 @@ import (
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/database"
|
"github.com/crowdsecurity/crowdsec/pkg/database"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/database/ent"
|
"github.com/crowdsecurity/crowdsec/pkg/database/ent"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -411,11 +413,8 @@ Note: This command requires database direct access, so is intended to be run on
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Aliases: []string{"machine"},
|
Aliases: []string{"machine"},
|
||||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := csConfig.LoadAPIServer(); err != nil || csConfig.DisableAPI {
|
if err := require.LAPI(csConfig); err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
log.Errorf("local api : %s", err)
|
|
||||||
}
|
|
||||||
return fmt.Errorf("local API is disabled, please run this command on the local API machine")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -25,6 +25,8 @@ import (
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/csplugin"
|
"github.com/crowdsecurity/crowdsec/pkg/csplugin"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/csprofiles"
|
"github.com/crowdsecurity/crowdsec/pkg/csprofiles"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NotificationsCfg struct {
|
type NotificationsCfg struct {
|
||||||
|
@ -41,16 +43,18 @@ func NewNotificationsCmd() *cobra.Command {
|
||||||
Args: cobra.MinimumNArgs(1),
|
Args: cobra.MinimumNArgs(1),
|
||||||
Aliases: []string{"notifications", "notification"},
|
Aliases: []string{"notifications", "notification"},
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
var (
|
if err := require.LAPI(csConfig); err != nil {
|
||||||
err error
|
return err
|
||||||
)
|
|
||||||
if err = csConfig.API.Server.LoadProfiles(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
}
|
||||||
if csConfig.ConfigPaths.NotificationDir == "" {
|
if err := require.Profiles(csConfig); err != nil {
|
||||||
log.Fatalf("config_paths.notification_dir is not set in crowdsec config")
|
return err
|
||||||
}
|
}
|
||||||
|
if err := require.Notifications(csConfig); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
@ -12,6 +11,8 @@ import (
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/apiserver"
|
"github.com/crowdsecurity/crowdsec/pkg/apiserver"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/database"
|
"github.com/crowdsecurity/crowdsec/pkg/database"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewPapiCmd() *cobra.Command {
|
func NewPapiCmd() *cobra.Command {
|
||||||
|
@ -21,14 +22,14 @@ func NewPapiCmd() *cobra.Command {
|
||||||
Args: cobra.MinimumNArgs(1),
|
Args: cobra.MinimumNArgs(1),
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := csConfig.LoadAPIServer(); err != nil || csConfig.DisableAPI {
|
if err := require.LAPI(csConfig); err != nil {
|
||||||
return fmt.Errorf("Local API is disabled, please run this command on the local API machine: %w", err)
|
return err
|
||||||
}
|
}
|
||||||
if csConfig.API.Server.OnlineClient == nil {
|
if err := require.CAPI(csConfig); err != nil {
|
||||||
log.Fatalf("no configuration for Central API in '%s'", *csConfig.FilePath)
|
return err
|
||||||
}
|
}
|
||||||
if csConfig.API.Server.OnlineClient.Credentials.PapiURL == "" {
|
if err := require.PAPI(csConfig); err != nil {
|
||||||
log.Fatalf("no PAPI URL in configuration")
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
|
85
cmd/crowdsec-cli/require/require.go
Normal file
85
cmd/crowdsec-cli/require/require.go
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
package require
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||||
|
)
|
||||||
|
|
||||||
|
func LAPI(c *csconfig.Config) error {
|
||||||
|
if err := c.LoadAPIServer(); err != nil {
|
||||||
|
return fmt.Errorf("failed to load Local API: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.DisableAPI {
|
||||||
|
return fmt.Errorf("local API is disabled -- this command must be run on the local API machine")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CAPI(c *csconfig.Config) error {
|
||||||
|
if c.API.Server.OnlineClient == nil {
|
||||||
|
return fmt.Errorf("no configuration for Central API (CAPI) in '%s'", *c.FilePath)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func PAPI(c *csconfig.Config) error {
|
||||||
|
if err := LAPI(c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := CAPI(c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.API.Server.OnlineClient.Credentials.PapiURL == "" {
|
||||||
|
return fmt.Errorf("no PAPI URL in configuration")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Enrolled(c *csconfig.Config) error {
|
||||||
|
if err := CAPI(c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.API.Server.OnlineClient.Credentials == nil {
|
||||||
|
return fmt.Errorf("the Central API (CAPI) must be configured with 'cscli capi register'")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DB(c *csconfig.Config) error {
|
||||||
|
if err := c.LoadDBConfig(); err != nil {
|
||||||
|
return fmt.Errorf("this command requires direct database access (must be run on the local API machine): %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Profiles(c *csconfig.Config) error {
|
||||||
|
if err := LAPI(c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.API.Server.LoadProfiles(); err != nil {
|
||||||
|
return fmt.Errorf("while loading profiles: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Notifications(c *csconfig.Config) error {
|
||||||
|
if err := LAPI(c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.ConfigPaths.NotificationDir == "" {
|
||||||
|
return fmt.Errorf("config_paths.notification_dir is not set in crowdsec config")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -249,13 +249,13 @@ func LoadConfig(configFile string, disableAgent bool, disableAPI bool, quiet boo
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !flags.DisableAgent {
|
if !cConfig.DisableAgent {
|
||||||
if err := cConfig.LoadCrowdsec(); err != nil {
|
if err := cConfig.LoadCrowdsec(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !flags.DisableAPI {
|
if !cConfig.DisableAPI {
|
||||||
if err := cConfig.LoadAPIServer(); err != nil {
|
if err := cConfig.LoadAPIServer(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -290,7 +290,7 @@ func LoadConfig(configFile string, disableAgent bool, disableAPI bool, quiet boo
|
||||||
cConfig.API.Server.OnlineClient = nil
|
cConfig.API.Server.OnlineClient = nil
|
||||||
}
|
}
|
||||||
/*if the api is disabled as well, just read file and exit, don't daemonize*/
|
/*if the api is disabled as well, just read file and exit, don't daemonize*/
|
||||||
if flags.DisableAPI {
|
if cConfig.DisableAPI {
|
||||||
cConfig.Common.Daemonize = false
|
cConfig.Common.Daemonize = false
|
||||||
}
|
}
|
||||||
log.Infof("single file mode : log_media=%s daemonize=%t", cConfig.Common.LogMedia, cConfig.Common.Daemonize)
|
log.Infof("single file mode : log_media=%s daemonize=%t", cConfig.Common.LogMedia, cConfig.Common.Daemonize)
|
||||||
|
|
|
@ -243,7 +243,7 @@ if istrue "$DISABLE_ONLINE_API"; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# registration to online API for signal push
|
# registration to online API for signal push
|
||||||
if isfalse "$DISABLE_ONLINE_API" ; then
|
if isfalse "$DISABLE_LOCAL_API" && isfalse "$DISABLE_ONLINE_API" ; then
|
||||||
CONFIG_DIR=$(conf_get '.config_paths.config_dir')
|
CONFIG_DIR=$(conf_get '.config_paths.config_dir')
|
||||||
export CONFIG_DIR
|
export CONFIG_DIR
|
||||||
config_exists=$(conf_get '.api.server.online_client | has("credentials_path")')
|
config_exists=$(conf_get '.api.server.online_client | has("credentials_path")')
|
||||||
|
@ -255,7 +255,7 @@ if isfalse "$DISABLE_ONLINE_API" ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Enroll instance if enroll key is provided
|
# Enroll instance if enroll key is provided
|
||||||
if isfalse "$DISABLE_ONLINE_API" && [ "$ENROLL_KEY" != "" ]; then
|
if isfalse "$DISABLE_LOCAL_API" && isfalse "$DISABLE_ONLINE_API" && [ "$ENROLL_KEY" != "" ]; then
|
||||||
enroll_args=""
|
enroll_args=""
|
||||||
if [ "$ENROLL_INSTANCE_NAME" != "" ]; then
|
if [ "$ENROLL_INSTANCE_NAME" != "" ]; then
|
||||||
enroll_args="--name $ENROLL_INSTANCE_NAME"
|
enroll_args="--name $ENROLL_INSTANCE_NAME"
|
||||||
|
@ -278,8 +278,7 @@ if [ "$GID" != "" ]; then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# XXX only with LAPI
|
if isfalse "$DISABLE_LOCAL_API" && istrue "$USE_TLS"; then
|
||||||
if istrue "$USE_TLS"; then
|
|
||||||
agents_allowed_yaml=$(csv2yaml "$AGENTS_ALLOWED_OU")
|
agents_allowed_yaml=$(csv2yaml "$AGENTS_ALLOWED_OU")
|
||||||
export agents_allowed_yaml
|
export agents_allowed_yaml
|
||||||
bouncers_allowed_yaml=$(csv2yaml "$BOUNCERS_ALLOWED_OU")
|
bouncers_allowed_yaml=$(csv2yaml "$BOUNCERS_ALLOWED_OU")
|
||||||
|
@ -369,6 +368,12 @@ shopt -u nullglob extglob
|
||||||
conf_set_if "$CAPI_WHITELISTS_PATH" '.api.server.capi_whitelists_path = strenv(CAPI_WHITELISTS_PATH)'
|
conf_set_if "$CAPI_WHITELISTS_PATH" '.api.server.capi_whitelists_path = strenv(CAPI_WHITELISTS_PATH)'
|
||||||
conf_set_if "$METRICS_PORT" '.prometheus.listen_port=env(METRICS_PORT)'
|
conf_set_if "$METRICS_PORT" '.prometheus.listen_port=env(METRICS_PORT)'
|
||||||
|
|
||||||
|
if istrue "$DISABLE_LOCAL_API"; then
|
||||||
|
conf_set '.api.server.enable=false'
|
||||||
|
else
|
||||||
|
conf_set '.api.server.enable=true'
|
||||||
|
fi
|
||||||
|
|
||||||
ARGS=""
|
ARGS=""
|
||||||
if [ "$CONFIG_FILE" != "" ]; then
|
if [ "$CONFIG_FILE" != "" ]; then
|
||||||
ARGS="-c $CONFIG_FILE"
|
ARGS="-c $CONFIG_FILE"
|
||||||
|
@ -390,10 +395,6 @@ if istrue "$DISABLE_AGENT"; then
|
||||||
ARGS="$ARGS -no-cs"
|
ARGS="$ARGS -no-cs"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if istrue "$DISABLE_LOCAL_API"; then
|
|
||||||
ARGS="$ARGS -no-api"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if istrue "$LEVEL_TRACE"; then
|
if istrue "$LEVEL_TRACE"; then
|
||||||
ARGS="$ARGS -trace"
|
ARGS="$ARGS -trace"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -234,6 +234,21 @@ func (c *Config) LoadAPIServer() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.API.Server.Enable == nil {
|
||||||
|
// if the option is not present, it is enabled by default
|
||||||
|
c.API.Server.Enable = ptr.Of(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !*c.API.Server.Enable {
|
||||||
|
log.Warning("crowdsec local API is disabled because 'enable' is set to false")
|
||||||
|
c.DisableAPI = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.DisableAPI {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
//inherit log level from common, then api->server
|
//inherit log level from common, then api->server
|
||||||
var logLevel log.Level
|
var logLevel log.Level
|
||||||
if c.API.Server.LogLevel != nil {
|
if c.API.Server.LogLevel != nil {
|
||||||
|
@ -268,21 +283,6 @@ func (c *Config) LoadAPIServer() error {
|
||||||
log.Infof("loaded capi whitelist from %s: %d IPs, %d CIDRs", c.API.Server.CapiWhitelistsPath, len(c.API.Server.CapiWhitelists.Ips), len(c.API.Server.CapiWhitelists.Cidrs))
|
log.Infof("loaded capi whitelist from %s: %d IPs, %d CIDRs", c.API.Server.CapiWhitelistsPath, len(c.API.Server.CapiWhitelists.Ips), len(c.API.Server.CapiWhitelists.Cidrs))
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.API.Server.Enable == nil {
|
|
||||||
// if the option is not present, it is enabled by default
|
|
||||||
c.API.Server.Enable = ptr.Of(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !*c.API.Server.Enable {
|
|
||||||
log.Warning("crowdsec local API is disabled because 'enable' is set to false")
|
|
||||||
c.DisableAPI = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.DisableAPI {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.LoadCommon(); err != nil {
|
if err := c.LoadCommon(); err != nil {
|
||||||
return fmt.Errorf("loading common configuration: %s", err)
|
return fmt.Errorf("loading common configuration: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,6 +234,7 @@ func TestLoadAPIServer(t *testing.T) {
|
||||||
DisableAPI: false,
|
DisableAPI: false,
|
||||||
},
|
},
|
||||||
expected: &LocalApiServerCfg{
|
expected: &LocalApiServerCfg{
|
||||||
|
Enable: ptr.Of(true),
|
||||||
PapiLogLevel: &logLevel,
|
PapiLogLevel: &logLevel,
|
||||||
},
|
},
|
||||||
expectedErr: "no database configuration provided",
|
expectedErr: "no database configuration provided",
|
||||||
|
|
|
@ -45,16 +45,23 @@ teardown() {
|
||||||
config_disable_lapi
|
config_disable_lapi
|
||||||
rune -1 cscli capi status
|
rune -1 cscli capi status
|
||||||
assert_stderr --partial "crowdsec local API is disabled"
|
assert_stderr --partial "crowdsec local API is disabled"
|
||||||
assert_stderr --partial "There is no configuration on 'api.server:'"
|
assert_stderr --partial "local API is disabled -- this command must be run on the local API machine"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "cscli config show -o human" {
|
@test "no lapi: cscli config show -o human" {
|
||||||
config_disable_lapi
|
config_set '.api.server.enable=false'
|
||||||
rune -0 cscli config show -o human
|
rune -0 cscli config show -o human
|
||||||
assert_output --partial "Global:"
|
assert_output --partial "Global:"
|
||||||
assert_output --partial "Crowdsec:"
|
assert_output --partial "Crowdsec:"
|
||||||
assert_output --partial "cscli:"
|
assert_output --partial "cscli:"
|
||||||
refute_output --partial "Local API Server:"
|
assert_output --partial "Local API Server (disabled):"
|
||||||
|
|
||||||
|
config_set 'del(.api.server)'
|
||||||
|
rune -0 cscli config show -o human
|
||||||
|
assert_output --partial "Global:"
|
||||||
|
assert_output --partial "Crowdsec:"
|
||||||
|
assert_output --partial "cscli:"
|
||||||
|
refute_output --partial "Local API Server"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "cscli config backup" {
|
@test "cscli config backup" {
|
||||||
|
@ -73,7 +80,7 @@ teardown() {
|
||||||
config_disable_lapi
|
config_disable_lapi
|
||||||
./instance-crowdsec start || true
|
./instance-crowdsec start || true
|
||||||
rune -1 cscli machines list
|
rune -1 cscli machines list
|
||||||
assert_stderr --partial "local API is disabled, please run this command on the local API machine"
|
assert_stderr --partial "local API is disabled -- this command must be run on the local API machine"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "cscli metrics" {
|
@test "cscli metrics" {
|
||||||
|
@ -85,5 +92,5 @@ teardown() {
|
||||||
assert_output --partial "/v1/watchers/login"
|
assert_output --partial "/v1/watchers/login"
|
||||||
|
|
||||||
assert_stderr --partial "crowdsec local API is disabled"
|
assert_stderr --partial "crowdsec local API is disabled"
|
||||||
assert_stderr --partial "local API is disabled, please run this command on the local API machine"
|
assert_stderr --partial "local API is disabled -- this command must be run on the local API machine"
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,13 +40,19 @@ teardown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "no agent: cscli config show" {
|
@test "no agent: cscli config show" {
|
||||||
config_disable_agent
|
config_set '.crowdsec_service.enable=false'
|
||||||
rune -0 cscli config show -o human
|
rune -0 cscli config show -o human
|
||||||
assert_output --partial "Global:"
|
assert_output --partial "Global:"
|
||||||
assert_output --partial "cscli:"
|
assert_output --partial "cscli:"
|
||||||
assert_output --partial "Local API Server:"
|
assert_output --partial "Local API Server:"
|
||||||
|
assert_output --partial "Crowdsec (disabled):"
|
||||||
|
|
||||||
refute_output --partial "Crowdsec:"
|
config_set 'del(.crowdsec_service)'
|
||||||
|
rune -0 cscli config show -o human
|
||||||
|
assert_output --partial "Global:"
|
||||||
|
assert_output --partial "cscli:"
|
||||||
|
assert_output --partial "Local API Server:"
|
||||||
|
refute_output --partial "Crowdsec"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "no agent: cscli config backup" {
|
@test "no agent: cscli config backup" {
|
||||||
|
|
|
@ -60,5 +60,11 @@ setup() {
|
||||||
ONLINE_API_CREDENTIALS_YAML="$(config_get '.api.server.online_client.credentials_path')"
|
ONLINE_API_CREDENTIALS_YAML="$(config_get '.api.server.online_client.credentials_path')"
|
||||||
rm "${ONLINE_API_CREDENTIALS_YAML}"
|
rm "${ONLINE_API_CREDENTIALS_YAML}"
|
||||||
rune -1 cscli capi status
|
rune -1 cscli capi status
|
||||||
assert_stderr --partial "local API is disabled, please run this command on the local API machine: loading online client credentials: failed to read api server credentials configuration file '${ONLINE_API_CREDENTIALS_YAML}': open ${ONLINE_API_CREDENTIALS_YAML}: no such file or directory"
|
assert_stderr --partial "failed to load Local API: loading online client credentials: failed to read api server credentials configuration file '${ONLINE_API_CREDENTIALS_YAML}': open ${ONLINE_API_CREDENTIALS_YAML}: no such file or directory"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "capi register must be run from lapi" {
|
||||||
|
config_disable_lapi
|
||||||
|
rune -1 cscli capi register --schmilblick githubciXXXXXXXXXXXXXXXXXXXXXXXX
|
||||||
|
assert_stderr --partial "local API is disabled -- this command must be run on the local API machine"
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ teardown() {
|
||||||
config_disable_capi
|
config_disable_capi
|
||||||
./instance-crowdsec start
|
./instance-crowdsec start
|
||||||
rune -1 cscli capi status
|
rune -1 cscli capi status
|
||||||
assert_stderr --partial "no configuration for Central API in "
|
assert_stderr --partial "no configuration for Central API (CAPI) in "
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "no capi: cscli config show" {
|
@test "no capi: cscli config show" {
|
||||||
|
|
|
@ -311,7 +311,7 @@ update-notifier-motd.timer enabled enabled
|
||||||
@test "cscli setup detect (process)" {
|
@test "cscli setup detect (process)" {
|
||||||
# This is harder to mock, because gopsutil requires proc/ to be a mount
|
# This is harder to mock, because gopsutil requires proc/ to be a mount
|
||||||
# point. So we pick a process that exists for sure.
|
# point. So we pick a process that exists for sure.
|
||||||
expected_process=$(basename "$SHELL")
|
expected_process=cscli
|
||||||
|
|
||||||
cat <<-EOT >"${DETECT_YAML}"
|
cat <<-EOT >"${DETECT_YAML}"
|
||||||
version: 1.0
|
version: 1.0
|
||||||
|
|
39
test/bats/12_notifications.bats
Normal file
39
test/bats/12_notifications.bats
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#!/usr/bin/env bats
|
||||||
|
# vim: ft=bats:list:ts=8:sts=4:sw=4:et:ai:si:
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
setup_file() {
|
||||||
|
load "../lib/setup_file.sh"
|
||||||
|
}
|
||||||
|
|
||||||
|
teardown_file() {
|
||||||
|
load "../lib/teardown_file.sh"
|
||||||
|
}
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
load "../lib/setup.sh"
|
||||||
|
load "../lib/bats-file/load.bash"
|
||||||
|
./instance-data load
|
||||||
|
./instance-crowdsec start
|
||||||
|
}
|
||||||
|
|
||||||
|
teardown() {
|
||||||
|
cd "$TEST_DIR" || exit 1
|
||||||
|
./instance-crowdsec stop
|
||||||
|
}
|
||||||
|
|
||||||
|
#----------
|
||||||
|
|
||||||
|
@test "cscli notifications list" {
|
||||||
|
rune -0 cscli notifications list
|
||||||
|
assert_output --partial "Name"
|
||||||
|
assert_output --partial "Type"
|
||||||
|
assert_output --partial "Profile name"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "cscli notifications must be run from lapi" {
|
||||||
|
config_disable_lapi
|
||||||
|
rune -1 cscli notifications list
|
||||||
|
assert_stderr --partial "local API is disabled -- this command must be run on the local API machine"
|
||||||
|
}
|
|
@ -67,7 +67,9 @@ config_set() {
|
||||||
export -f config_set
|
export -f config_set
|
||||||
|
|
||||||
config_disable_agent() {
|
config_disable_agent() {
|
||||||
config_set 'del(.crowdsec_service)'
|
config_set '.crowdsec_service.enable=false'
|
||||||
|
# this should be equivalent to:
|
||||||
|
# config_set 'del(.crowdsec_service)'
|
||||||
}
|
}
|
||||||
export -f config_disable_agent
|
export -f config_disable_agent
|
||||||
|
|
||||||
|
@ -77,7 +79,9 @@ config_log_stderr() {
|
||||||
export -f config_log_stderr
|
export -f config_log_stderr
|
||||||
|
|
||||||
config_disable_lapi() {
|
config_disable_lapi() {
|
||||||
config_set 'del(.api.server)'
|
config_set '.api.server.enable=false'
|
||||||
|
# this should be equivalent to:
|
||||||
|
# config_set 'del(.api.server)'
|
||||||
}
|
}
|
||||||
export -f config_disable_lapi
|
export -f config_disable_lapi
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue