Accessing variables from within a plugin (callback)

7,090 views
Skip to first unread message

Daniel Schroeder

unread,
Jul 30, 2014, 3:09:02 AM7/30/14
to ansibl...@googlegroups.com
Hello list,

is there a way how I can access host/group vars from within a callback plugin? Basically I want to modify the Hipchat callback plugin to use a room ID configured via group_vars (or maybe registered as a var right in a roles tasks), as we have hundred of chat rooms and to which room a message will be sent would depend on the role.

Thanks,
Daniel

Michael DeHaan

unread,
Jul 30, 2014, 8:40:39 AM7/30/14
to Daniel Schroeder, ansibl...@googlegroups.com
Currently the callback instances don't have a copy of the runner instance variable needed to get at that dictionary.

In playbook code, we do something like this so callbacks can know what play they are currently executing.


I can see something like this being set in Runner callbacks, but it may be more appropriate for the "on_stats" method (which is really the final callback when everything is all done) to get passed a reference to the per-host variable structure (internally referred to as the "setup_cache").

However, the easiest thing you could do, if possible, is just have your callback be responsive to an environment variable like ROOM_ID.   However, this would require launching your playbook appropriately.

I'd be interested in hearing more about the use case as having 100 different chatrooms all running playbooks seems like something I'd be interested in :)








--
You received this message because you are subscribed to the Google Groups "Ansible Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-deve...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Matt Martz

unread,
Jul 30, 2014, 11:11:42 AM7/30/14
to Michael DeHaan, Daniel Schroeder, ansibl...@googlegroups.com
Daniel,

Since I submitted the hipchat.py calback plugin PR, we have since modified it locally, to do something similar to what you are doing.

In our case, our hipchat API token lives in a vault encrypted vars file for all hosts, so we pull this var out during run time.  You can see the results at:


Specifically, you will be interested in:


and

Daniel Schroeder

unread,
Jul 31, 2014, 4:53:50 AM7/31/14
to ansibl...@googlegroups.com, mic...@ansible.com, deem...@googlemail.com
Matt, that's awesome. Thanks for the great example. (and the Hipchat callback)

So this snippet is what I was looking for to get to global definitions:
hosts = self.playbook.inventory.get_hosts()
host_vars
= self.playbook.inventory.get_variables(hosts[0].name)

Host specific methods in the callback then have the host parameter which can be used to get vars belonging to that host.

I'd be interested in hearing more about the use case as having 100 different chatrooms all running playbooks seems like something I'd be interested in :)

I think that question now is already answered here.

Cheers!
Daniel

Jakub Veverka

unread,
Dec 12, 2014, 9:14:43 AM12/12/14
to ansibl...@googlegroups.com, mic...@ansible.com, deem...@googlemail.com
Hi,

I am trying to create vars_plugins plugin and I would need variables passed from cmdline.

Is there any way I could access other vars than host_vars? I would like to pass on cmdline for example -e customer_name=demo and use this variable in my custom vars_plugin and obtain variables specific only for this user...

Thanks,
Jakub

Daniel Schroeder

unread,
Dec 12, 2014, 11:05:45 AM12/12/14
to Jakub Veverka, Abridged recipients, Michael DeHaan
Hi Jakub,

I have not yet looked into vars plugins. But in theory, if there is the runner object available, you should be able to access those. Try to access self.runner. If it is available the extra vars should be somewhere in there.

Another approach might be, to just dynamically include a yml file, if that's possible in your case.

- include_vars: {{ customer }}.yml

Cheers,
Daniel



 
 
 
 
 
On 12.12.2014 15:14:43, Jakub Veverka <veverk...@gmail.com> wrote:

Jakub Veverka

unread,
Dec 12, 2014, 11:38:05 AM12/12/14
to ansibl...@googlegroups.com, veverk...@gmail.com, mic...@ansible.com
Thanks for the tip Daniel.

Seems like I can't access runner:

AttributeError: 'VarsModule' object has no attribute 'runner'

Am I accessing it on right place though? Can't find runner in this module: https://github.com/ansible/ansible/tree/devel/lib/ansible/inventory.

I am afraid I will have to go with system envs as mentioned by Michael.
I am currently using dynamic include_vars, but my evil plan counts with having this config in etcd db. I wanna use watcher which will trigger appropriate deploys in case of config change.

Jakub

