Improve config, tests and docs

Add better support to env variables.
This commit is contained in:
vrde 2016-03-31 11:37:09 +02:00
parent e4d3915533
commit 804365db24
5 changed files with 58 additions and 28 deletions

View File

@ -26,7 +26,7 @@ def run_show_config(args):
# TODO Proposal: remove the "hidden" configuration. Only show config. If
# the system needs to be configured, then display information on how to
# configure the system.
bigchaindb.config_utils.file_config(args.config)
bigchaindb.config_utils.autoconfigure(filename=args.config, force=True)
pprint(bigchaindb.config)

View File

@ -155,20 +155,38 @@ def update_types(config):
reference = bigchaindb.config
def _coerce(current, value):
# Coerce a value to the `current` type.
try:
# First we try to apply current to the value, since it
# might be a function
return current(value)
except TypeError:
# Then we check if current is a list AND if the value
# is a string.
if isinstance(current, list) and isinstance(value, str):
# If so, we use the colon as the separator
return value.split(':')
try:
# If we are here, we should try to apply the type
# of `current` to the value
return type(current)(value)
except TypeError:
# Worst case scenario we return the value itself.
return value
def _update_type(value, path):
ref = reference
current = reference
for elem in path:
ref = ref[elem]
try:
return ref(value)
except TypeError:
try:
return type(ref)(value)
except TypeError:
current = current[elem]
except KeyError:
return value
return _coerce(current, value)
return map_leafs(_update_type, config)
@ -207,6 +225,7 @@ def autoconfigure(filename=None, config=None, force=False):
been initialized."""
if not force and bigchaindb.config.get('CONFIGURED'):
logger.info('System already configured, skipping autoconfiguration')
return
newconfig = env_config(bigchaindb.config)
@ -215,9 +234,10 @@ def autoconfigure(filename=None, config=None, force=False):
newconfig = update(newconfig, config)
try:
newconfig = update(newconfig, file_config())
except FileNotFoundError:
logger.warning('Cannot find your config file.')
# import pdb; pdb.set_trace()
newconfig = update(newconfig, file_config(filename=filename))
except FileNotFoundError as e:
logger.warning('Cannot find config file `%s`.' % e.filename)
dict_config(newconfig)
return newconfig

View File

@ -29,7 +29,6 @@ For more information check the help with `bigchaindb -h`.
# Precedence in reading configuration values
Note that there is a precedence in reading configuration values:
- (**not yet**) command line;
- local config file;
- environment vars;
- default config file (contained in ``bigchaindb.__init__``).
@ -46,29 +45,37 @@ This means that if the default configuration contains an entry that is:
while your local file `local.json` contains:
```
{...
"database": {"host": "whatever"}
"database": {"host": "ec2-xx-xx-xxx-xxx.eu-central-1.compute.amazonaws.com"}
...}
```
and you run this command:
```
$ BIGCHAINDB_DATABASE_HOST=foobar BIGCHAINDB_DATABASE_PORT=42000 bigchaindb -c local.json show-config
$ BIGCHAINDB_DATABASE_HOST=anotherhost.com \
BIGCHAINDB_DATABASE_PORT=4242 \
BIGCHAINDB_KEYRING=pubkey0:pubkey1 \
bigchaindb -c local.json show-config
```
you will get:
```
Cannot find config file `/home/vrde/.bigchaindb`.
INFO:bigchaindb.config_utils:Configuration loaded from `local.json`
{'CONFIGURED': True,
'api_endpoint': 'http://localhost:8008/api/v1',
'consensus_plugin': 'default',
'database': {'host': 'localhost', 'name': 'bigchain', 'port': 28015},
'keypair': {'private': 'Hbqvh...',
'public': '2Bi5NU...'},
'keyring': [],
'database': {'host': 'ec2-xx-xx-xxx-xxx.eu-central-1.compute.amazonaws.com',
'name': 'bigchain',
'port': 4242},
'keypair': {'private': None, 'public': None},
'keyring': ['pubkey0', 'pubkey1'],
'statsd': {'host': 'localhost', 'port': 8125, 'rate': 0.01}}
```
Note that the type of `keyring` is a list. If you want to pass a list as an
environ variable you need to use colon (`:`) as separator.
# List of env variables
```
@ -77,6 +84,7 @@ INFO:bigchaindb.config_utils:Configuration loaded from `local.json`
- BIGCHAINDB_DATABASE_NAME
- BIGCHAINDB_KEYPAIR_PUBLIC
- BIGCHAINDB_KEYPAIR_PRIVATE
- BIGCHAINDB_KEYRING
- BIGCHAINDB_STATSD_HOST
- BIGCHAINDB_STATSD_PORT
- BIGCHAINDB_STATSD_RATE

View File

@ -14,7 +14,7 @@ def mock_run_configure(monkeypatch):
@pytest.fixture
def mock_file_config(monkeypatch):
from bigchaindb import config_utils
monkeypatch.setattr(config_utils, 'file_config', lambda *args: None)
monkeypatch.setattr(config_utils, 'file_config', lambda *args, **kwargs: {})
@pytest.fixture

View File

@ -106,28 +106,30 @@ def test_env_config(monkeypatch):
def test_autoconfigure_read_both_from_file_and_env(monkeypatch):
monkeypatch.setattr('bigchaindb.config_utils.file_config', lambda: {})
monkeypatch.setattr('os.environ', {'BIGCHAINDB_DATABASE_HOST': 'test-host',
'BIGCHAINDB_DATABASE_PORT': '4242'})
file_config = {
'database': {'host': 'test-host'}
}
monkeypatch.setattr('bigchaindb.config_utils.file_config', lambda *args, **kwargs: file_config)
monkeypatch.setattr('os.environ', {'BIGCHAINDB_DATABASE_NAME': 'test-dbname',
'BIGCHAINDB_DATABASE_PORT': '4242',
'BIGCHAINDB_KEYRING': 'pubkey_0:pubkey_1:pubkey_2'})
import bigchaindb
from bigchaindb import config_utils
config_utils.autoconfigure()
assert bigchaindb.config['database']['host'] == 'test-host'
assert bigchaindb.config['database']['port'] == 4242
assert bigchaindb.config == {
'CONFIGURED': True,
'database': {
'host': 'test-host',
'port': 4242,
'name': 'bigchain',
'name': 'test-dbname',
},
'keypair': {
'public': None,
'private': None,
},
'keyring': [],
'keyring': ['pubkey_0', 'pubkey_1', 'pubkey_2'],
'statsd': {
'host': 'localhost',
'port': 8125,