Open ITD27M01 opened 3 years ago
Hi, testinfra will match hosts and/or groups but no patterns yet. I guess this should be feasible in the future.
Hi @philpep
As an example, you can consider the corresponding lookup plugin - inventory_hostnames. It returns the list of hostnames which can be used as a source for testinfra_hosts: https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/lookup/inventory_hostnames.py
Is there any reason to use external call to ansible-inventory cmd?
A've played with this:
> python
Python 3.8.5 (default, Sep 4 2020, 02:22:02)
[Clang 10.0.0 ] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from ansible.parsing.dataloader import DataLoader
>>> from ansible.inventory.manager import InventoryManager
>>> loader = DataLoader()
>>> inventory = InventoryManager(loader=loader, sources='inventory')
>>> inventory.get_hosts(pattern='db:&Prod')
>>> ['my', 'hosts', 'from', 'Prod']
>>> inventory.get_hosts(pattern='db:&Dev')
>>> ['my', 'hosts', 'from', 'Dev']
Inventory sources can be retrieved from config or from cmdline.
@ITD27M01 thanks for your inputs !
I think we must avoid to use the "API" because we do this in the past and caused us a lot of issues (tl;dr; ansible API isn't stable and practical).
I didn't manage to run inventory_hostnames
module with the command line but I just saw ansible
has a --list-hosts
option that output hosts matching pattern:
ansible -m noop --list-hosts <pattern>
If some of you have some time to spend on it that would be an awesome contribution :)
I played a bit with --list-hosts
, and it works.
patterns:
foo,bar
) - worksfoo[1:12]
) - worksfoo,!foo1
) - worksfoo,localhost
) - worksgroup1:&group2
) - worksIt looks like it solves all practical issues.
The problem I see here is the &
use. It's used in parameters of 'host url' (ansible://group?force_ansibe=True&sudo=True
), and adding & in the url (ansible://group:&group2?force_ansibe=True&sudo=True
) looks a bit hard to understand for humans (and robots?).
@amarao yes I think theses special characters should be urlencoded, which will not help humans :/
Note we can also use plain options instead of url, e.g. python -m pytest --connection ansible --sudo --force-ansible --hosts 'g1:&g2'
which is more readable. (but not supposed through testinfra_hosts
defined in module).
Command line options is not always available. Consider molecule scenario:
...
verifier:
name: testinfra
options:
sudo: false
showlocals: true
verbose: true
color: 'yes'
Molecule picks up all tests inside tests
directory, so if there are different tests for different groups, the single option is to have testinfra_hosts
magical variable inside each module.
The actual call to Testinfra from Molecule looks like this:
pytest --ansible-inventory ../cache/molecule/../default/inventory --color yes --connection ansible --debug -p no:cacheprovider --showlocals .../molecule/default/tests/test_one.py .../molecule/default/tests/test_two.py ....
So, the testinfra_hosts
, is, basically, the single way to customize tests target.
Hi,
Is there any way to pass the ansible hostpattern to testinfra_hosts? I have dynamic inventory which provides all the hosts from Prod and Dev environments. I'm working with them like:
But both environments have the same groups (db, web, app). Can I pass host pattern like 'db:&Prod' to testinfra_hosts ?
https://docs.ansible.com/ansible/latest/user_guide/intro_patterns.html