Skip to content

Commit

Permalink
cscli: refactor "cscli setup" to avoid global variable (#3075)
Browse files Browse the repository at this point in the history
* cscli refactor: extract method cliSetup.detect()
* cscli refactor: extract method cliSetup.install()
* cscli refactor: extract method cliSetup.dataSources()
* cscli refactor: method ccliSetup.validate()
* skip redundant pre-loop checks
  • Loading branch information
mmetc authored Jun 12, 2024
1 parent bd4540b commit fd433a7
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 170 deletions.
194 changes: 79 additions & 115 deletions cmd/crowdsec-cli/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"bytes"
"context"
"errors"
"fmt"
"os"
Expand Down Expand Up @@ -44,57 +45,85 @@ func (cli *cliSetup) NewCommand() *cobra.Command {
return cmd
}

type detectFlags struct {
detectConfigFile string
listSupportedServices bool
forcedUnits []string
forcedProcesses []string
forcedOSFamily string
forcedOSID string
forcedOSVersion string
skipServices []string
snubSystemd bool
outYaml bool
}

func (f *detectFlags) bind(cmd *cobra.Command) {
defaultServiceDetect := csconfig.DefaultConfigPath("hub", "detect.yaml")

flags := cmd.Flags()
flags.StringVar(&f.detectConfigFile, "detect-config", defaultServiceDetect, "path to service detection configuration")
flags.BoolVar(&f.listSupportedServices, "list-supported-services", false, "do not detect; only print supported services")
flags.StringSliceVar(&f.forcedUnits, "force-unit", nil, "force detection of a systemd unit (can be repeated)")
flags.StringSliceVar(&f.forcedProcesses, "force-process", nil, "force detection of a running process (can be repeated)")
flags.StringSliceVar(&f.skipServices, "skip-service", nil, "ignore a service, don't recommend hub/datasources (can be repeated)")
flags.StringVar(&f.forcedOSFamily, "force-os-family", "", "override OS.Family: one of linux, freebsd, windows or darwin")
flags.StringVar(&f.forcedOSID, "force-os-id", "", "override OS.ID=[debian | ubuntu | , redhat...]")
flags.StringVar(&f.forcedOSVersion, "force-os-version", "", "override OS.RawVersion (of OS or Linux distribution)")
flags.BoolVar(&f.snubSystemd, "snub-systemd", false, "don't use systemd, even if available")
flags.BoolVar(&f.outYaml, "yaml", false, "output yaml, not json")
}

func (cli *cliSetup) NewDetectCmd() *cobra.Command {
f := detectFlags{}

cmd := &cobra.Command{
Use: "detect",
Short: "detect running services, generate a setup file",
DisableAutoGenTag: true,
RunE: runSetupDetect,
RunE: func(_ *cobra.Command, args []string) error {
return cli.detect(f)
},
}

defaultServiceDetect := csconfig.DefaultConfigPath("hub", "detect.yaml")

flags := cmd.Flags()
flags.String("detect-config", defaultServiceDetect, "path to service detection configuration")
flags.Bool("list-supported-services", false, "do not detect; only print supported services")
flags.StringSlice("force-unit", nil, "force detection of a systemd unit (can be repeated)")
flags.StringSlice("force-process", nil, "force detection of a running process (can be repeated)")
flags.StringSlice("skip-service", nil, "ignore a service, don't recommend hub/datasources (can be repeated)")
flags.String("force-os-family", "", "override OS.Family: one of linux, freebsd, windows or darwin")
flags.String("force-os-id", "", "override OS.ID=[debian | ubuntu | , redhat...]")
flags.String("force-os-version", "", "override OS.RawVersion (of OS or Linux distribution)")
flags.Bool("snub-systemd", false, "don't use systemd, even if available")
flags.Bool("yaml", false, "output yaml, not json")

f.bind(cmd)
return cmd
}

func (cli *cliSetup) NewInstallHubCmd() *cobra.Command {
var dryRun bool

cmd := &cobra.Command{
Use: "install-hub [setup_file] [flags]",
Short: "install items from a setup file",
Args: cobra.ExactArgs(1),
DisableAutoGenTag: true,
RunE: runSetupInstallHub,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.install(cmd.Context(), dryRun, args[0])
},
}

flags := cmd.Flags()
flags.Bool("dry-run", false, "don't install anything; print out what would have been")
flags.BoolVar(&dryRun, "dry-run", false, "don't install anything; print out what would have been")

return cmd
}

func (cli *cliSetup) NewDataSourcesCmd() *cobra.Command {
var toDir string

cmd := &cobra.Command{
Use: "datasources [setup_file] [flags]",
Short: "generate datasource (acquisition) configuration from a setup file",
Args: cobra.ExactArgs(1),
DisableAutoGenTag: true,
RunE: runSetupDataSources,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.dataSources(args[0], toDir)
},
}

flags := cmd.Flags()
flags.String("to-dir", "", "write the configuration to a directory, in multiple files")
flags.StringVar(&toDir, "to-dir", "", "write the configuration to a directory, in multiple files")

return cmd
}
Expand All @@ -105,97 +134,50 @@ func (cli *cliSetup) NewValidateCmd() *cobra.Command {
Short: "validate a setup file",
Args: cobra.ExactArgs(1),
DisableAutoGenTag: true,
RunE: runSetupValidate,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.validate(args[0])
},
}

