depends: |
|
---|---|
configuration: | All authentication is done through Salt's external auth system which requires additional configuration not described here. |
In order to run rest_tornado with the salt-master add the following to the Salt master config file.
rest_tornado:
# can be any port
port: 8000
# address to bind to (defaults to 0.0.0.0)
address: 0.0.0.0
# socket backlog
backlog: 128
ssl_crt: /etc/pki/api/certs/server.crt
# no need to specify ssl_key if cert and key
# are in one single file
ssl_key: /etc/pki/api/certs/server.key
debug: False
disable_ssl: False
webhook_disable_auth: False
Authentication is performed by passing a session token with each request.
Tokens are generated via the SaltAuthHandler
URL.
The token may be sent in one of two ways:
See also
You can bypass the session handling via the RunSaltAPIHandler
URL.
Commands are sent to a running Salt master via this module by sending HTTP requests to the URLs detailed below.
Content negotiation
This REST interface is flexible in what data formats it will accept as well as what formats it will return (e.g., JSON, YAML, x-www-form-urlencoded).
Data sent in POST and PUT requests must be in the format of a list of lowstate dictionaries. This allows multiple commands to be executed in a single HTTP request.
A dictionary containing various keys that instruct Salt which command to run, where that command lives, any parameters for that command, any authentication credentials, what returner to use, etc.
Salt uses the lowstate data format internally in many places to pass command data between functions. Salt also uses lowstate for the LocalClient() Python API interface.
The following example (in JSON format) causes Salt to execute two commands:
[{
"client": "local",
"tgt": "*",
"fun": "test.fib",
"arg": ["10"]
},
{
"client": "runner",
"fun": "jobs.lookup_jid",
"jid": "20130603122505459265"
}]
Multiple commands in a Salt API request will be executed in serial and makes no gaurantees that all commands will run. Meaning that if test.fib (from the example above) had an exception, the API would still execute "jobs.lookup_jid".
Responses to these lowstates are an in-order list of dicts containing the return data, a yaml response could look like:
- ms-1: true
ms-2: true
- ms-1: foo
ms-2: bar
In the event of an exception while executing a command the return for that lowstate will be a string, for example if no minions matched the first lowstate we would get a return like:
- No minions matched the target. No command was sent, no jid was assigned.
- ms-1: true
ms-2: true
x-www-form-urlencoded
Sending JSON or YAML in the request body is simple and most flexible, however sending data in urlencoded format is also supported with the caveats below. It is the default format for HTML forms, many JavaScript libraries, and the curl command.
For example, the equivalent to running salt '*' test.ping
is sending
fun=test.ping&arg&client=local&tgt=*
in the HTTP request body.
Caveats:
Only a single command may be sent per HTTP request.
Repeating the arg
parameter multiple times will cause those
parameters to be combined into a single list.
Note, some popular frameworks and languages (notably jQuery, PHP, and
Ruby on Rails) will automatically append empty brackets onto repeated
parameters. E.g., arg=one
, arg=two
will be sent as arg[]=one
,
arg[]=two
. This is not supported; send JSON or YAML instead.
depends: |
|
---|
In order to enable saltnado_websockets you must add websockets: True to your saltnado config block.
rest_tornado:
# can be any port
port: 8000
ssl_crt: /etc/pki/api/certs/server.crt
# no need to specify ssl_key if cert and key
# are in one single file
ssl_key: /etc/pki/api/certs/server.key
debug: False
disable_ssl: False
websockets: True
Exposes all
"real-time" events from Salt's event bus on a websocket connection.
It should be noted that "Real-time" here means these events are made available
to the server as soon as any salt related action (changes to minions, new jobs etc) happens.
Clients are however assumed to be able to tolerate any network transport related latencies.
Functionality provided by this endpoint is similar to the /events
end point.
The event bus on the Salt master exposes a large variety of things, notably when executions are started on the master and also when minions ultimately return their results. This URL provides a real-time window into a running Salt infrastructure. Uses websocket as the transport mechanism.
Exposes GET method to return websocket connections. All requests should include an auth token. A way to obtain obtain authentication tokens is shown below.
% curl -si localhost:8000/login \
-H "Accept: application/json" \
-d username='salt' \
-d password='salt' \
-d eauth='pam'
Which results in the response
{
"return": [{
"perms": [".*", "@runner", "@wheel"],
"start": 1400556492.277421,
"token": "d0ce6c1a37e99dcc0374392f272fe19c0090cca7",
"expire": 1400599692.277422,
"user": "salt",
"eauth": "pam"
}]
}
In this example the token
returned is d0ce6c1a37e99dcc0374392f272fe19c0090cca7
and can be included
in subsequent websocket requests (as part of the URL).
The event stream can be easily consumed via JavaScript:
// Note, you must be authenticated!
// Get the Websocket connection to Salt
var source = new Websocket('wss://localhost:8000/all_events/d0ce6c1a37e99dcc0374392f272fe19c0090cca7');
// Get Salt's "real time" event stream.
source.onopen = function() { source.send('websocket client ready'); };
// Other handlers
source.onerror = function(e) { console.debug('error!', e); };
// e.data represents Salt's "real time" event data as serialized JSON.
source.onmessage = function(e) { console.debug(e.data); };
// Terminates websocket connection and Salt's "real time" event stream on the server.
source.close();
Or via Python, using the Python module websocket-client for example. Or the tornado client.
# Note, you must be authenticated!
from websocket import create_connection
# Get the Websocket connection to Salt
ws = create_connection('wss://localhost:8000/all_events/d0ce6c1a37e99dcc0374392f272fe19c0090cca7')
# Get Salt's "real time" event stream.
ws.send('websocket client ready')
# Simple listener to print results of Salt's "real time" event stream.
# Look at https://pypi.python.org/pypi/websocket-client/ for more examples.
while listening_to_events:
print ws.recv() # Salt's "real time" event data as serialized JSON.
# Terminates websocket connection and Salt's "real time" event stream on the server.
ws.close()
# Please refer to https://github.com/liris/websocket-client/issues/81 when using a self signed cert
Above examples show how to establish a websocket connection to Salt and activating
real time updates from Salt's event stream by signaling websocket client ready
.
Exposes formatted
"real-time" events from Salt's event bus on a websocket connection.
It should be noted that "Real-time" here means these events are made available
to the server as soon as any salt related action (changes to minions, new jobs etc) happens.
Clients are however assumed to be able to tolerate any network transport related latencies.
Functionality provided by this endpoint is similar to the /events
end point.
The event bus on the Salt master exposes a large variety of things, notably when executions are started on the master and also when minions ultimately return their results. This URL provides a real-time window into a running Salt infrastructure. Uses websocket as the transport mechanism.
Formatted events parses the raw "real time" event stream and maintains a current view of the following:
A change to the minions (such as addition, removal of keys or connection drops)
or jobs is processed and clients are updated.
Since we use salt's presence events to track minions,
please enable presence_events
and set a small value for the loop_interval
in the salt master config file.
Exposes GET method to return websocket connections. All requests should include an auth token. A way to obtain obtain authentication tokens is shown below.
% curl -si localhost:8000/login \
-H "Accept: application/json" \
-d username='salt' \
-d password='salt' \
-d eauth='pam'
Which results in the response
{
"return": [{
"perms": [".*", "@runner", "@wheel"],
"start": 1400556492.277421,
"token": "d0ce6c1a37e99dcc0374392f272fe19c0090cca7",
"expire": 1400599692.277422,
"user": "salt",
"eauth": "pam"
}]
}
In this example the token
returned is d0ce6c1a37e99dcc0374392f272fe19c0090cca7
and can be included
in subsequent websocket requests (as part of the URL).
The event stream can be easily consumed via JavaScript:
// Note, you must be authenticated!
// Get the Websocket connection to Salt
var source = new Websocket('wss://localhost:8000/formatted_events/d0ce6c1a37e99dcc0374392f272fe19c0090cca7');
// Get Salt's "real time" event stream.
source.onopen = function() { source.send('websocket client ready'); };
// Other handlers
source.onerror = function(e) { console.debug('error!', e); };
// e.data represents Salt's "real time" event data as serialized JSON.
source.onmessage = function(e) { console.debug(e.data); };
// Terminates websocket connection and Salt's "real time" event stream on the server.
source.close();
Or via Python, using the Python module websocket-client for example. Or the tornado client.
# Note, you must be authenticated!
from websocket import create_connection
# Get the Websocket connection to Salt
ws = create_connection('wss://localhost:8000/formatted_events/d0ce6c1a37e99dcc0374392f272fe19c0090cca7')
# Get Salt's "real time" event stream.
ws.send('websocket client ready')
# Simple listener to print results of Salt's "real time" event stream.
# Look at https://pypi.python.org/pypi/websocket-client/ for more examples.
while listening_to_events:
print ws.recv() # Salt's "real time" event data as serialized JSON.
# Terminates websocket connection and Salt's "real time" event stream on the server.
ws.close()
# Please refer to https://github.com/liris/websocket-client/issues/81 when using a self signed cert
Above examples show how to establish a websocket connection to Salt and activating
real time updates from Salt's event stream by signaling websocket client ready
.
Minion information
is a dictionary keyed by each connected minion's id
(mid
),
grains information for each minion is also included.
Minion information is sent in response to the following minion events:
manage.present
periodically every loop_interval
secondsminion addition
minon removal
# Not all grains are shown
data: {
"minions": {
"minion1": {
"id": "minion1",
"grains": {
"kernel": "Darwin",
"domain": "local",
"zmqversion": "4.0.3",
"kernelrelease": "13.2.0"
}
}
}
}
Job information
is also tracked and delivered.
Job information is also a dictionary
in which each job's information is keyed by salt's jid
.
data: {
"jobs": {
"20140609153646699137": {
"tgt_type": "glob",
"jid": "20140609153646699137",
"tgt": "*",
"start_time": "2014-06-09T15:36:46.700315",
"state": "complete",
"fun": "test.ping",
"minions": {
"minion1": {
"return": true,
"retcode": 0,
"success": true
}
}
}
}
}
/minions
¶salt.netapi.rest_tornado.saltnado.
MinionSaltAPIHandler
¶alias of <Mock object at 0x7fcfd7bb2bd0>
/jobs
¶salt.netapi.rest_tornado.saltnado.
JobsSaltAPIHandler
¶alias of <Mock object at 0x7fcfd7bb2950>