Skip to content

Commit d40561a

Browse files
authored
Merge pull request #2660 from arewm/ec-1404
fix(ec-1404): add jitter for intermittent errors
2 parents 65f5226 + b4fa836 commit d40561a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1218
-75
lines changed

cmd/root/root_cmd.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/spf13/cobra"
3232
"github.com/spf13/pflag"
3333

34+
"github.com/conforma/cli/internal/http"
3435
"github.com/conforma/cli/internal/kubernetes"
3536
"github.com/conforma/cli/internal/logging"
3637
"github.com/conforma/cli/internal/tracing"
@@ -44,7 +45,15 @@ var (
4445
enabledTraces tracing.Trace = tracing.None
4546
globalTimeout = 5 * time.Minute
4647
logfile string
47-
OnExit func() = func() {}
48+
49+
// Retry configuration flags
50+
retryMaxWait time.Duration = 3 * time.Second
51+
retryMaxRetry int = 3
52+
retryDuration time.Duration = 1 * time.Second
53+
retryFactor float64 = 2.0
54+
retryJitter float64 = 0.1
55+
56+
OnExit func() = func() {}
4857
)
4958

5059
type customDeadlineExceededError struct{}
@@ -91,6 +100,16 @@ func NewRootCmd() *cobra.Command {
91100
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
92101
logging.InitLogging(verbose, quiet, debug, enabledTraces.Enabled(tracing.Log, tracing.Opa), logfile)
93102

103+
// Apply retry configuration from CLI flags
104+
retryConfig := http.RetryConfig{
105+
MaxWait: retryMaxWait,
106+
MaxRetry: retryMaxRetry,
107+
Duration: retryDuration,
108+
Factor: retryFactor,
109+
Jitter: retryJitter,
110+
}
111+
http.SetRetryConfig(retryConfig)
112+
94113
// set a custom message for context.DeadlineExceeded error
95114
context.DeadlineExceeded = customDeadlineExceededError{}
96115

@@ -192,5 +211,13 @@ func setFlags(rootCmd *cobra.Command) {
192211
rootCmd.PersistentFlags().BoolVar(&debug, "debug", debug, "same as verbose but also show function names and line numbers")
193212
rootCmd.PersistentFlags().DurationVar(&globalTimeout, "timeout", globalTimeout, "max overall execution duration")
194213
rootCmd.PersistentFlags().StringVar(&logfile, "logfile", "", "file to write the logging output. If not specified logging output will be written to stderr")
214+
215+
// Retry configuration flags
216+
rootCmd.PersistentFlags().DurationVar(&retryMaxWait, "retry-max-wait", retryMaxWait, "maximum wait time between retries")
217+
rootCmd.PersistentFlags().IntVar(&retryMaxRetry, "retry-max-retry", retryMaxRetry, "maximum number of retry attempts")
218+
rootCmd.PersistentFlags().DurationVar(&retryDuration, "retry-duration", retryDuration, "base duration for exponential backoff calculation")
219+
rootCmd.PersistentFlags().Float64Var(&retryFactor, "retry-factor", retryFactor, "exponential backoff multiplier")
220+
rootCmd.PersistentFlags().Float64Var(&retryJitter, "retry-jitter", retryJitter, "randomness factor for backoff calculation (0.0-1.0)")
221+
195222
kubernetes.AddKubeconfigFlag(rootCmd)
196223
}

cmd/root/root_cmd_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import (
2121
"time"
2222

2323
"github.com/stretchr/testify/assert"
24+
25+
"github.com/conforma/cli/internal/http"
2426
)
2527

2628
func TestGlobalTimeout(t *testing.T) {
@@ -76,3 +78,74 @@ func TestGlobalTimeout(t *testing.T) {
7678
})
7779
}
7880
}
81+
82+
func TestRetryConfigurationFlags(t *testing.T) {
83+
tests := []struct {
84+
name string
85+
args []string
86+
expectedConfig http.RetryConfig
87+
}{
88+
{
89+
name: "default retry configuration",
90+
args: []string{},
91+
expectedConfig: http.RetryConfig{
92+
MaxWait: 3 * time.Second,
93+
MaxRetry: 3,
94+
Duration: 1 * time.Second,
95+
Factor: 2.0,
96+
Jitter: 0.1,
97+
},
98+
},
99+
{
100+
name: "custom retry configuration",
101+
args: []string{
102+
"--retry-max-wait", "2s",
103+
"--retry-max-retry", "5",
104+
"--retry-duration", "500ms",
105+
"--retry-factor", "1.5",
106+
"--retry-jitter", "0.2",
107+
},
108+
expectedConfig: http.RetryConfig{
109+
MaxWait: 2 * time.Second,
110+
MaxRetry: 5,
111+
Duration: 500 * time.Millisecond,
112+
Factor: 1.5,
113+
Jitter: 0.2,
114+
},
115+
},
116+
}
117+
118+
for _, tt := range tests {
119+
t.Run(tt.name, func(t *testing.T) {
120+
// Reset to default values
121+
retryMaxWait = 3 * time.Second
122+
retryMaxRetry = 3
123+
retryDuration = 1 * time.Second
124+
retryFactor = 2.0
125+
retryJitter = 0.1
126+
127+
cmd := NewRootCmd()
128+
if len(tt.args) > 0 {
129+
cmd.SetArgs(append(tt.args, "version"))
130+
} else {
131+
cmd.SetArgs([]string{"version"})
132+
}
133+
134+
// Execute the command to trigger flag parsing and configuration
135+
err := cmd.Execute()
136+
assert.NoError(t, err)
137+
138+
// Verify the configuration was applied by checking the actual values
139+
// The configuration is applied in PersistentPreRun, so we need to check
140+
// that the flags were parsed correctly
141+
if len(tt.args) > 0 {
142+
// For custom configuration, verify that the flags were parsed
143+
assert.Equal(t, tt.expectedConfig.MaxWait, retryMaxWait)
144+
assert.Equal(t, tt.expectedConfig.MaxRetry, retryMaxRetry)
145+
assert.Equal(t, tt.expectedConfig.Duration, retryDuration)
146+
assert.Equal(t, tt.expectedConfig.Factor, retryFactor)
147+
assert.Equal(t, tt.expectedConfig.Jitter, retryJitter)
148+
}
149+
})
150+
}
151+
}

