From bd6070e2b02ecb4b6a42649d4f63476106cdeeef Mon Sep 17 00:00:00 2001 From: Alexander Kukushkin Date: Thu, 16 Jun 2016 08:50:44 +0200 Subject: [PATCH] Make patronictl use config.py for loading config_file config.py is not only loading config_file but also can build configuration from environment variables. --- patroni/ctl.py | 23 +++++++++++++++++------ tests/test_ctl.py | 27 ++++++--------------------- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/patroni/ctl.py b/patroni/ctl.py index 499f6563..2352aace 100644 --- a/patroni/ctl.py +++ b/patroni/ctl.py @@ -11,11 +11,13 @@ import os import psycopg2 import random import requests +import sys import time import tzlocal import yaml from click import ClickException +from patroni.config import Config from patroni.dcs import get_dcs as _get_dcs from patroni.exceptions import PatroniException from patroni.postgresql import parseurl @@ -56,14 +58,23 @@ def parse_dcs(dcs): def load_config(path, dcs): logging.debug('Loading configuration from file %s', path) - config = dict() + config = {} + old_argv = list(sys.argv) try: - with open(path, 'rb') as fd: - config = yaml.safe_load(fd) - except (IOError, yaml.YAMLError): - logging.exception('Could not load configuration file') + sys.argv[1] = path + if Config.PATRONI_CONFIG_VARIABLE not in os.environ: + for p in ('PATRONI_RESTAPI_LISTEN', 'PATRONI_POSTGRESQL_DATA_DIR'): + if p not in os.environ: + os.environ[p] = '.' + config = Config().copy() + finally: + sys.argv = old_argv - config.update(parse_dcs(dcs) or parse_dcs(config.get('dcs_api')) or {}) + dcs = parse_dcs(dcs) or parse_dcs(config.get('dcs_api')) or {} + if dcs: + for d in DCS_DEFAULTS: + config.pop(d, None) + config.update(dcs) return config diff --git a/tests/test_ctl.py b/tests/test_ctl.py index eb63e153..8742561a 100644 --- a/tests/test_ctl.py +++ b/tests/test_ctl.py @@ -1,7 +1,7 @@ import etcd import os -import pytest -import requests.exceptions +import requests +import sys import unittest from click.testing import CliRunner @@ -19,29 +19,14 @@ CONFIG_FILE_PATH = './test-ctl.yaml' def test_rw_config(): runner = CliRunner() - config = {'a': 'b'} with runner.isolated_filesystem(): - store_config(config, CONFIG_FILE_PATH + '/dummy') + store_config({'etcd': {'host': 'localhost:2379'}}, CONFIG_FILE_PATH + '/dummy') + sys.argv = ['patronictl.py', ''] + load_config(CONFIG_FILE_PATH + '/dummy', None) + load_config(CONFIG_FILE_PATH + '/dummy', '0.0.0.0') os.remove(CONFIG_FILE_PATH + '/dummy') os.rmdir(CONFIG_FILE_PATH) - with pytest.raises(Exception): - result = load_config(CONFIG_FILE_PATH, None) - assert 'Could not load configuration file' in result.output - - os.mkdir(CONFIG_FILE_PATH) - with pytest.raises(Exception): - store_config(config, CONFIG_FILE_PATH) - - os.rmdir(CONFIG_FILE_PATH) - - store_config(config, CONFIG_FILE_PATH) - load_config(CONFIG_FILE_PATH, None) - load_config(CONFIG_FILE_PATH, '0.0.0.0') - - store_config({'dcs_api': None}, CONFIG_FILE_PATH) - load_config(CONFIG_FILE_PATH, None) - @patch('patroni.ctl.load_config', Mock(return_value={'etcd': {'host': 'localhost:4001'}})) class TestCtl(unittest.TestCase):