summaryrefslogtreecommitdiff
path: root/src/etcd/client.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/etcd/client.py')
-rw-r--r--src/etcd/client.py29
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."""