def get_settings(hostname: Optional[str] = None): """Get settings to use for device matching hostname or global settings if no hostname is specified.""" with open('/etc/cnaas-nms/repository.yml', 'r') as db_file: repo_config = yaml.safe_load(db_file) local_repo_path = repo_config['settings_local'] try: verify_dir_structure(local_repo_path, DIR_STRUCTURE) except VerifyPathException as e: logger.exception( "Exception when verifying settings repository directory structure") raise e # 1. Get CNaaS-NMS default settings data_dir = pkg_resources.resource_filename(__name__, 'data') with open(os.path.join(data_dir, 'default_settings.yml'), 'r') as f_default_settings: default_settings: dict = yaml.safe_load(f_default_settings) # 2. Get settings repo global settings with open(get_setting_filename(local_repo_path, ['global', 'base_system.yml']), 'r')\ as f_g_base_sys: global_settings: dict = yaml.safe_load(f_g_base_sys) (merged_settings, merged_settings_metadata) = \ merge_dict_origin(default_settings, global_settings, 'default', 'global') print(f_root(**merged_settings).dict()) print(merged_settings_metadata)
def check_settings_syntax(settings_dict: dict, settings_metadata_dict: dict): """Verify settings syntax and return a somewhat helpful error message. Raises: SettingsSyntaxError """ try: f_root(**settings_dict) except ValidationError as e: msg = '' for error in e.errors(): loc = error['loc'] error_msg = "Validation error for setting {}, bad value: {} (value origin: {})\n".format( '->'.join(str(x) for x in loc), get_pydantic_error_value(settings_dict, loc), settings_metadata_dict[loc[0]]) error_msg += "Message: {}\n".format(error['msg']) msg += error_msg logger.error(msg) raise SettingsSyntaxError(msg)
def get_settings(hostname: Optional[str] = None, device_type: Optional[DeviceType] = None): """Get settings to use for device matching hostname or global settings if no hostname is specified.""" with open('/etc/cnaas-nms/repository.yml', 'r') as repo_file: repo_config = yaml.safe_load(repo_file) local_repo_path = repo_config['settings_local'] try: verify_dir_structure(local_repo_path, DIR_STRUCTURE) except VerifyPathException as e: logger.exception( "Exception when verifying settings repository directory structure") raise e # 1. Get CNaaS-NMS default settings data_dir = pkg_resources.resource_filename(__name__, 'data') with open(os.path.join(data_dir, 'default_settings.yml'), 'r') as f_default_settings: settings: dict = yaml.safe_load(f_default_settings) settings_origin = {} for k in settings.keys(): settings_origin[k] = 'default' # 2. Get settings repo global settings settings, settings_origin = read_settings(local_repo_path, ['global', 'base_system.yml'], 'global', settings, settings_origin) # 3. Get settings from special fabric classification (dist + core) if device_type and (device_type == DeviceType.DIST or device_type == DeviceType.CORE): settings, settings_origin = read_settings( local_repo_path, ['fabric', 'base_system.yml'], 'fabric', settings, settings_origin) # 4. Get settings repo device type settings if device_type: settings, settings_origin = read_settings( local_repo_path, [device_type.name.lower(), 'base_system.yml'], 'devicetype', settings, settings_origin) # 5. Get settings repo device specific settings if hostname: if os.path.isdir(os.path.join(local_repo_path, 'devices', hostname)): settings, settings_origin = read_settings( local_repo_path, ['devices', hostname, 'base_system.yml'], 'device', settings, settings_origin) # Verify syntax check_settings_syntax(settings, settings_origin) return f_root(**settings).dict(), settings_origin
def check_settings_syntax(settings_dict: dict, settings_metadata_dict: dict) -> dict: """Verify settings syntax and return a somewhat helpful error message. Raises: SettingsSyntaxError """ logger = get_logger() try: ret_dict = f_root(**settings_dict).dict() except ValidationError as e: msg = '' for num, error in enumerate(e.errors()): # If there are two errors and the last one is of type none allowed # then skip recording the second error because it's an implication # of the first error (the value has to be correct or none) # TODO: handle multiple occurrences of this? if len( e.errors() ) == 2 and num == 1 and error['type'] == 'type_error.none.allowed': continue # TODO: Find a way to present customised error message when string # regex match fails instead of just showing the regex pattern. loc = error['loc'] origin = 'unknown' if loc[0] in settings_metadata_dict: origin = settings_metadata_dict[loc[0]] error_msg = "Validation error for setting {}, bad value: {} (value origin: {})\n".format( '->'.join(str(x) for x in loc), get_pydantic_error_value(settings_dict, loc), origin) try: pydantic_descr = get_pydantic_field_descr(f_root.schema(), loc) if pydantic_descr: pydantic_descr_msg = ", field should be: {}".format( pydantic_descr) else: pydantic_descr_msg = "" except Exception as e_pydantic_descr: logger.exception(e_pydantic_descr) pydantic_descr_msg = ", exception while getting pydantic description" error_msg += "Message: {}{}\n".format(error['msg'], pydantic_descr_msg) msg += error_msg raise SettingsSyntaxError(msg) else: return ret_dict