This document offers a basic understanding of the REST API used by Ansible Tower.
REST stands for Representational State Transfer and is sometimes spelled as “ReST”. It relies on a stateless, client-server, and cacheable communications protocol, usually the HTTP protocol.
You may find it helpful see which API calls Tower makes in sequence. To do this, you can use the UI from Firebug or Chrome with developer plugins.
Another alternative is Charles Proxy (http://www.charlesproxy.com/), which offers a visualizer that you may find helpful. While it is commercial software, it can insert itself as an OS X proxy, for example, and intercept both requests from web browsers as well as curl and other API consumers.
Other alternatives include:
REST APIs provide access to resources (data entities) via URI paths. You can visit the Ansible Tower REST API in a web browser at: http://<Tower server name>/api/
Clicking on various links in the API allows you to explore related resources.
Clicking on the next to the page name (toward the top of the screen) for an API endpoint gives you documentation on the access methods for that particular API endpoint and what data is returned when using those methods.
You can also use PUT and POST verbs on the specific API pages by formatting JSON in the various text fields.
Tower uses a standard REST API, rooted at /api/
on the server. The API is versioned for compatibility reasons, but only /api/v1/
is currently available. You can see information about what API versions are available by querying /api/
.
You may have to specify the content/type on POST or PUT requests accordingly.
All URIs not ending with "/"
receive a 301 redirect.
Note
Ansible Tower 2.4.5 API change: Formatting of extra_vars attached to Job Template records is preserved. Previously, YAML would be converted to JSON and returned as JSON. In 2.2.0 and newer, YAML is returned as YAML with formatting and comments preserved, and JSON is returned as JSON.
To provide examples that are easy to follow, the following URL is used throughout this guide:
http://<Tower server name>/api/v1/groups/
To specify that {{ model_verbose_name_plural }} are returned in a particular order, use the order_by
query string parameter on the GET request.
http://<Tower server name>/api/v1/model_verbose_name_plural?order_by={{ order_field }}
Prefix the field name with a dash (-
) to sort in reverse:
http://<Tower server name>/api/v1/model_verbose_name_plural?order_by=-{{ order_field }}
Multiple sorting fields may be specified by separating the field names with a comma (,
):
http://<Tower server name>/api/v1/model_verbose_name_plural?order_by={{ order_field }},some_other_field
Use the search query string parameter to perform a case-insensitive search within all designated text fields of a model.
http://<Tower server name>/api/v1/model_verbose_name?search=findme
(Note: Added in AWX 1.4)
Any collection is what the system calls a “queryset” and can be filtered via various operators.
For example, to find the groups that contain the name “foo”:
http://<Tower server name>/api/v1/groups/?name__contains=foo
To find an exact match:
http://<Tower server name>/api/v1/groups/?name=foo
If a resource is of an integer type, you must add \_\_int
to the end to cast your string input value to an integer, like so:
http://<Tower server name>/api/v1/arbitrary_resource/?x__int=5
Related resources can also be queried, like so:
http://<Tower server name>/api/v1/groups/?user__firstname__icontains=john
This will return all groups with users with names that include the string “John” in them.
You can also filter against multiple fields at once:
http://<Tower server name>/api/v1/groups/?user__firstname__icontains=john&group__name__icontains=foo
This finds all groups containing a user whose name contains “John” where the group contains the string foo.
For more about what types of operators are available, refer to:
Note
You can also watch the API as the UI is being used to see how it is filtering on various criteria.
Any additional query string parameters may be used to filter the list of results returned to those matching a given value. Only fields and relations that exist in the database may be used for filtering. Any special characters in the specified value should be url-encoded. For example:
?field=value%20xyz
Fields may also span relations, only for fields and relationships defined in the database:
?other__field=value
To exclude results matching certain criteria, prefix the field parameter with not__
:
?not__field=value
(Added in AWX 1.4) By default, all query string filters are AND’ed together, so only the results matching all filters will be returned. To combine results matching any one of multiple criteria, prefix each query string parameter with or__
:
?or__field=value&or__field=othervalue
?or__not__field=value&or__field=othervalue
(Added in Ansible Tower 1.4.5) The default AND filtering applies all filters simultaneously to each related object being filtered across database relationships. The chain filter instead applies filters separately for each related object. To use, prefix the query string parameter with chain__
:
?chain__related__field=value&chain__related__field2=othervalue
?chain__not__related__field=value&chain__related__field2=othervalue
If the first query above were written as ?related__field=value&related__field2=othervalue
, it would return only the primary objects where the same related object satisfied both conditions. As written using the chain filter, it would return the intersection of primary objects matching each condition.
Field lookups may also be used for more advanced queries, by appending the lookup to the field name:
?field__lookup=value
The following field lookups are supported:
exact
: Exact match (default lookup if not specified).iexact
: Case-insensitive version of exact.contains
: Field contains value.icontains
: Case-insensitive version of contains.startswith
: Field starts with value.istartswith
: Case-insensitive version of startswith.endswith
: Field ends with value.iendswith
: Case-insensitive version of endswith.regex
: Field matches the given regular expression.iregex
: Case-insensitive version of regex.gt
: Greater than comparison.gte
: Greater than or equal to comparison.lt
: Less than comparison.lte
: Less than or equal to comparison.isnull
: Check whether the given field or related object is null; expects a boolean value.in
: Check whether the given field’s value is present in the list provided; expects a list of items.True
or 1
for true, False
or 0
for false (both case-insensitive).Null values may be specified as None
or Null
(both case-insensitive), though it is preferred to use the isnull
lookup to explicitly check for null values.
Lists (for the in
lookup) may be specified as a comma-separated list of values.
Responses for collections in the API are paginated. This means that while a collection may contain tens or hundreds of thousands of objects, in each web request, only a limited number of results are returned for API performance reasons.
When you get back the result for a collection you will see something similar to the following:
{'count': 25, 'next': 'http://testserver/api/v1/some_resource?page=2', 'previous': None, 'results': [ ... ] }
To get the next page, simply request the page given by the ‘next’ sequential URL.
Use the page_size=XX
query string parameter to change the number of results returned for each request.
Use the page
query string parameter to retrieve a particular page of results.
http://<Tower server name>/api/v1/model_verbose_name?page_size=100&page=2
The previous and next links returned with the results will set these query string parameters automatically.
The serializer is quite efficient, but you should probably not request page sizes beyond a couple of hundred.
The user interface uses smaller values to avoid the user having to do a lot of scrolling.
Certain fields in the REST API are marked read-only. These usually
include the URL of a resource, the ID, and occasionally some internal
fields. For instance, the 'created\_by'
attribute of each object
indicates which user created the resource, and cannot be edited.
If you post some values and notice that they are not changing, these fields may be read-only.
tower-cli is a command line tool for Ansible Tower. It allows Tower commands to be easily run from the UNIX command line. It can also be used as a client library for other python apps, or as a reference for others developing API interactions with Tower’s REST API.
Note
tower-cli is an open source project currently under development and, until a complete implementation occurs, only implements a subset of Tower’s features.
While Tower is commercially licensed software, tower-cli is an open source project. Specifically, this project is licensed under the Apache 2.0 license. Pull requests, contributions, and tickets filed in GitHub are warmly welcomed.
tower-cli sends commands to the Tower API. It is capable of retrieving, creating, modifying, and deleting most objects within Tower.
A few potential uses include:
tower-cli is available as a package on PyPI.
The preferred way to install is through pip:
$ pip install ansible-tower-cli
The main branch of this project may also be consumed directly from source.
For more information on tower-cli, refer to the project page at:
tower-cli can edit its own configuration or users can directly edit the configuration file, allowing configuration to be set in multiple ways.
The preferred way to set configuration is with the tower-cli config command.
$ tower-cli config key value
By issuing the tower-cli config
command without arguments, you can view a full list of configuration options and where they are set.
You will generally need to set at least three configuration options–host, username, and password–which correspond to the location of your Ansible Tower instance and your credentials to authenticate to Tower.
$ tower-cli config host tower.example.com
$ tower-cli config username leeroyjenkins
$ tower-cli config password myPassw0rd
The configuration file can also be edited directly. A configuration file is a simple file with keys and values, separated by :
or =
:
host: tower.example.com
username: admin
password: p4ssw0rd
The order of precedence for configuration file locations is as follows, from least to greatest:
/etc/awx/tower_cli.cfg
(written using tower-cli config --global
)~/.tower_cli.cfg
(written using tower-cli config
)CLI invocation generally follows this format:
$ tower-cli {resource} {action} ...
The “resource” is a type of object within Tower (a noun), such as user
, organization
, job_template
, etc.; resource names are always singular in Tower CLI (use tower-cli user
, never tower-cli users
).
The “action” is the thing you want to do (a verb). Most Tower CLI resources have the following actions–get
, list
, create
, modify
, and delete
–and have options corresponding to fields on the object in Tower.
Some examples:
# List all users.
$ tower-cli user list
# List all non-superusers
$ tower-cli user list --is-superuser=false
# Get the user with the ID of 42.
$ tower-cli user get 42
# Get the user with the given username.
$ tower-cli user get --username=guido
# Create a new user.
$ tower-cli user create --username=guido --first-name=Guido \
--last-name="Van Rossum" [email protected]
# Modify an existing user.
# This would modify the first name of the user with the ID of "42" to "Guido".
$ tower-cli user modify 42 --first-name=Guido
# Modify an existing user, lookup by username.
# This would use "username" as the lookup, and modify the first name.
# Which fields are used as lookups vary by resource, but are generally
# the resource's name.
$ tower-cli user modify --username=guido --first-name=Guido
# Delete a user.
$ tower-cli user delete 42
# Launch a job.
$ tower-cli job launch --job-template=144
# Monitor a job.
$ tower-cli job monitor 95
When in doubt, help is available:
$ tower-cli # help
$ tower-cli user --help # resource specific help
$ tower-cli user create --help # command specific help
Ansible Tower makes it simple to launch a job based on a Job Template from Tower’s API or by using the tower-cli
command line tool.
Launching a Job Template also:
Runtime data takes precedence over the Job Template data, and is not always allowed. For example, a runtime credential is only accepted if the Job Template does not have a credential set.
Launching from Job Templates via the API follows the following workflow:
GET https://your.tower.server/api/v1/job_templates/<your job template id>/launch/
Inspect returned data for runtime data that is needed to launch. Inspecting the OPTIONS of the launch endpoint may also help deduce what POST fields are allowed.
Warning
Providing certain runtime credentials could introduce the need for a password not listed in
passwords_needed_to_start
.
passwords_needed_to_start
: List of passwords neededcredential_needed_to_start
: Booleanvariables_needed_to_start
: List of fields that need to be passed inside of theextra_vars
dictionary
Inspect returned data for optionally allowed runtime data that the user should be asked for
ask_variables_on_launch
: Boolean specifying whether to prompt the user for additional variables to pass to Ansible inside of extra_vars
POST https://your.tower.server/api/v1/job_templates/<your job template id>/launch/
with any required data gathered during the previous step(s)
Please note that variables are provided to the playbook (and used in surveys) are accepted as sub-fields inside of the extra_vars field. Other data, such as passwords and credentials, are expected in the top-level JSON POST data.
Additionally, the extra_vars
field is where survey question answers should be placed.
The POST will return something similar to:
{ "job": 4 }
If you save that number and then do a GET request to the job page, /jobs/4
, you can find details about the job, get an updated status, a link to cancel the job run, and so forth.
tower-cli
Job Template Launching¶From the Tower command line, you can use tower-cli
as a method of launching your Job Templates.
For help with tower-cli
launch, use:
tower-cli job launch --help.
For launching from a job template, invoke tower-cli in a way similar to:
For an example of how to use the API, you can also add the -v
flag here:
tower-cli job launch --job-template=4 -v