4
4
import rsa
5
5
import yaml
6
6
7
+ from docker_registry .core import compat
7
8
from docker_registry .core import exceptions
8
9
9
10
10
11
class Config (object ):
12
+ """A simple config class that:
13
+ * gives properties access through either items or attributes
14
+ * enforce types (thanks to yaml)
15
+ * interpolate from ENV
16
+ """
11
17
12
- def __init__ (self , config ):
13
- self ._config = config
18
+ def __init__ (self , config = '' ):
19
+ try :
20
+ # Config is kept as-is...
21
+ self ._config = config
22
+ # ... save Strings, that are yaml loaded
23
+ if isinstance (config , compat .basestring ):
24
+ self ._config = yaml .load (config )
25
+ except Exception as e :
26
+ # Failed yaml loading? Stop here!
27
+ raise exceptions .ConfigError (
28
+ 'Config is not valid yaml (%s): \n %s' % (e , config ))
14
29
15
30
def __repr__ (self ):
16
31
return repr (self ._config )
17
32
33
+ def __dir__ (self ):
34
+ return self ._config .keys ()
35
+
36
+ # Python 2.6 and below need this
37
+ @property
38
+ def __members__ (self ):
39
+ return self ._config .keys ()
40
+
41
+ @property
42
+ def __methods__ (self ):
43
+ return []
44
+
18
45
def __getattr__ (self , key ):
19
- if key in self ._config :
20
- return self ._config [key ]
21
-
22
- def get (self , * args , ** kwargs ):
23
- return self ._config .get (* args , ** kwargs )
24
-
25
-
26
- def _walk_object (obj , callback ):
27
- if not hasattr (obj , '__iter__' ):
28
- return callback (obj )
29
- obj_new = {}
30
- if isinstance (obj , dict ):
31
- for i , value in obj .iteritems ():
32
- value = _walk_object (value , callback )
33
- if value or value == '' :
34
- obj_new [i ] = value
35
- return obj_new
36
- for i , value in enumerate (obj ):
37
- value = _walk_object (value , callback )
38
- if value or value == '' :
39
- obj_new [i ] = value
40
- return obj_new
41
-
42
-
43
- def convert_env_vars (config ):
44
- def _replace_env (s ):
45
- if isinstance (s , basestring ) and s .startswith ('_env:' ):
46
- parts = s .split (':' , 2 )
47
- varname = parts [1 ]
48
- vardefault = None if len (parts ) < 3 else parts [2 ]
49
- return os .environ .get (varname , vardefault )
50
- return s
51
-
52
- return _walk_object (config , _replace_env )
46
+ # Unset keys return None
47
+ if key not in self ._config :
48
+ return None
49
+ # raise exceptions.ConfigError("No such attribute: %s" % key)
50
+ result = self ._config [key ]
51
+ # Dicts are rewrapped inside a Config object
52
+ if isinstance (result , dict ):
53
+ return Config (result )
54
+ # Strings starting with `_env:' get evaluated
55
+ if isinstance (
56
+ result , compat .basestring ) and result .startswith ('_env:' ):
57
+ result = result .split (':' , 2 )
58
+ varname = result [1 ]
59
+ vardefault = '' if len (result ) < 3 else result [2 ]
60
+ try :
61
+ result = yaml .load (os .environ .get (varname , vardefault ))
62
+ except Exception as e :
63
+ raise exceptions .ConfigError (
64
+ 'Config `%s` (value: `%s`) is not valid: %s' % (
65
+ varname , e , result ))
66
+ return result
67
+
68
+ def __getitem__ (self , key ):
69
+ return getattr (self , key )
70
+
71
+ def __contains__ (self , key ):
72
+ return key in self ._config
53
73
54
74
55
75
_config = None
@@ -59,8 +79,10 @@ def load():
59
79
global _config
60
80
if _config is not None :
61
81
return _config
62
- data = None
82
+
83
+ flavor = os .environ .get ('SETTINGS_FLAVOR' , 'dev' )
63
84
config_path = os .environ .get ('DOCKER_REGISTRY_CONFIG' , 'config.yml' )
85
+
64
86
if not os .path .isabs (config_path ):
65
87
config_path = os .path .join (os .path .dirname (__file__ ), '../../' ,
66
88
'config' , config_path )
@@ -70,29 +92,25 @@ def load():
70
92
raise exceptions .FileNotFoundError (
71
93
'Heads-up! File is missing: %s' % config_path )
72
94
73
- try :
74
- data = yaml .load (f )
75
- except Exception :
76
- raise exceptions .ConfigError (
77
- 'Config file (%s) is not valid yaml' % config_path )
95
+ _config = Config (f .read ())
96
+ if flavor :
97
+ _config = _config [flavor ]
98
+ _config .flavor = flavor
78
99
79
- config = data .get ('common' , {})
80
- flavor = os .environ .get ('SETTINGS_FLAVOR' , 'dev' )
81
- config .update (data .get (flavor , {}))
82
- config ['flavor' ] = flavor
83
- config = convert_env_vars (config )
84
- if 'privileged_key' in config :
100
+ if _config .privileged_key :
85
101
try :
86
- f = open (config [ ' privileged_key' ] )
102
+ f = open (_config . privileged_key )
87
103
except Exception :
88
104
raise exceptions .FileNotFoundError (
89
- 'Heads-up! File is missing: %s' % config [ ' privileged_key' ] )
105
+ 'Heads-up! File is missing: %s' % _config . privileged_key )
90
106
91
107
try :
92
- config [ ' privileged_key' ] = rsa .PublicKey .load_pkcs1 (f .read ())
108
+ _config . privileged_key = rsa .PublicKey .load_pkcs1 (f .read ())
93
109
except Exception :
94
110
raise exceptions .ConfigError (
95
- 'Key at %s is not a valid RSA key' % config ['privileged_key' ])
111
+ 'Key at %s is not a valid RSA key' % _config .privileged_key )
112
+
113
+ if _config .index_endpoint :
114
+ _config .index_endpoint = _config .index_endpoint .strip ('/' )
96
115
97
- _config = Config (config )
98
116
return _config
0 commit comments