config.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "io/ioutil"
  6. "os"
  7. "path"
  8. "strings"
  9. log "github.com/sirupsen/logrus"
  10. "github.com/spf13/cobra"
  11. "gopkg.in/yaml.v2"
  12. )
  13. /*CliCfg is the cli configuration structure, might be unexported*/
  14. type cliConfig struct {
  15. configured bool
  16. simulation bool /*are we in simulation mode*/
  17. configFolder string `yaml:"cliconfig,omitempty"` /*overload ~/.cscli/*/
  18. output string /*output is human, json*/
  19. logLevel log.Level /*debug,info,warning,error*/
  20. hubFolder string
  21. InstallFolder string `yaml:"installdir"` /*/etc/crowdsec/*/
  22. BackendPluginFolder string `yaml:"backend"`
  23. dbPath string
  24. }
  25. func interactiveCfg() error {
  26. var err error
  27. reader := bufio.NewReader(os.Stdin)
  28. fmt.Print("crowdsec installation directory (default: /etc/crowdsec/config/): ")
  29. config.InstallFolder, err = reader.ReadString('\n')
  30. config.InstallFolder = strings.Replace(config.InstallFolder, "\n", "", -1) //CRLF to LF (windows)
  31. if config.InstallFolder == "" {
  32. config.InstallFolder = "/etc/crowdsec/config/"
  33. }
  34. if err != nil {
  35. log.Fatalf("failed to read input : %v", err.Error())
  36. }
  37. fmt.Print("crowdsec backend plugin directory (default: /etc/crowdsec/plugin/backend): ")
  38. config.BackendPluginFolder, err = reader.ReadString('\n')
  39. config.BackendPluginFolder = strings.Replace(config.BackendPluginFolder, "\n", "", -1) //CRLF to LF (windows)
  40. if config.BackendPluginFolder == "" {
  41. config.BackendPluginFolder = "/etc/crowdsec/plugin/backend"
  42. }
  43. if err != nil {
  44. log.Fatalf("failed to read input : %v", err.Error())
  45. }
  46. if err := writeCfg(); err != nil {
  47. log.Fatalf("failed writting configuration file : %s", err)
  48. }
  49. return nil
  50. }
  51. func writeCfg() error {
  52. if config.configFolder == "" {
  53. return fmt.Errorf("config dir is unset")
  54. }
  55. config.hubFolder = config.configFolder + "/hub/"
  56. if _, err := os.Stat(config.hubFolder); os.IsNotExist(err) {
  57. log.Warningf("creating skeleton!")
  58. if err := os.MkdirAll(config.hubFolder, os.ModePerm); err != nil {
  59. return fmt.Errorf("failed to create missing directory : '%s'", config.hubFolder)
  60. }
  61. }
  62. out := path.Join(config.configFolder, "/config")
  63. configYaml, err := yaml.Marshal(&config)
  64. if err != nil {
  65. return fmt.Errorf("failed marshaling config: %s", err)
  66. }
  67. err = ioutil.WriteFile(out, configYaml, 0644)
  68. if err != nil {
  69. return fmt.Errorf("failed to write to %s : %s", out, err)
  70. }
  71. log.Infof("wrote config to %s ", out)
  72. return nil
  73. }
  74. func NewConfigCmd() *cobra.Command {
  75. var cmdConfig = &cobra.Command{
  76. Use: "config [command] <value>",
  77. Short: "Allows to view/edit cscli config",
  78. Long: `Allow to configure sqlite path and installation directory.
  79. If no commands are specified, config is in interactive mode.`,
  80. Example: ` - cscli config show
  81. - cscli config prompt`,
  82. Args: cobra.ExactArgs(1),
  83. }
  84. var cmdConfigShow = &cobra.Command{
  85. Use: "show",
  86. Short: "Displays current config",
  87. Long: `Displays the current cli configuration.`,
  88. Args: cobra.ExactArgs(0),
  89. Run: func(cmd *cobra.Command, args []string) {
  90. if config.output == "json" {
  91. log.WithFields(log.Fields{
  92. "installdir": config.InstallFolder,
  93. "cliconfig": path.Join(config.configFolder, "/config"),
  94. }).Warning("Current config")
  95. } else {
  96. x, err := yaml.Marshal(config)
  97. if err != nil {
  98. log.Fatalf("failed to marshal current configuration : %v", err)
  99. }
  100. fmt.Printf("%s", x)
  101. fmt.Printf("#cliconfig: %s", path.Join(config.configFolder, "/config"))
  102. }
  103. },
  104. }
  105. cmdConfig.AddCommand(cmdConfigShow)
  106. var cmdConfigInterctive = &cobra.Command{
  107. Use: "prompt",
  108. Short: "Prompt for configuration values in an interactive fashion",
  109. Long: `Start interactive configuration of cli. It will successively ask for install dir, db path.`,
  110. Args: cobra.ExactArgs(0),
  111. Run: func(cmd *cobra.Command, args []string) {
  112. err := interactiveCfg()
  113. if err != nil {
  114. log.Fatalf("Failed to run interactive config : %s", err)
  115. }
  116. log.Warningf("Configured, please run update.")
  117. },
  118. }
  119. cmdConfig.AddCommand(cmdConfigInterctive)
  120. var cmdConfigInstalldir = &cobra.Command{
  121. Use: "installdir [value]",
  122. Short: `Configure installation directory`,
  123. Long: `Configure the installation directory of crowdsec, such as /etc/crowdsec/config/`,
  124. Args: cobra.ExactArgs(1),
  125. Run: func(cmd *cobra.Command, args []string) {
  126. config.InstallFolder = args[0]
  127. if err := writeCfg(); err != nil {
  128. log.Fatalf("failed writting configuration: %s", err)
  129. }
  130. },
  131. }
  132. cmdConfig.AddCommand(cmdConfigInstalldir)
  133. var cmdConfigBackendFolder = &cobra.Command{
  134. Use: "backend [value]",
  135. Short: `Configure installation directory`,
  136. Long: `Configure the backend plugin directory of crowdsec, such as /etc/crowdsec/plugins/backend`,
  137. Args: cobra.ExactArgs(1),
  138. Run: func(cmd *cobra.Command, args []string) {
  139. config.BackendPluginFolder = args[0]
  140. if err := writeCfg(); err != nil {
  141. log.Fatalf("failed writting configuration: %s", err)
  142. }
  143. },
  144. }
  145. cmdConfig.AddCommand(cmdConfigBackendFolder)
  146. return cmdConfig
  147. }