NFVBENCH-153 Add support for python3
[nfvbench.git] / nfvbench / config.py
1 # Copyright 2016 Cisco Systems, Inc.  All rights reserved.
2 #
3 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
4 #    not use this file except in compliance with the License. You may obtain
5 #    a copy of the License at
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
9 #    Unless required by applicable law or agreed to in writing, software
10 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 #    License for the specific language governing permissions and limitations
13 #    under the License.
14 #
15
16 from attrdict import AttrDict
17 import yaml
18
19 from .log import LOG
20
21 def config_load(file_name, from_cfg=None, whitelist_keys=None):
22     """Load a yaml file into a config dict, merge with from_cfg if not None
23     The config file content taking precedence in case of duplicate
24     """
25     try:
26         with open(file_name) as fileobj:
27             cfg = AttrDict(yaml.safe_load(fileobj))
28     except IOError:
29         raise Exception("Configuration file at '{}' was not found. Please use correct path "
30                         "and verify it is visible to container if you run nfvbench in container."
31                         .format(file_name))
32
33     if from_cfg:
34         if not whitelist_keys:
35             whitelist_keys = []
36         _validate_config(cfg, from_cfg, whitelist_keys)
37         cfg = from_cfg + cfg
38
39     return cfg
40
41
42 def config_loads(cfg_text, from_cfg=None, whitelist_keys=None):
43     """Same as config_load but load from a string
44     """
45     try:
46         cfg = AttrDict(yaml.safe_load(cfg_text))
47     except TypeError:
48         # empty string
49         cfg = AttrDict()
50     except ValueError as e:
51         # In case of wrong path or file not readable or string not well formatted
52         LOG.error("String %s is not well formatted. Please verify your yaml/json string. "
53                   "If string is a file path, file was not found. Please use correct path and "
54                   "verify it is visible to container if you run nfvbench in container.", cfg_text)
55         raise Exception(e)
56     if from_cfg:
57         if not whitelist_keys:
58             whitelist_keys = []
59         _validate_config(cfg, from_cfg, whitelist_keys)
60         return from_cfg + cfg
61     return cfg
62
63
64 def _validate_config(subset, superset, whitelist_keys):
65     def get_err_config(subset, superset):
66         result = {}
67         for k, v in list(subset.items()):
68             if k not in whitelist_keys:
69                 if k not in superset:
70                     result.update({k: v})
71                 elif v is not None and superset[k] is not None:
72                     if not isinstance(v, type(superset[k])):
73                         result.update({k: v})
74                         continue
75                 if isinstance(v, dict):
76                     res = get_err_config(v, superset[k])
77                     if res:
78                         result.update({k: res})
79         if not result:
80             return None
81         return result
82
83     err_cfg = get_err_config(subset, superset)
84     if err_cfg:
85         err_msg = 'The provided configuration has unknown options or values with invalid type: '\
86                   + str(err_cfg)
87         LOG.error(err_msg)
88         raise Exception(err_msg)