diff options
Diffstat (limited to 'src/etcd/client.py')
-rw-r--r-- | src/etcd/client.py | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/src/etcd/client.py b/src/etcd/client.py index 7d32ccf..c0cae84 100644 --- a/src/etcd/client.py +++ b/src/etcd/client.py @@ -18,6 +18,7 @@ import urllib3 import urllib3.util import json import ssl +import dns.resolver import etcd try: @@ -46,6 +47,7 @@ class Client(object): self, host='127.0.0.1', port=4001, + srv_domain=None, version_prefix='/v2', read_timeout=60, allow_redirect=True, @@ -67,6 +69,8 @@ class Client(object): port (int): Port used to connect to etcd. + srv_domain (str): Domain to search the SRV record for cluster autodiscovery. + version_prefix (str): Url or version prefix in etcd url (default=/v2). read_timeout (int): max seconds to wait for a read. @@ -98,8 +102,15 @@ class Client(object): by host. By default this will use up to 10 connections. """ - _log.debug("New etcd client created for %s:%s%s", - host, port, version_prefix) + + # If a DNS record is provided, use it to get the hosts list + if srv_domain is not None: + try: + host = self._discover(srv_domain) + except Exception as e: + _log.error("Could not discover the etcd hosts from %s: %s", + srv_domain, e) + self._protocol = protocol def uri(protocol, host, port): @@ -153,6 +164,8 @@ class Client(object): self.http = urllib3.PoolManager(num_pools=10, **kw) + _log.debug("New etcd client created for %s", self.base_uri) + if self._allow_reconnect: # we need the set of servers in the cluster in order to try # reconnecting upon error. The cluster members will be @@ -174,6 +187,18 @@ class Client(object): _log.debug("Machines cache initialised to %s", self._machines_cache) + def _discover(self, domain): + srv_name = "_etcd._tcp.{}".format(domain) + answers = dns.resolver.query(srv_name, 'SRV') + hosts = [] + for answer in answers: + hosts.append( + (answer.target.to_text(omit_final_dot=True), answer.port)) + _log.debug("Found %s", hosts) + if not len(hosts): + raise ValueError("The SRV record is present but no host were found") + return tuple(hosts) + @property def base_uri(self): """URI used by the client to connect to etcd.""" |