Module Expr Str ImportFrom alias Import alias Import alias Import alias Import alias Import alias Import alias Assign NameStore Dict Num Num Num Num Num Num Num Str Str Str Str Str Str Str Assign NameStore Str Assign NameStore Call AttributeLoad NameLoad attr NameLoad FunctionDef arguments args defaults body Assign NameStore Call AttributeLoad NameLoad attr NameLoad Dict If CompareIn Str NameLoad body Return NameLoad Return NameLoad decorator_list ClassDef bases NameLoad body Expr Str FunctionDef arguments args NameParam NameParam NameParam defaults body Assign AttributeStore NameLoad attr NameLoad Expr Call AttributeLoad NameLoad attr NameLoad Call AttributeLoad Str attr NameLoad NameLoad decorator_list decorator_list FunctionDef arguments args NameParam defaults body Expr Str TryExcept body Expr Call AttributeLoad NameLoad attr NameLoad handlers ExceptHandler type NameLoad name NameStore body If BoolOpAnd CompareEq AttributeLoad NameLoad attr AttributeLoad NameLoad attr Call AttributeLoad AttributeLoad NameLoad attr attr NameLoad body Pass orelse Raise decorator_list FunctionDef arguments args NameParam defaults body Expr Str Assign NameStore Call AttributeLoad NameLoad attr Str Str Assign NameStore IfExp CompareEq NameLoad Str Num Call NameLoad NameLoad Return Call AttributeLoad SubscriptLoad NameLoad Index Str attr NameLoad decorator_list FunctionDef arguments args NameParam defaults body Expr Str Assign NameStore Call AttributeLoad NameLoad attr Str Str If CompareNotEq NameLoad Str body Raise Call NameLoad Num Str TryExcept body Return Call AttributeLoad NameLoad attr Call NameLoad NameLoad handlers ExceptHandler type NameLoad name NameStore body Raise Call NameLoad Num NameLoad decorator_list FunctionDef arguments args NameParam NameParam defaults NameLoad body Expr Str Assign NameStore Dict Str Call NameLoad Call NameLoad NameLoad If NameLoad body Expr Call AttributeLoad NameLoad attr NameLoad Return Call NameLoad Call AttributeLoad NameLoad attr decorator_list FunctionDef arguments args NameParam NameParam defaults body Expr Str Assign NameStore SubscriptLoad NameLoad Index Str For NameStore NameLoad body Expr Yield Call AttributeLoad NameLoad attr NameLoad decorator_list FunctionDef arguments args NameParam defaults body Expr Str Assign NameStore Call AttributeLoad SubscriptLoad NameLoad Index Str attr If CompareEq NameLoad Str body Return Str orelse If CompareEq NameLoad Str body Assign NameStore Call NameLoad NameLoad Return Call NameLoad NameLoad NameLoad orelse Raise Call NameLoad Num Str decorator_list FunctionDef arguments args NameParam defaults body Expr Str If CompareNotIn Str Call NameLoad body Import alias Assign NameStore Call AttributeLoad AttributeLoad NameLoad attr attr Call AttributeLoad AttributeLoad NameLoad attr attr Str Str Assign SubscriptStore NameLoad Index Str NameLoad Assign SubscriptStore NameLoad Index Str Call AttributeLoad AttributeLoad NameLoad attr attr NameLoad decorator_list FunctionDef arguments args NameParam NameParam defaults body Expr Str Expr Call NameLoad NameLoad TryExcept body Assign NameStore Call NameLoad Call NameLoad NameLoad Assign NameStore Num handlers ExceptHandler type NameLoad name NameStore body Assign NameStore AttributeLoad NameLoad attr Assign NameStore Call NameLoad NameLoad ExceptHandler type AttributeLoad AttributeLoad NameLoad attr attr name NameStore body Assign NameStore Num Assign NameStore Call NameLoad NameLoad ExceptHandler type NameLoad name NameStore body Assign NameStore Num Assign NameStore Call NameLoad NameLoad TryExcept body Assign NameStore Call AttributeLoad NameLoad attr Dict Str NameLoad handlers ExceptHandler type NameLoad name NameStore body Assign NameStore Num Assign NameStore Call NameLoad NameLoad Expr Call NameLoad SubscriptLoad NameLoad Index NameLoad Call NameLoad NameLoad Dict Str Str Return TupleLoad NameLoad decorator_list FunctionDef arguments args defaults body Expr Str Import alias Return Call AttributeLoad AttributeLoad NameLoad attr attr Call AttributeLoad AttributeLoad NameLoad attr attr Str Str decorator_list FunctionDef arguments args defaults body Expr Str ImportFrom alias If CompareNotIn Str Call NameLoad body Assign SubscriptStore Call NameLoad Index Str Call NameLoad If CompareIs Call NameLoad NameLoad body Raise Call NameLoad Num Assign NameStore Call AttributeLoad NameLoad attr NameLoad Dict Assign NameStore Call NameLoad Str SubscriptLoad NameLoad Index Str NameLoad TryExcept body Expr Call AttributeLoad NameLoad attr handlers ExceptHandler type NameLoad body Raise Call NameLoad Num decorator_list If CompareEq NameLoad Str body Expr Call NameLoad
N/A N/A 
A minimalist REST API for Salt
==============================

