refact "cscli config", remove flag "cscli restore --old-backup" (#2832)
* refact "cscli config show" * refact "cscli config backup" * refact "cscli confgi show-yaml" * refact "cscli config restore" * refact "cscli config feature-flags" * cscli restore: remove 'old-backup' option * lint (whitespace, wrapped errors)
This commit is contained in:
parent
f3ea88f64c
commit
3e3df5e4c6
7 changed files with 168 additions and 210 deletions
|
@ -4,19 +4,29 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewConfigCmd() *cobra.Command {
|
||||
cmdConfig := &cobra.Command{
|
||||
type cliConfig struct {
|
||||
cfg configGetter
|
||||
}
|
||||
|
||||
func NewCLIConfig(cfg configGetter) *cliConfig {
|
||||
return &cliConfig{
|
||||
cfg: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
func (cli *cliConfig) NewCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "config [command]",
|
||||
Short: "Allows to view current config",
|
||||
Args: cobra.ExactArgs(0),
|
||||
DisableAutoGenTag: true,
|
||||
}
|
||||
|
||||
cmdConfig.AddCommand(NewConfigShowCmd())
|
||||
cmdConfig.AddCommand(NewConfigShowYAMLCmd())
|
||||
cmdConfig.AddCommand(NewConfigBackupCmd())
|
||||
cmdConfig.AddCommand(NewConfigRestoreCmd())
|
||||
cmdConfig.AddCommand(NewConfigFeatureFlagsCmd())
|
||||
cmd.AddCommand(cli.newShowCmd())
|
||||
cmd.AddCommand(cli.newShowYAMLCmd())
|
||||
cmd.AddCommand(cli.newBackupCmd())
|
||||
cmd.AddCommand(cli.newRestoreCmd())
|
||||
cmd.AddCommand(cli.newFeatureFlagsCmd())
|
||||
|
||||
return cmdConfig
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
@ -13,8 +14,8 @@ import (
|
|||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||
)
|
||||
|
||||
func backupHub(dirPath string) error {
|
||||
hub, err := require.Hub(csConfig, nil, nil)
|
||||
func (cli *cliConfig) backupHub(dirPath string) error {
|
||||
hub, err := require.Hub(cli.cfg(), nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -32,7 +33,7 @@ func backupHub(dirPath string) error {
|
|||
|
||||
itemDirectory := fmt.Sprintf("%s/%s/", dirPath, itemType)
|
||||
if err = os.MkdirAll(itemDirectory, os.ModePerm); err != nil {
|
||||
return fmt.Errorf("error while creating %s : %s", itemDirectory, err)
|
||||
return fmt.Errorf("error while creating %s: %w", itemDirectory, err)
|
||||
}
|
||||
|
||||
upstreamParsers := []string{}
|
||||
|
@ -41,18 +42,18 @@ func backupHub(dirPath string) error {
|
|||
clog = clog.WithFields(log.Fields{
|
||||
"file": v.Name,
|
||||
})
|
||||
if !v.State.Installed { //only backup installed ones
|
||||
clog.Debugf("[%s] : not installed", k)
|
||||
if !v.State.Installed { // only backup installed ones
|
||||
clog.Debugf("[%s]: not installed", k)
|
||||
continue
|
||||
}
|
||||
|
||||
//for the local/tainted ones, we back up the full file
|
||||
// for the local/tainted ones, we back up the full file
|
||||
if v.State.Tainted || v.State.IsLocal() || !v.State.UpToDate {
|
||||
//we need to backup stages for parsers
|
||||
// we need to backup stages for parsers
|
||||
if itemType == cwhub.PARSERS || itemType == cwhub.POSTOVERFLOWS {
|
||||
fstagedir := fmt.Sprintf("%s%s", itemDirectory, v.Stage)
|
||||
if err = os.MkdirAll(fstagedir, os.ModePerm); err != nil {
|
||||
return fmt.Errorf("error while creating stage dir %s : %s", fstagedir, err)
|
||||
return fmt.Errorf("error while creating stage dir %s: %w", fstagedir, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,7 +61,7 @@ func backupHub(dirPath string) error {
|
|||
|
||||
tfile := fmt.Sprintf("%s%s/%s", itemDirectory, v.Stage, v.FileName)
|
||||
if err = CopyFile(v.State.LocalPath, tfile); err != nil {
|
||||
return fmt.Errorf("failed copy %s %s to %s : %s", itemType, v.State.LocalPath, tfile, err)
|
||||
return fmt.Errorf("failed copy %s %s to %s: %w", itemType, v.State.LocalPath, tfile, err)
|
||||
}
|
||||
|
||||
clog.Infof("local/tainted saved %s to %s", v.State.LocalPath, tfile)
|
||||
|
@ -68,21 +69,21 @@ func backupHub(dirPath string) error {
|
|||
continue
|
||||
}
|
||||
|
||||
clog.Debugf("[%s] : from hub, just backup name (up-to-date:%t)", k, v.State.UpToDate)
|
||||
clog.Debugf("[%s]: from hub, just backup name (up-to-date:%t)", k, v.State.UpToDate)
|
||||
clog.Infof("saving, version:%s, up-to-date:%t", v.Version, v.State.UpToDate)
|
||||
upstreamParsers = append(upstreamParsers, v.Name)
|
||||
}
|
||||
//write the upstream items
|
||||
// write the upstream items
|
||||
upstreamParsersFname := fmt.Sprintf("%s/upstream-%s.json", itemDirectory, itemType)
|
||||
|
||||
upstreamParsersContent, err := json.MarshalIndent(upstreamParsers, "", " ")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed marshaling upstream parsers : %s", err)
|
||||
return fmt.Errorf("failed marshaling upstream parsers: %w", err)
|
||||
}
|
||||
|
||||
err = os.WriteFile(upstreamParsersFname, upstreamParsersContent, 0o644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to write to %s %s : %s", itemType, upstreamParsersFname, err)
|
||||
return fmt.Errorf("unable to write to %s %s: %w", itemType, upstreamParsersFname, err)
|
||||
}
|
||||
|
||||
clog.Infof("Wrote %d entries for %s to %s", len(upstreamParsers), itemType, upstreamParsersFname)
|
||||
|
@ -102,11 +103,13 @@ func backupHub(dirPath string) error {
|
|||
- Tainted/local/out-of-date scenarios, parsers, postoverflows and collections
|
||||
- Acquisition files (acquis.yaml, acquis.d/*.yaml)
|
||||
*/
|
||||
func backupConfigToDirectory(dirPath string) error {
|
||||
func (cli *cliConfig) backup(dirPath string) error {
|
||||
var err error
|
||||
|
||||
cfg := cli.cfg()
|
||||
|
||||
if dirPath == "" {
|
||||
return fmt.Errorf("directory path can't be empty")
|
||||
return errors.New("directory path can't be empty")
|
||||
}
|
||||
|
||||
log.Infof("Starting configuration backup")
|
||||
|
@ -121,10 +124,10 @@ func backupConfigToDirectory(dirPath string) error {
|
|||
return fmt.Errorf("while creating %s: %w", dirPath, err)
|
||||
}
|
||||
|
||||
if csConfig.ConfigPaths.SimulationFilePath != "" {
|
||||
if cfg.ConfigPaths.SimulationFilePath != "" {
|
||||
backupSimulation := filepath.Join(dirPath, "simulation.yaml")
|
||||
if err = CopyFile(csConfig.ConfigPaths.SimulationFilePath, backupSimulation); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s: %w", csConfig.ConfigPaths.SimulationFilePath, backupSimulation, err)
|
||||
if err = CopyFile(cfg.ConfigPaths.SimulationFilePath, backupSimulation); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s: %w", cfg.ConfigPaths.SimulationFilePath, backupSimulation, err)
|
||||
}
|
||||
|
||||
log.Infof("Saved simulation to %s", backupSimulation)
|
||||
|
@ -134,22 +137,22 @@ func backupConfigToDirectory(dirPath string) error {
|
|||
- backup AcquisitionFilePath
|
||||
- backup the other files of acquisition directory
|
||||
*/
|
||||
if csConfig.Crowdsec != nil && csConfig.Crowdsec.AcquisitionFilePath != "" {
|
||||
if cfg.Crowdsec != nil && cfg.Crowdsec.AcquisitionFilePath != "" {
|
||||
backupAcquisition := filepath.Join(dirPath, "acquis.yaml")
|
||||
if err = CopyFile(csConfig.Crowdsec.AcquisitionFilePath, backupAcquisition); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s: %s", csConfig.Crowdsec.AcquisitionFilePath, backupAcquisition, err)
|
||||
if err = CopyFile(cfg.Crowdsec.AcquisitionFilePath, backupAcquisition); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s: %w", cfg.Crowdsec.AcquisitionFilePath, backupAcquisition, err)
|
||||
}
|
||||
}
|
||||
|
||||
acquisBackupDir := filepath.Join(dirPath, "acquis")
|
||||
if err = os.Mkdir(acquisBackupDir, 0o700); err != nil {
|
||||
return fmt.Errorf("error while creating %s: %s", acquisBackupDir, err)
|
||||
return fmt.Errorf("error while creating %s: %w", acquisBackupDir, err)
|
||||
}
|
||||
|
||||
if csConfig.Crowdsec != nil && len(csConfig.Crowdsec.AcquisitionFiles) > 0 {
|
||||
for _, acquisFile := range csConfig.Crowdsec.AcquisitionFiles {
|
||||
if cfg.Crowdsec != nil && len(cfg.Crowdsec.AcquisitionFiles) > 0 {
|
||||
for _, acquisFile := range cfg.Crowdsec.AcquisitionFiles {
|
||||
/*if it was the default one, it was already backup'ed*/
|
||||
if csConfig.Crowdsec.AcquisitionFilePath == acquisFile {
|
||||
if cfg.Crowdsec.AcquisitionFilePath == acquisFile {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -169,56 +172,48 @@ func backupConfigToDirectory(dirPath string) error {
|
|||
if ConfigFilePath != "" {
|
||||
backupMain := fmt.Sprintf("%s/config.yaml", dirPath)
|
||||
if err = CopyFile(ConfigFilePath, backupMain); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s: %s", ConfigFilePath, backupMain, err)
|
||||
return fmt.Errorf("failed copy %s to %s: %w", ConfigFilePath, backupMain, err)
|
||||
}
|
||||
|
||||
log.Infof("Saved default yaml to %s", backupMain)
|
||||
}
|
||||
|
||||
if csConfig.API != nil && csConfig.API.Server != nil && csConfig.API.Server.OnlineClient != nil && csConfig.API.Server.OnlineClient.CredentialsFilePath != "" {
|
||||
if cfg.API != nil && cfg.API.Server != nil && cfg.API.Server.OnlineClient != nil && cfg.API.Server.OnlineClient.CredentialsFilePath != "" {
|
||||
backupCAPICreds := fmt.Sprintf("%s/online_api_credentials.yaml", dirPath)
|
||||
if err = CopyFile(csConfig.API.Server.OnlineClient.CredentialsFilePath, backupCAPICreds); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s: %s", csConfig.API.Server.OnlineClient.CredentialsFilePath, backupCAPICreds, err)
|
||||
if err = CopyFile(cfg.API.Server.OnlineClient.CredentialsFilePath, backupCAPICreds); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s: %w", cfg.API.Server.OnlineClient.CredentialsFilePath, backupCAPICreds, err)
|
||||
}
|
||||
|
||||
log.Infof("Saved online API credentials to %s", backupCAPICreds)
|
||||
}
|
||||
|
||||
if csConfig.API != nil && csConfig.API.Client != nil && csConfig.API.Client.CredentialsFilePath != "" {
|
||||
if cfg.API != nil && cfg.API.Client != nil && cfg.API.Client.CredentialsFilePath != "" {
|
||||
backupLAPICreds := fmt.Sprintf("%s/local_api_credentials.yaml", dirPath)
|
||||
if err = CopyFile(csConfig.API.Client.CredentialsFilePath, backupLAPICreds); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s: %s", csConfig.API.Client.CredentialsFilePath, backupLAPICreds, err)
|
||||
if err = CopyFile(cfg.API.Client.CredentialsFilePath, backupLAPICreds); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s: %w", cfg.API.Client.CredentialsFilePath, backupLAPICreds, err)
|
||||
}
|
||||
|
||||
log.Infof("Saved local API credentials to %s", backupLAPICreds)
|
||||
}
|
||||
|
||||
if csConfig.API != nil && csConfig.API.Server != nil && csConfig.API.Server.ProfilesPath != "" {
|
||||
if cfg.API != nil && cfg.API.Server != nil && cfg.API.Server.ProfilesPath != "" {
|
||||
backupProfiles := fmt.Sprintf("%s/profiles.yaml", dirPath)
|
||||
if err = CopyFile(csConfig.API.Server.ProfilesPath, backupProfiles); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s: %s", csConfig.API.Server.ProfilesPath, backupProfiles, err)
|
||||
if err = CopyFile(cfg.API.Server.ProfilesPath, backupProfiles); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s: %w", cfg.API.Server.ProfilesPath, backupProfiles, err)
|
||||
}
|
||||
|
||||
log.Infof("Saved profiles to %s", backupProfiles)
|
||||
}
|
||||
|
||||
if err = backupHub(dirPath); err != nil {
|
||||
return fmt.Errorf("failed to backup hub config: %s", err)
|
||||
if err = cli.backupHub(dirPath); err != nil {
|
||||
return fmt.Errorf("failed to backup hub config: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runConfigBackup(cmd *cobra.Command, args []string) error {
|
||||
if err := backupConfigToDirectory(args[0]); err != nil {
|
||||
return fmt.Errorf("failed to backup config: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewConfigBackupCmd() *cobra.Command {
|
||||
cmdConfigBackup := &cobra.Command{
|
||||
func (cli *cliConfig) newBackupCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: `backup "directory"`,
|
||||
Short: "Backup current config",
|
||||
Long: `Backup the current crowdsec configuration including :
|
||||
|
@ -232,8 +227,14 @@ func NewConfigBackupCmd() *cobra.Command {
|
|||
Example: `cscli config backup ./my-backup`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
DisableAutoGenTag: true,
|
||||
RunE: runConfigBackup,
|
||||
RunE: func(_ *cobra.Command, args []string) error {
|
||||
if err := cli.backup(args[0]); err != nil {
|
||||
return fmt.Errorf("failed to backup config: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
return cmdConfigBackup
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -11,14 +11,7 @@ import (
|
|||
"github.com/crowdsecurity/crowdsec/pkg/fflag"
|
||||
)
|
||||
|
||||
func runConfigFeatureFlags(cmd *cobra.Command, args []string) error {
|
||||
flags := cmd.Flags()
|
||||
|
||||
showRetired, err := flags.GetBool("retired")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func (cli *cliConfig) featureFlags(showRetired bool) error {
|
||||
green := color.New(color.FgGreen).SprintFunc()
|
||||
red := color.New(color.FgRed).SprintFunc()
|
||||
yellow := color.New(color.FgYellow).SprintFunc()
|
||||
|
@ -121,18 +114,22 @@ func runConfigFeatureFlags(cmd *cobra.Command, args []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func NewConfigFeatureFlagsCmd() *cobra.Command {
|
||||
cmdConfigFeatureFlags := &cobra.Command{
|
||||
func (cli *cliConfig) newFeatureFlagsCmd() *cobra.Command {
|
||||
var showRetired bool
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "feature-flags",
|
||||
Short: "Displays feature flag status",
|
||||
Long: `Displays the supported feature flags and their current status.`,
|
||||
Args: cobra.ExactArgs(0),
|
||||
DisableAutoGenTag: true,
|
||||
RunE: runConfigFeatureFlags,
|
||||
RunE: func(_ *cobra.Command, _ []string) error {
|
||||
return cli.featureFlags(showRetired)
|
||||
},
|
||||
}
|
||||
|
||||
flags := cmdConfigFeatureFlags.Flags()
|
||||
flags.Bool("retired", false, "Show retired features")
|
||||
flags := cmd.Flags()
|
||||
flags.BoolVar(&showRetired, "retired", false, "Show retired features")
|
||||
|
||||
return cmdConfigFeatureFlags
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -3,25 +3,17 @@ package main
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||
)
|
||||
|
||||
type OldAPICfg struct {
|
||||
MachineID string `json:"machine_id"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
func restoreHub(dirPath string) error {
|
||||
func (cli *cliConfig) restoreHub(dirPath string) error {
|
||||
hub, err := require.Hub(csConfig, require.RemoteHub(csConfig), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -38,14 +30,14 @@ func restoreHub(dirPath string) error {
|
|||
|
||||
file, err := os.ReadFile(upstreamListFN)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error while opening %s : %s", upstreamListFN, err)
|
||||
return fmt.Errorf("error while opening %s: %w", upstreamListFN, err)
|
||||
}
|
||||
|
||||
var upstreamList []string
|
||||
|
||||
err = json.Unmarshal(file, &upstreamList)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error unmarshaling %s : %s", upstreamListFN, err)
|
||||
return fmt.Errorf("error unmarshaling %s: %w", upstreamListFN, err)
|
||||
}
|
||||
|
||||
for _, toinstall := range upstreamList {
|
||||
|
@ -55,8 +47,7 @@ func restoreHub(dirPath string) error {
|
|||
continue
|
||||
}
|
||||
|
||||
err := item.Install(false, false)
|
||||
if err != nil {
|
||||
if err = item.Install(false, false); err != nil {
|
||||
log.Errorf("Error while installing %s : %s", toinstall, err)
|
||||
}
|
||||
}
|
||||
|
@ -64,17 +55,17 @@ func restoreHub(dirPath string) error {
|
|||
/*restore the local and tainted items*/
|
||||
files, err := os.ReadDir(itemDirectory)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed enumerating files of %s : %s", itemDirectory, err)
|
||||
return fmt.Errorf("failed enumerating files of %s: %w", itemDirectory, err)
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
//this was the upstream data
|
||||
// this was the upstream data
|
||||
if file.Name() == fmt.Sprintf("upstream-%s.json", itype) {
|
||||
continue
|
||||
}
|
||||
|
||||
if itype == cwhub.PARSERS || itype == cwhub.POSTOVERFLOWS {
|
||||
//we expect a stage here
|
||||
// we expect a stage here
|
||||
if !file.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
@ -84,22 +75,23 @@ func restoreHub(dirPath string) error {
|
|||
log.Debugf("Found stage %s in %s, target directory : %s", stage, itype, stagedir)
|
||||
|
||||
if err = os.MkdirAll(stagedir, os.ModePerm); err != nil {
|
||||
return fmt.Errorf("error while creating stage directory %s : %s", stagedir, err)
|
||||
return fmt.Errorf("error while creating stage directory %s: %w", stagedir, err)
|
||||
}
|
||||
|
||||
// find items
|
||||
ifiles, err := os.ReadDir(itemDirectory + "/" + stage + "/")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed enumerating files of %s : %s", itemDirectory+"/"+stage, err)
|
||||
return fmt.Errorf("failed enumerating files of %s: %w", itemDirectory+"/"+stage, err)
|
||||
}
|
||||
//finally copy item
|
||||
|
||||
// finally copy item
|
||||
for _, tfile := range ifiles {
|
||||
log.Infof("Going to restore local/tainted [%s]", tfile.Name())
|
||||
sourceFile := fmt.Sprintf("%s/%s/%s", itemDirectory, stage, tfile.Name())
|
||||
|
||||
destinationFile := fmt.Sprintf("%s%s", stagedir, tfile.Name())
|
||||
if err = CopyFile(sourceFile, destinationFile); err != nil {
|
||||
return fmt.Errorf("failed copy %s %s to %s : %s", itype, sourceFile, destinationFile, err)
|
||||
return fmt.Errorf("failed copy %s %s to %s: %w", itype, sourceFile, destinationFile, err)
|
||||
}
|
||||
|
||||
log.Infof("restored %s to %s", sourceFile, destinationFile)
|
||||
|
@ -108,9 +100,11 @@ func restoreHub(dirPath string) error {
|
|||
log.Infof("Going to restore local/tainted [%s]", file.Name())
|
||||
sourceFile := fmt.Sprintf("%s/%s", itemDirectory, file.Name())
|
||||
destinationFile := fmt.Sprintf("%s/%s/%s", csConfig.ConfigPaths.ConfigDir, itype, file.Name())
|
||||
|
||||
if err = CopyFile(sourceFile, destinationFile); err != nil {
|
||||
return fmt.Errorf("failed copy %s %s to %s : %s", itype, sourceFile, destinationFile, err)
|
||||
return fmt.Errorf("failed copy %s %s to %s: %w", itype, sourceFile, destinationFile, err)
|
||||
}
|
||||
|
||||
log.Infof("restored %s to %s", sourceFile, destinationFile)
|
||||
}
|
||||
}
|
||||
|
@ -130,95 +124,60 @@ func restoreHub(dirPath string) error {
|
|||
- Tainted/local/out-of-date scenarios, parsers, postoverflows and collections
|
||||
- Acquisition files (acquis.yaml, acquis.d/*.yaml)
|
||||
*/
|
||||
func restoreConfigFromDirectory(dirPath string, oldBackup bool) error {
|
||||
func (cli *cliConfig) restore(dirPath string) error {
|
||||
var err error
|
||||
|
||||
if !oldBackup {
|
||||
backupMain := fmt.Sprintf("%s/config.yaml", dirPath)
|
||||
if _, err = os.Stat(backupMain); err == nil {
|
||||
if csConfig.ConfigPaths != nil && csConfig.ConfigPaths.ConfigDir != "" {
|
||||
if err = CopyFile(backupMain, fmt.Sprintf("%s/config.yaml", csConfig.ConfigPaths.ConfigDir)); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s : %s", backupMain, csConfig.ConfigPaths.ConfigDir, err)
|
||||
}
|
||||
backupMain := fmt.Sprintf("%s/config.yaml", dirPath)
|
||||
if _, err = os.Stat(backupMain); err == nil {
|
||||
if csConfig.ConfigPaths != nil && csConfig.ConfigPaths.ConfigDir != "" {
|
||||
if err = CopyFile(backupMain, fmt.Sprintf("%s/config.yaml", csConfig.ConfigPaths.ConfigDir)); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s: %w", backupMain, csConfig.ConfigPaths.ConfigDir, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now we have config.yaml, we should regenerate config struct to have rights paths etc
|
||||
ConfigFilePath = fmt.Sprintf("%s/config.yaml", csConfig.ConfigPaths.ConfigDir)
|
||||
// Now we have config.yaml, we should regenerate config struct to have rights paths etc
|
||||
ConfigFilePath = fmt.Sprintf("%s/config.yaml", csConfig.ConfigPaths.ConfigDir)
|
||||
|
||||
log.Debug("Reloading configuration")
|
||||
log.Debug("Reloading configuration")
|
||||
|
||||
csConfig, _, err = loadConfigFor("config")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to reload configuration: %s", err)
|
||||
csConfig, _, err = loadConfigFor("config")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to reload configuration: %w", err)
|
||||
}
|
||||
|
||||
backupCAPICreds := fmt.Sprintf("%s/online_api_credentials.yaml", dirPath)
|
||||
if _, err = os.Stat(backupCAPICreds); err == nil {
|
||||
if err = CopyFile(backupCAPICreds, csConfig.API.Server.OnlineClient.CredentialsFilePath); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s: %w", backupCAPICreds, csConfig.API.Server.OnlineClient.CredentialsFilePath, err)
|
||||
}
|
||||
}
|
||||
|
||||
backupCAPICreds := fmt.Sprintf("%s/online_api_credentials.yaml", dirPath)
|
||||
if _, err = os.Stat(backupCAPICreds); err == nil {
|
||||
if err = CopyFile(backupCAPICreds, csConfig.API.Server.OnlineClient.CredentialsFilePath); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s : %s", backupCAPICreds, csConfig.API.Server.OnlineClient.CredentialsFilePath, err)
|
||||
}
|
||||
backupLAPICreds := fmt.Sprintf("%s/local_api_credentials.yaml", dirPath)
|
||||
if _, err = os.Stat(backupLAPICreds); err == nil {
|
||||
if err = CopyFile(backupLAPICreds, csConfig.API.Client.CredentialsFilePath); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s: %w", backupLAPICreds, csConfig.API.Client.CredentialsFilePath, err)
|
||||
}
|
||||
}
|
||||
|
||||
backupLAPICreds := fmt.Sprintf("%s/local_api_credentials.yaml", dirPath)
|
||||
if _, err = os.Stat(backupLAPICreds); err == nil {
|
||||
if err = CopyFile(backupLAPICreds, csConfig.API.Client.CredentialsFilePath); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s : %s", backupLAPICreds, csConfig.API.Client.CredentialsFilePath, err)
|
||||
}
|
||||
}
|
||||
|
||||
backupProfiles := fmt.Sprintf("%s/profiles.yaml", dirPath)
|
||||
if _, err = os.Stat(backupProfiles); err == nil {
|
||||
if err = CopyFile(backupProfiles, csConfig.API.Server.ProfilesPath); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s : %s", backupProfiles, csConfig.API.Server.ProfilesPath, err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var oldAPICfg OldAPICfg
|
||||
backupOldAPICfg := fmt.Sprintf("%s/api_creds.json", dirPath)
|
||||
|
||||
jsonFile, err := os.Open(backupOldAPICfg)
|
||||
if err != nil {
|
||||
log.Warningf("failed to open %s : %s", backupOldAPICfg, err)
|
||||
} else {
|
||||
byteValue, _ := io.ReadAll(jsonFile)
|
||||
err = json.Unmarshal(byteValue, &oldAPICfg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load json file %s : %s", backupOldAPICfg, err)
|
||||
}
|
||||
|
||||
apiCfg := csconfig.ApiCredentialsCfg{
|
||||
Login: oldAPICfg.MachineID,
|
||||
Password: oldAPICfg.Password,
|
||||
URL: CAPIBaseURL,
|
||||
}
|
||||
apiConfigDump, err := yaml.Marshal(apiCfg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to dump api credentials: %s", err)
|
||||
}
|
||||
apiConfigDumpFile := fmt.Sprintf("%s/online_api_credentials.yaml", csConfig.ConfigPaths.ConfigDir)
|
||||
if csConfig.API.Server.OnlineClient != nil && csConfig.API.Server.OnlineClient.CredentialsFilePath != "" {
|
||||
apiConfigDumpFile = csConfig.API.Server.OnlineClient.CredentialsFilePath
|
||||
}
|
||||
err = os.WriteFile(apiConfigDumpFile, apiConfigDump, 0o600)
|
||||
if err != nil {
|
||||
return fmt.Errorf("write api credentials in '%s' failed: %s", apiConfigDumpFile, err)
|
||||
}
|
||||
log.Infof("Saved API credentials to %s", apiConfigDumpFile)
|
||||
backupProfiles := fmt.Sprintf("%s/profiles.yaml", dirPath)
|
||||
if _, err = os.Stat(backupProfiles); err == nil {
|
||||
if err = CopyFile(backupProfiles, csConfig.API.Server.ProfilesPath); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s: %w", backupProfiles, csConfig.API.Server.ProfilesPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
backupSimulation := fmt.Sprintf("%s/simulation.yaml", dirPath)
|
||||
if _, err = os.Stat(backupSimulation); err == nil {
|
||||
if err = CopyFile(backupSimulation, csConfig.ConfigPaths.SimulationFilePath); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s : %s", backupSimulation, csConfig.ConfigPaths.SimulationFilePath, err)
|
||||
return fmt.Errorf("failed copy %s to %s: %w", backupSimulation, csConfig.ConfigPaths.SimulationFilePath, err)
|
||||
}
|
||||
}
|
||||
|
||||
/*if there is a acquisition dir, restore its content*/
|
||||
if csConfig.Crowdsec.AcquisitionDirPath != "" {
|
||||
if err = os.MkdirAll(csConfig.Crowdsec.AcquisitionDirPath, 0o700); err != nil {
|
||||
return fmt.Errorf("error while creating %s : %s", csConfig.Crowdsec.AcquisitionDirPath, err)
|
||||
return fmt.Errorf("error while creating %s: %w", csConfig.Crowdsec.AcquisitionDirPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,7 +187,7 @@ func restoreConfigFromDirectory(dirPath string, oldBackup bool) error {
|
|||
log.Debugf("restoring backup'ed %s", backupAcquisition)
|
||||
|
||||
if err = CopyFile(backupAcquisition, csConfig.Crowdsec.AcquisitionFilePath); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s : %s", backupAcquisition, csConfig.Crowdsec.AcquisitionFilePath, err)
|
||||
return fmt.Errorf("failed copy %s to %s: %w", backupAcquisition, csConfig.Crowdsec.AcquisitionFilePath, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,7 +203,7 @@ func restoreConfigFromDirectory(dirPath string, oldBackup bool) error {
|
|||
log.Debugf("restoring %s to %s", acquisFile, targetFname)
|
||||
|
||||
if err = CopyFile(acquisFile, targetFname); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s : %s", acquisFile, targetFname, err)
|
||||
return fmt.Errorf("failed copy %s to %s: %w", acquisFile, targetFname, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -265,37 +224,22 @@ func restoreConfigFromDirectory(dirPath string, oldBackup bool) error {
|
|||
}
|
||||
|
||||
if err = CopyFile(acquisFile, targetFname); err != nil {
|
||||
return fmt.Errorf("failed copy %s to %s : %s", acquisFile, targetFname, err)
|
||||
return fmt.Errorf("failed copy %s to %s: %w", acquisFile, targetFname, err)
|
||||
}
|
||||
|
||||
log.Infof("Saved acquis %s to %s", acquisFile, targetFname)
|
||||
}
|
||||
}
|
||||
|
||||
if err = restoreHub(dirPath); err != nil {
|
||||
return fmt.Errorf("failed to restore hub config : %s", err)
|
||||
if err = cli.restoreHub(dirPath); err != nil {
|
||||
return fmt.Errorf("failed to restore hub config: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runConfigRestore(cmd *cobra.Command, args []string) error {
|
||||
flags := cmd.Flags()
|
||||
|
||||
oldBackup, err := flags.GetBool("old-backup")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := restoreConfigFromDirectory(args[0], oldBackup); err != nil {
|
||||
return fmt.Errorf("failed to restore config from %s: %w", args[0], err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewConfigRestoreCmd() *cobra.Command {
|
||||
cmdConfigRestore := &cobra.Command{
|
||||
func (cli *cliConfig) newRestoreCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: `restore "directory"`,
|
||||
Short: `Restore config in backup "directory"`,
|
||||
Long: `Restore the crowdsec configuration from specified backup "directory" including:
|
||||
|
@ -308,11 +252,16 @@ func NewConfigRestoreCmd() *cobra.Command {
|
|||
- Backup of API credentials (local API and online API)`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
DisableAutoGenTag: true,
|
||||
RunE: runConfigRestore,
|
||||
RunE: func(_ *cobra.Command, args []string) error {
|
||||
dirPath := args[0]
|
||||
|
||||
if err := cli.restore(dirPath); err != nil {
|
||||
return fmt.Errorf("failed to restore config from %s: %w", dirPath, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
flags := cmdConfigRestore.Flags()
|
||||
flags.BoolP("old-backup", "", false, "To use when you are upgrading crowdsec v0.X to v1.X and you need to restore backup from v0.X")
|
||||
|
||||
return cmdConfigRestore
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -182,31 +182,26 @@ Central API:
|
|||
{{- end }}
|
||||
`
|
||||
|
||||
func runConfigShow(cmd *cobra.Command, args []string) error {
|
||||
flags := cmd.Flags()
|
||||
func (cli *cliConfig) show(key string) error {
|
||||
cfg := cli.cfg()
|
||||
|
||||
if err := csConfig.LoadAPIClient(); err != nil {
|
||||
if err := cfg.LoadAPIClient(); err != nil {
|
||||
log.Errorf("failed to load API client configuration: %s", err)
|
||||
// don't return, we can still show the configuration
|
||||
}
|
||||
|
||||
key, err := flags.GetString("key")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if key != "" {
|
||||
return showConfigKey(key)
|
||||
}
|
||||
|
||||
switch csConfig.Cscli.Output {
|
||||
switch cfg.Cscli.Output {
|
||||
case "human":
|
||||
// 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 },
|
||||
"ValueBool": func(b *bool) bool { return b != nil && *b },
|
||||
}
|
||||
|
||||
tmp, err := template.New("config").Funcs(funcs).Parse(configShowTemplate)
|
||||
|
@ -214,19 +209,19 @@ func runConfigShow(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
err = tmp.Execute(os.Stdout, csConfig)
|
||||
err = tmp.Execute(os.Stdout, cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case "json":
|
||||
data, err := json.MarshalIndent(csConfig, "", " ")
|
||||
data, err := json.MarshalIndent(cfg, "", " ")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal configuration: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("%s\n", string(data))
|
||||
case "raw":
|
||||
data, err := yaml.Marshal(csConfig)
|
||||
data, err := yaml.Marshal(cfg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal configuration: %w", err)
|
||||
}
|
||||
|
@ -237,18 +232,22 @@ func runConfigShow(cmd *cobra.Command, args []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func NewConfigShowCmd() *cobra.Command {
|
||||
cmdConfigShow := &cobra.Command{
|
||||
func (cli *cliConfig) newShowCmd() *cobra.Command {
|
||||
var key string
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "show",
|
||||
Short: "Displays current config",
|
||||
Long: `Displays the current cli configuration.`,
|
||||
Args: cobra.ExactArgs(0),
|
||||
DisableAutoGenTag: true,
|
||||
RunE: runConfigShow,
|
||||
RunE: func(_ *cobra.Command, _ []string) error {
|
||||
return cli.show(key)
|
||||
},
|
||||
}
|
||||
|
||||
flags := cmdConfigShow.Flags()
|
||||
flags.StringP("key", "", "", "Display only this value (Config.API.Server.ListenURI)")
|
||||
flags := cmd.Flags()
|
||||
flags.StringVarP(&key, "key", "", "", "Display only this value (Config.API.Server.ListenURI)")
|
||||
|
||||
return cmdConfigShow
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -6,19 +6,21 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func runConfigShowYAML(cmd *cobra.Command, args []string) error {
|
||||
func (cli *cliConfig) showYAML() error {
|
||||
fmt.Println(mergedConfig)
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewConfigShowYAMLCmd() *cobra.Command {
|
||||
cmdConfigShow := &cobra.Command{
|
||||
func (cli *cliConfig) newShowYAMLCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "show-yaml",
|
||||
Short: "Displays merged config.yaml + config.yaml.local",
|
||||
Args: cobra.ExactArgs(0),
|
||||
DisableAutoGenTag: true,
|
||||
RunE: runConfigShowYAML,
|
||||
RunE: func(_ *cobra.Command, _ []string) error {
|
||||
return cli.showYAML()
|
||||
},
|
||||
}
|
||||
|
||||
return cmdConfigShow
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -231,7 +231,7 @@ It is meant to allow you to manage bans, parsers/scenarios/etc, api and generall
|
|||
|
||||
cmd.AddCommand(NewCLIDoc().NewCommand(cmd))
|
||||
cmd.AddCommand(NewCLIVersion().NewCommand())
|
||||
cmd.AddCommand(NewConfigCmd())
|
||||
cmd.AddCommand(NewCLIConfig(cli.cfg).NewCommand())
|
||||
cmd.AddCommand(NewCLIHub(cli.cfg).NewCommand())
|
||||
cmd.AddCommand(NewCLIMetrics(cli.cfg).NewCommand())
|
||||
cmd.AddCommand(NewCLIDashboard(cli.cfg).NewCommand())
|
||||
|
|
Loading…
Add table
Reference in a new issue