summaryrefslogtreecommitdiff
path: root/src/etcd/__init__.py
blob: 69de598cdb145ce2ab4b9b62d7f5e27781259797 (plain)
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