@@ -39,24 +39,26 @@ import (
3939)
4040
4141const (
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"
6062)
6163
6264var (
@@ -74,24 +76,26 @@ var (
7476
7577// Config contains configuration options for ACK service controllers
7678type 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
9599}
96100
97101// BindFlags defines CLI/runtime configuration options
@@ -202,6 +206,19 @@ func (cfg *Config) BindFlags() {
202206 " configuration maps resource kinds to drift remediation periods in seconds. If provided, " +
203207 " resource-specific resync periods take precedence over the default period." ,
204208 )
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+ )
205222}
206223
207224// SetupLogger initializes the logger used in the service controller
@@ -222,7 +239,6 @@ func (cfg *Config) SetupLogger() {
222239// SetAWSAccountID uses sts GetCallerIdentity API to find AWS AccountId and set
223240// in Config
224241func (cfg * Config ) SetAWSAccountID () error {
225-
226242 awsCfg := aws.Config {}
227243 if cfg .IdentityEndpointURL != "" {
228244 awsCfg .Endpoint = aws .String (cfg .IdentityEndpointURL )
@@ -297,6 +313,9 @@ func (cfg *Config) Validate(options ...Option) error {
297313 if cfg .ReconcileDefaultResyncSeconds < 0 {
298314 return fmt .Errorf ("invalid value for flag '%s': resync seconds default must be greater than 0" , flagReconcileDefaultResyncSeconds )
299315 }
316+ if cfg .ReconcileDefaultMaxConcurrency < 1 {
317+ return fmt .Errorf ("invalid value for flag '%s': max concurrency default must be greater than 0" , flagReconcileDefaultMaxConcurrency )
318+ }
300319 return nil
301320}
302321
@@ -309,28 +328,45 @@ func (cfg *Config) checkUnsafeEndpoint(endpoint *url.URL) error {
309328 return nil
310329}
311330
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.
314334func (cfg * Config ) validateReconcileConfigResources (supportedGVKs []schema.GroupVersionKind ) error {
315335 validResourceNames := []string {}
316336 for _ , gvk := range supportedGVKs {
317337 validResourceNames = append (validResourceNames , gvk .Kind )
318338 }
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 )
323342 }
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 )
329347 }
330348 }
331349 return nil
332350}
333351
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+
334370// ParseReconcileResourceResyncSeconds parses the values of the --reconcile-resource-resync-seconds
335371// flag and returns a map that maps resource names to resync periods.
336372// 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
346382 return resourceResyncPeriods , nil
347383}
348384
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+
349399// parseReconcileFlagArgument parses a flag argument of the form "key=value" into
350400// its individual elements. The key must be a non-empty string and the value must be
351401// 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) {
365415 return "" , 0 , fmt .Errorf ("missing value in flag argument" )
366416 }
367417
368- resyncSeconds , err := strconv .Atoi (elements [1 ])
418+ value , err := strconv .Atoi (elements [1 ])
369419 if err != nil {
370420 return "" , 0 , fmt .Errorf ("invalid value in flag argument: %v" , err )
371421 }
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" )
374424 }
375- return elements [0 ], resyncSeconds , nil
425+ return elements [0 ], value , nil
376426}
377427
378428// GetWatchNamespaces returns a slice of namespaces to watch for custom resource events.
0 commit comments