mirror of
https://github.com/coredns/coredns.git
synced 2025-12-06 10:25:10 -05:00
Merge commit from fork
Instead of casting lease ID to uint32, fix the TTL() function to use etcd time-to-live API for determining TTL. Add configurable min-lease-ttl and max-lease-ttl options to prevent extreme TTL values. By default, lease records now go through bounds checking with 30s to 1d as the min/max. Added unit tests for validation and docs. Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
This commit is contained in:
@@ -66,6 +66,31 @@ func TestSetupEtcd(t *testing.T) {
|
||||
}
|
||||
`, true, "skydns", []string{"http://localhost:2379"}, "Wrong argument count", "", "",
|
||||
},
|
||||
// with custom min-lease-ttl
|
||||
{
|
||||
`etcd {
|
||||
endpoint http://localhost:2379
|
||||
min-lease-ttl 60
|
||||
}
|
||||
`, false, "skydns", []string{"http://localhost:2379"}, "", "", "",
|
||||
},
|
||||
// with custom max-lease-ttl
|
||||
{
|
||||
`etcd {
|
||||
endpoint http://localhost:2379
|
||||
max-lease-ttl 1h
|
||||
}
|
||||
`, false, "skydns", []string{"http://localhost:2379"}, "", "", "",
|
||||
},
|
||||
// with both custom min-lease-ttl and max-lease-ttl
|
||||
{
|
||||
`etcd {
|
||||
endpoint http://localhost:2379
|
||||
min-lease-ttl 120
|
||||
max-lease-ttl 7200
|
||||
}
|
||||
`, false, "skydns", []string{"http://localhost:2379"}, "", "", "",
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
@@ -113,6 +138,84 @@ func TestSetupEtcd(t *testing.T) {
|
||||
t.Errorf("Etcd password not correctly set for input %s. Expected: '%+v', actual: '%+v'", test.input, test.password, etcd.Client.Password)
|
||||
}
|
||||
}
|
||||
|
||||
// Check TTL configuration for specific test cases
|
||||
if strings.Contains(test.input, "min-lease-ttl 60") {
|
||||
if etcd.MinLeaseTTL != 60 {
|
||||
t.Errorf("MinLeaseTTL not set correctly for input %s. Expected: 60, actual: %d", test.input, etcd.MinLeaseTTL)
|
||||
}
|
||||
}
|
||||
if strings.Contains(test.input, "max-lease-ttl 1h") {
|
||||
if etcd.MaxLeaseTTL != 3600 {
|
||||
t.Errorf("MaxLeaseTTL not set correctly for input %s. Expected: 3600, actual: %d", test.input, etcd.MaxLeaseTTL)
|
||||
}
|
||||
}
|
||||
if strings.Contains(test.input, "min-lease-ttl 120") && strings.Contains(test.input, "max-lease-ttl 7200") {
|
||||
if etcd.MinLeaseTTL != 120 {
|
||||
t.Errorf("MinLeaseTTL not set correctly for input %s. Expected: 120, actual: %d", test.input, etcd.MinLeaseTTL)
|
||||
}
|
||||
if etcd.MaxLeaseTTL != 7200 {
|
||||
t.Errorf("MaxLeaseTTL not set correctly for input %s. Expected: 7200, actual: %d", test.input, etcd.MaxLeaseTTL)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseTTL(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected uint32
|
||||
hasError bool
|
||||
desc string
|
||||
}{
|
||||
// Plain numbers (assumed to be seconds)
|
||||
{"30", 30, false, "plain number should be treated as seconds"},
|
||||
{"300", 300, false, "plain number should be treated as seconds"},
|
||||
|
||||
// Explicit seconds
|
||||
{"30s", 30, false, "explicit seconds"},
|
||||
{"90s", 90, false, "explicit seconds"},
|
||||
|
||||
// Minutes
|
||||
{"5m", 300, false, "5 minutes"},
|
||||
{"1m", 60, false, "1 minute"},
|
||||
|
||||
// Hours
|
||||
{"1h", 3600, false, "1 hour"},
|
||||
{"2h", 7200, false, "2 hours"},
|
||||
|
||||
// Complex durations (Go's ParseDuration supports this)
|
||||
{"2h30m", 9000, false, "2 hours 30 minutes"},
|
||||
{"1h30m45s", 5445, false, "1 hour 30 minutes 45 seconds"},
|
||||
|
||||
// Edge cases
|
||||
{"0", 0, false, "zero should be allowed"},
|
||||
{"0s", 0, false, "zero seconds should be allowed"},
|
||||
{"", 0, false, "empty string should return 0"},
|
||||
|
||||
// Error cases
|
||||
{"-30s", 0, true, "negative duration should error"},
|
||||
{"abc", 0, true, "invalid format should error"},
|
||||
{"1y", 0, true, "unsupported unit should error"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
result, err := parseTTL(tt.input)
|
||||
|
||||
if tt.hasError {
|
||||
if err == nil {
|
||||
t.Errorf("parseTTL(%q) expected error but got none", tt.input)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("parseTTL(%q) unexpected error: %v", tt.input, err)
|
||||
}
|
||||
if result != tt.expected {
|
||||
t.Errorf("parseTTL(%q) = %d, expected %d", tt.input, result, tt.expected)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user