Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refact "cscli config" #2832

Merged
merged 7 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions cmd/crowdsec-cli/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
99 changes: 50 additions & 49 deletions cmd/crowdsec-cli/config_backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import (
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
Expand All @@ -13,8 +14,8 @@
"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
}
Expand All @@ -32,7 +33,7 @@

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)

Check warning on line 36 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L36

Added line #L36 was not covered by tests
}

upstreamParsers := []string{}
Expand All @@ -41,48 +42,48 @@
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

Check warning on line 52 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L52

Added line #L52 was not covered by tests
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)

Check warning on line 56 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L56

Added line #L56 was not covered by tests
}
}

clog.Debugf("[%s]: backing up file (tainted:%t local:%t up-to-date:%t)", k, v.State.Tainted, v.State.IsLocal(), v.State.UpToDate)

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)

Check warning on line 64 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L64

Added line #L64 was not covered by tests
}

clog.Infof("local/tainted saved %s to %s", v.State.LocalPath, tfile)

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)

Check warning on line 72 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L72

Added line #L72 was not covered by tests
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)

Check warning on line 81 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L81

Added line #L81 was not covered by tests
}

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)

Check warning on line 86 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L86

Added line #L86 was not covered by tests
}

clog.Infof("Wrote %d entries for %s to %s", len(upstreamParsers), itemType, upstreamParsersFname)
Expand All @@ -102,11 +103,13 @@
- 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")

Check warning on line 112 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L112

Added line #L112 was not covered by tests
}

log.Infof("Starting configuration backup")
Expand All @@ -121,10 +124,10 @@
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)
Expand All @@ -134,22 +137,22 @@
- 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)

Check warning on line 143 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L143

Added line #L143 was not covered by tests
}
}

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)

Check warning on line 149 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L149

Added line #L149 was not covered by tests
}

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 {

Check warning on line 153 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L153

Added line #L153 was not covered by tests
/*if it was the default one, it was already backup'ed*/
if csConfig.Crowdsec.AcquisitionFilePath == acquisFile {
if cfg.Crowdsec.AcquisitionFilePath == acquisFile {

Check warning on line 155 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L155

Added line #L155 was not covered by tests
continue
}

Expand All @@ -169,56 +172,48 @@
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)

Check warning on line 175 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L175

Added line #L175 was not covered by tests
}

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)

Check warning on line 184 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L183-L184

Added lines #L183 - L184 were not covered by tests
}

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)

Check warning on line 193 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L193

Added line #L193 was not covered by tests
}

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)

Check warning on line 202 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L202

Added line #L202 was not covered by tests
}

log.Infof("Saved profiles to %s", backupProfiles)
}

if err = backupHub(dirPath); err != nil {
return fmt.Errorf("failed to backup hub config: %s", 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)
if err = cli.backupHub(dirPath); err != nil {
return fmt.Errorf("failed to backup hub config: %w", err)

Check warning on line 209 in cmd/crowdsec-cli/config_backup.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_backup.go#L209

Added line #L209 was not covered by tests
}

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 :
Expand All @@ -232,8 +227,14 @@
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
}
25 changes: 11 additions & 14 deletions cmd/crowdsec-cli/config_feature_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,7 @@
"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 {

Check warning on line 14 in cmd/crowdsec-cli/config_feature_flags.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_feature_flags.go#L14

Added line #L14 was not covered by tests
green := color.New(color.FgGreen).SprintFunc()
red := color.New(color.FgRed).SprintFunc()
yellow := color.New(color.FgYellow).SprintFunc()
Expand Down Expand Up @@ -121,18 +114,22 @@
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)
},

Check warning on line 128 in cmd/crowdsec-cli/config_feature_flags.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/config_feature_flags.go#L127-L128

Added lines #L127 - L128 were not covered by tests
}

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
}
Loading
Loading