This ``rest_wsgi`` module provides a no-frills REST interface for sending
commands to the Salt master. There are no dependencies.

Extra care must be taken when deploying this module into production. Please
read this documentation in entirety.

All authentication is done through Salt's :ref:`external auth <acl-eauth>`
system.

Usage
=====

* All requests must be sent to the root URL (``/``).
* All requests must be sent as a POST request with JSON content in the request
  body.
* All responses are in JSON.

.. seealso:: :py:mod:`rest_cherrypy <salt.netapi.rest_cherrypy.app>`

    The :py:mod:`rest_cherrypy <salt.netapi.rest_cherrypy.app>` module is
    more full-featured, production-ready, and has builtin security features.

Deployment
==========

The ``rest_wsgi`` netapi module is a standard Python WSGI app. It can be
deployed one of two ways.

Using a WSGI-compliant web server
---------------------------------

This module may be run via any WSGI-compliant production server such as Apache
with mod_wsgi or Nginx with FastCGI.

It is strongly recommended that this app be used with a server that supports
HTTPS encryption since raw Salt authentication credentials must be sent with
every request. Any apps that access Salt through this interface will need to
manually manage authentication credentials (either username and password or a
Salt token). Tread carefully.

:program:`salt-api` using a development-only server
---------------------------------------------------

If run directly via the salt-api daemon it uses the `wsgiref.simple_server()`__
that ships in the Python standard library. This is a single-threaded server
that is intended for testing and development. **This server does not use
encryption**; please note that raw Salt authentication credentials must be sent
with every HTTP request.

**Running this module via salt-api is not recommended!**

In order to start this module via the ``salt-api`` daemon the following must be
put into the Salt master config::

    rest_wsgi:
        port: 8001

.. __: http://docs.python.org/2/library/wsgiref.html#module-wsgiref.simple_server

Usage examples
==============

.. http:post:: /

    **Example request** for a basic ``test.ping``::

        % curl -sS -i \
                -H 'Content-Type: application/json' \
                -d '[{"eauth":"pam","username":"saltdev","password":"saltdev","client":"local","tgt":"*","fun":"test.ping"}]' localhost:8001

    **Example response**:

    .. code-block:: http

        HTTP/1.0 200 OK
        Content-Length: 89
        Content-Type: application/json

        {"return": [{"ms--4": true, "ms--3": true, "ms--2": true, "ms--1": true, "ms--0": true}]}

    **Example request** for an asynchronous ``test.ping``::

        % curl -sS -i \
                -H 'Content-Type: application/json' \
                -d '[{"eauth":"pam","username":"saltdev","password":"saltdev","client":"local_async","tgt":"*","fun":"test.ping"}]' localhost:8001

    **Example response**:

    .. code-block:: http

        HTTP/1.0 200 OK
        Content-Length: 103
        Content-Type: application/json

        {"return": [{"jid": "20130412192112593739", "minions": ["ms--4", "ms--3", "ms--2", "ms--1", "ms--0"]}]}

    **Example request** for looking up a job ID::

        % curl -sS -i \
                -H 'Content-Type: application/json' \
                -d '[{"eauth":"pam","username":"saltdev","password":"saltdev","client":"runner","fun":"jobs.lookup_jid","jid":"20130412192112593739"}]' localhost:8001

    **Example response**:

    .. code-block:: http

        HTTP/1.0 200 OK
        Content-Length: 89
        Content-Type: application/json

        {"return": [{"ms--4": true, "ms--3": true, "ms--2": true, "ms--1": true, "ms--0": true}]}

:form lowstate: A list of :term:`lowstate` data appropriate for the
    :ref:`client <client-apis>` interface you are calling.
