salt/doc/topics/event/index.rst

233 lines
6.1 KiB
ReStructuredText
Raw Normal View History

.. _events:
.. index:: ! Event, event bus, event system
see: Reactor; Event
2012-06-08 01:37:55 +00:00
=================
Salt Event System
=================
2014-02-19 23:50:26 +00:00
The Salt Event System is used to fire off events enabling third party
applications or external processes to react to behavior within Salt.
2012-06-08 01:37:55 +00:00
2014-02-19 23:50:26 +00:00
The event system is comprised of a two primary components:
* The event sockets which publishes events.
* The event library which can listen to events and send events into the salt system.
2012-06-08 01:37:55 +00:00
2014-04-30 01:58:47 +00:00
Event types
===========
.. toctree::
:maxdepth: 2
master_events
2012-06-08 01:37:55 +00:00
Listening for Events
====================
Salt's Event Bus is used heavily within Salt and it is also written to
integrate heavily with existings tooling and scripts. There is a variety of
ways to consume it.
From the CLI
------------
The quickest way to watch the event bus is by calling the :py:func:`state.event
runner <salt.runners.state.event>`:
.. code-block:: bash
salt-run state.event pretty=True
That runner is designed to interact with the event bus from external tools and
shell scripts. See the documentation for more examples.
Remotely via the REST API
-------------------------
Salt's event bus can be consumed
:py:class:`salt.netapi.rest_cherrypy.app.Events` as an HTTP stream from
external tools or services.
.. code-block:: bash
curl -SsNk https://salt-api.example.com:8000/events?token=05A3
From Python
-----------
Python scripts can access the event bus only as the same system user that Salt
is running as.
2012-06-08 01:51:40 +00:00
The event system is accessed via the event library and can only be accessed
2012-06-08 01:37:55 +00:00
by the same system user that Salt is running as. To listen to events a
SaltEvent object needs to be created and then the get_event function needs to
be run. The SaltEvent object needs to know the location that the Salt Unix
2012-06-08 01:37:55 +00:00
sockets are kept. In the configuration this is the ``sock_dir`` option. The
``sock_dir`` option defaults to "/var/run/salt/master" on most systems.
2012-06-08 01:37:55 +00:00
The following code will check for a single event:
.. code-block:: python
import salt.config
2012-06-08 01:37:55 +00:00
import salt.utils.event
opts = salt.config.client_config('/etc/salt/master')
event = salt.utils.event.get_event(
'master',
sock_dir=opts['sock_dir'],
transport=opts['transport'],
opts=opts)
2012-06-08 01:37:55 +00:00
data = event.get_event()
Events will also use a "tag". Tags allow for events to be filtered by prefix.
By default all events will be returned. If only authentication events are
desired, then pass the tag "salt/auth".
2014-02-19 23:50:26 +00:00
The ``get_event`` method has a default poll time assigned of 5 seconds. To
change this time set the "wait" option.
The following example will only listen for auth events and will wait for 10 seconds
2012-06-08 01:51:40 +00:00
instead of the default 5.
.. code-block:: python
data = event.get_event(wait=10, tag='salt/auth')
To retrieve the tag as well as the event data, pass ``full=True``:
.. code-block:: python
evdata = event.get_event(wait=10, tag='salt/job', full=True)
tag, data = evdata['tag'], evdata['data']
2012-06-08 01:51:40 +00:00
2014-02-19 23:50:26 +00:00
Instead of looking for a single event, the ``iter_events`` method can be used to
make a generator which will continually yield salt events.
The iter_events method also accepts a tag but not a wait time:
2012-06-08 01:51:40 +00:00
.. code-block:: python
for data in event.iter_events(tag='salt/auth'):
2012-06-08 01:51:40 +00:00
print(data)
And finally event tags can be globbed, such as they can be in the Reactor,
using the fnmatch library.
.. code-block:: python
import fnmatch
import salt.config
2012-06-08 01:51:40 +00:00
import salt.utils.event
opts = salt.config.client_config('/etc/salt/master')
2012-06-08 01:51:40 +00:00
sevent = salt.utils.event.get_event(
'master',
sock_dir=opts['sock_dir'],
transport=opts['transport'],
opts=opts)
while True:
ret = sevent.get_event(full=True)
if ret is None:
continue
if fnmatch.fnmatch(ret['tag'], 'salt/job/*/ret/*'):
do_something_with_job_return(ret['data'])
Firing Events
=============
2014-02-19 23:50:26 +00:00
It is possible to fire events on either the minion's local bus or to fire
events intended for the master.
To fire a local event from the minion on the command line call the
:py:func:`event.fire <salt.modules.event.fire>` execution function:
.. code-block:: bash
salt-call event.fire '{"data": "message to be sent in the event"}' 'tag'
To fire an event to be sent up to the master from the minion call the
:py:func:`event.send <salt.modules.event.send>` execution function. Remember
YAML can be used at the CLI in function arguments:
.. code-block:: bash
salt-call event.send 'myco/mytag/success' '{success: True, message: "It works!"}'
If a process is listening on the minion, it may be useful for a user on the
master to fire an event to it:
.. code-block:: python
2014-11-18 07:53:40 +00:00
# Job on minion
import salt.utils.event
event = salt.utils.event.MinionEvent(**__opts__)
for evdata in event.iter_events(tag='customtag/'):
return evdata # do your processing here...
.. code-block:: bash
salt minionname event.fire '{"data": "message for the minion"}' 'customtag/african/unladen'
Firing Events from Python
=========================
From Salt execution modules
---------------------------
Events can be very useful when writing execution modules, in order to inform
various processes on the master when a certain task has taken place. This is
easily done using the normal cross-calling syntax:
.. code-block:: python
# /srv/salt/_modules/my_custom_module.py
def do_something():
'''
Do something and fire an event to the master when finished
CLI Example::
salt '*' my_custom_module:do_something
'''
# do something!
__salt__['event.send']('myco/my_custom_module/finished', {
'finished': True,
'message': "The something is finished!",
})
From Custom Python Scripts
--------------------------
Firing events from custom Python code is quite simple and mirrors how it is
done at the CLI:
.. code-block:: python
import salt.client
caller = salt.client.Caller()
2014-02-19 23:50:26 +00:00
caller.sminion.functions['event.send'](
'myco/myevent/success',
{
'success': True,
'message': "It works!",
}
)