diff options
Diffstat (limited to 'policyhandler/config.py')
-rw-r--r-- | policyhandler/config.py | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/policyhandler/config.py b/policyhandler/config.py new file mode 100644 index 0000000..ea10167 --- /dev/null +++ b/policyhandler/config.py @@ -0,0 +1,194 @@ +"""read and use the config""" + +# org.onap.dcae +# ================================================================================ +# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. + +import os +import json +import copy +import base64 +import logging + +from .discovery import DiscoveryClient +from .onap.crypto import Cipher + +logging.basicConfig( + filename='logs/policy_handler.log', \ + format='%(asctime)s.%(msecs)03d %(levelname)+8s ' + \ + '%(threadName)s %(name)s.%(funcName)s: %(message)s', \ + datefmt='%Y%m%d_%H%M%S', level=logging.DEBUG) + +class Config(object): + """main config of the application""" + CONFIG_FILE_PATH = "etc/config.json" + LOGGER_CONFIG_FILE_PATH = "etc/common_logger.config" + UPLOAD_CONFIG_FILE_PATH = "etc_upload/config.json" + SERVICE_NAME_POLICY_HANDLER = "policy_handler" + FIELD_SYSTEM = "system" + FIELD_CONFIG_PWD = "config_pwd" + FIELD_WSERVICE_PORT = "wservice_port" + FIELD_POLICY_ENGINE = "policy_engine" + CRYPTED_FIELDS = ["ClientAuth", "Authorization", "config_pwd"] + config_pwd = "donottell150&$" + wservice_port = 25577 + _logger = logging.getLogger("policy_handler.config") + config = None + + @staticmethod + def merge(new_config): + """merge the new_config into current config - override the values""" + if not new_config: + return + + if not Config.config: + Config.config = new_config + return + + new_config = copy.deepcopy(new_config) + Config.config.update(new_config) + + @staticmethod + def decrypt_secret_value(field_name, field_value): + """decrypt the value of the secret field""" + if field_name in Config.CRYPTED_FIELDS and isinstance(field_value, basestring): + return Cipher.decrypt(Config.config_pwd, field_value) + return field_value + + @staticmethod + def encrypt_secret_value(field_name, field_value): + """encrypt the value of the secret field""" + if field_name in Config.CRYPTED_FIELDS and isinstance(field_value, basestring): + return Cipher.encrypt(Config.config_pwd, field_value) + return field_value + + @staticmethod + def update_tree_leaves(tree_element, func_on_leaf): + """traverse through json tree and apply function func_on_leaf to each leaf""" + if not tree_element: + return + + for field_name in tree_element: + field_value = func_on_leaf(field_name, tree_element[field_name]) + tree_element[field_name] = field_value + if isinstance(field_value, dict): + Config.update_tree_leaves(field_value, func_on_leaf) + + @staticmethod + def get_system_name(): + """find the name of the policy-handler system + to be used as the key in consul-kv for config of policy-handler + """ + system_name = None + if Config.config: + system_name = Config.config.get(Config.FIELD_SYSTEM) + + return system_name or Config.SERVICE_NAME_POLICY_HANDLER + + @staticmethod + def discover(): + """bring and merge the config settings from the discovery service""" + discovery_key = Config.get_system_name() + new_config = DiscoveryClient.get_value(discovery_key) + + if not new_config or not isinstance(new_config, dict): + Config._logger.warn("unexpected config from discovery: %s", new_config) + return + + Config._logger.debug("loaded config from discovery(%s): %s", \ + discovery_key, json.dumps(new_config)) + Config.update_tree_leaves(new_config, Config.decrypt_secret_value) + Config._logger.debug("config before merge from discovery: %s", json.dumps(Config.config)) + Config.merge(new_config) + Config._logger.debug("merged config from discovery: %s", json.dumps(Config.config)) + + @staticmethod + def upload_to_discovery(): + """upload the current config settings to the discovery service""" + if not Config.config or not isinstance(Config.config, dict): + Config._logger.error("unexpected config: %s", Config.config) + return + + latest_config = copy.deepcopy(Config.config) + Config.update_tree_leaves(latest_config, Config.encrypt_secret_value) + + discovery_key = Config.get_system_name() + latest_config = json.dumps(latest_config) + DiscoveryClient.put_kv(discovery_key, latest_config) + Config._logger.debug("uploaded config to discovery(%s): %s", \ + discovery_key, latest_config) + + @staticmethod + def load_from_file(file_path=None): + """read and store the config from config file""" + if not file_path: + file_path = Config.CONFIG_FILE_PATH + + loaded_config = None + if os.access(file_path, os.R_OK): + with open(file_path, 'r') as config_json: + loaded_config = json.load(config_json) + + if not loaded_config: + Config._logger.info("config not loaded from file: %s", file_path) + return + + Config._logger.info("config loaded from file: %s", file_path) + logging_config = loaded_config.get("logging") + if logging_config: + logging.config.dictConfig(logging_config) + + Config.config_pwd = loaded_config.get(Config.FIELD_CONFIG_PWD, Config.config_pwd) + Config.wservice_port = loaded_config.get(Config.FIELD_WSERVICE_PORT, Config.wservice_port) + Config.merge(loaded_config.get(Config.SERVICE_NAME_POLICY_HANDLER)) + return True + +class PolicyEngineConfig(object): + """main config of the application""" + # PATH_TO_PROPERTIES = r'logs/policy_engine.properties' + PATH_TO_PROPERTIES = r'tmp/policy_engine.properties' + PYPDP_URL = "PYPDP_URL = {0}{1}, {2}, {3}\n" + CLIENT_ID = "CLIENT_ID = {0}\n" + CLIENT_KEY = "CLIENT_KEY = {0}\n" + ENVIRONMENT = "ENVIRONMENT = {0}\n" + _logger = logging.getLogger("policy_handler.pe_config") + + @staticmethod + def save_to_file(): + """create the policy_engine.properties for policy-engine client""" + file_path = PolicyEngineConfig.PATH_TO_PROPERTIES + + try: + config = Config.config[Config.FIELD_POLICY_ENGINE] + headers = config["headers"] + client_parts = base64.b64decode(headers["ClientAuth"].split()[1]).split(":") + auth_parts = base64.b64decode(headers["Authorization"].split()[1]).split(":") + + props = PolicyEngineConfig.PYPDP_URL.format(config["url"], config["path_pdp"], + auth_parts[0], auth_parts[1]) + props += PolicyEngineConfig.CLIENT_ID.format(client_parts[0]) + props += PolicyEngineConfig.CLIENT_KEY.format(base64.b64encode(client_parts[1])) + props += PolicyEngineConfig.ENVIRONMENT.format(headers["Environment"]) + + with open(file_path, 'w') as prp_file: + prp_file.write(props) + PolicyEngineConfig._logger.info("created %s", file_path) + except IOError: + PolicyEngineConfig._logger.error("failed to save to %s", file_path) + except KeyError: + PolicyEngineConfig._logger.error("unexpected config for %s", Config.FIELD_POLICY_ENGINE) |