Hi,
I am attempting to integrate Ansible with our systems management framework (python/Django) as a way to run commands on remote machines. We’ve already been using Ansible for a while and the application I’m integrating it is already responsible for generating the Ansible inventory (which I have available in my application as a python dictionary).
I’m trying to find a way to make the Ansible runner use this inventory without having to execute an external application, or having to dump it to a temporary file (in ini format).
I see the Inventory init() method already accepts the host_list as a (python) list, but this way any group-information and host variables are lost. Is there a way to do this with a dictionary instead?
Thanks,
Jasper
I don’t believe there’s a way to do this right now, without dumping the data to a temporary file.
It sounds like you might need a new inventory type, similar to the script.py one but instead taking the data structure directly rather than reading it from the output of the file and a small modification to lib/ansible/inventory/init.py to check if it’s a dictionary. If you’re interested in contributing something like that, let us know.
I would actually be interested in developing this.
An option could be create a `DictionaryInventory` to use as a parser
to parse a dictionary and create a dictionary of Group() class, like
what InventoryParser and InventoryScript are doing.
In Inventory.__init__ then we could add a test, so that if host_list
is a dictionary, then self.parser = DictionaryInvenetory(host_list)
and self.groups = self.parser.groups.values().
.a.
I just sent a pull request with a test implementation of this idea.
.a.
I’m not interested in this per se.
What you should do is use the Inventory API and Runner/Playbook API as per /usr/bin/ansible-playbook OR write a suitable inventory plugin that reads the file format you like from whatever location.
So the preferred method of invoking Ansible from another Python application is dumping the inventory to a temporary location and telling Ansible to read it from that location, or having ansible execute an external script? That seems inefficient to me, as it’s passing data around through various locations that could easily be passed in directly.
I understand the desire to keep the codebase small/simple, but I don’t think the dict-implementation is fundamentally different from the string- and list-implementations, it’s just a more powerful variant.
But if this is not to be implemented, is it possible to instantiate an empty Inventory object (giving it an empty list) and use the add_group() method to populate the object myself? Or should I expect things to go wrong if I use it this way?
Thanks,
Jasper
I would be happy to maintain the code, we are using ansible as part of
one of our software, and we are interested in this feature. So far we
are using an external, temporary file, but we are not completely
satisfied with this solution, (we are basically using an external file
to copy data from a python class to another) and we would like to use
the implementation I sent or similar approaches.
I also think that without this feature (programmatically create a
complete inventory class with groups), there is no way to effectively
use ansible from external programs, which is something that at least
two people in this mailing list are trying to do.
.a.
“So the preferred method of invoking Ansible from another Python application is dumping the inventory to a temporary location and telling Ansible to read it from that location, or having ansible execute an external script?”
No.
I’m saying if you are doing Python things, you should use the Inventory class, rather than passing a raw datastructure.
This is how Ansible’s userland implements both external inventory scripts and it’s own API parsing.
Also, this is really a discussion for ansible-devel list.
Moving this discussion to ansible-devel.
I was actually trying to use the Inventory class and passing that to the runner. The problem arises when attempting to instantiate the Inventory object. In the init method, it wants either a string, or a list, or a file, or a script. Being able to pass a dict (containing also groups information and host-vars) would be very convenient.
Alternatively, I could just instantiate the Inventory object with an empty list and populate it myself afterwards. It just seemed like the less elegant option.
Jasper
Another non-eligant solution would be to have another pre-inventory class that upon being populated can be pinv.dict 'd into json (the same as the result from an inventory script) into a proper inventory. Haven’t tried this yet.
Actually, nevermind, I dug into the code and this isn’t easily possible either, I guess I’m back to a NamedTemporaryFile…
It has been nearly 5 months since the last thread on this topic. I was wanting to know if there have been any significant updates.
I am developing Python code to integrate with our Ansible solution for maintaining Ansible dict files with up-to-date Applications-RemoteHost-ApplicationsVersion information.
I need some sleek Python code which will read an Ansible dict file (like the one below), then Add or Del certain RemoteHost-ApplicationsVersion then write back out to the same Ansible dict format.
Does anyone inside or outside of Ansible have any working examples?
Thanks.
And here’s my example Ansible dict file: