diff --git a/changelogs/fragments/41-fix-vault-addr.yml b/changelogs/fragments/41-fix-vault-addr.yml new file mode 100644 index 000000000..220342550 --- /dev/null +++ b/changelogs/fragments/41-fix-vault-addr.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - hashi_vault - restore use of ``VAULT_ADDR`` environment variable as a low preference env var (https://github.com/ansible-collections/community.hashi_vault/pull/61). diff --git a/plugins/lookup/hashi_vault.py b/plugins/lookup/hashi_vault.py index c852c8555..3dcbd3d0a 100644 --- a/plugins/lookup/hashi_vault.py +++ b/plugins/lookup/hashi_vault.py @@ -84,13 +84,13 @@ description: - URL to the Vault service. - If not specified by any other means, the value of the C(VAULT_ADDR) environment variable will be used. + - If C(VAULT_ADDR) is also not defined then a default of C(http://127.0.0.1:8200) will be used. env: - name: ANSIBLE_HASHI_VAULT_ADDR version_added: '0.2.0' ini: - section: lookup_hashi_vault key: url - default: 'http://127.0.0.1:8200' username: description: Authentication user name. password: @@ -640,8 +640,19 @@ def process_options(self): # proxies (dict or str) self.process_option_proxies() + # apply additional defaults + self.apply_additional_defaults(url='http://127.0.0.1:8200') + # begin options processing methods + # this is a temporary method + # https://github.com/ansible-collections/community.hashi_vault/pull/61 + # low preference env vars will be updated to take defaults into account + def apply_additional_defaults(self, **kwargs): + for k, v in kwargs.items(): + if self.get_option(k) is None: + self.set_option(k, v) + def set_default_option_env(self, option, var): '''sets an option to the value of an env var if None''' if self.get_option(option) is None: diff --git a/tests/unit/plugins/lookup/test_hashi_vault.py b/tests/unit/plugins/lookup/test_hashi_vault.py index 1e2e3ed56..2e2ea8e76 100644 --- a/tests/unit/plugins/lookup/test_hashi_vault.py +++ b/tests/unit/plugins/lookup/test_hashi_vault.py @@ -5,18 +5,52 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type +import os import pytest +from ansible.errors import AnsibleError + +from ansible.plugins.loader import lookup_loader + +from ansible.module_utils.six.moves.urllib.parse import urlparse + +from ansible_collections.community.hashi_vault.tests.unit.compat import mock + from ansible_collections.community.hashi_vault.plugins.lookup.hashi_vault import LookupModule # , HashiVault from ansible_collections.community.hashi_vault.plugins.lookup.__init__ import HashiVaultLookupBase +from requests.exceptions import ConnectionError + @pytest.fixture def hashi_vault_lookup_module(): - return LookupModule() + return lookup_loader.get('community.hashi_vault.hashi_vault') class TestHashiVaultLookup(object): def test_is_hashi_vault_lookup_base(self, hashi_vault_lookup_module): assert issubclass(type(hashi_vault_lookup_module), HashiVaultLookupBase) + + @pytest.mark.parametrize( + 'envpatch,expected', + [ + ({}, 'http://127.0.0.1:8200'), + ({'VAULT_ADDR': 'http://vault:0'}, 'http://vault:0'), + ({'ANSIBLE_HASHI_VAULT_ADDR': 'https://vaultalt'}, 'https://vaultalt'), + ({'VAULT_ADDR': 'https://vaultlow:8443', 'ANSIBLE_HASHI_VAULT_ADDR': 'http://vaulthigh:8200'}, 'http://vaulthigh:8200'), + ], + ) + def test_vault_addr_low_pref(self, hashi_vault_lookup_module, envpatch, expected): + url = urlparse(expected) + host = url.hostname + port = url.port if url.port is not None else {'http': 80, 'https': 443}[url.scheme] + + with mock.patch.dict(os.environ, envpatch): + with pytest.raises(ConnectionError) as e: + hashi_vault_lookup_module.run(['secret/fake'], token='fake') + + s_err = str(e.value) + + assert str(host) in s_err, "host '%s' not found in exception: %r" % (host, str(e.value)) + assert str(port) in s_err, "port '%i' not found in exception: %r" % (port, str(e.value))