question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[bug] Dynaconf loosing VAULT_URL setting from .env file

See original GitHub issue

Describe the bug Dynaconf setting object is losing the VAULT_URL and VAULT_VERIFY settings from .env depending on something(unknown) configured in the environment and trying to access the secrets from the localhost:8200 vault server instead.

To Reproduce Steps to reproduce the behavior:

  1. Having the following folder structure
Project structure
# ll -a

-rw-r--r--   1 jitendrayejare  staff    253 May  2 21:25 .codecov.yml
-rw-r--r--   1 jitendrayejare  staff    195 May  2 21:25 .coveragerc
-rwxr-xr-x   1 jitendrayejare  staff    340 May  6 00:03 .env
-rw-r--r--   1 jitendrayejare  staff   1715 May  2 21:25 .env.example
-rw-r--r--   1 jitendrayejare  staff   1467 May  2 21:25 .gitignore
-rw-r--r--   1 jitendrayejare  staff    880 May  2 21:25 .pre-commit-config.yaml
-rw-r--r--   1 jitendrayejare  staff    119 May  2 21:25 .pyup.yml
-rw-r--r--   1 jitendrayejare  staff    458 May  2 21:25 Dockerfile
-rw-r--r--   1 jitendrayejare  staff  35121 May  2 21:25 LICENSE
-rw-r--r--   1 jitendrayejare  staff   7989 May  2 21:25 Makefile
-rw-r--r--   1 jitendrayejare  staff   1921 May  2 21:25 README.rst
drwxr-xr-x   3 jitendrayejare  staff     96 May  2 23:41 __pycache__
-rw-r--r--   1 jitendrayejare  staff   2085 May  2 22:16 broker_settings.yaml
drwxr-xr-x  84 jitendrayejare  staff   2688 May  6 00:12 conf
-rw-r--r--   1 jitendrayejare  staff   1977 May  2 21:25 conftest.py
-rw-r--r--   1 jitendrayejare  staff   1306 May  2 23:42 inventory.yaml
-rw-r--r--   1 jitendrayejare  staff    554 May  2 21:25 logging.yaml
-rw-r--r--   1 jitendrayejare  staff    765 May  2 21:25 manage.yml
-rw-r--r--   1 jitendrayejare  staff    303 May  2 21:25 pyproject.toml
drwxr-xr-x   4 jitendrayejare  staff    128 May  2 21:25 pytest_fixtures
drwxr-xr-x  15 jitendrayejare  staff    480 May  2 23:41 pytest_plugins
-rw-r--r--   1 jitendrayejare  staff    266 May  2 21:25 requirements-optional.txt
-rw-r--r--   1 jitendrayejare  staff    873 May  2 21:25 requirements.txt
drwxr-xr-x  29 jitendrayejare  staff    928 May  2 23:41 robottelo
-rw-r--r--   1 jitendrayejare  staff   1072 May  2 21:25 robottelo.yaml.sample
drwxr-xr-x  12 jitendrayejare  staff    384 May  2 21:25 scripts
-rw-r--r--   1 jitendrayejare  staff    416 May  2 21:25 settings.sample.yaml
-rwxr-xr-x   1 jitendrayejare  staff   1037 May  2 21:25 setup.py
-rw-r--r--   1 jitendrayejare  staff   3134 May  2 21:25 testimony.yaml
drwxr-xr-x   7 jitendrayejare  staff    224 May  2 23:48 tests

The dynaconf settings object initializing in `robottelo/config/__init__.py` in above file structure. There is also a conf directory that the dynaconf setting object uses to read configutation YAMLs.
  1. Having the following config files:
Config files

.env

VAULT_ENABLED_FOR_DYNACONF=true
VAULT_URL_FOR_DYNACONF=https://vault.company.com:8200
VAULT_KV_VERSION_FOR_DYNACONF=2
VAULT_VERIFY_FOR_DYNACONF=false
VAULT_MOUNT_POINT_FOR_DYNACONF=apps
VAULT_PATH_FOR_DYNACONF=dir/subdir
# VAULT_TOKEN_FOR_DYNACONF=myroot
# VAULT_ROLE_ID_FOR_DYNACONF=
# VAULT_SECRET_ID_FOR_DYNACONF=

and

/conf/azure.yaml

AZURERM:
  # Client ID of the AzureRM account
  CLIENT_ID: some_client_id
  # Client Secret of the AzureRM account
  CLIENT_SECRET: '@format {this.vault_azure_client_secret}'
  1. Having the following app code:
Code

/robottelo/config/init.py

from dynaconf import settings

def get_settings():
    """Return Lazy settings object after validating

    :return: A validated Lazy settings object
    """
    settings = LazySettings(
        envvar_prefix="ROBOTTELO",
        core_loaders=["YAML"],
        settings_file="settings.yaml",
        preload=["conf/*.yaml"],
        includes=["settings.local.yaml", ".secrets.yaml", ".secrets_*.yaml"],
        envless_mode=True,
        lowercase_read=True,
        load_dotenv=True,
    )
    settings.validators.register(**VALIDATORS)

    try:
        settings.validators.validate()
    except ValidationError as err:
        logger.warning(f'Dynaconf validation failed, continuing for the sake of unit tests\n{err}')

    return settings


