99 "regexp"
1010 "strconv"
1111 "strings"
12+ "time"
1213
1314 "github.com/sirupsen/logrus" // OK for logrus.Fatal
1415)
@@ -34,6 +35,9 @@ const (
3435 SenderStatusDebug // Not a failure
3536)
3637
38+ // see also https://brandur.org/fragments/go-max-time-duration
39+ const maxDuration time.Duration = 1 << 63 - 1
40+
3741// String prints ASCII
3842func (status SenderStatus ) String () string {
3943 switch status {
@@ -434,6 +438,8 @@ const (
434438 ConfigItemTypeString
435439 // ConfigItemTypeTriState - for config item's who's value is a tristate
436440 ConfigItemTypeTriState
441+ // ConfigItemTypeDuration - for config item's who's value is a duration
442+ ConfigItemTypeDuration
437443)
438444
439445var (
@@ -485,6 +491,10 @@ type ConfigItemSpec struct {
485491 IntMax uint32
486492 IntDefault uint32
487493
494+ DurationMin time.Duration
495+ DurationMax time.Duration
496+ DurationDefault time.Duration
497+
488498 StringValidator Validator
489499 StringDefault string
490500 BoolDefault bool
@@ -505,6 +515,8 @@ func (configSpec ConfigItemSpec) DefaultValue() ConfigItemValue {
505515 item .StrValue = configSpec .StringDefault
506516 case ConfigItemTypeTriState :
507517 item .TriStateValue = configSpec .TriStateDefault
518+ case ConfigItemTypeDuration :
519+ item .DurationValue = configSpec .DurationDefault
508520 }
509521 return item
510522}
@@ -520,6 +532,24 @@ type ConfigItemSpecMap struct {
520532 AgentSettings map [AgentSettingKey ]ConfigItemSpec
521533}
522534
535+ // AddDurationItem - Adds integer item to specMap
536+ func (specMap * ConfigItemSpecMap ) AddDurationItem (key GlobalSettingKey ,
537+ defaultDuration , minDuration , maxDuration time.Duration ) {
538+
539+ if defaultDuration < minDuration || defaultDuration > maxDuration {
540+ logrus .Fatalf ("Adding int item %s failed. Value does not meet given min/max criteria" , key )
541+ }
542+
543+ configItem := ConfigItemSpec {
544+ ItemType : ConfigItemTypeDuration ,
545+ Key : string (key ),
546+ DurationDefault : defaultDuration ,
547+ DurationMin : minDuration ,
548+ DurationMax : maxDuration ,
549+ }
550+ specMap .GlobalSettings [key ] = configItem
551+ }
552+
523553// AddIntItem - Adds integer item to specMap
524554func (specMap * ConfigItemSpecMap ) AddIntItem (key GlobalSettingKey ,
525555 defaultInt uint32 , min uint32 , max uint32 ) {
@@ -691,6 +721,7 @@ type ConfigItemValue struct {
691721 StrValue string
692722 BoolValue bool
693723 TriStateValue TriState
724+ DurationValue time.Duration
694725}
695726
696727// StringValue - Returns the value in String Format
@@ -704,6 +735,8 @@ func (val ConfigItemValue) StringValue() string {
704735 return val .StrValue
705736 case ConfigItemTypeTriState :
706737 return FormatTriState (val .TriStateValue )
738+ case ConfigItemTypeDuration :
739+ return fmt .Sprintf ("%d" , uint64 (val .DurationValue .Seconds ()))
707740 default :
708741 return fmt .Sprintf ("UnknownType(%d)" , val .ItemType )
709742 }
@@ -771,6 +804,17 @@ func (configPtr *ConfigItemValueMap) GlobalValueInt(key GlobalSettingKey) uint32
771804 }
772805}
773806
807+ // GlobalValueDuration - Gets a duration global setting value
808+ func (configPtr * ConfigItemValueMap ) GlobalValueDuration (key GlobalSettingKey ) time.Duration {
809+ val := configPtr .globalConfigItemValue (key )
810+ if val .ItemType == ConfigItemTypeDuration {
811+ return val .DurationValue
812+ } else {
813+ logrus .Fatalf ("***Key(%s) is of Type(%d) NOT time.Duration" , key , val .ItemType )
814+ return 0
815+ }
816+ }
817+
774818// GlobalValueString - Gets a string global setting value
775819func (configPtr * ConfigItemValueMap ) GlobalValueString (key GlobalSettingKey ) string {
776820 val := configPtr .globalConfigItemValue (key )
@@ -842,7 +886,7 @@ func (configPtr *ConfigItemValueMap) DelAgentValue(key AgentSettingKey, agentNam
842886 }
843887}
844888
845- // SetGlobalValueInt - sets a int value for a key
889+ // SetGlobalValueInt - sets an int value for a key
846890func (configPtr * ConfigItemValueMap ) SetGlobalValueInt (key GlobalSettingKey , value uint32 ) {
847891 if configPtr .GlobalSettings == nil {
848892 configPtr .GlobalSettings = make (map [GlobalSettingKey ]ConfigItemValue )
@@ -896,22 +940,29 @@ func (configPtr *ConfigItemValueMap) ResetGlobalValue(key GlobalSettingKey) {
896940 configPtr .GlobalSettings [key ] = specMap .GlobalSettings [key ].DefaultValue ()
897941}
898942
943+ func (configSpec ConfigItemSpec ) parseUint (itemValue string ) (uint32 , error ) {
944+ i64 , err := strconv .ParseUint (itemValue , 10 , 32 )
945+ if err == nil {
946+ val := uint32 (i64 )
947+ if val > configSpec .IntMax || val < configSpec .IntMin {
948+ retErr := fmt .Errorf ("value out of bounds. Parsed value: %d, Max: %d, Min: %d" ,
949+ val , configSpec .IntMax , configSpec .IntMin )
950+ return val , retErr
951+ } else {
952+ return val , err
953+ }
954+ }
955+
956+ return 0 , err
957+ }
958+
899959func (configSpec ConfigItemSpec ) parseValue (itemValue string ) (ConfigItemValue , error ) {
900960 value := configSpec .DefaultValue ()
901961 var retErr error
902962 if configSpec .ItemType == ConfigItemTypeInt {
903- i64 , err := strconv .ParseUint (itemValue , 10 , 32 )
904- if err == nil {
905- val := uint32 (i64 )
906- if val > configSpec .IntMax || val < configSpec .IntMin {
907- retErr = fmt .Errorf ("value out of bounds. Parsed value: %d, Max: %d, Min: %d" ,
908- val , configSpec .IntMax , configSpec .IntMin )
909- } else {
910- value .IntValue = val
911- }
912- } else {
963+ value .IntValue , retErr = configSpec .parseUint (itemValue )
964+ if retErr != nil {
913965 value .IntValue = configSpec .IntDefault
914- retErr = err
915966 }
916967 } else if configSpec .ItemType == ConfigItemTypeTriState {
917968 newTs , err := ParseTriState (itemValue )
@@ -936,6 +987,19 @@ func (configSpec ConfigItemSpec) parseValue(itemValue string) (ConfigItemValue,
936987 } else {
937988 return value , err
938989 }
990+ } else if configSpec .ItemType == ConfigItemTypeDuration {
991+ val , err := configSpec .parseUint (itemValue )
992+ if err == nil {
993+ if val > configSpec .IntMax || val < configSpec .IntMin {
994+ retErr = fmt .Errorf ("value out of bounds. Parsed value: %d, Max: %d, Min: %d" ,
995+ val , configSpec .IntMax , configSpec .IntMin )
996+ } else {
997+ value .DurationValue = time .Duration (val * uint32 (time .Second ))
998+ }
999+ } else {
1000+ value .DurationValue = configSpec .DurationDefault
1001+ retErr = err
1002+ }
9391003 }
9401004 return value , retErr
9411005}
@@ -959,7 +1023,7 @@ func NewConfigItemSpecMap() ConfigItemSpecMap {
9591023 configItemSpecMap .AddIntItem (ConfigInterval , 60 , 5 , HourInSec )
9601024 // Additional safety to periodically fetch the controller certificate
9611025 // Useful for odd cases when the triggered updates do not work.
962- configItemSpecMap .AddIntItem (CertInterval , 24 * HourInSec , 60 , 0xFFFFFFFF )
1026+ configItemSpecMap .AddDurationItem (CertInterval , 24 * time . Hour , 60 * time . Second , maxDuration )
9631027 // timer.metric.diskscan.interval (seconds)
9641028 // Shorter interval can lead to device scanning the disk frequently which is a costly operation.
9651029 configItemSpecMap .AddIntItem (DiskScanMetricInterval , 300 , 5 , HourInSec )
@@ -969,7 +1033,7 @@ func NewConfigItemSpecMap() ConfigItemSpecMap {
9691033 configItemSpecMap .AddIntItem (MetricInterval , 60 , 5 , HourInSec )
9701034 // timer.metric.hardwarehealth.interval (seconds)
9711035 // Default value 12 hours minimum value 6 hours.
972- configItemSpecMap .AddIntItem (HardwareHealthInterval , 43200 , 21600 , 0xFFFFFFFF )
1036+ configItemSpecMap .AddDurationItem (HardwareHealthInterval , 43200 * time . Second , 21600 * time . Second , maxDuration )
9731037 // timer.reboot.no.network (seconds) - reboot after no controller connectivity
9741038 // Max designed to allow the option of never rebooting even if device
9751039 // can't connect to the cloud
0 commit comments