/
providers.py
96 lines (74 loc) · 2.75 KB
/
providers.py
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
import errno
import os
import hvac
from functools import partial
NOT_PROVIDED = object()
class ConfigurationProvider(object):
def get(self, key):
raise NotImplementedError()
def iterprefixed(self, prefix):
raise NotImplementedError()
class DictConfig(ConfigurationProvider):
"""
Loads configuration values from the passed dictionary.
"""
def __init__(self, conf_dict, prefix=""):
self._conf_dict = conf_dict
self._prefix = prefix
def get(self, key):
try:
return self._conf_dict[self._prefix + key]
except KeyError:
return NOT_PROVIDED
def iterprefixed(self, prefix):
prefix = self._prefix + prefix
for k in self._conf_dict:
if k.startswith(prefix):
yield (k[len(self._prefix) :], self._conf_dict[k])
class EnvDirConfig(ConfigurationProvider):
def __init__(self, base_path, prefix=""):
self._base_path = base_path
self._prefix = prefix
def get(self, key):
path = os.path.join(self._base_path, key)
try:
with open(path) as fh:
return fh.read()
except IOError as e:
if e.errno == errno.EACCES: # Wrong permissions
raise
return NOT_PROVIDED # File does not exist
def iterprefixed(self, prefix):
prefix = self._prefix + prefix
if os.path.exists(self._base_path):
for k in os.listdir(self._base_path):
path = os.path.join(self._base_path, k)
if k.startswith(prefix) and os.path.isfile(path):
yield (k[len(self._prefix) :], self.get(k))
class VaultProvider(DictConfig):
def __init__(self, url, path, role, prefix=""):
token = open("/run/secrets/kubernetes.io/serviceaccount/token").read()
self.client = hvac.Client(url=url)
self.auth = self.client.auth_kubernetes(role, token)
secret = self.client.read('secret/{}'.format(path))
config = {str(k): str(v) for k, v in secret["data"].items()}
super(VaultProvider, self).__init__(config, prefix)
class FallbackProvider(ConfigurationProvider):
def __init__(self, providers):
self._providers = list(providers)
def get(self, key):
for provider in self._providers:
value = provider.get(key)
if value is not NOT_PROVIDED:
break
else:
value = NOT_PROVIDED
return value
def iterprefixed(self, prefix):
seen = set()
for provider in self._providers:
for k, v in provider.iterprefixed(prefix):
if k not in seen:
seen.add(k)
yield k, v
EnvConfig = partial(DictConfig, os.environ)