def setup_listeners(config): # Register basic subscriber predicates, to filter events. config.add_subscriber_predicate('for_actions', EventActionFilter) config.add_subscriber_predicate('for_resources', EventResourceFilter) write_actions = (ACTIONS.CREATE, ACTIONS.UPDATE, ACTIONS.DELETE) settings = config.get_settings() project_name = settings.get('project_name', '') listeners = aslist(settings['event_listeners']) for name in listeners: logger.info('Setting up %r listener' % name) prefix = 'event_listeners.%s.' % name try: listener_mod = config.maybe_dotted(name) prefix = 'event_listeners.%s.' % name.split('.')[-1] listener = listener_mod.load_from_config(config, prefix) except (ImportError, AttributeError): module_setting = prefix + "use" # Read from ENV or settings. module_value = utils.read_env(project_name + "." + module_setting, settings.get(module_setting)) listener_mod = config.maybe_dotted(module_value) listener = listener_mod.load_from_config(config, prefix) # If StatsD is enabled, monitor execution time of listeners. if getattr(config.registry, "statsd", None): statsd_client = config.registry.statsd key = 'listeners.%s' % name listener = statsd_client.timer(key)(listener.__call__) # Optional filter by event action. actions_setting = prefix + "actions" # Read from ENV or settings. actions_value = utils.read_env(project_name + "." + actions_setting, settings.get(actions_setting, "")) actions = aslist(actions_value) if len(actions) > 0: actions = ACTIONS.from_string_list(actions) else: actions = write_actions # Optional filter by event resource name. resource_setting = prefix + "resources" # Read from ENV or settings. resource_value = utils.read_env(project_name + "." + resource_setting, settings.get(resource_setting, "")) resource_names = aslist(resource_value) # Pyramid event predicates. options = dict(for_actions=actions, for_resources=resource_names) if ACTIONS.READ in actions: config.add_subscriber(listener, ResourceRead, **options) if len(actions) == 1: return config.add_subscriber(listener, ResourceChanged, **options)
def load_default_settings(config, default_settings): """Read settings provided in Paste ini file, set default values and replace if defined as environment variable. """ settings = config.get_settings() project_name = settings['project_name'] def _prefixed_keys(key): unprefixed = key if key.startswith('kinto.') or key.startswith(project_name + '.'): unprefixed = key.split('.', 1)[1] project_prefix = '{}.{}'.format(project_name, unprefixed) kinto_prefix = 'kinto.{}'.format(unprefixed) return unprefixed, project_prefix, kinto_prefix # Fill settings with default values if not defined. for key, default_value in sorted(default_settings.items()): unprefixed, project_prefix, kinto_prefix = keys = _prefixed_keys(key) is_defined = len(set(settings.keys()).intersection(set(keys))) > 0 if not is_defined: settings[unprefixed] = default_value for key, value in sorted(settings.items()): unprefixed, project_prefix, kinto_prefix = keys = _prefixed_keys(key) # Fail if not only one is defined. defined = set(settings.keys()).intersection(set(keys)) distinct_values = set([str(settings[d]) for d in defined]) if len(defined) > 1 and len(distinct_values) > 1: names = "', '".join(defined) raise ValueError("Settings '{}' are in conflict.".format(names)) # Override settings from OS env values. # e.g. HTTP_PORT, READINGLIST_HTTP_PORT, KINTO_HTTP_PORT from_env = utils.read_env(unprefixed, value) from_env = utils.read_env(project_prefix, from_env) from_env = utils.read_env(kinto_prefix, from_env) settings[unprefixed] = from_env config.add_settings(settings)
def load_default_settings(config, default_settings): """Read settings provided in Paste ini file, set default values and replace if defined as environment variable. """ settings = config.get_settings() settings_prefix = settings["settings_prefix"] def _prefixed_keys(key): unprefixed = key if key.startswith(settings_prefix + "."): unprefixed = key.split(".", 1)[1] project_prefix = f"{settings_prefix}.{unprefixed}" return unprefixed, project_prefix # Fill settings with default values if not defined. for key, default_value in sorted(default_settings.items()): unprefixed, project_prefix = keys = _prefixed_keys(key) is_defined = len(set(settings.keys()).intersection(set(keys))) > 0 if not is_defined: settings[unprefixed] = default_value for key, value in sorted(settings.items()): value = utils.native_value(value) unprefixed, project_prefix = keys = _prefixed_keys(key) # Fail if not only one is defined. defined = set(settings.keys()).intersection(set(keys)) distinct_values = set([str(settings[d]) for d in defined]) if len(defined) > 1 and len(distinct_values) > 1: names = "', '".join(defined) raise ValueError(f"Settings '{names}' are in conflict.") # Override settings from OS env values. # e.g. HTTP_PORT, READINGLIST_HTTP_PORT, KINTO_HTTP_PORT from_env = utils.read_env(unprefixed, value) from_env = utils.read_env(project_prefix, from_env) settings[unprefixed] = from_env config.add_settings(settings)
def get_first_matching_setting(setting_name, settings, prefixes, default=None): """Helper to look up the `setting_name` key in the provided `settings`, with different `prefixes`. The first encountered value is returned, and if none is found, `default` is returned. """ for prefix in prefixes: prefixed_setting_name = prefix + setting_name # Prefix `setting_name` with global «settings prefix» to lookup env vars. # It is forced to `kinto.` in Kinto main(), and allows to read # `signer.resources` from the `KINTO_SIGNER_RESOURCES` env var. # https://github.com/Kinto/kinto/blob/9c322f2adc/kinto/__init__.py#L48-L49 full_prefixed_setting = (settings["settings_prefix"] + f".{prefixed_setting_name}") from_env = read_env(full_prefixed_setting, None) if from_env is not None: return from_env if prefixed_setting_name in settings: return settings[prefixed_setting_name] return default
def test_return_env_name_as_uppercase(self): os.environ.setdefault('KINTO_NAME', 'abc') self.assertEqual(read_env('kinto.name', 12), 'abc')
def load_default_settings(config, default_settings): """Read settings provided in Paste ini file, set default values and replace if defined as environment variable. """ settings = config.get_settings() project_name = settings['project_name'] def _prefixed_keys(key): unprefixed = key if key.startswith('kinto.') or key.startswith(project_name + '.'): unprefixed = key.split('.', 1)[1] project_prefix = project_name + '.' + unprefixed kinto_prefix = 'kinto.' + unprefixed return unprefixed, project_prefix, kinto_prefix # Fill settings with default values if not defined. for key, default_value in sorted(default_settings.items()): unprefixed, project_prefix, kinto_prefix = keys = _prefixed_keys(key) is_defined = len(set(settings.keys()).intersection(set(keys))) > 0 if not is_defined: settings[unprefixed] = default_value for key, value in sorted(settings.items()): unprefixed, project_prefix, kinto_prefix = keys = _prefixed_keys(key) # Fail if not only one is defined. defined = set(settings.keys()).intersection(set(keys)) distinct_values = set([str(settings[d]) for d in defined]) if len(defined) > 1 and len(distinct_values) > 1: names = "', '".join(defined) raise ValueError("Settings '%s' are in conflict." % names) # Maintain backwards compatibility with old settings files that # have backend settings like cliquet.foo (which is now # kinto.core.foo). unprefixed, _, _ = _prefixed_keys(key) CONTAIN_CLIQUET_MODULE_NAMES = [ 'storage_backend', 'cache_backend', 'permission_backend', 'logging_renderer', ] if unprefixed in CONTAIN_CLIQUET_MODULE_NAMES and \ value.startswith('cliquet.'): new_value = value.replace('cliquet.', 'kinto.core.') logger.warn( "Backend settings referring to cliquet are DEPRECATED. " "Please update your {} setting to {} (was: {}).".format( key, new_value, value)) value = new_value # Override settings from OS env values. # e.g. HTTP_PORT, READINGLIST_HTTP_PORT, KINTO_HTTP_PORT from_env = utils.read_env(unprefixed, value) from_env = utils.read_env(project_prefix, from_env) from_env = utils.read_env(kinto_prefix, from_env) settings[unprefixed] = from_env config.add_settings(settings)
def test_return_env_value_if_defined_in_env(self): os.environ.setdefault("KINTO_CONF", "abc") self.assertEqual(read_env("KINTO_CONF", 12), "abc")
def test_default_value_is_not_coerced_to_python(self): self.assertEqual(read_env("kinto-conf.name", "12"), "12")
def test_return_env_value_is_coerced_to_python(self): os.environ.setdefault("KINTO_CONF_NAME", "3.14") self.assertEqual(read_env("kinto-conf.name", 12), 3.14)
def test_return_passed_value_if_not_defined_in_env(self): self.assertEqual(read_env('missing', 12), 12)
def __init__(self, settings): super(MozillaHekaRenderer, self).__init__() self.appname = settings['project_name'] self.hostname = utils.read_env('HOSTNAME', os.uname()[1]) self.pid = os.getpid()
def test_return_env_value_if_defined_in_env(self): os.environ.setdefault('KINTO_CONF', 'abc') self.assertEqual(read_env('KINTO_CONF', 12), 'abc')
def test_return_env_name_as_uppercase(self): os.environ.setdefault("KINTO_NAME", "abc") self.assertEqual(read_env("kinto.name", 12), "abc")
def setup_listeners(config): # Register basic subscriber predicates, to filter events. config.add_subscriber_predicate("for_actions", EventActionFilter) config.add_subscriber_predicate("for_resources", EventResourceFilter) write_actions = (ACTIONS.CREATE, ACTIONS.UPDATE, ACTIONS.DELETE) settings = config.get_settings() settings_prefix = settings.get("settings_prefix", "") listeners = aslist(settings["event_listeners"]) for name in listeners: logger.info(f"Setting up '{name}' listener") prefix = f"event_listeners.{name}." try: listener_mod = config.maybe_dotted(name) prefix = f"event_listeners.{name.split('.')[-1]}." listener = listener_mod.load_from_config(config, prefix) except (ImportError, AttributeError): module_setting = prefix + "use" # Read from ENV or settings. module_value = utils.read_env( f"{settings_prefix}.{module_setting}", settings.get(module_setting)) listener_mod = config.maybe_dotted(module_value) listener = listener_mod.load_from_config(config, prefix) # If StatsD is enabled, monitor execution time of listeners. if getattr(config.registry, "statsd", None): statsd_client = config.registry.statsd key = f"listeners.{name}" listener = statsd_client.timer(key)(listener.__call__) # Optional filter by event action. actions_setting = prefix + "actions" # Read from ENV or settings. actions_value = utils.read_env(f"{settings_prefix}.{actions_setting}", settings.get(actions_setting, "")) actions = aslist(actions_value) if len(actions) > 0: actions = ACTIONS.from_string_list(actions) else: actions = write_actions # Optional filter by event resource name. resource_setting = prefix + "resources" # Read from ENV or settings. resource_value = utils.read_env( f"{settings_prefix}.{resource_setting}", settings.get(resource_setting, "")) resource_names = aslist(resource_value) # Pyramid event predicates. options = dict(for_actions=actions, for_resources=resource_names) if ACTIONS.READ in actions: config.add_subscriber(listener, ResourceRead, **options) actions = [a for a in actions if a != ACTIONS.READ] if len(actions) > 0: config.add_subscriber(listener, ResourceChanged, **options)
def test_return_env_value_is_coerced_to_python(self): os.environ.setdefault('KINTO_CONF_NAME', '3.14') self.assertEqual(read_env('kinto-conf.name', 12), 3.14)
def __init__(self, settings): super().__init__() self.appname = settings['project_name'] self.hostname = utils.read_env('HOSTNAME', os.uname()[1]) self.pid = os.getpid()
def test_return_passed_value_if_not_defined_in_env(self): self.assertEqual(read_env("missing", 12), 12)