Esempio n. 1
0
    def load(self, filename=None, key=None, silent=True):
        """
        Reads and loads in to `self.obj` a single key or all keys from source

        :param filename: Optional filename to load
        :param key: if provided load a single key
        :param silent: if load erros should be silenced
        """
        filename = filename or self.obj.get(self.identifier.upper())
        if not filename:
            return

        if not isinstance(filename, (list, tuple)):
            split_files = ensure_a_list(filename)
            if all([f.endswith(self.extensions) for f in split_files]):  # noqa
                files = split_files  # it is a ['file.ext', ...]
            else:  # it is a single config as string
                files = [filename]
        else:  # it is already a list/tuple
            files = filename

        self.obj._loaded_files.extend(files)

        env_list = build_env_list(self.obj, self.env)

        # load all envs
        self._read(files, env_list, silent, key)
Esempio n. 2
0
    def _load_all_envs(self, source_data, silent=True, key=None):
        """Load configs from files separating by each environment"""

        for file_data in source_data.values():

            # env name is checked in lower
            file_data = {k.lower(): value for k, value in file_data.items()}

            # is there a `dynaconf_merge` on top level of file?
            file_merge = file_data.get("dynaconf_merge")

            for env in build_env_list(self.obj, self.env):
                env = env.lower()  # lower for better comparison
                data = {}

                try:
                    data = file_data[env] or {}
                except KeyError:
                    if silent:
                        continue
                    raise

                if not data:
                    continue

                if env != self.obj.get("DEFAULT_ENV_FOR_DYNACONF").lower():
                    identifier = f"{self.identifier}_{env}"
                else:
                    identifier = self.identifier

                self._set_data_to_obj(data, identifier, file_merge, key)
Esempio n. 3
0
def load(obj, env=None, silent=True, key=None):
    """Reads and loads in to "settings" a single key or all keys from redis

    :param obj: the settings instance
    :param env: settings env default='DYNACONF'
    :param silent: if errors should raise
    :param key: if defined load a single key, else load all in env
    :return: None
    """
    redis = StrictRedis(**obj.get("REDIS_FOR_DYNACONF"))
    prefix = obj.get("ENVVAR_PREFIX_FOR_DYNACONF")
    # prefix is added to env_list to keep backwards compatibility
    env_list = [prefix] + build_env_list(obj, env or obj.current_env)
    for env_name in env_list:
        holder = f"{prefix.upper()}_{env_name.upper()}"
        try:
            if key:
                value = redis.hget(holder.upper(), key)
                if value:
                    parsed_value = parse_conf_data(value,
                                                   tomlfy=True,
                                                   box_settings=obj)
                    if parsed_value:
                        obj.set(key, parsed_value)
            else:
                data = {
                    key: parse_conf_data(value, tomlfy=True, box_settings=obj)
                    for key, value in redis.hgetall(holder.upper()).items()
                }
                if data:
                    obj.update(data, loader_identifier=IDENTIFIER)
        except Exception as e:
            if silent:
                return False
            raise
Esempio n. 4
0
    def _load_all_envs(self, source_data, silent=True, key=None):
        """Load configs from files separating by each environment"""

        for file_data in source_data.values():

            # env name is checked in lower
            file_data = {k.lower(): value for k, value in file_data.items()}

            # is there a `dynaconf_merge` on top level of file?
            file_merge = file_data.get("dynaconf_merge")

            # is there a flag disabling dotted lookup on file?
            file_dotted_lookup = file_data.get("dynaconf_dotted_lookup")

            for env in build_env_list(self.obj, self.env):
                env = env.lower()  # lower for better comparison

                try:
                    data = file_data[env] or {}
                except KeyError:
                    if silent:
                        continue
                    raise

                if not data:
                    continue

                self._set_data_to_obj(
                    data,
                    f"{self.identifier}_{env}",
                    file_merge,
                    key,
                    file_dotted_lookup=file_dotted_lookup,
                )
