Skip to content

Commit 7493bc4

Browse files
committed
Increase default AWS max retry attempts and make it configurable
Signed-off-by: Matt Welke <matt.welke@spectrocloud.com>
1 parent 585e14b commit 7493bc4

File tree

9 files changed

+85
-13
lines changed

9 files changed

+85
-13
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ Authentication details for the AWS validator controller are provided within each
4040
> [!NOTE]
4141
> See [values.yaml](https://github.com/validator-labs/validator-plugin-aws/tree/main/chart/validator-plugin-aws/values.yaml) for additional configuration details for each authentication option.
4242
43+
# Configuring AWS SDK
44+
45+
* The max attempts setting for retries is set to 25. Use `auth.MaxAttempts` to increase this further or set any other desired value. Valid values are those gte 0.
46+
4347
### Minimal AWS managed IAM permission policies by validation type
4448
For validation to succeed, certain AWS managed permission policies must be attached to the principal used and/or assumed by the AWS validator controller. The minimal required IAM policies, broken out by validation category, are as follows:
4549
* IAM

api/v1alpha1/awsvalidator_types.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func (s AwsValidatorSpec) ResultCount() int {
6969
len(s.IamUserRules) + len(s.ServiceQuotaRules) + len(s.TagRules)
7070
}
7171

72-
// AwsAuth defines authentication configuration for an AwsValidator.
72+
// AwsAuth defines authentication and AWS SDK configuration for an AwsValidator.
7373
type AwsAuth struct {
7474
// If true, the AwsValidator will use the AWS SDK's default credential chain to authenticate.
7575
// Set to true if using node instance IAM role or IAM roles for Service Accounts.
@@ -82,6 +82,11 @@ type AwsAuth struct {
8282
Credentials *Credentials `json:"credentials,omitempty" yaml:"credentials,omitempty"`
8383
// STS authentication properties (optional)
8484
StsAuth *AwsSTSAuth `json:"stsAuth,omitempty" yaml:"stsAuth,omitempty"`
85+
// MaxAttempts is the number of times the AWS SDK should retry retryable operations. If
86+
// specified, overrides the setting the plugin uses by default for this AwsValidator. Set to 0
87+
// to disable retrying.
88+
// +kubebuilder:validation:Minimum=0
89+
MaxAttempts *int `json:"maxAttempts,omitempty" yaml:"maxAttempts,omitempty"`
8590
}
8691

8792
// Credentials is the credentials to use when running in direct mode.

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build

chart/validator-plugin-aws/crds/validation.spectrocloud.labs_awsvalidators.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ spec:
8787
- message: AmiRules must have unique names
8888
rule: self.all(e, size(self.filter(x, x.name == e.name)) == 1)
8989
auth:
90-
description: AwsAuth defines authentication configuration for an AwsValidator.
90+
description: AwsAuth defines authentication and AWS SDK configuration
91+
for an AwsValidator.
9192
properties:
9293
credentials:
9394
description: The credentials to use when running in direct mode.
@@ -107,6 +108,13 @@ spec:
107108
If true, the AwsValidator will use the AWS SDK's default credential chain to authenticate.
108109
Set to true if using node instance IAM role or IAM roles for Service Accounts.
109110
type: boolean
111+
maxAttempts:
112+
description: |-
113+
MaxAttempts is the number of times the AWS SDK should retry retryable operations. If
114+
specified, overrides the setting the plugin uses by default for this AwsValidator. Set to 0
115+
to disable retrying.
116+
minimum: 0
117+
type: integer
110118
secretName:
111119
description: |-
112120
Name of a Secret in the same namespace as the AwsValidator that contains AWS credentials.

config/crd/bases/validation.spectrocloud.labs_awsvalidators.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ spec:
8787
- message: AmiRules must have unique names
8888
rule: self.all(e, size(self.filter(x, x.name == e.name)) == 1)
8989
auth:
90-
description: AwsAuth defines authentication configuration for an AwsValidator.
90+
description: AwsAuth defines authentication and AWS SDK configuration
91+
for an AwsValidator.
9192
properties:
9293
credentials:
9394
description: The credentials to use when running in direct mode.
@@ -107,6 +108,13 @@ spec:
107108
If true, the AwsValidator will use the AWS SDK's default credential chain to authenticate.
108109
Set to true if using node instance IAM role or IAM roles for Service Accounts.
109110
type: boolean
111+
maxAttempts:
112+
description: |-
113+
MaxAttempts is the number of times the AWS SDK should retry retryable operations. If
114+
specified, overrides the setting the plugin uses by default for this AwsValidator. Set to 0
115+
to disable retrying.
116+
minimum: 0
117+
type: integer
110118
secretName:
111119
description: |-
112120
Name of a Secret in the same namespace as the AwsValidator that contains AWS credentials.

pkg/constants/constants.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,8 @@ const (
2828

2929
// IAMWildcard is the wildcard used in IAM policies.
3030
IAMWildcard string = "*"
31+
32+
// RetryMaxAttemptsDefault is the default we use for the max retries setting of the AWS SDK.
33+
// It's greater than the SDK's default.
34+
RetryMaxAttemptsDefault int = 25
3135
)

pkg/validate/validate.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@ import (
2222
"github.com/validator-labs/validator-plugin-aws/pkg/validators/tag"
2323
)
2424

25-
var errInvalidAccessKeyID = errors.New("access key ID is invalid, must be a non-empty string")
26-
var errInvalidSecretAccessKey = errors.New("secret access key is invalid, must be a non-empty string")
27-
2825
// Validate validates the AwsValidatorSpec and returns a ValidationResponse.
2926
func Validate(spec v1alpha1.AwsValidatorSpec, log logr.Logger) types.ValidationResponse {
3027
resp := types.ValidationResponse{
@@ -155,10 +152,14 @@ func validateAuth(auth v1alpha1.AwsAuth) error {
155152
var validationErrors []error
156153

157154
if auth.Credentials.AccessKeyID == "" {
158-
validationErrors = append(validationErrors, errInvalidAccessKeyID)
155+
validationErrors = append(validationErrors, errors.New("access key ID is invalid, must be a non-empty string"))
159156
}
160157
if auth.Credentials.SecretAccessKey == "" {
161-
validationErrors = append(validationErrors, errInvalidSecretAccessKey)
158+
validationErrors = append(validationErrors, errors.New("secret access key is invalid, must be a non-empty string"))
159+
}
160+
161+
if auth.MaxAttempts != nil && *auth.MaxAttempts < 0 {
162+
validationErrors = append(validationErrors, fmt.Errorf("invalid max retries setting (%d), must be gte 0", *auth.MaxAttempts))
162163
}
163164

164165
if len(validationErrors) > 0 {
@@ -179,13 +180,20 @@ func configureAuth(auth v1alpha1.AwsAuth, log logr.Logger) error {
179180
nonSecretData := map[string]string{
180181
"accessKeyId": auth.Credentials.AccessKeyID,
181182
}
182-
log.Info("Determined AWS auth data.", "nonSecretData", nonSecretData)
183+
if auth.MaxAttempts != nil {
184+
nonSecretData["maxAttempts"] = fmt.Sprintf("%d", *auth.MaxAttempts)
185+
}
186+
log.Info("Determined AWS auth and SDK config data.", "nonSecretData", nonSecretData)
183187

184188
// Use collected and validated values to set env vars.
185189
data := map[string]string{
186190
"AWS_ACCESS_KEY_ID": auth.Credentials.AccessKeyID,
187191
"AWS_SECRET_ACCESS_KEY": auth.Credentials.SecretAccessKey,
188192
}
193+
data["AWS_MAX_ATTEMPTS"] = fmt.Sprintf("%d", constants.RetryMaxAttemptsDefault)
194+
if auth.MaxAttempts != nil {
195+
data["AWS_MAX_ATTEMPTS"] = fmt.Sprintf("%d", *auth.MaxAttempts)
196+
}
189197
for k, v := range data {
190198
if err := os.Setenv(k, v); err != nil {
191199
return err

pkg/validate/validate_test.go

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/go-logr/logr"
99
"github.com/validator-labs/validator-plugin-aws/api/v1alpha1"
10+
"github.com/validator-labs/validator/pkg/util"
1011
//+kubebuilder:scaffold:imports
1112
)
1213

@@ -19,6 +20,13 @@ func Test_validateAuth(t *testing.T) {
1920
args args
2021
wantErr bool
2122
}{
23+
{
24+
name: "No panic for nil auth.Credentials",
25+
args: args{
26+
auth: v1alpha1.AwsAuth{},
27+
},
28+
wantErr: true,
29+
},
2230
{
2331
name: "No error for valid inline auth data",
2432
args: args{
@@ -27,16 +35,22 @@ func Test_validateAuth(t *testing.T) {
2735
AccessKeyID: "a",
2836
SecretAccessKey: "b",
2937
},
38+
MaxAttempts: util.Ptr(0),
3039
},
3140
},
3241
wantErr: false,
3342
},
3443
{
35-
name: "No panic for nil auth.Credentials",
44+
name: "No error for omitted max attempts",
3645
args: args{
37-
auth: v1alpha1.AwsAuth{},
46+
auth: v1alpha1.AwsAuth{
47+
Credentials: &v1alpha1.Credentials{
48+
AccessKeyID: "a",
49+
SecretAccessKey: "b",
50+
},
51+
},
3852
},
39-
wantErr: true,
53+
wantErr: false,
4054
},
4155
{
4256
name: "Error for invalid access key ID",
@@ -46,6 +60,7 @@ func Test_validateAuth(t *testing.T) {
4660
AccessKeyID: "",
4761
SecretAccessKey: "b",
4862
},
63+
MaxAttempts: util.Ptr(0),
4964
},
5065
},
5166
wantErr: true,
@@ -62,6 +77,19 @@ func Test_validateAuth(t *testing.T) {
6277
},
6378
wantErr: true,
6479
},
80+
{
81+
name: "Error for invalid max attempts",
82+
args: args{
83+
auth: v1alpha1.AwsAuth{
84+
Credentials: &v1alpha1.Credentials{
85+
AccessKeyID: "a",
86+
SecretAccessKey: "b",
87+
},
88+
MaxAttempts: util.Ptr(-1),
89+
},
90+
},
91+
wantErr: true,
92+
},
6593
}
6694
for _, tt := range tests {
6795
t.Run(tt.name, func(t *testing.T) {
@@ -91,12 +119,14 @@ func Test_configureAuth(t *testing.T) {
91119
AccessKeyID: "a",
92120
SecretAccessKey: "b",
93121
},
122+
MaxAttempts: util.Ptr(0),
94123
},
95124
},
96125
wantErr: false,
97126
wantEnvVars: map[string]string{
98127
"AWS_ACCESS_KEY_ID": "a",
99128
"AWS_SECRET_ACCESS_KEY": "b",
129+
"AWS_MAX_ATTEMPTS": "0",
100130
},
101131
},
102132
{

0 commit comments

Comments
 (0)