@@ -39,24 +39,26 @@ import (
39
39
)
40
40
41
41
const (
42
- flagEnableLeaderElection = "enable-leader-election"
43
- flagLeaderElectionNamespace = "leader-election-namespace"
44
- flagMetricAddr = "metrics-addr"
45
- flagHealthzAddr = "healthz-addr"
46
- flagEnableDevLogging = "enable-development-logging"
47
- flagAWSRegion = "aws-region"
48
- flagAWSEndpointURL = "aws-endpoint-url"
49
- flagAWSIdentityEndpointURL = "aws-identity-endpoint-url"
50
- flagUnsafeAWSEndpointURLs = "allow-unsafe-aws-endpoint-urls"
51
- flagLogLevel = "log-level"
52
- flagResourceTags = "resource-tags"
53
- flagWatchNamespace = "watch-namespace"
54
- flagEnableWebhookServer = "enable-webhook-server"
55
- flagWebhookServerAddr = "webhook-server-addr"
56
- flagDeletionPolicy = "deletion-policy"
57
- flagReconcileDefaultResyncSeconds = "reconcile-default-resync-seconds"
58
- flagReconcileResourceResyncSeconds = "reconcile-resource-resync-seconds"
59
- envVarAWSRegion = "AWS_REGION"
42
+ flagEnableLeaderElection = "enable-leader-election"
43
+ flagLeaderElectionNamespace = "leader-election-namespace"
44
+ flagMetricAddr = "metrics-addr"
45
+ flagHealthzAddr = "healthz-addr"
46
+ flagEnableDevLogging = "enable-development-logging"
47
+ flagAWSRegion = "aws-region"
48
+ flagAWSEndpointURL = "aws-endpoint-url"
49
+ flagAWSIdentityEndpointURL = "aws-identity-endpoint-url"
50
+ flagUnsafeAWSEndpointURLs = "allow-unsafe-aws-endpoint-urls"
51
+ flagLogLevel = "log-level"
52
+ flagResourceTags = "resource-tags"
53
+ flagWatchNamespace = "watch-namespace"
54
+ flagEnableWebhookServer = "enable-webhook-server"
55
+ flagWebhookServerAddr = "webhook-server-addr"
56
+ flagDeletionPolicy = "deletion-policy"
57
+ flagReconcileDefaultResyncSeconds = "reconcile-default-resync-seconds"
58
+ flagReconcileResourceResyncSeconds = "reconcile-resource-resync-seconds"
59
+ flagReconcileDefaultMaxConcurrency = "reconcile-default-max-concurrent-syncs"
60
+ flagReconcileResourceMaxConcurrency = "reconcile-resource-max-concurrent-syncs"
61
+ envVarAWSRegion = "AWS_REGION"
60
62
)
61
63
62
64
var (
@@ -74,24 +76,26 @@ var (
74
76
75
77
// Config contains configuration options for ACK service controllers
76
78
type Config struct {
77
- MetricsAddr string
78
- HealthzAddr string
79
- EnableLeaderElection bool
80
- LeaderElectionNamespace string
81
- EnableDevelopmentLogging bool
82
- AccountID string
83
- Region string
84
- IdentityEndpointURL string
85
- EndpointURL string
86
- AllowUnsafeEndpointURL bool
87
- LogLevel string
88
- ResourceTags []string
89
- WatchNamespace string
90
- EnableWebhookServer bool
91
- WebhookServerAddr string
92
- DeletionPolicy ackv1alpha1.DeletionPolicy
93
- ReconcileDefaultResyncSeconds int
94
- ReconcileResourceResyncSeconds []string
79
+ MetricsAddr string
80
+ HealthzAddr string
81
+ EnableLeaderElection bool
82
+ LeaderElectionNamespace string
83
+ EnableDevelopmentLogging bool
84
+ AccountID string
85
+ Region string
86
+ IdentityEndpointURL string
87
+ EndpointURL string
88
+ AllowUnsafeEndpointURL bool
89
+ LogLevel string
90
+ ResourceTags []string
91
+ WatchNamespace string
92
+ EnableWebhookServer bool
93
+ WebhookServerAddr string
94
+ DeletionPolicy ackv1alpha1.DeletionPolicy
95
+ ReconcileDefaultResyncSeconds int
96
+ ReconcileResourceResyncSeconds []string
97
+ ReconcileDefaultMaxConcurrency int
98
+ ReconcileResourceMaxConcurrency []string
95
99
}
96
100
97
101
// BindFlags defines CLI/runtime configuration options
@@ -202,6 +206,19 @@ func (cfg *Config) BindFlags() {
202
206
" configuration maps resource kinds to drift remediation periods in seconds. If provided, " +
203
207
" resource-specific resync periods take precedence over the default period." ,
204
208
)
209
+ flag .IntVar (
210
+ & cfg .ReconcileDefaultMaxConcurrency , flagReconcileDefaultMaxConcurrency ,
211
+ 1 ,
212
+ "The default maximum number of concurrent reconciles for a resource reconciler. This value is used if no " +
213
+ "resource-specific override has been specified. Default is 1." ,
214
+ )
215
+ flag .StringArrayVar (
216
+ & cfg .ReconcileResourceMaxConcurrency , flagReconcileResourceMaxConcurrency ,
217
+ []string {},
218
+ "A Key/Value list of strings representing the reconcile max concurrency configuration for each resource. This" +
219
+ " configuration maps resource kinds to maximum number of concurrent reconciles. If provided, " +
220
+ " resource-specific max concurrency takes precedence over the default max concurrency." ,
221
+ )
205
222
}
206
223
207
224
// SetupLogger initializes the logger used in the service controller
@@ -222,7 +239,6 @@ func (cfg *Config) SetupLogger() {
222
239
// SetAWSAccountID uses sts GetCallerIdentity API to find AWS AccountId and set
223
240
// in Config
224
241
func (cfg * Config ) SetAWSAccountID () error {
225
-
226
242
awsCfg := aws.Config {}
227
243
if cfg .IdentityEndpointURL != "" {
228
244
awsCfg .Endpoint = aws .String (cfg .IdentityEndpointURL )
@@ -297,6 +313,9 @@ func (cfg *Config) Validate(options ...Option) error {
297
313
if cfg .ReconcileDefaultResyncSeconds < 0 {
298
314
return fmt .Errorf ("invalid value for flag '%s': resync seconds default must be greater than 0" , flagReconcileDefaultResyncSeconds )
299
315
}
316
+ if cfg .ReconcileDefaultMaxConcurrency < 1 {
317
+ return fmt .Errorf ("invalid value for flag '%s': max concurrency default must be greater than 0" , flagReconcileDefaultMaxConcurrency )
318
+ }
300
319
return nil
301
320
}
302
321
@@ -309,28 +328,45 @@ func (cfg *Config) checkUnsafeEndpoint(endpoint *url.URL) error {
309
328
return nil
310
329
}
311
330
312
- // validateReconcileConfigResources validates the --reconcile-resource-resync-seconds flag
313
- // by checking the resource names and their corresponding duration.
331
+ // validateReconcileConfigResources validates the --reconcile-resource-resync-seconds and
332
+ // --reconcile-resource-max-concurrent-syncs flags. It ensures that the resource names provided
333
+ // in the flags are valid and managed by the controller.
314
334
func (cfg * Config ) validateReconcileConfigResources (supportedGVKs []schema.GroupVersionKind ) error {
315
335
validResourceNames := []string {}
316
336
for _ , gvk := range supportedGVKs {
317
337
validResourceNames = append (validResourceNames , gvk .Kind )
318
338
}
319
- for _ , resourceResyncSecondsFlag := range cfg .ReconcileResourceResyncSeconds {
320
- resourceName , _ , err := parseReconcileFlagArgument (resourceResyncSecondsFlag )
321
- if err != nil {
322
- return fmt .Errorf ("error parsing flag argument '%v': %v. Expected format: resource=seconds" , resourceResyncSecondsFlag , err )
339
+ for _ , resourceFlagArgument := range cfg .ReconcileResourceResyncSeconds {
340
+ if err := validateReconcileConfigResource (validResourceNames , resourceFlagArgument ); err != nil {
341
+ return fmt .Errorf ("invalid value for flag '%s': %v" , flagReconcileResourceResyncSeconds , err )
323
342
}
324
- if ! ackutil .InStrings (resourceName , validResourceNames ) {
325
- return fmt .Errorf (
326
- "error parsing flag argument '%v': resource '%v' is not managed by this controller. Expected one of %v" ,
327
- resourceResyncSecondsFlag , resourceName , strings .Join (validResourceNames , ", " ),
328
- )
343
+ }
344
+ for _ , resourceFlagArgument := range cfg .ReconcileResourceMaxConcurrency {
345
+ if err := validateReconcileConfigResource (validResourceNames , resourceFlagArgument ); err != nil {
346
+ return fmt .Errorf ("invalid value for flag '%s': %v" , flagReconcileResourceMaxConcurrency , err )
329
347
}
330
348
}
331
349
return nil
332
350
}
333
351
352
+ // validateReconcileConfigResource validates a single flag argument of any flag that is used to configure
353
+ // resource-specific reconcile settings. It ensures that the resource name is valid and managed by the
354
+ // controller, and that the value is a positive integer. If the flag argument is not in the expected format
355
+ // or has invalid elements, an error is returned.
356
+ func validateReconcileConfigResource (validResourceNames []string , resourceFlagArgument string ) error {
357
+ resourceName , _ , err := parseReconcileFlagArgument (resourceFlagArgument )
358
+ if err != nil {
359
+ return fmt .Errorf ("error parsing flag argument '%v': %v. Expected format: string=number" , resourceFlagArgument , err )
360
+ }
361
+ if ! ackutil .InStrings (resourceName , validResourceNames ) {
362
+ return fmt .Errorf (
363
+ "error parsing flag argument '%v': resource '%v' is not managed by this controller. Expected one of %v" ,
364
+ resourceFlagArgument , resourceName , strings .Join (validResourceNames , ", " ),
365
+ )
366
+ }
367
+ return nil
368
+ }
369
+
334
370
// ParseReconcileResourceResyncSeconds parses the values of the --reconcile-resource-resync-seconds
335
371
// flag and returns a map that maps resource names to resync periods.
336
372
// The flag arguments are expected to have the format "resource=seconds", where "resource" is the
@@ -346,6 +382,20 @@ func (cfg *Config) ParseReconcileResourceResyncSeconds() (map[string]time.Durati
346
382
return resourceResyncPeriods , nil
347
383
}
348
384
385
+ // GetReconcileResourceMaxConcurrency returns the maximum number of concurrent reconciles for a
386
+ // given resource name. If the resource name is not found in the --reconcile-resource-max-concurrent-syncs
387
+ // flag, the function returns the default maximum concurrency value.
388
+ func (cfg * Config ) GetReconcileResourceMaxConcurrency (resourceName string ) int {
389
+ for _ , resourceMaxConcurrencyFlag := range cfg .ReconcileResourceMaxConcurrency {
390
+ // Parse the resource name and max concurrency from the flag argument
391
+ name , maxConcurrency , _ := parseReconcileFlagArgument (resourceMaxConcurrencyFlag )
392
+ if strings .EqualFold (name , resourceName ) {
393
+ return maxConcurrency
394
+ }
395
+ }
396
+ return cfg .ReconcileDefaultMaxConcurrency
397
+ }
398
+
349
399
// parseReconcileFlagArgument parses a flag argument of the form "key=value" into
350
400
// its individual elements. The key must be a non-empty string and the value must be
351
401
// a non-empty positive integer. If the flag argument is not in the expected format
@@ -365,14 +415,14 @@ func parseReconcileFlagArgument(flagArgument string) (string, int, error) {
365
415
return "" , 0 , fmt .Errorf ("missing value in flag argument" )
366
416
}
367
417
368
- resyncSeconds , err := strconv .Atoi (elements [1 ])
418
+ value , err := strconv .Atoi (elements [1 ])
369
419
if err != nil {
370
420
return "" , 0 , fmt .Errorf ("invalid value in flag argument: %v" , err )
371
421
}
372
- if resyncSeconds < 0 {
373
- return "" , 0 , fmt .Errorf ("invalid value in flag argument: expected non-negative integer, got %d" , resyncSeconds )
422
+ if value <= 0 {
423
+ return "" , 0 , fmt .Errorf ("invalid value in flag argument: value must be greater than 0" )
374
424
}
375
- return elements [0 ], resyncSeconds , nil
425
+ return elements [0 ], value , nil
376
426
}
377
427
378
428
// GetWatchNamespaces returns a slice of namespaces to watch for custom resource events.
0 commit comments