Esempio n. 5
0
def test_env_list():
    class Obj(dict):
        @property
        def current_env(self):
            return "other"

    assert build_env_list(Obj(), env="OTHER") == [
        "default",
        "dynaconf",
        "other",
        "global",
    ]
Esempio n. 6
0
def load(obj, env=None, silent=None, key=None):
    """Reads and loads in to "settings" a single key or all keys from vault

    :param obj: the settings instance
    :param env: settings env default='DYNACONF'
    :param silent: if errors should raise
    :param key: if defined load a single key, else load all in env
    :return: None
    """
    client = get_client(obj)
    try:
        dirs = client.secrets.kv.list_secrets(
            path=obj.VAULT_PATH_FOR_DYNACONF,
            mount_point=obj.VAULT_MOUNT_POINT_FOR_DYNACONF,
        )["data"]["keys"]
    except InvalidPath:
        # The given path is not a directory
        dirs = []
    env_list = build_env_list(obj, env) + dirs
    for env in env_list:
        path = "/".join([obj.VAULT_PATH_FOR_DYNACONF, env])
        try:
            if obj.VAULT_KV_VERSION_FOR_DYNACONF == 2:
                data = client.secrets.kv.v2.read_secret_version(
                    path, mount_point=obj.VAULT_MOUNT_POINT_FOR_DYNACONF)
            else:
                data = client.secrets.kv.read_secret(
                    "data/" + path,
                    mount_point=obj.VAULT_MOUNT_POINT_FOR_DYNACONF,
                )
        except InvalidPath:
            # If the path doesn't exist, ignore it and set data to None
            data = None
        if data:
            # There seems to be a data dict within a data dict,
            # extract the inner data
            data = data.get("data", {}).get("data", {})
        try:
            if obj.VAULT_KV_VERSION_FOR_DYNACONF == 2 and data:
                data = data.get("data", {})
            if data and key:
                value = parse_conf_data(data.get(key),
                                        tomlfy=True,
                                        box_settings=obj)
                if value:
                    obj.set(key, value)
            elif data:
                obj.update(data, loader_identifier=IDENTIFIER, tomlfy=True)
        except Exception:
            if silent:
                return False
            raise
Esempio n. 7
0
    def _load_all_envs(self, source_data, silent=True, key=None):
        """Load configs from files separating by each environment"""

        for source_file, file_data in source_data.items():

            # env name is checked in lower
            file_data = {k.lower(): value for k, value in file_data.items()}

            # is there a `dynaconf_merge` on top level of file?
            file_merge = file_data.get("dynaconf_merge")

            # all lower case for comparison
            base_envs = [
                # DYNACONF or MYPROGRAM
                (self.obj.get("ENVVAR_PREFIX_FOR_DYNACONF") or "").lower(),
                # DEFAULT
                self.obj.get("DEFAULT_ENV_FOR_DYNACONF").lower(),
                # default active env unless ENV_FOR_DYNACONF is changed
                "development",
                # backwards compatibility for global
                "dynaconf",
                # global that rules all
                "global",
            ]

            for env in build_env_list(self.obj, self.env):
                env = env.lower()  # lower for better comparison
                data = {}
                try:
                    data = file_data[env] or {}
                except KeyError:
                    if env not in base_envs:
                        message = (
                            f"{self.identifier}_loader: {env} env not"
                            f"defined in {source_file}"
                        )
                        if silent:
                            warnings.warn(message)
                        else:
                            raise KeyError(message)
                    continue

                if env != self.obj.get("DEFAULT_ENV_FOR_DYNACONF").lower():
                    identifier = f"{self.identifier}_{env}"
                else:
                    identifier = self.identifier

                self._set_data_to_obj(
                    data, identifier, source_file, file_merge, key, env
                )
