dashboard.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "path/filepath"
  6. "github.com/AlecAivazis/survey/v2"
  7. "github.com/crowdsecurity/crowdsec/pkg/metabase"
  8. log "github.com/sirupsen/logrus"
  9. "github.com/spf13/cobra"
  10. )
  11. var (
  12. metabaseUser = "crowdsec@crowdsec.net"
  13. metabasePassword string
  14. metabaseDbPath string
  15. metabaseConfigPath string
  16. metabaseConfigFolder = "metabase/"
  17. metabaseConfigFile = "metabase.yaml"
  18. metabaseImage = "metabase/metabase"
  19. /**/
  20. metabaseListenAddress = "127.0.0.1"
  21. metabaseListenPort = "3000"
  22. metabaseContainerID = "/crowdsec-metabase"
  23. forceYes bool
  24. dockerGatewayIPAddr = "172.17.0.1"
  25. /*informations needed to setup a random password on user's behalf*/
  26. )
  27. func NewDashboardCmd() *cobra.Command {
  28. /* ---- UPDATE COMMAND */
  29. var cmdDashboard = &cobra.Command{
  30. Use: "dashboard [command]",
  31. Short: "Manage your metabase dashboard container",
  32. Long: `Install/Start/Stop/Remove a metabase container exposing dashboard and metrics.`,
  33. Args: cobra.ExactArgs(1),
  34. Example: `
  35. cscli dashboard setup
  36. cscli dashboard start
  37. cscli dashboard stop
  38. cscli dashboard remove
  39. `,
  40. PersistentPreRun: func(cmd *cobra.Command, args []string) {
  41. metabaseConfigFolderPath := filepath.Join(csConfig.ConfigPaths.ConfigDir, metabaseConfigFolder)
  42. metabaseConfigPath = filepath.Join(metabaseConfigFolderPath, metabaseConfigFile)
  43. if err := os.MkdirAll(metabaseConfigFolderPath, os.ModePerm); err != nil {
  44. log.Fatalf(err.Error())
  45. }
  46. },
  47. }
  48. var force bool
  49. var cmdDashSetup = &cobra.Command{
  50. Use: "setup",
  51. Short: "Setup a metabase container.",
  52. Long: `Perform a metabase docker setup, download standard dashboards, create a fresh user and start the container`,
  53. Args: cobra.ExactArgs(0),
  54. Example: `
  55. cscli dashboard setup
  56. cscli dashboard setup --listen 0.0.0.0
  57. cscli dashboard setup -l 0.0.0.0 -p 443 --password <password>
  58. `,
  59. Run: func(cmd *cobra.Command, args []string) {
  60. if metabaseDbPath == "" {
  61. metabaseDbPath = csConfig.ConfigPaths.DataDir
  62. }
  63. if metabasePassword == "" {
  64. metabasePassword = generatePassword(16)
  65. }
  66. mb, err := metabase.SetupMetabase(csConfig.API.Server.DbConfig, metabaseListenAddress, metabaseListenPort, metabaseUser, metabasePassword, metabaseDbPath)
  67. if err != nil {
  68. log.Fatalf(err.Error())
  69. }
  70. if err := mb.DumpConfig(metabaseConfigPath); err != nil {
  71. log.Fatalf(err.Error())
  72. }
  73. log.Infof("Metabase is ready")
  74. fmt.Println()
  75. fmt.Printf("\tURL : '%s'\n", mb.Config.ListenURL)
  76. fmt.Printf("\tusername : '%s'\n", mb.Config.Username)
  77. fmt.Printf("\tpassword : '%s'\n", mb.Config.Password)
  78. },
  79. }
  80. cmdDashSetup.Flags().BoolVarP(&force, "force", "f", false, "Force setup : override existing files.")
  81. cmdDashSetup.Flags().StringVarP(&metabaseDbPath, "dir", "d", "", "Shared directory with metabase container.")
  82. cmdDashSetup.Flags().StringVarP(&metabaseListenAddress, "listen", "l", metabaseListenAddress, "Listen address of container")
  83. cmdDashSetup.Flags().StringVarP(&metabaseListenPort, "port", "p", metabaseListenPort, "Listen port of container")
  84. //cmdDashSetup.Flags().StringVarP(&metabaseUser, "user", "u", "crowdsec@crowdsec.net", "metabase user")
  85. cmdDashSetup.Flags().StringVar(&metabasePassword, "password", "", "metabase password")
  86. cmdDashboard.AddCommand(cmdDashSetup)
  87. var cmdDashStart = &cobra.Command{
  88. Use: "start",
  89. Short: "Start the metabase container.",
  90. Long: `Stats the metabase container using docker.`,
  91. Args: cobra.ExactArgs(0),
  92. Run: func(cmd *cobra.Command, args []string) {
  93. mb, err := metabase.NewMetabase(metabaseConfigPath)
  94. if err != nil {
  95. log.Fatalf(err.Error())
  96. }
  97. if err := mb.Container.Start(); err != nil {
  98. log.Fatalf("Failed to start metabase container : %s", err)
  99. }
  100. log.Infof("Started metabase")
  101. log.Infof("url : http://%s:%s", metabaseListenAddress, metabaseListenPort)
  102. },
  103. }
  104. cmdDashboard.AddCommand(cmdDashStart)
  105. var cmdDashStop = &cobra.Command{
  106. Use: "stop",
  107. Short: "Stops the metabase container.",
  108. Long: `Stops the metabase container using docker.`,
  109. Args: cobra.ExactArgs(0),
  110. Run: func(cmd *cobra.Command, args []string) {
  111. if err := metabase.StopContainer(metabaseContainerID); err != nil {
  112. log.Fatalf("unable to stop container '%s': %s", metabaseContainerID, err)
  113. }
  114. },
  115. }
  116. cmdDashboard.AddCommand(cmdDashStop)
  117. var cmdDashRemove = &cobra.Command{
  118. Use: "remove",
  119. Short: "removes the metabase container.",
  120. Long: `removes the metabase container using docker.`,
  121. Args: cobra.ExactArgs(0),
  122. Example: `
  123. cscli dashboard remove
  124. cscli dashboard remove --force
  125. `,
  126. Run: func(cmd *cobra.Command, args []string) {
  127. answer := true
  128. if !forceYes {
  129. prompt := &survey.Confirm{
  130. Message: "Do you really want to remove crowdsec dashboard? (all your changes will be lost)",
  131. Default: true,
  132. }
  133. if err := survey.AskOne(prompt, &answer); err != nil {
  134. log.Fatalf("unable to ask to force: %s", err)
  135. }
  136. }
  137. if answer {
  138. if metabase.IsContainerExist(metabaseContainerID) {
  139. log.Debugf("Stopping container %s", metabaseContainerID)
  140. if err := metabase.StopContainer(metabaseContainerID); err != nil {
  141. log.Warningf("unable to stop container '%s': %s", metabaseContainerID, err)
  142. }
  143. log.Debugf("Removing container %s", metabaseContainerID)
  144. if err := metabase.RemoveContainer(metabaseContainerID); err != nil {
  145. log.Warningf("unable to remove container '%s': %s", metabaseContainerID, err)
  146. }
  147. log.Infof("container %s stopped & removed", metabaseContainerID)
  148. }
  149. log.Debugf("Removing database %s", csConfig.ConfigPaths.DataDir)
  150. if err := metabase.RemoveDatabase(csConfig.ConfigPaths.DataDir); err != nil {
  151. log.Warningf("failed to remove metabase internal db : %s", err)
  152. }
  153. if force {
  154. log.Debugf("Removing image %s", metabaseImage)
  155. if err := metabase.RemoveImageContainer(metabaseImage); err != nil {
  156. log.Warningf("Failed to remove metabase container %s : %s", metabaseImage, err)
  157. }
  158. }
  159. }
  160. },
  161. }
  162. cmdDashRemove.Flags().BoolVarP(&force, "force", "f", false, "Force remove : stop the container if running and remove.")
  163. cmdDashRemove.Flags().BoolVarP(&forceYes, "yes", "y", false, "force yes")
  164. cmdDashboard.AddCommand(cmdDashRemove)
  165. return cmdDashboard
  166. }