mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-30 09:43:17 -04:00 
			
		
		
		
	Plugin/Proxy - add new policy always_first to mimic windows dns resolvers (#1459)
* add new policy always_first to mimic windows dns resolvers fill documentation, add UT and cleanup fmt * change name of policy from always_first to first. Update docs
This commit is contained in:
		
				
					committed by
					
						 John Belamaric
						John Belamaric
					
				
			
			
				
	
			
			
			
						parent
						
							0af9b9b16f
						
					
				
				
					commit
					b93a36b213
				
			| @@ -38,7 +38,7 @@ However, advanced features including load balancing can be utilized with an expa | |||||||
| .nf | .nf | ||||||
|  |  | ||||||
| proxy FROM TO\.\.\. { | proxy FROM TO\.\.\. { | ||||||
|     policy random|least_conn|round_robin |     policy random|least_conn|round_robin|first | ||||||
|     fail_timeout DURATION |     fail_timeout DURATION | ||||||
|     max_fails INTEGER |     max_fails INTEGER | ||||||
|     health_check PATH:PORT [DURATION] |     health_check PATH:PORT [DURATION] | ||||||
| @@ -58,7 +58,7 @@ proxy FROM TO\.\.\. { | |||||||
| \fBTO\fR is the destination endpoint to proxy to\. At least one is required, but multiple may be specified\. \fBTO\fR may be an IP:Port pair, or may reference a file in resolv\.conf format | \fBTO\fR is the destination endpoint to proxy to\. At least one is required, but multiple may be specified\. \fBTO\fR may be an IP:Port pair, or may reference a file in resolv\.conf format | ||||||
| . | . | ||||||
| .IP "\(bu" 4 | .IP "\(bu" 4 | ||||||
| \fBpolicy\fR is the load balancing policy to use; applies only with multiple backends\. May be one of random, least_conn, or round_robin\. Default is random\. | \fBpolicy\fR is the load balancing policy to use; applies only with multiple backends\. May be one of random, least_conn, round_robin or first\. Default is random\. | ||||||
| . | . | ||||||
| .IP "\(bu" 4 | .IP "\(bu" 4 | ||||||
| \fBfail_timeout\fR specifies how long to consider a backend as down after it has failed\. While it is down, requests will not be routed to that backend\. A backend is "down" if CoreDNS fails to communicate with it\. The default value is 2 seconds ("2s")\. | \fBfail_timeout\fR specifies how long to consider a backend as down after it has failed\. While it is down, requests will not be routed to that backend\. A backend is "down" if CoreDNS fails to communicate with it\. The default value is 2 seconds ("2s")\. | ||||||
|   | |||||||
| @@ -27,6 +27,7 @@ func init() { | |||||||
| 	RegisterPolicy("random", func() Policy { return &Random{} }) | 	RegisterPolicy("random", func() Policy { return &Random{} }) | ||||||
| 	RegisterPolicy("least_conn", func() Policy { return &LeastConn{} }) | 	RegisterPolicy("least_conn", func() Policy { return &LeastConn{} }) | ||||||
| 	RegisterPolicy("round_robin", func() Policy { return &RoundRobin{} }) | 	RegisterPolicy("round_robin", func() Policy { return &RoundRobin{} }) | ||||||
|  | 	RegisterPolicy("first", func() Policy { return &First{} }) | ||||||
| } | } | ||||||
|  |  | ||||||
| // Random is a policy that selects up hosts from a pool at random. | // Random is a policy that selects up hosts from a pool at random. | ||||||
| @@ -118,3 +119,19 @@ func (r *RoundRobin) Select(pool HostPool) *UpstreamHost { | |||||||
| 	} | 	} | ||||||
| 	return host | 	return host | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // First is a policy that selects always the first healthy host in the list order. | ||||||
|  | type First struct{} | ||||||
|  |  | ||||||
|  | // Select always the first that is not Down. | ||||||
|  | func (r *First) Select(pool HostPool) *UpstreamHost { | ||||||
|  | 	for i := 0; i < len(pool); i++ { | ||||||
|  | 		host := pool[i] | ||||||
|  | 		if host.Down() { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		return host | ||||||
|  | 	} | ||||||
|  | 	// return the first one, anyway none is correct | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|   | |||||||
| @@ -32,8 +32,8 @@ func (r *customPolicy) Select(pool HostPool) *UpstreamHost { | |||||||
|  |  | ||||||
| func testPool() HostPool { | func testPool() HostPool { | ||||||
| 	pool := []*UpstreamHost{ | 	pool := []*UpstreamHost{ | ||||||
| 		{Name: workableServer.URL},         // this should resolve (healthcheck test) | 		{Name: workableServer.URL},            // this should resolve (healthcheck test) | ||||||
| 		{Name: "http://shouldnot.resolve"}, // this shouldn't | 		{Name: "http://shouldnot.resolve:85"}, // this shouldn't, especially on port other than 80 | ||||||
| 		{Name: "http://C"}, | 		{Name: "http://C"}, | ||||||
| 	} | 	} | ||||||
| 	return HostPool(pool) | 	return HostPool(pool) | ||||||
| @@ -136,3 +136,24 @@ func TestCustomPolicy(t *testing.T) { | |||||||
| 		t.Error("Expected custom policy host to be the first host.") | 		t.Error("Expected custom policy host to be the first host.") | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func TestFirstPolicy(t *testing.T) { | ||||||
|  | 	pool := testPool() | ||||||
|  | 	rrPolicy := &First{} | ||||||
|  | 	h := rrPolicy.Select(pool) | ||||||
|  | 	// First selected host is 1, because counter starts at 0 | ||||||
|  | 	// and increments before host is selected | ||||||
|  | 	if h != pool[0] { | ||||||
|  | 		t.Error("Expected always first to be first host in the pool.") | ||||||
|  | 	} | ||||||
|  | 	h = rrPolicy.Select(pool) | ||||||
|  | 	if h != pool[0] { | ||||||
|  | 		t.Error("Expected always first to be first host in the pool, even in second call") | ||||||
|  | 	} | ||||||
|  | 	// set this first in pool as failed | ||||||
|  | 	pool[0].Fails = 1 | ||||||
|  | 	h = rrPolicy.Select(pool) | ||||||
|  | 	if h != pool[1] { | ||||||
|  | 		t.Error("Expected first to be he second in pool if the first one is down.") | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ However, advanced features including load balancing can be utilized with an expa | |||||||
|  |  | ||||||
| ~~~ | ~~~ | ||||||
| proxy FROM TO... { | proxy FROM TO... { | ||||||
|     policy random|least_conn|round_robin |     policy random|least_conn|round_robin|first | ||||||
|     fail_timeout DURATION |     fail_timeout DURATION | ||||||
|     max_fails INTEGER |     max_fails INTEGER | ||||||
|     health_check PATH:PORT [DURATION] |     health_check PATH:PORT [DURATION] | ||||||
| @@ -39,7 +39,7 @@ proxy FROM TO... { | |||||||
| * **TO** is the destination endpoint to proxy to. At least one is required, but multiple may be | * **TO** is the destination endpoint to proxy to. At least one is required, but multiple may be | ||||||
|   specified. **TO** may be an IP:Port pair, or may reference a file in resolv.conf format |   specified. **TO** may be an IP:Port pair, or may reference a file in resolv.conf format | ||||||
| * `policy` is the load balancing policy to use; applies only with multiple backends. May be one of | * `policy` is the load balancing policy to use; applies only with multiple backends. May be one of | ||||||
|   random, least_conn, or round_robin. Default is random. |   random, least_conn, round_robin or first. Default is random. | ||||||
| * `fail_timeout` specifies how long to consider a backend as down after it has failed. While it is | * `fail_timeout` specifies how long to consider a backend as down after it has failed. While it is | ||||||
|   down, requests will not be routed to that backend. A backend is "down" if CoreDNS fails to |   down, requests will not be routed to that backend. A backend is "down" if CoreDNS fails to | ||||||
|   communicate with it. The default value is 2 seconds ("2s"). |   communicate with it. The default value is 2 seconds ("2s"). | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user