Skip to content
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
2 changes: 1 addition & 1 deletion pkg/env/alert_renotif_debounce.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ var (
// between an alert being resolved, and a new alert being generated for the same deployment-policy pair,
// such that notifications are sent for the new alert.
// If it is set to 0 (the default), notifications are always sent, and there is no debouncing.
AlertRenotifDebounceDuration = registerDurationSetting("ROX_ALERT_RENOTIF_DEBOUNCE_DURATION", 0)
AlertRenotifDebounceDuration = registerDurationSetting("ROX_ALERT_RENOTIF_DEBOUNCE_DURATION", 0, WithDurationZeroAllowed())
)
28 changes: 25 additions & 3 deletions pkg/env/durationsetting.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package env

import (
"fmt"
"os"
"time"

"github.com/stackrox/rox/pkg/logging"
"github.com/stackrox/rox/pkg/utils"
)

var (
Expand All @@ -15,6 +17,7 @@ var (
type DurationSetting struct {
envVar string
defaultDuration time.Duration
opts durationSettingOpts
}

// EnvVar returns the string name of the environment variable
Expand All @@ -32,20 +35,39 @@ func (d *DurationSetting) DurationSetting() time.Duration {
val := os.Getenv(d.envVar)
if val != "" {
dur, err := time.ParseDuration(val)
if err == nil {
if err == nil && validateDuration(dur, d.opts) == nil {
return dur
}
log.Warnf("%s is not a valid environment variable for %s, using default value: %s", val, d.envVar, d.defaultDuration.String())
log.Warnf("%s is not a valid environment variable for %s, using default value: %v", val, d.envVar, d.defaultDuration)
}
return d.defaultDuration
}

func registerDurationSetting(envVar string, defaultDuration time.Duration) *DurationSetting {
func registerDurationSetting(envVar string, defaultDuration time.Duration, options ...DurationSettingOption) *DurationSetting {
var opts durationSettingOpts
for _, o := range options {
o.apply(&opts)
}

utils.CrashOnError(validateDuration(defaultDuration, opts))

s := &DurationSetting{
envVar: envVar,
defaultDuration: defaultDuration,
opts: opts,
}

Settings[s.EnvVar()] = s
return s
}

func validateDuration(d time.Duration, opts durationSettingOpts) error {
if d < 0 {
return fmt.Errorf("invalid duration: %v < 0", d)
}
if !opts.zeroAllowed && d == 0 {
return fmt.Errorf("invalid duration: %v == 0", d)
}

return nil
}
24 changes: 24 additions & 0 deletions pkg/env/durationsetting_options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package env

type durationSettingOpts struct {
zeroAllowed bool
}

// DurationSettingOption represents an option which may be specified
// for a DurationSetting environment variable.
type DurationSettingOption interface {
apply(opts *durationSettingOpts)
}

type durationSettingOptsFunc func(opts *durationSettingOpts)

func (f durationSettingOptsFunc) apply(opts *durationSettingOpts) {
f(opts)
}

// WithDurationZeroAllowed specifies the DurationSetting may have a value of 0.
func WithDurationZeroAllowed() DurationSettingOption {
return durationSettingOptsFunc(func(opts *durationSettingOpts) {
opts.zeroAllowed = true
})
}