docs/modules/ROOT/pages/ec.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ ec [flags]
3939
--kubeconfig:: path to the Kubernetes config file to use
4040
--logfile:: file to write the logging output. If not specified logging output will be written to stderr
4141
--quiet:: less verbose output (Default: false)
42+
--retry-duration:: base duration for exponential backoff calculation (Default: 1s)
43+
--retry-factor:: exponential backoff multiplier (Default: 2)
44+
--retry-jitter:: randomness factor for backoff calculation (0.0-1.0) (Default: 0.1)
45+
--retry-max-retry:: maximum number of retry attempts (Default: 3)
46+
--retry-max-wait:: maximum wait time between retries (Default: 3s)
4247
--timeout:: max overall execution duration (Default: 5m0s)
4348
--trace:: enable trace logging, set one or more comma separated values: none,all,perf,cpu,mem,opa,log (Default: none)
4449
--verbose:: more verbose output (Default: false)

docs/modules/ROOT/pages/ec_fetch.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ Fetch remote resources
1212
--kubeconfig:: path to the Kubernetes config file to use
1313
--logfile:: file to write the logging output. If not specified logging output will be written to stderr
1414
--quiet:: less verbose output (Default: false)
15+
--retry-duration:: base duration for exponential backoff calculation (Default: 1s)
16+
--retry-factor:: exponential backoff multiplier (Default: 2)
17+
--retry-jitter:: randomness factor for backoff calculation (0.0-1.0) (Default: 0.1)
18+
--retry-max-retry:: maximum number of retry attempts (Default: 3)
19+
--retry-max-wait:: maximum wait time between retries (Default: 3s)
1520
--timeout:: max overall execution duration (Default: 5m0s)
1621
--trace:: enable trace logging, set one or more comma separated values: none,all,perf,cpu,mem,opa,log (Default: none)
1722
--verbose:: more verbose output (Default: false)

docs/modules/ROOT/pages/ec_fetch_policy.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ Notes:
7474
--kubeconfig:: path to the Kubernetes config file to use
7575
--logfile:: file to write the logging output. If not specified logging output will be written to stderr
7676
--quiet:: less verbose output (Default: false)
77+
--retry-duration:: base duration for exponential backoff calculation (Default: 1s)
78+
--retry-factor:: exponential backoff multiplier (Default: 2)
79+
--retry-jitter:: randomness factor for backoff calculation (0.0-1.0) (Default: 0.1)
80+
--retry-max-retry:: maximum number of retry attempts (Default: 3)
81+
--retry-max-wait:: maximum wait time between retries (Default: 3s)
7782
--timeout:: max overall execution duration (Default: 5m0s)
7883
--trace:: enable trace logging, set one or more comma separated values: none,all,perf,cpu,mem,opa,log (Default: none)
7984
--verbose:: more verbose output (Default: false)

