1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
import collections
from client import Client
class EtcdResult(collections.namedtuple(
'EtcdResult',
[
'action',
'key',
'value',
'expiration',
'ttl',
'modifiedIndex',
'prevValue',
'newKey',
'dir',
'kvs'
]
)):
def __new__(
cls,
action=None,
key=None,
value=None,
expiration=None,
ttl=None,
modifiedIndex=None,
prevValue=None,
newKey=False,
dir=False,
kvs=None
):
if dir and kvs:
keys = []
for result in kvs:
keys.append(EtcdResult(**result))
kvs = keys
return super(EtcdResult, cls).__new__(
cls,
action,
key,
value,
expiration,
ttl,
modifiedIndex,
prevValue,
newKey,
dir,
kvs
)
class EtcdException(Exception):
"""
Generic Etcd Exception.
"""
pass
class EtcdError(object):
# See https://github.com/coreos/etcd/blob/master/Documentation/errorcode.md
error_exceptions = {
100: KeyError,
101: ValueError,
102: KeyError,
103: Exception,
104: KeyError,
105: KeyError,
106: KeyError,
200: ValueError,
201: ValueError,
202: ValueError,
203: ValueError,
300: Exception,
301: Exception,
400: Exception,
401: EtcdException,
500: EtcdException
}
@classmethod
def handle(cls, errorCode=None, message=None, cause=None, **kwdargs):
""" Decodes the error and throws the appropriate error message"""
try:
msg = "{} : {}".format(message, cause)
exc = cls.error_exceptions[errorCode]
except:
msg = "Unable to decode server response"
exc = EtcdException
raise exc(msg)
# Attempt to enable urllib3's SNI support, if possible
# Blatantly copied from requests.
try:
from urllib3.contrib import pyopenssl
pyopenssl.inject_into_urllib3()
except ImportError:
pass
|