parse inventory using Ansible Python API #215
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Some changes to optionally use the Ansible Python API to parse the inventory files. This could replace the builtin parser which would lead to some simplification, but I took the more conservative approach of leaving the builtin parse intact and adding a
--use-ansible-api
flag to select this as an alternative parser.There are a few things that the builtin ansible-cmdb parser doesn't do the same as Ansible does, especially in parsing :var sections and in the order of reading inventory files. (When multiple inventory files are read from a directory including the group_vars and host_vars cases, the files should be read in sorted order. Then there's
ansible_group_priority
, which I don't use and wouldn't want to implement.)An earlier experiment with running the
ansible-inventory
command to parse the inventory revealed that the mixed static and dynamic inventory test has a bug that makes ansible-cmdb parse it differently than ansible does. Ansible requires that every host be in some group, andtest/f_inventory/mixeddir/dyninv.py
generates json that has a couple hosts that aren't in any group. It looks like Ansible uses a dummy "ungrouped" group in that case, so that's how I fixed the test data. The test of the builtin ansible-cmdb inventory parser passes without modification and this lets parsers based on Ansible code or commands pass as well. (The ansible-inventory experiment was successful, but it seems better to use the Ansible Python API directly rather than spawning another program and parsing its output.)It isn't easy to import the Ansible libraries without renaming
src/ansiblecmdb/ansible.py
because a file in the directory namedansible.py
will confound the import. I renamed the file toansible_cmdb.py
so thatfrom ansible.parsing.dataloader import DataLoader
, etc. work as expected. I also made minimal changes to ansible_cmdb.py (formerly ansible.py) to make it a more useful base class by moving some code out of__init__
to expose key methods to override, specificallyload_inventories
.The tests are duplicated because I was too lazy to use dependency injection to specify whether to use
Ansible
orAnsibleViaInventory
.A random nit: The docstring for the
get_hosts
method says "Return a list of parsed hosts info, with the limit applied if required", but the method returns a dict of hosts info rather than a list.