Skip to content

Commit

Permalink
⭐️ allow customisation of scan interval (#1044)
Browse files Browse the repository at this point in the history
* ⭐️ allow customisation of scan interval

* 🧹 ignore viper errors
  • Loading branch information
chris-rock authored Jan 15, 2024
1 parent f345d22 commit 7fba869
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 24 deletions.
18 changes: 11 additions & 7 deletions apps/cnspec/cmd/backgroundjob/background.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ package backgroundjob

import (
"time"

"github.com/spf13/viper"
)

const (
Expand All @@ -16,16 +14,22 @@ const (

type JobRunner func() error

func New() (*BackgroundScanner, error) {
return &BackgroundScanner{}, nil
func New(timer, splay time.Duration) (*BackgroundScanner, error) {
return &BackgroundScanner{
timer: timer,
splay: splay,
}, nil
}

type BackgroundScanner struct{}
type BackgroundScanner struct {
timer time.Duration
splay time.Duration
}

func (bs *BackgroundScanner) Run(runScanFn JobRunner) error {
Serve(
time.Duration(viper.GetInt64("timer"))*time.Minute,
time.Duration(viper.GetInt64("splay"))*time.Minute,
bs.timer,
bs.splay,
runScanFn)
return nil
}
13 changes: 13 additions & 0 deletions apps/cnspec/cmd/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import (
"go.mondoo.com/cnquery/v10/cli/config"
)

const (
DefaultScanIntervalTimer = 60
DefaultScanIntervalSplay = 60
)

func ReadConfig() (*CliConfig, error) {
// load viper config into a struct
var opts CliConfig
Expand All @@ -27,4 +32,12 @@ type CliConfig struct {
// Asset Category
Category string `json:"category,omitempty" mapstructure:"category"`
AutoDetectCICDCategory bool `json:"detect-cicd,omitempty" mapstructure:"detect-cicd"`

// Configure scan interval
ScanInterval *ScanInterval `json:"scan_interval,omitempty" mapstructure:"scan_interval"`
}

type ScanInterval struct {
Timer int `json:"timer,omitempty" mapstructure:"timer"`
Splay int `json:"splay,omitempty" mapstructure:"splay"`
}
8 changes: 8 additions & 0 deletions apps/cnspec/cmd/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ private_key: |
MIG2AgE....C0Dvs=
-----END PRIVATE KEY-----
space_mrn: //captain.api.mondoo.app/spaces/musing-saha-952142
scan_interval:
timer: 10
splay: 20
`

viper.SetConfigType("yaml")
Expand All @@ -40,4 +44,8 @@ space_mrn: //captain.api.mondoo.app/spaces/musing-saha-952142
assert.Equal(t, "//agents.api.mondoo.app/spaces/musing-saha-952142/serviceaccounts/1zDY7cJ7bA84JxxNBWDxBdui2xE", cfg.ServiceAccountMrn)
assert.Equal(t, "-----BEGIN PRIVATE KEY-----\nMIG2AgE....C0Dvs=\n-----END PRIVATE KEY-----\n", cfg.PrivateKey)
assert.Equal(t, "-----BEGIN CERTIFICATE-----\nMIICV .. fis=\n-----END CERTIFICATE-----\n", cfg.Certificate)

assert.Equal(t, 10, cfg.ScanInterval.Timer)
assert.Equal(t, 20, cfg.ScanInterval.Splay)

}
43 changes: 26 additions & 17 deletions apps/cnspec/cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@ const ConfigurationErrorCode = 78
func init() {
rootCmd.AddCommand(serveCmd)
// background scan flags
serveCmd.Flags().Int("timer", 60, "scan interval in minutes")
serveCmd.Flags().Int("splay", 60, "randomize the timer by up to this many minutes")
serveCmd.Flags().MarkHidden("timer")
serveCmd.Flags().MarkHidden("splay")
serveCmd.Flags().Int("timer", cnspec_config.DefaultScanIntervalTimer, "scan interval in minutes")
serveCmd.Flags().Int("splay", cnspec_config.DefaultScanIntervalSplay, "randomize the timer by up to this many minutes")
// set inventory
serveCmd.Flags().String("inventory-file", "", "Set the path to the inventory file")
}
Expand All @@ -46,9 +44,9 @@ var serveCmd = &cobra.Command{
Short: "Start cnspec in background mode.",

PreRun: func(cmd *cobra.Command, args []string) {
viper.BindPFlag("timer", cmd.Flags().Lookup("timer"))
viper.BindPFlag("splay", cmd.Flags().Lookup("splay"))
viper.BindPFlag("inventory-file", cmd.Flags().Lookup("inventory-file"))
_ = viper.BindPFlag("scan_interval.timer", cmd.Flags().Lookup("timer"))
_ = viper.BindPFlag("scan_interval.splay", cmd.Flags().Lookup("splay"))
_ = viper.BindPFlag("inventory-file", cmd.Flags().Lookup("inventory-file"))
},
RunE: func(cmd *cobra.Command, args []string) error {
prof.InitProfiler()
Expand All @@ -66,21 +64,21 @@ var serveCmd = &cobra.Command{
}

// determine the scan config from pipe or args
conf, err := getServeConfig()
scanConf, cliConfig, err := getServeConfig()
if err != nil {
// we return the specific error code to prevent systemd from restarting
return cli_errors.NewCommandError(errors.Wrap(err, "could not load configuration"), ConfigurationErrorCode)
}

ctx := cnquery.SetFeatures(context.Background(), cnquery.DefaultFeatures)

if conf != nil && conf.runtime.UpstreamConfig != nil {
client, err := conf.runtime.UpstreamConfig.InitClient()
if scanConf != nil && scanConf.runtime.UpstreamConfig != nil {
client, err := scanConf.runtime.UpstreamConfig.InitClient()
if err != nil {
return cli_errors.NewCommandError(errors.Wrap(err, "could not initialize upstream client"), 1)
}

checkin, err := backgroundjob.NewCheckinPinger(ctx, client.HttpClient, client.ApiEndpoint, conf.AgentMrn, conf.runtime.UpstreamConfig, 2*time.Hour)
checkin, err := backgroundjob.NewCheckinPinger(ctx, client.HttpClient, client.ApiEndpoint, scanConf.AgentMrn, scanConf.runtime.UpstreamConfig, 2*time.Hour)
if err != nil {
log.Error().Err(err).Msg("could not initialize upstream check-in")
} else {
Expand All @@ -89,7 +87,10 @@ var serveCmd = &cobra.Command{
}
}

bj, err := backgroundjob.New()
bj, err := backgroundjob.New(
time.Duration(cliConfig.ScanInterval.Timer)*time.Minute,
time.Duration(cliConfig.ScanInterval.Splay)*time.Minute,
)
if err != nil {
return cli_errors.NewCommandError(errors.Wrap(err, "could not start background listener"), 1)
}
Expand All @@ -101,7 +102,7 @@ var serveCmd = &cobra.Command{
log.Error().Err(err).Msg("could not update providers")
}
// TODO: check in every 5 min via timer, init time in Background job
result, err := RunScan(conf, scan.DisableProgressBar())
result, err := RunScan(scanConf, scan.DisableProgressBar())
if err != nil {
return cli_errors.NewCommandError(errors.Wrap(err, "could not successfully complete scan"), 1)
}
Expand All @@ -119,10 +120,10 @@ var serveCmd = &cobra.Command{
},
}

func getServeConfig() (*scanConfig, error) {
func getServeConfig() (*scanConfig, *cnspec_config.CliConfig, error) {
opts, optsErr := cnspec_config.ReadConfig()
if optsErr != nil {
return nil, errors.Wrap(optsErr, "could not load configuration")
return nil, nil, errors.Wrap(optsErr, "could not load configuration")
}
config.DisplayUsedConfig()

Expand Down Expand Up @@ -180,7 +181,7 @@ func getServeConfig() (*scanConfig, error) {
var err error
conf.Inventory, err = inventoryloader.ParseOrUse(nil, viper.GetBool("insecure"), optAnnotations)
if err != nil {
return nil, errors.Wrap(err, "could not load configuration")
return nil, nil, errors.Wrap(err, "could not load configuration")
}

// fall back to local machine if no inventory was localed
Expand All @@ -193,7 +194,15 @@ func getServeConfig() (*scanConfig, error) {
}))
}

return &conf, nil
// set the default scan interval if not set
if opts.ScanInterval == nil {
opts.ScanInterval = &cnspec_config.ScanInterval{
Timer: cnspec_config.DefaultScanIntervalSplay,
Splay: cnspec_config.DefaultScanIntervalSplay,
}
}

return &conf, opts, nil
}

func logClientInfo(spaceMrn string, clientMrn string, serviceAccountMrn string) {
Expand Down

0 comments on commit 7fba869

Please sign in to comment.