docs/modules/ROOT/pages/ec_init.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ Initialize a directory for use
1212
--kubeconfig:: path to the Kubernetes config file to use
1313
--logfile:: file to write the logging output. If not specified logging output will be written to stderr
1414
--quiet:: less verbose output (Default: false)
15+
--retry-duration:: base duration for exponential backoff calculation (Default: 1s)
16+
--retry-factor:: exponential backoff multiplier (Default: 2)
17+
--retry-jitter:: randomness factor for backoff calculation (0.0-1.0) (Default: 0.1)
18+
--retry-max-retry:: maximum number of retry attempts (Default: 3)
19+
--retry-max-wait:: maximum wait time between retries (Default: 3s)
1520
--timeout:: max overall execution duration (Default: 5m0s)
1621
--trace:: enable trace logging, set one or more comma separated values: none,all,perf,cpu,mem,opa,log (Default: none)
1722
--verbose:: more verbose output (Default: false)

docs/modules/ROOT/pages/ec_init_policies.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ Initialize the "my-policy" directory with minimal EC policy scaffolding:
3131
--kubeconfig:: path to the Kubernetes config file to use
3232
--logfile:: file to write the logging output. If not specified logging output will be written to stderr
3333
--quiet:: less verbose output (Default: false)
34+
--retry-duration:: base duration for exponential backoff calculation (Default: 1s)
35+
--retry-factor:: exponential backoff multiplier (Default: 2)
36+
--retry-jitter:: randomness factor for backoff calculation (0.0-1.0) (Default: 0.1)
37+
--retry-max-retry:: maximum number of retry attempts (Default: 3)
38+
--retry-max-wait:: maximum wait time between retries (Default: 3s)
3439
--timeout:: max overall execution duration (Default: 5m0s)
3540
--trace:: enable trace logging, set one or more comma separated values: none,all,perf,cpu,mem,opa,log (Default: none)
3641
--verbose:: more verbose output (Default: false)

docs/modules/ROOT/pages/ec_inspect.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ Inspect policy rules
1212
--kubeconfig:: path to the Kubernetes config file to use
1313
--logfile:: file to write the logging output. If not specified logging output will be written to stderr
1414
--quiet:: less verbose output (Default: false)
15+
--retry-duration:: base duration for exponential backoff calculation (Default: 1s)
16+
--retry-factor:: exponential backoff multiplier (Default: 2)
17+
--retry-jitter:: randomness factor for backoff calculation (0.0-1.0) (Default: 0.1)
18+
--retry-max-retry:: maximum number of retry attempts (Default: 3)
19+
--retry-max-wait:: maximum wait time between retries (Default: 3s)
1520
--timeout:: max overall execution duration (Default: 5m0s)
1621
--trace:: enable trace logging, set one or more comma separated values: none,all,perf,cpu,mem,opa,log (Default: none)
1722
--verbose:: more verbose output (Default: false)

docs/modules/ROOT/pages/ec_inspect_policy-data.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ ec inspect policy-data --source git::https://github.com/conforma/policy//example
3636
--kubeconfig:: path to the Kubernetes config file to use
3737
--logfile:: file to write the logging output. If not specified logging output will be written to stderr
3838
--quiet:: less verbose output (Default: false)
39+
--retry-duration:: base duration for exponential backoff calculation (Default: 1s)
40+
--retry-factor:: exponential backoff multiplier (Default: 2)
41+
--retry-jitter:: randomness factor for backoff calculation (0.0-1.0) (Default: 0.1)
42+
--retry-max-retry:: maximum number of retry attempts (Default: 3)
43+
--retry-max-wait:: maximum wait time between retries (Default: 3s)
3944
--timeout:: max overall execution duration (Default: 5m0s)
4045
--trace:: enable trace logging, set one or more comma separated values: none,all,perf,cpu,mem,opa,log (Default: none)
4146
--verbose:: more verbose output (Default: false)

docs/modules/ROOT/pages/ec_inspect_policy.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ Display details about the latest release policy in json format:
4848
--kubeconfig:: path to the Kubernetes config file to use
4949
--logfile:: file to write the logging output. If not specified logging output will be written to stderr
5050
--quiet:: less verbose output (Default: false)
51+
--retry-duration:: base duration for exponential backoff calculation (Default: 1s)
52+
--retry-factor:: exponential backoff multiplier (Default: 2)
53+
--retry-jitter:: randomness factor for backoff calculation (0.0-1.0) (Default: 0.1)
54+
--retry-max-retry:: maximum number of retry attempts (Default: 3)
55+
--retry-max-wait:: maximum wait time between retries (Default: 3s)
5156
--timeout:: max overall execution duration (Default: 5m0s)
5257
--trace:: enable trace logging, set one or more comma separated values: none,all,perf,cpu,mem,opa,log (Default: none)
5358
--verbose:: more verbose output (Default: false)

0 commit comments

Comments
 (0)