config_backup.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "path/filepath"
  6. "github.com/pkg/errors"
  7. log "github.com/sirupsen/logrus"
  8. "github.com/spf13/cobra"
  9. "github.com/crowdsecurity/crowdsec/pkg/cwhub"
  10. )
  11. /* Backup crowdsec configurations to directory <dirPath> :
  12. - Main config (config.yaml)
  13. - Profiles config (profiles.yaml)
  14. - Simulation config (simulation.yaml)
  15. - Backup of API credentials (local API and online API)
  16. - List of scenarios, parsers, postoverflows and collections that are up-to-date
  17. - Tainted/local/out-of-date scenarios, parsers, postoverflows and collections
  18. */
  19. func backupConfigToDirectory(dirPath string) error {
  20. var err error
  21. if dirPath == "" {
  22. return fmt.Errorf("directory path can't be empty")
  23. }
  24. log.Infof("Starting configuration backup")
  25. /*if parent directory doesn't exist, bail out. create final dir with Mkdir*/
  26. parentDir := filepath.Dir(dirPath)
  27. if _, err := os.Stat(parentDir); err != nil {
  28. return errors.Wrapf(err, "while checking parent directory %s existence", parentDir)
  29. }
  30. if err = os.Mkdir(dirPath, 0o700); err != nil {
  31. return errors.Wrapf(err, "while creating %s", dirPath)
  32. }
  33. if csConfig.ConfigPaths.SimulationFilePath != "" {
  34. backupSimulation := filepath.Join(dirPath, "simulation.yaml")
  35. if err = CopyFile(csConfig.ConfigPaths.SimulationFilePath, backupSimulation); err != nil {
  36. return errors.Wrapf(err, "failed copy %s to %s", csConfig.ConfigPaths.SimulationFilePath, backupSimulation)
  37. }
  38. log.Infof("Saved simulation to %s", backupSimulation)
  39. }
  40. /*
  41. - backup AcquisitionFilePath
  42. - backup the other files of acquisition directory
  43. */
  44. if csConfig.Crowdsec != nil && csConfig.Crowdsec.AcquisitionFilePath != "" {
  45. backupAcquisition := filepath.Join(dirPath, "acquis.yaml")
  46. if err = CopyFile(csConfig.Crowdsec.AcquisitionFilePath, backupAcquisition); err != nil {
  47. return fmt.Errorf("failed copy %s to %s : %s", csConfig.Crowdsec.AcquisitionFilePath, backupAcquisition, err)
  48. }
  49. }
  50. acquisBackupDir := filepath.Join(dirPath, "acquis")
  51. if err = os.Mkdir(acquisBackupDir, 0o700); err != nil {
  52. return fmt.Errorf("error while creating %s : %s", acquisBackupDir, err)
  53. }
  54. if csConfig.Crowdsec != nil && len(csConfig.Crowdsec.AcquisitionFiles) > 0 {
  55. for _, acquisFile := range csConfig.Crowdsec.AcquisitionFiles {
  56. /*if it was the default one, it was already backup'ed*/
  57. if csConfig.Crowdsec.AcquisitionFilePath == acquisFile {
  58. continue
  59. }
  60. targetFname, err := filepath.Abs(filepath.Join(acquisBackupDir, filepath.Base(acquisFile)))
  61. if err != nil {
  62. return errors.Wrapf(err, "while saving %s to %s", acquisFile, acquisBackupDir)
  63. }
  64. if err = CopyFile(acquisFile, targetFname); err != nil {
  65. return fmt.Errorf("failed copy %s to %s : %s", acquisFile, targetFname, err)
  66. }
  67. log.Infof("Saved acquis %s to %s", acquisFile, targetFname)
  68. }
  69. }
  70. if ConfigFilePath != "" {
  71. backupMain := fmt.Sprintf("%s/config.yaml", dirPath)
  72. if err = CopyFile(ConfigFilePath, backupMain); err != nil {
  73. return fmt.Errorf("failed copy %s to %s : %s", ConfigFilePath, backupMain, err)
  74. }
  75. log.Infof("Saved default yaml to %s", backupMain)
  76. }
  77. if csConfig.API != nil && csConfig.API.Server != nil && csConfig.API.Server.OnlineClient != nil && csConfig.API.Server.OnlineClient.CredentialsFilePath != "" {
  78. backupCAPICreds := fmt.Sprintf("%s/online_api_credentials.yaml", dirPath)
  79. if err = CopyFile(csConfig.API.Server.OnlineClient.CredentialsFilePath, backupCAPICreds); err != nil {
  80. return fmt.Errorf("failed copy %s to %s : %s", csConfig.API.Server.OnlineClient.CredentialsFilePath, backupCAPICreds, err)
  81. }
  82. log.Infof("Saved online API credentials to %s", backupCAPICreds)
  83. }
  84. if csConfig.API != nil && csConfig.API.Client != nil && csConfig.API.Client.CredentialsFilePath != "" {
  85. backupLAPICreds := fmt.Sprintf("%s/local_api_credentials.yaml", dirPath)
  86. if err = CopyFile(csConfig.API.Client.CredentialsFilePath, backupLAPICreds); err != nil {
  87. return fmt.Errorf("failed copy %s to %s : %s", csConfig.API.Client.CredentialsFilePath, backupLAPICreds, err)
  88. }
  89. log.Infof("Saved local API credentials to %s", backupLAPICreds)
  90. }
  91. if csConfig.API != nil && csConfig.API.Server != nil && csConfig.API.Server.ProfilesPath != "" {
  92. backupProfiles := fmt.Sprintf("%s/profiles.yaml", dirPath)
  93. if err = CopyFile(csConfig.API.Server.ProfilesPath, backupProfiles); err != nil {
  94. return fmt.Errorf("failed copy %s to %s : %s", csConfig.API.Server.ProfilesPath, backupProfiles, err)
  95. }
  96. log.Infof("Saved profiles to %s", backupProfiles)
  97. }
  98. if err = BackupHub(dirPath); err != nil {
  99. return fmt.Errorf("failed to backup hub config : %s", err)
  100. }
  101. return nil
  102. }
  103. func runConfigBackup(cmd *cobra.Command, args []string) error {
  104. if err := csConfig.LoadHub(); err != nil {
  105. return err
  106. }
  107. if err := cwhub.GetHubIdx(csConfig.Hub); err != nil {
  108. log.Info("Run 'sudo cscli hub update' to get the hub index")
  109. return fmt.Errorf("failed to get Hub index: %w", err)
  110. }
  111. if err := backupConfigToDirectory(args[0]); err != nil {
  112. return fmt.Errorf("failed to backup config: %w", err)
  113. }
  114. return nil
  115. }
  116. func NewConfigBackupCmd() *cobra.Command {
  117. cmdConfigBackup := &cobra.Command{
  118. Use: `backup "directory"`,
  119. Short: "Backup current config",
  120. Long: `Backup the current crowdsec configuration including :
  121. - Main config (config.yaml)
  122. - Simulation config (simulation.yaml)
  123. - Profiles config (profiles.yaml)
  124. - List of scenarios, parsers, postoverflows and collections that are up-to-date
  125. - Tainted/local/out-of-date scenarios, parsers, postoverflows and collections
  126. - Backup of API credentials (local API and online API)`,
  127. Example: `cscli config backup ./my-backup`,
  128. Args: cobra.ExactArgs(1),
  129. DisableAutoGenTag: true,
  130. RunE: runConfigBackup,
  131. }
  132. return cmdConfigBackup
  133. }