:status 200: success
:status 401: authentication required

 __future__ absolute_import N/A errno N/A json N/A logging N/A os N/A salt N/A salt.netapi N/A H N/A 200 400 401 404 405 406 500 200 OK 400 BAD REQUEST 401 UNAUTHORIZED 404 NOT FOUND 405 METHOD NOT ALLOWED 406 NOT ACCEPTABLE 500 INTERNAL SERVER ERROR N/A __virtualname__ rest_wsgi N/A logger N/A N/A logging getLogger __virtualname__ __virtual__ N/A N/A N/A N/A N/A mod_opts N/A N/A __opts__ get __virtualname__ N/A N/A N/A port mod_opts N/A N/A __virtualname__ N/A False N/A HTTPError N/A Exception N/A N/A 
    A custom exception that can take action based on an HTTP error code
     __init__ N/A N/A self code message N/A N/A N/A N/A self code code N/A N/A N/A Exception __init__ self N/A N/A {0}: {1} format code message N/A N/A mkdir_p N/A N/A path N/A N/A N/A 
    mkdir -p
    http://stackoverflow.com/a/600612/127816
     N/A N/A N/A N/A N/A os makedirs path N/A N/A N/A OSError N/A exc N/A N/A N/A N/A N/A exc errno N/A errno EEXIST N/A N/A N/A os path isdir path N/A N/A N/A N/A N/A read_body N/A N/A environ N/A N/A N/A 
    Pull the body from the request and return it
     N/A length N/A N/A environ get CONTENT_LENGTH 0 N/A length N/A N/A length 0 N/A int length N/A N/A N/A N/A environ N/A wsgi.input read length N/A get_json N/A N/A environ N/A N/A N/A 
    Return the request body as JSON
     N/A content_type N/A N/A environ get CONTENT_TYPE N/A N/A content_type application/json N/A N/A N/A HTTPError 406 JSON required N/A N/A N/A N/A N/A json loads N/A read_body environ N/A N/A N/A ValueError N/A exc N/A N/A N/A HTTPError 400 exc N/A get_headers N/A N/A data extra_headers N/A None N/A N/A 
    Takes the response data as well as any additional headers and returns a
    tuple of tuples of headers suitable for passing to start_response()
     N/A response_headers N/A Content-Length N/A str N/A len data N/A extra_headers N/A N/A N/A N/A response_headers update extra_headers N/A N/A list N/A N/A response_headers items N/A run_chunk N/A N/A environ lowstate N/A N/A N/A 
    Expects a list of lowstate dictionaries that are executed and returned in
    order
     N/A client N/A environ N/A SALT_APIClient N/A chunk lowstate N/A N/A N/A N/A N/A client run chunk N/A dispatch N/A N/A environ N/A N/A N/A 
    Do any path/method dispatching here and return a JSON-serializable data
    structure appropriate for the response
     N/A method N/A N/A N/A environ N/A REQUEST_METHOD upper N/A N/A method GET N/A N/A They found me. I don't know how, but they found me. Run for it, Marty! N/A N/A N/A method POST N/A N/A data N/A get_json environ N/A N/A run_chunk environ data N/A N/A N/A HTTPError 405 Method Not Allowed N/A saltenviron N/A N/A environ N/A N/A N/A 
    Make Salt's opts dict and the APIClient available in the WSGI environ
     N/A N/A __opts__ N/A locals N/A N/A salt.config N/A __opts__ N/A N/A N/A salt config client_config N/A N/A N/A os environ get SALT_MASTER_CONFIG /etc/salt/master N/A N/A environ N/A SALT_OPTS __opts__ N/A N/A environ N/A SALT_APIClient N/A N/A N/A salt netapi NetapiClient __opts__ N/A application N/A N/A environ start_response N/A N/A N/A 
    Process the request and return a JSON response. Catch errors and return the
    appropriate HTTP code.
     N/A N/A saltenviron environ N/A N/A N/A resp N/A list N/A dispatch environ N/A code 200 N/A N/A N/A HTTPError N/A exc N/A N/A code N/A exc code N/A resp N/A str exc N/A N/A N/A N/A salt exceptions EauthAuthenticationError N/A exc N/A N/A code 401 N/A resp N/A str exc N/A N/A Exception N/A exc N/A N/A code 500 N/A resp N/A str exc N/A N/A N/A ret N/A N/A json dumps N/A return resp N/A N/A N/A TypeError N/A exc N/A N/A code 500 N/A ret N/A str exc N/A N/A start_response N/A H N/A code N/A get_headers ret N/A Content-Type application/json N/A N/A ret N/A get_opts N/A N/A N/A N/A N/A 
    Return the Salt master config as __opts__
     N/A salt.config N/A N/A N/A N/A salt config client_config N/A N/A N/A os environ get SALT_MASTER_CONFIG /etc/salt/master N/A start N/A N/A N/A N/A N/A 
    Start simple_server()
     wsgiref.simple_server make_server N/A N/A __opts__ N/A globals N/A N/A N/A N/A globals N/A __opts__ N/A get_opts N/A N/A N/A __virtual__ False N/A N/A N/A SystemExit 1 N/A mod_opts N/A N/A __opts__ get __virtualname__ N/A N/A httpd N/A make_server localhost N/A mod_opts N/A port application N/A N/A N/A N/A N/A httpd serve_forever N/A N/A N/A KeyboardInterrupt N/A N/A N/A SystemExit 0 N/A N/A N/A __name__ __main__ N/A N/A N/A start