User can differentiate configs for nodes and roles

* override.yaml file fan be used to configure configs for a particular
  nodes/roles
* Configs for all nodes should be placed in repo root directory
* Parameters in config files in repo root directory will be overridden by
  parameters for roles in corresponding file. Parameters for role will be
  overridden by node-specific parameters.

Change-Id: Ic182302526a944f0f0943f675751a65728685111
This commit is contained in:
Ukov Dmitry 2016-08-15 16:25:38 +03:00
parent 19bff61093
commit ed9b6d5fb1
2 changed files with 55 additions and 16 deletions

View File

@ -9,7 +9,7 @@ from nailgun.extensions import BasePipeline
from fuel_external_git import handlers
from fuel_external_git.objects import GitRepo
from fuel_external_git import const
from fuel_external_git.openstack_config import OpenStackConfig
from fuel_external_git import utils
class OpenStackConfigPipeline(BasePipeline):
@ -34,11 +34,12 @@ class OpenStackConfigPipeline(BasePipeline):
GitRepo.checkout(repo)
repo_path = os.path.join(const.REPOS_DIR, repo.repo_name)
global_config = utils.get_config_hash(repo_path)
# Read config for overrides
# TODO(dukov) We need to ba able to differentiate configs.
# Overrides file should contain following mapping
# - role:config_file
# - node_id:config_file
# - role:config_file_dir
# - node_id:config_file_dir
# Config options from files for roles should override global
# configs (placed in repo root).
# Config options from files for nodes should override global
@ -46,20 +47,30 @@ class OpenStackConfigPipeline(BasePipeline):
overrides_file = os.path.join(repo_path, 'overrides.yaml')
if os.path.exists(overrides_file):
overrides = yaml.load(open(overrides_file))
else:
overrides = {}
config_files = [conf for conf in os.listdir(repo_path)
if conf.endswith('conf')]
override_configs = {}
# ent = roles|nodes
for ent, override in overrides.items():
override_configs[ent] = {}
# key = role_name|node_id
for key, path in override.items():
file_dir = os.path.join(repo_path, path)
override_configs[ent][key] = utils.get_config_hash(file_dir)
adv_config = {}
for conf_file in config_files:
# TODO(dukov) Config resource name may differ from file name
config = OpenStackConfig(os.path.join(repo_path, conf_file),
conf_file)
adv_config[config.config_name] = config.to_config_dict()
if adv_config != {}:
for node_config in data:
node_config['configuration'] = adv_config
logger.info(adv_config)
for node_config in data:
roles = node_config['roles']
uid = node_config['uid']
for role in roles:
utils.deep_merge(global_config,
override_configs['roles'].get(role, {}))
utils.deep_merge(global_config,
override_configs['nodes'].get(uid, {}))
node_config['configuration'] = global_config
logger.debug("Node config from git {}".format(global_config))
return data

View File

@ -0,0 +1,28 @@
import os
from nailgun.logger import logger
from fuel_external_git.openstack_config import OpenStackConfig
def get_config_hash(file_dir):
res = {}
if not os.path.isdir(file_dir):
logger.debug(
"Directory {} not found. Returning emty dict".format(file_dir))
return {}
conf_files = [conf for conf in os.listdir(file_dir)
if conf.endswith('conf')]
for conf_file in conf_files:
# TODO(dukov) Config resource name may differ from file name
config = OpenStackConfig(os.path.join(file_dir, conf_file), conf_file)
res[config.config_name] = config.to_config_dict()
return res
def deep_merge(dct, merge_dct):
for k, v in merge_dct.iteritems():
if (k in dct and isinstance(dct[k], dict)):
deep_merge(dct[k], merge_dct[k])
else:
dct[k] = merge_dct[k]