Esempio n. 8
0
def load(obj, env=None, silent=None, key=None):
    """Reads and loads in to "settings" a single key or all keys from vault

    :param obj: the settings instance
    :param env: settings env default='DYNACONF'
    :param silent: if errors should raise
    :param key: if defined load a single key, else load all in env
    :return: None
    """

    client = get_client(obj)
    env_list = build_env_list(obj, env)
    for env in env_list:
        path = "/".join([obj.VAULT_PATH_FOR_DYNACONF, env])
        try:
            data = client.secrets.kv.read_secret_version(path)
        except InvalidPath:
            # If the path doesn't exist, ignore it and set data to None
            data = None
        if data:
            # There seems to be a data dict within a data dict,
            # extract the inner data
            data = data.get("data", {}).get("data", {})
        try:
            if data and key:
                value = parse_conf_data(data.get(key), tomlfy=True)
                if value:
                    obj.logger.debug(
                        "vault_loader: loading by key: %s:%s (%s:%s)",
                        key,
                        "****",
                        IDENTIFIER,
                        path,
                    )
                    obj.set(key, value)
            elif data:
                obj.logger.debug(
                    "vault_loader: loading: %s (%s:%s)",
                    list(data.keys()),
                    IDENTIFIER,
                    path,
                )
                obj.update(data, loader_identifier=IDENTIFIER, tomlfy=True)
        except Exception as e:
            if silent:
                if hasattr(obj, "logger"):
                    obj.logger.error(str(e))
                return False
            raise
Esempio n. 9
0
def load(obj, env=None, silent=None, key=None):
    """Reads and loads in to "settings" a single key or all keys from vault

    :param obj: the settings instance
    :param env: settings env default='DYNACONF'
    :param silent: if errors should raise
    :param key: if defined load a single key, else load all in env
    :return: None
    """
    client = get_client(obj)
    try:
        if obj.VAULT_KV_VERSION_FOR_DYNACONF == 2:
            dirs = client.secrets.kv.v2.list_secrets(
                path=obj.VAULT_PATH_FOR_DYNACONF,
                mount_point=obj.VAULT_MOUNT_POINT_FOR_DYNACONF,
            )["data"]["keys"]
        else:
            dirs = client.secrets.kv.v1.list_secrets(
                path=obj.VAULT_PATH_FOR_DYNACONF,
                mount_point=obj.VAULT_MOUNT_POINT_FOR_DYNACONF,
            )["data"]["keys"]
    except InvalidPath:
        # The given path is not a directory
        dirs = []
    # First look for secrets into environments less store
    if not obj.ENVIRONMENTS_FOR_DYNACONF:
        # By adding '', dynaconf will now read secrets from environments-less
        # store which are not written by `dynaconf write` to Vault store
        env_list = [obj.MAIN_ENV_FOR_DYNACONF.lower(), ""]
    # Finally, look for secret into all the environments
    else:
        env_list = dirs + build_env_list(obj, env)
    for env in env_list:
        path = "/".join([obj.VAULT_PATH_FOR_DYNACONF, env])
        try:
            if obj.VAULT_KV_VERSION_FOR_DYNACONF == 2:
                data = client.secrets.kv.v2.read_secret_version(
                    path, mount_point=obj.VAULT_MOUNT_POINT_FOR_DYNACONF)
            else:
                data = client.secrets.kv.read_secret(
                    "data/" + path,
                    mount_point=obj.VAULT_MOUNT_POINT_FOR_DYNACONF,
                )
        except InvalidPath:
            # If the path doesn't exist, ignore it and set data to None
            data = None
        if data:
            # There seems to be a data dict within a data dict,
            # extract the inner data
            data = data.get("data", {}).get("data", {})
        try:
            if (obj.VAULT_KV_VERSION_FOR_DYNACONF == 2
                    and obj.ENVIRONMENTS_FOR_DYNACONF and data):
                data = data.get("data", {})
            if data and key:
                value = parse_conf_data(data.get(key),
                                        tomlfy=True,
                                        box_settings=obj)
                if value:
                    obj.set(key, value)
            elif data:
                obj.update(data, loader_identifier=IDENTIFIER, tomlfy=True)
        except Exception:
            if silent:
                return False
            raise