From fd72e102b0d6b6b62f72a06ad950e7959c54d7ef Mon Sep 17 00:00:00 2001 From: ahothan Date: Mon, 28 Aug 2017 08:04:52 -0700 Subject: NFVBENCH-11 Cannot override extra_specs in flavor using -c Add a whitelist for keys that can't be verified Change-Id: I8d56cb850fb133eec0097ae80f6ee5f827e651c6 Signed-off-by: ahothan --- nfvbench/config.py | 46 +++++++++++++++++++++++----------------------- nfvbench/nfvbench.py | 6 ++++-- test/test_nfvbench.py | 8 +++++++- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/nfvbench/config.py b/nfvbench/config.py index 915b42c..2ed726d 100644 --- a/nfvbench/config.py +++ b/nfvbench/config.py @@ -18,7 +18,7 @@ from log import LOG import yaml -def config_load(file_name, from_cfg=None): +def config_load(file_name, from_cfg=None, whitelist_keys=[]): """Load a yaml file into a config dict, merge with from_cfg if not None The config file content taking precedence in case of duplicate """ @@ -31,13 +31,13 @@ def config_load(file_name, from_cfg=None): .format(file_name)) if from_cfg: - _validate_config(cfg, from_cfg) + _validate_config(cfg, from_cfg, whitelist_keys) cfg = from_cfg + cfg return cfg -def config_loads(cfg_text, from_cfg=None): +def config_loads(cfg_text, from_cfg=None, whitelist_keys=[]): """Same as config_load but load from a string """ try: @@ -46,30 +46,30 @@ def config_loads(cfg_text, from_cfg=None): # empty string cfg = AttrDict() if from_cfg: - _validate_config(cfg, from_cfg) + _validate_config(cfg, from_cfg, whitelist_keys) return from_cfg + cfg return cfg +def _validate_config(subset, superset, whitelist_keys): + def get_err_config(subset, superset): + result = {} + for k, v in subset.items(): + if k not in whitelist_keys: + if k not in superset: + result.update({k: v}) + elif v is not None and superset[k] is not None: + if not isinstance(v, type(superset[k])): + result.update({k: v}) + continue + if isinstance(v, dict): + res = get_err_config(v, superset[k]) + if res: + result.update({k: res}) + if not result: + return None + return result -def _get_err_config(subset, superset): - result = {} - for k, v in subset.items(): - if k not in superset: - result.update({k: v}) - elif v is not None and superset[k] is not None: - if not isinstance(v, type(superset[k])): - result.update({k: v}) - continue - if isinstance(v, dict): - res = _get_err_config(v, superset[k]) - if res: - result.update({k: res}) - if not result: - return None - return result - -def _validate_config(subset, superset): - err_cfg = _get_err_config(subset, superset) + err_cfg = get_err_config(subset, superset) if err_cfg: err_msg = 'The provided configuration has unknown options or values with invalid type: '\ + str(err_cfg) diff --git a/nfvbench/nfvbench.py b/nfvbench/nfvbench.py index e9594d5..b36d328 100644 --- a/nfvbench/nfvbench.py +++ b/nfvbench/nfvbench.py @@ -461,15 +461,17 @@ def main(): config.name = '' if opts.config: + # do not check extra_specs in flavor as it can contain any key/value pairs + whitelist_keys = ['extra_specs'] # override default config options with start config at path parsed from CLI # check if it is an inline yaml/json config or a file name if os.path.isfile(opts.config): LOG.info('Loading configuration file: ' + opts.config) - config = config_load(opts.config, config) + config = config_load(opts.config, config, whitelist_keys) config.name = os.path.basename(opts.config) else: LOG.info('Loading configuration string: ' + opts.config) - config = config_loads(opts.config, config) + config = config_loads(opts.config, config, whitelist_keys) # traffic profile override options override_custom_traffic(config, opts.frame_sizes, opts.unidir) diff --git a/test/test_nfvbench.py b/test/test_nfvbench.py index 1d985b8..ff4625b 100644 --- a/test/test_nfvbench.py +++ b/test/test_nfvbench.py @@ -673,7 +673,13 @@ def test_config(): expected = fail_pair[0] assert expected in e_info.value.message - + # whitelist keys + flavor = {'flavor': {'vcpus': 2, 'ram': 8192, 'disk': 0, + 'extra_specs': {'hw:cpu_policy': 'dedicated'}}} + new_flavor = {'flavor': {'vcpus': 2, 'ram': 8192, 'disk': 0, + 'extra_specs': {'hw:cpu_policy': 'dedicated', 'hw:numa_nodes': 2}}} + assert(config_loads("{'flavor': {'extra_specs': {'hw:numa_nodes': 2}}}", flavor, + whitelist_keys=['alpha', 'extra_specs']) == new_flavor) def test_fluentd(): logger = logging.getLogger('fluent-logger') -- cgit 1.2.3-korg