pytest-testinfra icon indicating copy to clipboard operation
pytest-testinfra copied to clipboard

Vaulted variable cannot be read by ansible.get_variables()

Open blackillzone opened this issue 7 years ago • 1 comments

Ansible version

ansible 2.5.0
  executable location = /home/fdhaussy/.virtualenvs/ansible/bin/ansible
  python version = 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609]

Testinfra version

This is pytest version 3.5.0, imported from /home/fdhaussy/.virtualenvs/ansible/local/lib/python2.7/site-packages/pytest.pyc
setuptools registered plugins:
  testinfra-1.7.1 at /home/fdhaussy/.virtualenvs/ansible/local/lib/python2.7/site-packages/testinfra/plugin.py
  pytest-xdist-1.22.2 at /home/fdhaussy/.virtualenvs/ansible/local/lib/python2.7/site-packages/xdist/looponfail.py
  pytest-xdist-1.22.2 at /home/fdhaussy/.virtualenvs/ansible/local/lib/python2.7/site-packages/xdist/plugin.py
  pytest-forked-0.2 at /home/fdhaussy/.virtualenvs/ansible/local/lib/python2.7/site-packages/pytest_forked/__init__.pyc

Behaviour

Using an in-line vaulted ansible variable, it seems that testinfra cannot be able to use or load it with get_variables().

For example, in my inventory (here for a mongodb instance):

mongodb:
   host: 192.168.0.10
mongodb_admin:
  username: admin
  password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          myvaulhash

And in the testinfra code:

def test_mongodb_cluster(host):
     """Testing if mongodb cluster is healthy."""
    ans_dict = host.ansible.get_variables()
    mongodb_host = ans_dict['mongodb']['host']
    mongodb_admin_username = ans_dict['mongodb_admin']['username']
    mongodb_admin_pwd = ans_dict['mongodb_admin']['password']
    mongodb_json = host.run('mongo --host ' + mongodb_host + '\
                            --eval \'JSON.stringify(rs.status())\' --quiet\
                            -u ' + mongodb_admin_username + '\
                            -p ' + mongodb_admin_pwd + ' admin')

Using this code, result in no problem loading mongodb.host variable, nor mongodb_admin.username, but for mongodb_admin.password, I have the following trace:

    def test_mongodb_cluster(host):
        """Testing if mongodb cluster is healthy."""
        ans_dict = host.ansible.get_variables()
        mongodb_host = ans_dict['mongodb']['host']
        mongodb_admin_username = ans_dict['mongodb_admin']['username']
        mongodb_admin_pwd = ans_dict['mongodb_admin']['password']
        mongodb_json = host.run('mongo --host ' + mongodb_host + '\
                                --eval \'JSON.stringify(rs.status())\' --quiet\
                                -u ' + mongodb_admin_username + '\
>                               -p ' + mongodb_admin_pwd + ' admin')
E       TypeError: coercing to Unicode: need string or buffer, AnsibleVaultEncryptedUnicode found

Is there any specific things to add, to load a vaulted variable ? Or is it something that isn't implemented/supported yet, by testinfra ?

blackillzone avatar Apr 09 '18 15:04 blackillzone

I got that working internally decrypting in my tests by:

from ansible import constants as C
from ansible.parsing.vault import VaultLib
from ansible.cli import CLI
from ansible.parsing.dataloader import DataLoader

and then:

    token = host.ansible.get_variables()["netbox_token"]

    loader = DataLoader()
    vault_secret = CLI.setup_vault_secrets(
        loader=loader,
        vault_ids=C.DEFAULT_VAULT_IDENTITY_LIST
    )
    vault = VaultLib(vault_secret)
    dec_tok = vault.decrypt(token['__ansible_vault'])

cinek810 avatar Apr 07 '23 04:04 cinek810