Add deep merging when loading component configs
Change-Id: I05428668fefcb62462eccef945e2acc8efa784ff
This commit is contained in:
parent
5a9f70b83f
commit
7d818d2827
|
@ -24,8 +24,7 @@ def get_resource_path(path):
|
|||
return pkg_resources.resource_filename(fuel_ccp.version_info.package, path)
|
||||
|
||||
|
||||
def get_global_parameters(*config_groups):
|
||||
cfg = {}
|
||||
def get_config_paths():
|
||||
components = list(CONF.repositories.names)
|
||||
paths = []
|
||||
# Order does matter. At first we add global defaults.
|
||||
|
@ -37,30 +36,7 @@ def get_global_parameters(*config_groups):
|
|||
paths.append(os.path.join(CONF.repositories.path, component,
|
||||
"service/files/defaults.yaml"))
|
||||
|
||||
for path in paths:
|
||||
if os.path.isfile(path):
|
||||
LOG.debug("Adding parameters from \"%s\"", path)
|
||||
with open(path, "r") as f:
|
||||
data = yaml.load(f)
|
||||
for group in config_groups:
|
||||
cfg.setdefault(group, {})
|
||||
cfg[group].update(data.get(group, {}))
|
||||
else:
|
||||
LOG.debug("\"%s\" not found, skipping", path)
|
||||
|
||||
for group in config_groups:
|
||||
cfg.setdefault(group, {})
|
||||
try:
|
||||
config_group = CONF[group]
|
||||
except KeyError:
|
||||
continue
|
||||
else:
|
||||
cfg[group].update(config_group._items())
|
||||
|
||||
if 'configs' in cfg:
|
||||
cfg['configs']['namespace'] = CONF.kubernetes.namespace
|
||||
|
||||
return cfg
|
||||
return paths
|
||||
|
||||
|
||||
def address(service):
|
||||
|
|
|
@ -100,10 +100,20 @@ def load_component_defaults():
|
|||
from fuel_ccp.common import utils
|
||||
|
||||
sections = ['versions', 'sources', 'configs', 'nodes', 'roles', 'replicas']
|
||||
gp = utils.get_global_parameters(*sections)
|
||||
new_config = _yaml.AttrDict()
|
||||
new_config._merge(gp)
|
||||
new_config = _yaml.AttrDict((k, _yaml.AttrDict()) for k in sections)
|
||||
for path in utils.get_config_paths():
|
||||
if not os.path.exists(path):
|
||||
LOG.debug("\"%s\" not found, skipping", path)
|
||||
continue
|
||||
LOG.debug("Adding parameters from \"%s\"", path)
|
||||
with open(path) as f:
|
||||
data = _yaml.load(f)
|
||||
for section in sections:
|
||||
if section in data:
|
||||
new_config[section]._merge(data[section])
|
||||
|
||||
global _REAL_CONF
|
||||
new_config['configs']['namespace'] = _REAL_CONF.kubernetes.namespace
|
||||
new_config._merge(_REAL_CONF)
|
||||
_REAL_CONF = new_config
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import collections
|
||||
import json
|
||||
import os
|
||||
|
||||
import six
|
||||
|
@ -67,6 +68,16 @@ class AttrDict(object):
|
|||
other_value = AttrDict(other_value)
|
||||
self._dict[key] = other_value
|
||||
|
||||
def _json(self, **kwargs):
|
||||
return JSONEncoder(**kwargs).encode(self)
|
||||
|
||||
|
||||
class JSONEncoder(json.JSONEncoder):
|
||||
def default(self, obj):
|
||||
if not isinstance(obj, AttrDict):
|
||||
return super(self, JSONEncoder).default(obj)
|
||||
return obj._dict
|
||||
|
||||
|
||||
class Loader(yaml.SafeLoader):
|
||||
pass
|
||||
|
|
|
@ -258,9 +258,7 @@ def _push_files_to_workflow(workflow, files):
|
|||
|
||||
|
||||
def _create_globals_configmap(config):
|
||||
data = {
|
||||
templates.GLOBAL_CONFIG: json.dumps(config, sort_keys=True)
|
||||
}
|
||||
data = {templates.GLOBAL_CONFIG: config._json(sort_keys=True)}
|
||||
cm = templates.serialize_configmap(templates.GLOBAL_CONFIG, data)
|
||||
return kubernetes.process_object(cm)
|
||||
|
||||
|
@ -407,7 +405,7 @@ def deploy_components(components_map, components):
|
|||
|
||||
_create_namespace(CONF.configs)
|
||||
|
||||
_create_globals_configmap(CONF.configs._dict)
|
||||
_create_globals_configmap(CONF.configs)
|
||||
start_script_cm = _create_start_script_configmap()
|
||||
configmaps = (start_script_cm,)
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import os
|
||||
|
||||
from jinja2 import exceptions as jinja_exceptions
|
||||
from mock import mock
|
||||
import yaml
|
||||
|
||||
from fuel_ccp.common import utils
|
||||
|
@ -11,9 +10,7 @@ from fuel_ccp.tests import base
|
|||
|
||||
class TestUtils(base.TestCase):
|
||||
|
||||
@mock.patch("fuel_ccp.common.utils.get_global_parameters")
|
||||
def test_get_deploy_components_info_with_default_context(
|
||||
self, get_global_parameters_mock):
|
||||
def test_get_deploy_components_info_with_default_context(self):
|
||||
|
||||
default_params = {
|
||||
"configs": {
|
||||
|
@ -31,15 +28,16 @@ class TestUtils(base.TestCase):
|
|||
}
|
||||
}
|
||||
|
||||
get_global_parameters_mock.return_value = default_params
|
||||
conf = config._yaml.AttrDict()
|
||||
conf._merge(default_params)
|
||||
conf._merge(config._REAL_CONF)
|
||||
config._REAL_CONF = conf
|
||||
|
||||
base_dir = os.path.dirname(__file__)
|
||||
|
||||
self.conf.repositories.path = os.path.join(base_dir, "test_repo_dir")
|
||||
self.conf.repositories.names = ["component"]
|
||||
|
||||
config.load_component_defaults()
|
||||
|
||||
res = (
|
||||
utils.get_deploy_components_info()["keystone"]["service_content"]
|
||||
)
|
||||
|
@ -50,9 +48,7 @@ class TestUtils(base.TestCase):
|
|||
|
||||
self.assertDictEqual(expected, res)
|
||||
|
||||
@mock.patch("fuel_ccp.common.utils.get_global_parameters")
|
||||
def test_get_deploy_components_info_with_custom_context(
|
||||
self, get_global_parameters_mock):
|
||||
def test_get_deploy_components_info_with_custom_context(self):
|
||||
|
||||
custom_params = {
|
||||
"configs": {
|
||||
|
@ -70,6 +66,10 @@ class TestUtils(base.TestCase):
|
|||
}
|
||||
}
|
||||
|
||||
conf = config._yaml.AttrDict()
|
||||
conf._merge(custom_params)
|
||||
conf._merge(config._REAL_CONF)
|
||||
config._REAL_CONF = conf
|
||||
base_dir = os.path.dirname(__file__)
|
||||
|
||||
self.conf.repositories.path = os.path.join(base_dir, "test_repo_dir")
|
||||
|
@ -87,9 +87,7 @@ class TestUtils(base.TestCase):
|
|||
|
||||
self.assertDictEqual(expected, res)
|
||||
|
||||
@mock.patch("fuel_ccp.common.utils.get_global_parameters")
|
||||
def test_get_deploy_components_info_with_not_enough_context(
|
||||
self, get_global_parameters_mock):
|
||||
def test_get_deploy_components_info_with_not_enough_context(self):
|
||||
|
||||
default_params = {
|
||||
"configs": {
|
||||
|
@ -105,7 +103,10 @@ class TestUtils(base.TestCase):
|
|||
}
|
||||
}
|
||||
|
||||
get_global_parameters_mock.return_value = default_params
|
||||
conf = config._yaml.AttrDict()
|
||||
conf._merge(default_params)
|
||||
conf._merge(config._REAL_CONF)
|
||||
config._REAL_CONF = conf
|
||||
|
||||
base_dir = os.path.dirname(__file__)
|
||||
|
||||
|
|
|
@ -130,3 +130,10 @@ class TestLoadDump(testscenarios.WithScenarios, base.TestCase):
|
|||
stream = io.StringIO()
|
||||
_yaml.dump(obj, stream)
|
||||
self.assertEqual(self.yaml, stream.getvalue())
|
||||
|
||||
|
||||
class TestAttrDict(base.TestCase):
|
||||
def test_json(self):
|
||||
source = _yaml.AttrDict({'a': 1, 'b': _yaml.AttrDict({'c': 2})})
|
||||
res = source._json(sort_keys=True)
|
||||
self.assertEqual(res, '{"a": 1, "b": {"c": 2}}')
|
||||
|
|
Loading…
Reference in New Issue