From 033c8e17e8ee6c12dfd831e7a24c071443d25ac5 Mon Sep 17 00:00:00 2001 From: "Thibault \"bui\" Koechlin" Date: Thu, 1 Jul 2021 18:15:22 +0200 Subject: [PATCH] fix #842 #837 (#845) * fix #842 and move preflight checks tgth * handle new container name Co-authored-by: AlteredCoder --- cmd/crowdsec-cli/dashboard.go | 23 +++++++++++++++------- pkg/metabase/container.go | 4 ++-- pkg/metabase/metabase.go | 36 +++++++++++++++++++++++------------ 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/cmd/crowdsec-cli/dashboard.go b/cmd/crowdsec-cli/dashboard.go index 514cda95b..83d268991 100644 --- a/cmd/crowdsec-cli/dashboard.go +++ b/cmd/crowdsec-cli/dashboard.go @@ -6,7 +6,6 @@ import ( "os/exec" "os/user" "path/filepath" - "runtime" "strconv" "strings" "unicode" @@ -29,7 +28,7 @@ var ( /**/ metabaseListenAddress = "127.0.0.1" metabaseListenPort = "3000" - metabaseContainerID = "/crowdsec-metabase" + metabaseContainerID = "crowdsec-metabase" crowdsecGroup = "crowdsec" forceYes bool @@ -54,9 +53,8 @@ cscli dashboard stop cscli dashboard remove `, PersistentPreRun: func(cmd *cobra.Command, args []string) { - - if runtime.GOARCH != "amd64" { - log.Fatalf("cscli dashboard is only available on amd64, but you are running %s", runtime.GOARCH) + if err := metabase.TestAvailability(); err != nil { + log.Fatalf("%s", err) } if err := csConfig.LoadAPIServer(); err != nil || csConfig.DisableAPI { @@ -73,6 +71,17 @@ cscli dashboard remove log.Fatalf(err.Error()) } + /* + Old container name was "/crowdsec-metabase" but podman doesn't + allow '/' in container name. We do this check to not break + existing dashboard setup. + */ + if !metabase.IsContainerExist(metabaseContainerID) { + oldContainerID := fmt.Sprintf("/%s", metabaseContainerID) + if metabase.IsContainerExist(oldContainerID) { + metabaseContainerID = oldContainerID + } + } }, } @@ -140,7 +149,7 @@ cscli dashboard setup -l 0.0.0.0 -p 443 --password log.Fatalf("unable to chown sqlite db file '%s': %s", csConfig.DbConfig.DbPath, err) } - mb, err := metabase.SetupMetabase(csConfig.API.Server.DbConfig, metabaseListenAddress, metabaseListenPort, metabaseUser, metabasePassword, metabaseDbPath, dockerGroup.Gid) + mb, err := metabase.SetupMetabase(csConfig.API.Server.DbConfig, metabaseListenAddress, metabaseListenPort, metabaseUser, metabasePassword, metabaseDbPath, dockerGroup.Gid, metabaseContainerID) if err != nil { log.Fatalf(err.Error()) } @@ -172,7 +181,7 @@ cscli dashboard setup -l 0.0.0.0 -p 443 --password Long: `Stats the metabase container using docker.`, Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { - mb, err := metabase.NewMetabase(metabaseConfigPath) + mb, err := metabase.NewMetabase(metabaseConfigPath, metabaseContainerID) if err != nil { log.Fatalf(err.Error()) } diff --git a/pkg/metabase/container.go b/pkg/metabase/container.go index da571b71f..76788b096 100644 --- a/pkg/metabase/container.go +++ b/pkg/metabase/container.go @@ -27,7 +27,7 @@ type Container struct { DockerGroupID string } -func NewContainer(listenAddr string, listenPort string, sharedFolder string, name string, image string, mbDBURI string, dockerGroupID string) (*Container, error) { +func NewContainer(listenAddr string, listenPort string, sharedFolder string, containerName string, image string, mbDBURI string, dockerGroupID string) (*Container, error) { cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { return nil, fmt.Errorf("failed to create docker client : %s", err) @@ -37,7 +37,7 @@ func NewContainer(listenAddr string, listenPort string, sharedFolder string, nam ListenPort: listenPort, SharedFolder: sharedFolder, Image: image, - Name: name, + Name: containerName, CLI: cli, MBDBUri: mbDBURI, DockerGroupID: dockerGroupID, diff --git a/pkg/metabase/metabase.go b/pkg/metabase/metabase.go index 495274c25..27cc7edd6 100644 --- a/pkg/metabase/metabase.go +++ b/pkg/metabase/metabase.go @@ -3,15 +3,18 @@ package metabase import ( "archive/zip" "bytes" + "context" "fmt" "io" "io/ioutil" "net/http" "os" "path" + "runtime" "strings" "time" + "github.com/docker/docker/client" log "github.com/sirupsen/logrus" "github.com/crowdsecurity/crowdsec/pkg/csconfig" @@ -41,14 +44,27 @@ type Config struct { var ( metabaseDefaultUser = "crowdsec@crowdsec.net" metabaseDefaultPassword = "!!Cr0wdS3c_M3t4b4s3??" - containerName = "/crowdsec-metabase" metabaseImage = "metabase/metabase:v0.37.0.2" containerSharedFolder = "/metabase-data" - - metabaseSQLiteDBURL = "https://crowdsec-statics-assets.s3-eu-west-1.amazonaws.com/metabase_sqlite.zip" + metabaseSQLiteDBURL = "https://crowdsec-statics-assets.s3-eu-west-1.amazonaws.com/metabase_sqlite.zip" ) -func (m *Metabase) Init() error { +func TestAvailability() error { + if runtime.GOARCH != "amd64" { + return fmt.Errorf("cscli dashboard is only available on amd64, but you are running %s", runtime.GOARCH) + } + + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + return fmt.Errorf("failed to create docker client : %s", err) + } + + _, err = cli.Ping(context.TODO()) + return err + +} + +func (m *Metabase) Init(containerName string) error { var err error var DBConnectionURI string var remoteDBAddr string @@ -81,12 +97,12 @@ func (m *Metabase) Init() error { return nil } -func NewMetabase(configPath string) (*Metabase, error) { +func NewMetabase(configPath string, containerName string) (*Metabase, error) { m := &Metabase{} if err := m.LoadConfig(configPath); err != nil { return m, err } - if err := m.Init(); err != nil { + if err := m.Init(containerName); err != nil { return m, err } return m, nil @@ -118,15 +134,11 @@ func (m *Metabase) LoadConfig(configPath string) error { m.Config = config - if err := m.Init(); err != nil { - return err - } - return nil } -func SetupMetabase(dbConfig *csconfig.DatabaseCfg, listenAddr string, listenPort string, username string, password string, mbDBPath string, dockerGroupID string) (*Metabase, error) { +func SetupMetabase(dbConfig *csconfig.DatabaseCfg, listenAddr string, listenPort string, username string, password string, mbDBPath string, dockerGroupID string, containerName string) (*Metabase, error) { metabase := &Metabase{ Config: &Config{ Database: dbConfig, @@ -139,7 +151,7 @@ func SetupMetabase(dbConfig *csconfig.DatabaseCfg, listenAddr string, listenPort DockerGroupID: dockerGroupID, }, } - if err := metabase.Init(); err != nil { + if err := metabase.Init(containerName); err != nil { return nil, errors.Wrap(err, "metabase setup init") }