1818import urllib3 .util
1919import json
2020import ssl
21+ import dns .resolver
2122import etcd
2223
2324try :
@@ -46,6 +47,7 @@ def __init__(
4647 self ,
4748 host = '127.0.0.1' ,
4849 port = 4001 ,
50+ srv_domain = None ,
4951 version_prefix = '/v2' ,
5052 read_timeout = 60 ,
5153 allow_redirect = True ,
@@ -67,6 +69,8 @@ def __init__(
6769
6870 port (int): Port used to connect to etcd.
6971
72+ srv_domain (str): Domain to search the SRV record for cluster autodiscovery.
73+
7074 version_prefix (str): Url or version prefix in etcd url (default=/v2).
7175
7276 read_timeout (int): max seconds to wait for a read.
@@ -98,8 +102,15 @@ def __init__(
98102 by host. By default this will use up to 10
99103 connections.
100104 """
101- _log .debug ("New etcd client created for %s:%s%s" ,
102- host , port , version_prefix )
105+
106+ # If a DNS record is provided, use it to get the hosts list
107+ if srv_domain is not None :
108+ try :
109+ host = self ._discover (srv_domain )
110+ except Exception as e :
111+ _log .error ("Could not discover the etcd hosts from %s: %s" ,
112+ srv_domain , e )
113+
103114 self ._protocol = protocol
104115
105116 def uri (protocol , host , port ):
@@ -153,6 +164,8 @@ def uri(protocol, host, port):
153164
154165 self .http = urllib3 .PoolManager (num_pools = 10 , ** kw )
155166
167+ _log .debug ("New etcd client created for %s" , self .base_uri )
168+
156169 if self ._allow_reconnect :
157170 # we need the set of servers in the cluster in order to try
158171 # reconnecting upon error. The cluster members will be
@@ -174,6 +187,18 @@ def uri(protocol, host, port):
174187 _log .debug ("Machines cache initialised to %s" ,
175188 self ._machines_cache )
176189
190+ def _discover (self , domain ):
191+ srv_name = "_etcd._tcp.{}" .format (domain )
192+ answers = dns .resolver .query (srv_name , 'SRV' )
193+ hosts = []
194+ for answer in answers :
195+ hosts .append (
196+ (answer .target .to_text (omit_final_dot = True ), answer .port ))
197+ _log .debug ("Found %s" , hosts )
198+ if not len (hosts ):
199+ raise ValueError ("The SRV record is present but no host were found" )
200+ return tuple (hosts )
201+
177202 @property
178203 def base_uri (self ):
179204 """URI used by the client to connect to etcd."""
0 commit comments