[bug] Dynaconf loosing VAULT_URL setting from .env file
See original GitHub issueDescribe 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:
- 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
- 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}'
- 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()
...
- 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:
- Created a year ago
- Comments:10 (10 by maintainers)
Top GitHub Comments
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 theenvvar_prefix
from each application.VAULT_FOR_MYAPP
,VAULT_FOR_OTHER_APP
etc@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.