settings = get_settings()
...
  1. Executing under the following environment
Execution
# virtualenv activated

$  pytest tests/foreman/api/test_computeresource_azurerm.py::TestAzureRMComputeResourceTestCase

<eating some big trace here>

./../../Envs/robotteloPRT/lib/python3.9/site-packages/broker/broker.py:329: in from_inventory
    return [self.reconstruct_host(inv_host) for inv_host in inv_hosts]
../../../Envs/robotteloPRT/lib/python3.9/site-packages/broker/broker.py:329: in <listcomp>
    return [self.reconstruct_host(inv_host) for inv_host in inv_hosts]
../../../Envs/robotteloPRT/lib/python3.9/site-packages/broker/broker.py:317: in reconstruct_host
    provider_inst = provider(**host_export_data)
../../../Envs/robotteloPRT/lib/python3.9/site-packages/broker/providers/ansible_tower.py:80: in __init__
    self._validate_settings(instance_name)
../../../Envs/robotteloPRT/lib/python3.9/site-packages/broker/providers/__init__.py:51: in _validate_settings
    settings.execute_loaders()
../../DynaConf/dynaconf/dynaconf/base.py:989: in execute_loaders
    core_loader.load(self, env, silent=silent, key=key)
../../DynaConf/dynaconf/dynaconf/loaders/vault_loader.py:72: in load
    client = get_client(obj)
../../DynaConf/dynaconf/dynaconf/loaders/vault_loader.py:34: in get_client
    client.auth_approle(
../../../Envs/robotteloPRT/lib/python3.9/site-packages/hvac/utils.py:201: in new_func
    return method(*args, **kwargs)
../../../Envs/robotteloPRT/lib/python3.9/site-packages/hvac/v1/__init__.py:1805: in auth_approle
    return self.login(
../../../Envs/robotteloPRT/lib/python3.9/site-packages/hvac/v1/__init__.py:1495: in login
    return self._adapter.login(url=url, use_token=use_token, **kwargs)
../../../Envs/robotteloPRT/lib/python3.9/site-packages/hvac/adapters.py:197: in login
    response = self.post(url, **kwargs)
../../../Envs/robotteloPRT/lib/python3.9/site-packages/hvac/adapters.py:126: in post
    return self.request("post", url, **kwargs)
../../../Envs/robotteloPRT/lib/python3.9/site-packages/hvac/adapters.py:364: in request
    response = super(JSONAdapter, self).request(*args, **kwargs)
../../../Envs/robotteloPRT/lib/python3.9/site-packages/hvac/adapters.py:313: in request
    response = self.session.request(
../../../Envs/robotteloPRT/lib/python3.9/site-packages/requests/sessions.py:529: in request
    resp = self.send(prep, **send_kwargs)
../../../Envs/robotteloPRT/lib/python3.9/site-packages/requests/sessions.py:645: in send
    r = adapter.send(request, **kwargs)

requests.exceptions.ConnectionError: HTTPConnectionPool(host='localhost', port=8200): Max retries exceeded with url: /v1/auth/approle/login (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x1122120d0>: Failed to establish a new connection: [Errno 61] Connection refused'))

Expected behaviour The settings object should read secrets from the given VAULT_URL instead of defaulting to localhost depending upon on some environmental conditions.

Environment (please complete the following information):

  • OS: [MacOS 12.3.1]
  • Dynaconf Version [3.1.8]
  • Frameworks in use [PyTest]

Additional context Interestingly this behaviour is only with the execution of tests in a specific environment only(not sure what I am missing or adding there) and not when I attempt to access secrets from the settings object from Ipython(Python Interactive shell) where the secrets are available as attributes of the settings object(settings.vault_azure_client_secret written a secret value from vault).

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:10 (10 by maintainers)

github_iconTop GitHub Comments

3reactions
rochacbrunocommented, Jun 27, 2022

Ohh I see there are multiple projects using dynaconf running on the same environment, so the _FOR_DYNACONF variables are shared.

We need to implement multi-tenancy to isolate those variables, maybe those settings should follow in some way the envvar_prefix from each application. VAULT_FOR_MYAPP, VAULT_FOR_OTHER_APP etc

1reaction
rochacbrunocommented, Jul 6, 2022

@JacobCallahan @jyejare I have no spare time to work on it right now.

This week I will be onboarding some new people to work on Dynaconf and hopefully they can start contributing to fix issues soon.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Env vars - Dynaconf - 3.1.11
Dynaconf prioritizes environment variables over files as the best ... Write your variables in a settings file in the format of your choice....
Read more >
Configuring Dynaconf — dynaconf 2.2.3 documentation
Variable Type Usage AUTO_CAST bool @casting like @int is parsed. COMMENTJSON_ENABLED bool Enable comments in json files. CORE_LOADERS list A list of enabled core loaders.
Read more >
dynaconf 0.5.4 - PyPI
dynaconf is an OSM (Object Settings Mapper) it can read settings variables from a set of different data stores such as python settings...
Read more >
YAML config file is not loaded in dyanconf settings
For older Dynaconf you can set the ROOT_PATH_FOR_DYNACONF environment variable to the base path of the project. For Dynaconf version > 3, the ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found