Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ansible hostpattern for ansible connection #602

Open
ITD27M01 opened this issue Feb 20, 2021 · 8 comments
Open

Ansible hostpattern for ansible connection #602

ITD27M01 opened this issue Feb 20, 2021 · 8 comments
Labels
enhancement This issue/PR relates to a feature request. question

Comments

@ITD27M01
Copy link

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:

ansible-playbook play.yaml --limit Prod
ansible-playbook play.yaml --limit Dev

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

@philpep
Copy link
Contributor

philpep commented Feb 22, 2021

Hi, testinfra will match hosts and/or groups but no patterns yet. I guess this should be feasible in the future.

@ITD27M01
Copy link
Author

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?

@ITD27M01
Copy link
Author

ITD27M01 commented Feb 22, 2021

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.

@philpep philpep added the enhancement This issue/PR relates to a feature request. label Apr 8, 2021
@philpep
Copy link
Contributor

philpep commented Apr 8, 2021

@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 :)

@amarao
Copy link
Contributor

amarao commented Apr 8, 2021

I played a bit with --list-hosts, and it works.

patterns:

  • groups and host names separated by comma (foo,bar) - works
  • groups with ranges (foo[1:12]) - works
  • negation (foo,!foo1) - works
  • explicit localhost (foo,localhost) - works
  • intersection (group1:&group2) - works

It 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?).

@philpep
Copy link
Contributor

philpep commented Apr 8, 2021

@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).

@amarao
Copy link
Contributor

amarao commented Apr 8, 2021

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.

@Code0x58
Copy link

#753 improves matching to allow patterns, without being dependent on ansible modules

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement This issue/PR relates to a feature request. question
Projects
None yet
Development

No branches or pull requests

4 participants