@@ -17,6 +17,9 @@ import (
1717	"errors" 
1818	"fmt" 
1919	"net/url" 
20+ 	"strconv" 
21+ 	"strings" 
22+ 	"time" 
2023
2124	"github.com/aws/aws-sdk-go/aws" 
2225	"github.com/aws/aws-sdk-go/aws/session" 
@@ -32,20 +35,22 @@ import (
3235)
3336
3437const  (
35- 	flagEnableLeaderElection    =  "enable-leader-election" 
36- 	flagMetricAddr              =  "metrics-addr" 
37- 	flagEnableDevLogging        =  "enable-development-logging" 
38- 	flagAWSRegion               =  "aws-region" 
39- 	flagAWSEndpointURL          =  "aws-endpoint-url" 
40- 	flagAWSIdentityEndpointURL  =  "aws-identity-endpoint-url" 
41- 	flagUnsafeAWSEndpointURLs   =  "allow-unsafe-aws-endpoint-urls" 
42- 	flagLogLevel                =  "log-level" 
43- 	flagResourceTags            =  "resource-tags" 
44- 	flagWatchNamespace          =  "watch-namespace" 
45- 	flagEnableWebhookServer     =  "enable-webhook-server" 
46- 	flagWebhookServerAddr       =  "webhook-server-addr" 
47- 	flagDeletionPolicy          =  "deletion-policy" 
48- 	envVarAWSRegion             =  "AWS_REGION" 
38+ 	flagEnableLeaderElection            =  "enable-leader-election" 
39+ 	flagMetricAddr                      =  "metrics-addr" 
40+ 	flagEnableDevLogging                =  "enable-development-logging" 
41+ 	flagAWSRegion                       =  "aws-region" 
42+ 	flagAWSEndpointURL                  =  "aws-endpoint-url" 
43+ 	flagAWSIdentityEndpointURL          =  "aws-identity-endpoint-url" 
44+ 	flagUnsafeAWSEndpointURLs           =  "allow-unsafe-aws-endpoint-urls" 
45+ 	flagLogLevel                        =  "log-level" 
46+ 	flagResourceTags                    =  "resource-tags" 
47+ 	flagWatchNamespace                  =  "watch-namespace" 
48+ 	flagEnableWebhookServer             =  "enable-webhook-server" 
49+ 	flagWebhookServerAddr               =  "webhook-server-addr" 
50+ 	flagDeletionPolicy                  =  "deletion-policy" 
51+ 	flagReconcileDefaultResyncSeconds   =  "reconcile-default-resync-seconds" 
52+ 	flagReconcileResourceResyncSeconds  =  "reconcile-resource-resync-seconds" 
53+ 	envVarAWSRegion                     =  "AWS_REGION" 
4954)
5055
5156var  (
@@ -63,20 +68,22 @@ var (
6368
6469// Config contains configuration options for ACK service controllers 
6570type  Config  struct  {
66- 	MetricsAddr               string 
67- 	EnableLeaderElection      bool 
68- 	EnableDevelopmentLogging  bool 
69- 	AccountID                 string 
70- 	Region                    string 
71- 	IdentityEndpointURL       string 
72- 	EndpointURL               string 
73- 	AllowUnsafeEndpointURL    bool 
74- 	LogLevel                  string 
75- 	ResourceTags              []string 
76- 	WatchNamespace            string 
77- 	EnableWebhookServer       bool 
78- 	WebhookServerAddr         string 
79- 	DeletionPolicy            ackv1alpha1.DeletionPolicy 
71+ 	MetricsAddr                     string 
72+ 	EnableLeaderElection            bool 
73+ 	EnableDevelopmentLogging        bool 
74+ 	AccountID                       string 
75+ 	Region                          string 
76+ 	IdentityEndpointURL             string 
77+ 	EndpointURL                     string 
78+ 	AllowUnsafeEndpointURL          bool 
79+ 	LogLevel                        string 
80+ 	ResourceTags                    []string 
81+ 	WatchNamespace                  string 
82+ 	EnableWebhookServer             bool 
83+ 	WebhookServerAddr               string 
84+ 	DeletionPolicy                  ackv1alpha1.DeletionPolicy 
85+ 	ReconcileDefaultResyncSeconds   int 
86+ 	ReconcileResourceResyncSeconds  []string 
8087}
8188
8289// BindFlags defines CLI/runtime configuration options 
@@ -152,6 +159,19 @@ func (cfg *Config) BindFlags() {
152159		& cfg .DeletionPolicy , flagDeletionPolicy ,
153160		"The default deletion policy for all resources managed by the controller" ,
154161	)
162+ 	flag .IntVar (
163+ 		& cfg .ReconcileDefaultResyncSeconds , flagReconcileDefaultResyncSeconds ,
164+ 		0 ,
165+ 		"The default duration, in seconds, to wait before resyncing desired state of custom resources. " + 
166+ 			"This value is used if no resource-specific override has been specified. Default is 10 hours." ,
167+ 	)
168+ 	flag .StringArrayVar (
169+ 		& cfg .ReconcileResourceResyncSeconds , flagReconcileResourceResyncSeconds ,
170+ 		[]string {},
171+ 		"A Key/Value list of strings representing the reconcile resync configuration for each resource. This" + 
172+ 			" configuration maps resource kinds to drift remediation periods in seconds. If provided, " + 
173+ 			" resource-specific resync periods take precedence over the default period." ,
174+ 	)
155175}
156176
157177// SetupLogger initializes the logger used in the service controller 
@@ -233,6 +253,16 @@ func (cfg *Config) Validate() error {
233253	if  cfg .DeletionPolicy  ==  ""  {
234254		cfg .DeletionPolicy  =  ackv1alpha1 .DeletionPolicyDelete 
235255	}
256+ 
257+ 	if  cfg .ReconcileDefaultResyncSeconds  <  0  {
258+ 		return  fmt .Errorf ("invalid value for flag '%s': resync seconds default must be greater than 0" , flagReconcileDefaultResyncSeconds )
259+ 	}
260+ 
261+ 	_ , err  :=  cfg .ParseReconcileResourceResyncSeconds ()
262+ 	if  err  !=  nil  {
263+ 		return  fmt .Errorf ("invalid value for flag '%s': %v" , flagReconcileResourceResyncSeconds , err )
264+ 	}
265+ 
236266	return  nil 
237267}
238268
@@ -244,3 +274,50 @@ func (cfg *Config) checkUnsafeEndpoint(endpoint *url.URL) error {
244274	}
245275	return  nil 
246276}
277+ 
278+ // ParseReconcileResourceResyncSeconds parses the values of the --reconcile-resource-resync-seconds 
279+ // flag and returns a map that maps resource names to resync periods. 
280+ // The flag arguments are expected to have the format "resource=seconds", where "resource" is the 
281+ // name of the resource and "seconds" is the number of seconds that the reconciler should wait before 
282+ // reconciling the resource again. 
283+ func  (cfg  * Config ) ParseReconcileResourceResyncSeconds () (map [string ]time.Duration , error ) {
284+ 	resourceResyncPeriods  :=  make (map [string ]time.Duration , len (cfg .ReconcileResourceResyncSeconds ))
285+ 	for  _ , resourceResyncSecondsFlag  :=  range  cfg .ReconcileResourceResyncSeconds  {
286+ 		// Parse the resource name and resync period from the flag argument 
287+ 		resourceName , resyncSeconds , err  :=  parseReconcileFlagArgument (resourceResyncSecondsFlag )
288+ 		if  err  !=  nil  {
289+ 			return  nil , fmt .Errorf ("error parsing flag argument '%v': %v. Expected format: resource=seconds" , resourceResyncSecondsFlag , err )
290+ 		}
291+ 		resourceResyncPeriods [strings .ToLower (resourceName )] =  time .Duration (resyncSeconds )
292+ 	}
293+ 	return  resourceResyncPeriods , nil 
294+ }
295+ 
296+ // parseReconcileFlagArgument parses a flag argument of the form "key=value" into 
297+ // its individual elements. The key must be a non-empty string and the value must be 
298+ // a non-empty positive integer. If the flag argument is not in the expected format 
299+ // or has invalid elements, an error is returned. 
300+ // 
301+ // The function returns the parsed key and value as separate elements. 
302+ func  parseReconcileFlagArgument (flagArgument  string ) (string , int , error ) {
303+ 	delimiter  :=  "=" 
304+ 	elements  :=  strings .Split (flagArgument , delimiter )
305+ 	if  len (elements ) !=  2  {
306+ 		return  "" , 0 , fmt .Errorf ("invalid flag argument format: expected key=value" )
307+ 	}
308+ 	if  elements [0 ] ==  ""  {
309+ 		return  "" , 0 , fmt .Errorf ("missing key in flag argument" )
310+ 	}
311+ 	if  elements [1 ] ==  ""  {
312+ 		return  "" , 0 , fmt .Errorf ("missing value in flag argument" )
313+ 	}
314+ 
315+ 	resyncSeconds , err  :=  strconv .Atoi (elements [1 ])
316+ 	if  err  !=  nil  {
317+ 		return  "" , 0 , fmt .Errorf ("invalid value in flag argument: %v" , err )
318+ 	}
319+ 	if  resyncSeconds  <  0  {
320+ 		return  "" , 0 , fmt .Errorf ("invalid value in flag argument: expected non-negative integer, got %d" , resyncSeconds )
321+ 	}
322+ 	return  elements [0 ], resyncSeconds , nil 
323+ }
0 commit comments