1"""Configuration utilty functions"""
2import logging
3from copy import deepcopy
4from voluptuous import Schema
5from curator.validators import SchemaCheck, config_file
6from curator.utils import ensure_list, get_yaml, prune_nones, test_client_options
7from curator.logtools import LogInfo, Whitelist, Blacklist
8
9def test_config(config):
10    """Test YAML against the schema"""
11    # Get config from yaml file
12    yaml_config = get_yaml(config)
13    # if the file is empty, which is still valid yaml, set as an empty dict
14    yaml_config = {} if not yaml_config else prune_nones(yaml_config)
15    # Voluptuous can't verify the schema of a dict if it doesn't have keys,
16    # so make sure the keys are at least there and are dict()
17    for k in ['client', 'logging']:
18        if k not in yaml_config:
19            yaml_config[k] = {}
20        else:
21            yaml_config[k] = prune_nones(yaml_config[k])
22    return SchemaCheck(
23        yaml_config, config_file.client(), 'Client Configuration', 'full configuration dictionary'
24    ).result()
25
26def set_logging(log_opts):
27    """Configure global logging options"""
28    # Set up logging
29    loginfo = LogInfo(log_opts)
30    logging.root.addHandler(loginfo.handler)
31    logging.root.setLevel(loginfo.numeric_log_level)
32    _ = logging.getLogger('curator.cli')
33    # Set up NullHandler() to handle nested elasticsearch.trace Logger
34    # instance in elasticsearch python client
35    logging.getLogger('elasticsearch.trace').addHandler(logging.NullHandler())
36    if log_opts['blacklist']:
37        for bl_entry in ensure_list(log_opts['blacklist']):
38            for handler in logging.root.handlers:
39                handler.addFilter(Blacklist(bl_entry))
40
41def process_config(yaml_file):
42    """Process yaml_file and return a valid client configuration"""
43    config = test_config(yaml_file)
44    set_logging(config['logging'])
45    test_client_options(config['client'])
46    return config['client']
47
48def password_filter(data):
49    """
50    Return a deepcopy of the dictionary with any password fields hidden
51    """
52    def iterdict(mydict):
53        for key, value in mydict.items():
54            if isinstance(value, dict):
55                iterdict(value)
56            elif key == "password":
57                mydict.update({"password": "REDACTED"})
58        return mydict
59    return iterdict(deepcopy(data))
60