mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 10:13:14 -04: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