Michael DeHaan

unread,
Dec 15, 2014, 6:45:11 AM12/15/14
to Jakub Veverka, ansibl...@googlegroups.com
vars_plugins are mostly just a way to implement inventory (at a point in time, anyway), and were not really meant to be user serviceable.

Not quite following this part:  "and I would need variables passed from cmdline."

It sounds like you are trying to generate variables from an external source like a CMDB or cloud, and might want to read an environment variable.

if you are doing this, an inventory plugin (if this source already contains the list of hosts/groups/etc as well) would be a good place to return variables at the same time and is usually how we do that.


Jakub Veverka

unread,
Dec 15, 2014, 7:02:22 AM12/15/14
to ansibl...@googlegroups.com, veverk...@gmail.com
I am not using inventory plugin because it wouldn't make sense in my case. Please correct me if it does.

I have dynamic ec2 inventory after I provision CoreOS hosts.
I am running apps in docker containers on top of CoreOS cluster so there can be more or less apps than actual hosts and I mostly don't specify on which host the app is running.
The apps (fleet unit files) are configured and started using action on local host using fleet module to interact with coreos cluster.

I have general configuration which could be in group_vars/all so that this info is accessible from each host.
Variables are different for each environment, thats why I am loading these values dynamically during run and don't have those in single static file.

Currently my variables are read first from general config and after overwritten (if present) by customer specific config and after by environment specific config.

When I think about it now I could perhaps convert vars script to dynamic inventory and add variables to local host this way. I believe this should be the only host that I am running those commands from.

My problem with passing variables from cmdline is that if I run ansible-paybook with -e "customer_name=demo customer_env=dev" I would like to import variables for demo customer's dev environmnent but unfortunatelly I can't access this variable in my vars_plugin custom python script...

Will I have this variable if I try to implement dynamic inventory?

Thanks,
Jakub

Daniel Schroeder

unread,
Dec 15, 2014, 7:21:53 AM12/15/14
to Jakub Veverka, Abridged recipients
If it doesn't bother you to have an extra task, you could do it with an action plugin. At least I know you have access to the runner there. But actually it wouldn't matter as you could simply pass it in the task like so:

- load_customer_vars: {{ customer_name }}

In the set_facts or include_vars plugins you could see how to return facts from an action plugin:


Cheers,
Daniel


Jakub Veverka

unread,
Dec 15, 2014, 7:27:40 AM12/15/14
to ansibl...@googlegroups.com, veverk...@gmail.com
Excelent idea, its not as elegant as having a fancy dynamic inventory, but seems a lot simpler :)

Thanks a lot,
Jakub

Mike Biancaniello

unread,
Jan 27, 2016, 12:25:11 PM1/27/16
to Ansible Development, mic...@ansible.com, deem...@googlemail.com
Hi, I am trying to do something similar and am having issues. Does this work with 2.0?

Specifically this piece:
 
   def playbook_on_play_start(self, pattern):
       
self.playbook = self.play.playbook
       
self.inventory = self.playbook.inventory



where you reference self.play, but I can't figure out where self.play is ever created. The play object is passed in v2_playbook_on_play_start, but that does not have a playbook attribute.

Matt Martz

unread,
Jan 27, 2016, 1:51:55 PM1/27/16
to Mike Biancaniello, Ansible Development
That code no longer works with Ansible 2.0 as the internal structure is completely different due to changes in the python API.

You will want to look at what you get from the `play` variable.  You have things like `play._variable_manager`

You may find some help in a recent discussion had here on ansible-devel: https://groups.google.com/forum/#ansible-devel/DQiGednLgU0/lXWDiwuQFQAJ
Matt Martz
@sivel
sivel.net

tiny...@gmail.com

unread,
Feb 5, 2016, 7:53:41 AM2/5/16
to Ansible Development, chep...@gmail.com
Looks like link to discussion is not working.
So can anyone help on how to get access to variables from callback plugin in Ansible 2.0?

Udondan

unread,
Mar 3, 2016, 8:40:07 AM3/3/16
to Ansible Development, chep...@gmail.com
You already found it, as it seems. But for others who are looking for a solution, this is the correct link to mentioned discussion: https://groups.google.com/forum/#!msg/ansible-devel/DQiGednLgU0/JIvQ2Z-zFQAJ
Reply all
Reply to author
Forward
0 new messages