return cmd
}

func runSetupDetect(cmd *cobra.Command, args []string) error {
flags := cmd.Flags()

detectConfigFile, err := flags.GetString("detect-config")
if err != nil {
return err
}

var detectReader *os.File
func (cli *cliSetup) detect(f detectFlags) error {
var (
detectReader *os.File
err error
)

switch detectConfigFile {
switch f.detectConfigFile {
case "-":
log.Tracef("Reading detection rules from stdin")

detectReader = os.Stdin
default:
log.Tracef("Reading detection rules: %s", detectConfigFile)
log.Tracef("Reading detection rules: %s", f.detectConfigFile)

detectReader, err = os.Open(detectConfigFile)
detectReader, err = os.Open(f.detectConfigFile)
if err != nil {
return err
}
}

listSupportedServices, err := flags.GetBool("list-supported-services")
if err != nil {
return err
}

forcedUnits, err := flags.GetStringSlice("force-unit")
if err != nil {
return err
}

forcedProcesses, err := flags.GetStringSlice("force-process")
if err != nil {
return err
}

forcedOSFamily, err := flags.GetString("force-os-family")
if err != nil {
return err
}

forcedOSID, err := flags.GetString("force-os-id")
if err != nil {
return err
}

forcedOSVersion, err := flags.GetString("force-os-version")
if err != nil {
return err
}

skipServices, err := flags.GetStringSlice("skip-service")
if err != nil {
return err
}

snubSystemd, err := flags.GetBool("snub-systemd")
if err != nil {
return err
}

if !snubSystemd {
if !f.snubSystemd {
_, err := exec.LookPath("systemctl")
if err != nil {
log.Debug("systemctl not available: snubbing systemd")

snubSystemd = true
f.snubSystemd = true
}
}

outYaml, err := flags.GetBool("yaml")
if err != nil {
return err
}

if forcedOSFamily == "" && forcedOSID != "" {
if f.forcedOSFamily == "" && f.forcedOSID != "" {
log.Debug("force-os-id is set: force-os-family defaults to 'linux'")

forcedOSFamily = "linux"
f.forcedOSFamily = "linux"
}

if listSupportedServices {
if f.listSupportedServices {
supported, err := setup.ListSupported(detectReader)
if err != nil {
return err
Expand All @@ -209,23 +191,23 @@ func runSetupDetect(cmd *cobra.Command, args []string) error {
}

opts := setup.DetectOptions{
ForcedUnits: forcedUnits,
ForcedProcesses: forcedProcesses,
ForcedUnits: f.forcedUnits,
ForcedProcesses: f.forcedProcesses,
ForcedOS: setup.ExprOS{
Family: forcedOSFamily,
ID: forcedOSID,
RawVersion: forcedOSVersion,
Family: f.forcedOSFamily,
ID: f.forcedOSID,
RawVersion: f.forcedOSVersion,
},
SkipServices: skipServices,
SnubSystemd: snubSystemd,
SkipServices: f.skipServices,
SnubSystemd: f.snubSystemd,
}

hubSetup, err := setup.Detect(detectReader, opts)
if err != nil {
return fmt.Errorf("detecting services: %w", err)
}

setup, err := setupAsString(hubSetup, outYaml)
setup, err := setupAsString(hubSetup, f.outYaml)
if err != nil {
return err
}
Expand Down Expand Up @@ -273,16 +255,7 @@ func setupAsString(cs setup.Setup, outYaml bool) (string, error) {
return string(ret), nil
}

func runSetupDataSources(cmd *cobra.Command, args []string) error {
flags := cmd.Flags()

fromFile := args[0]

toDir, err := flags.GetString("to-dir")
if err != nil {
return err
}

func (cli *cliSetup) dataSources(fromFile string, toDir string) error {
input, err := os.ReadFile(fromFile)
if err != nil {
return fmt.Errorf("while reading setup file: %w", err)
Expand All @@ -300,32 +273,23 @@ func runSetupDataSources(cmd *cobra.Command, args []string) error {
return nil
}

func runSetupInstallHub(cmd *cobra.Command, args []string) error {
flags := cmd.Flags()

fromFile := args[0]

dryRun, err := flags.GetBool("dry-run")
if err != nil {
return err
}

func (cli *cliSetup) install(ctx context.Context, dryRun bool, fromFile string) error {
input, err := os.ReadFile(fromFile)
if err != nil {
return fmt.Errorf("while reading file %s: %w", fromFile, err)
}

hub, err := require.Hub(csConfig, require.RemoteHub(cmd.Context(), csConfig), log.StandardLogger())
cfg := cli.cfg()

hub, err := require.Hub(cfg, require.RemoteHub(ctx, cfg), log.StandardLogger())
if err != nil {
return err
}

return setup.InstallHubItems(cmd.Context(), hub, input, dryRun)
return setup.InstallHubItems(ctx, hub, input, dryRun)
}

func runSetupValidate(cmd *cobra.Command, args []string) error {
fromFile := args[0]

func (cli *cliSetup) validate(fromFile string) error {
input, err := os.ReadFile(fromFile)
if err != nil {
return fmt.Errorf("while reading stdin: %w", err)
Expand Down
Loading

0 comments on commit fd433a7

Please sign in to comment.