Merge "Handle nodes configs and merge them with globals"
This commit is contained in:
commit
f5192e3f71
|
@ -6,6 +6,7 @@ import functools
|
|||
import logging
|
||||
import os
|
||||
import pwd
|
||||
import re
|
||||
import signal
|
||||
import socket
|
||||
import subprocess
|
||||
|
@ -23,6 +24,7 @@ import six
|
|||
|
||||
VARIABLES = {}
|
||||
GLOBALS_PATH = '/etc/ccp/globals/globals.json'
|
||||
NODES_CONFIG_PATH = '/etc/ccp/nodes-config/nodes-config.json'
|
||||
META_FILE = "/etc/ccp/meta/meta.json"
|
||||
CACERT = "/opt/ccp/etc/tls/ca.pem"
|
||||
WORKFLOW_PATH_TEMPLATE = '/etc/ccp/role/%s.json'
|
||||
|
@ -461,10 +463,43 @@ def get_workflow(role_name):
|
|||
return workflow
|
||||
|
||||
|
||||
def find_node_config_keys(nodes_config):
|
||||
current_node = os.environ['CCP_NODE_NAME']
|
||||
config_keys = []
|
||||
for node in sorted(nodes_config):
|
||||
if re.match(node, current_node):
|
||||
config_keys.append(node)
|
||||
return config_keys
|
||||
|
||||
|
||||
def merge_nodes_configs(variables, node_config):
|
||||
for k, v in node_config.items():
|
||||
if k not in variables:
|
||||
variables[k] = v
|
||||
continue
|
||||
if isinstance(v, dict) and isinstance(variables[k], dict):
|
||||
merge_nodes_configs(variables[k], v)
|
||||
else:
|
||||
variables[k] = v
|
||||
|
||||
|
||||
def get_variables(role_name):
|
||||
LOG.info("Getting global variables from %s", GLOBALS_PATH)
|
||||
with open(GLOBALS_PATH) as f:
|
||||
variables = json.load(f)
|
||||
LOG.info("Getting nodes variables from %s", NODES_CONFIG_PATH)
|
||||
with open(NODES_CONFIG_PATH) as f:
|
||||
nodes_config = json.load(f)
|
||||
config_keys = find_node_config_keys(nodes_config)
|
||||
if config_keys:
|
||||
# merge configs for all keys and get final node_configs for this node.
|
||||
# Note that if there several override configs, variables will be
|
||||
# override with order of list this configs.
|
||||
node_config = nodes_config[config_keys.pop(0)]
|
||||
for key in config_keys:
|
||||
merge_nodes_configs(node_config, nodes_config[key])
|
||||
# and then merge variables with final node_config.
|
||||
merge_nodes_configs(variables, node_config)
|
||||
if os.path.exists(META_FILE):
|
||||
LOG.info("Getting meta information from %s", META_FILE)
|
||||
with open(META_FILE) as f:
|
||||
|
|
|
@ -85,9 +85,7 @@ class TestGetVariables(base.TestCase):
|
|||
@mock.patch('json.load')
|
||||
@mock.patch('fuel_ccp_entrypoint.start_script.create_network_topology')
|
||||
def test_get_variables(self, m_create_network_topology, m_json_load):
|
||||
def side_effect(file_name):
|
||||
return {'glob': 'glob_val'}
|
||||
m_json_load.return_value = {'glob': 'glob_val'}
|
||||
m_json_load.side_effect = [{'glob': 'glob_val'}, {}]
|
||||
m_create_network_topology.return_value = 'network_topology'
|
||||
r_value = start_script.get_variables('role')
|
||||
e_value = {
|
||||
|
@ -99,6 +97,71 @@ class TestGetVariables(base.TestCase):
|
|||
}
|
||||
self.assertEqual(r_value, e_value)
|
||||
|
||||
@mock.patch('six.moves.builtins.open', mock.mock_open())
|
||||
@mock.patch('json.load')
|
||||
@mock.patch('fuel_ccp_entrypoint.start_script.create_network_topology')
|
||||
def test_get_variables_with_node_config(self, m_create_network_topology,
|
||||
m_json_load):
|
||||
m_json_load.side_effect = [
|
||||
# globals
|
||||
{
|
||||
'a': {
|
||||
'b': {
|
||||
'c': ['d', 'e', 'f'],
|
||||
'g': 'h',
|
||||
},
|
||||
'i': ['j', 'k'],
|
||||
'l': 'm'
|
||||
},
|
||||
'n': ['o', 'p', 'q'],
|
||||
'r': 's'
|
||||
},
|
||||
# nodes configs
|
||||
{
|
||||
'node[1-3]': {
|
||||
'a': {
|
||||
'b': {
|
||||
'c': ['e', 'f', 't'],
|
||||
'u': 'v'
|
||||
},
|
||||
'w': {
|
||||
'x': 'y'
|
||||
}
|
||||
},
|
||||
'n': ['o', 'p'],
|
||||
'z': 'NaN'
|
||||
},
|
||||
'node[1-2]': {
|
||||
'aa': {'ab': 'ac'},
|
||||
'r': {'ad': ['ae', 'af', 'ag']}
|
||||
|
||||
}
|
||||
}
|
||||
]
|
||||
m_create_network_topology.return_value = 'network_topology'
|
||||
actual = start_script.get_variables('fake_role')
|
||||
expected = {
|
||||
'role_name': 'fake_role',
|
||||
'network_topology': 'network_topology',
|
||||
'node_name': 'node1',
|
||||
'pod_name': 'pod1',
|
||||
'a': {
|
||||
'b': {
|
||||
'c': ['e', 'f', 't'],
|
||||
'g': 'h',
|
||||
'u': 'v'
|
||||
},
|
||||
'w': {'x': 'y'},
|
||||
'i': ['j', 'k'],
|
||||
'l': 'm'
|
||||
},
|
||||
'n': ['o', 'p'],
|
||||
'r': {'ad': ['ae', 'af', 'ag']},
|
||||
'z': 'NaN',
|
||||
'aa': {'ab': 'ac'},
|
||||
}
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
|
||||
class TestRetry(base.TestCase):
|
||||
def setUp(self):
|
||||
|
|
Loading…
Reference in New Issue