Awx Rest Api
AWX: Rest API Docs#
REST - Representation State Transfer
- Stateless
- Client - server
- Over HTTP using HTTP verbs and resources for crud operations
- Hypermedia - links
Api Visualisers#
To visualise the API calls being made use the built in network inspect in you browser’s developer tools or one of these:
- https://www.charlesproxy.com/
- https://www.telerik.com/fiddler
- https://mitmproxy.org/
- https://addons.mozilla.org/en-US/firefox/addon/live-http-headers/
- https://sourceforge.net/projects/paros/
Browsabel API#
AWX provides a browsable API (brought to you by DRF), it is at:
http://<Tower server name>/api/
There are 2 versions, v1
will be removed in future releases.
Resources#
The resources in v2
:
{
"ping": "/api/v2/ping/",
"instances": "/api/v2/instances/",
"instance_groups": "/api/v2/instance_groups/",
"config": "/api/v2/config/",
"settings": "/api/v2/settings/",
"me": "/api/v2/me/",
"dashboard": "/api/v2/dashboard/",
"organizations": "/api/v2/organizations/",
"users": "/api/v2/users/",
"projects": "/api/v2/projects/",
"project_updates": "/api/v2/project_updates/",
"teams": "/api/v2/teams/",
"credentials": "/api/v2/credentials/",
"credential_types": "/api/v2/credential_types/",
"credential_input_sources": "/api/v2/credential_input_sources/",
"applications": "/api/v2/applications/",
"tokens": "/api/v2/tokens/",
"metrics": "/api/v2/metrics/",
"inventory": "/api/v2/inventories/",
"inventory_scripts": "/api/v2/inventory_scripts/",
"inventory_sources": "/api/v2/inventory_sources/",
"inventory_updates": "/api/v2/inventory_updates/",
"groups": "/api/v2/groups/",
"hosts": "/api/v2/hosts/",
"job_templates": "/api/v2/job_templates/",
"jobs": "/api/v2/jobs/",
"job_events": "/api/v2/job_events/",
"ad_hoc_commands": "/api/v2/ad_hoc_commands/",
"system_job_templates": "/api/v2/system_job_templates/",
"system_jobs": "/api/v2/system_jobs/",
"schedules": "/api/v2/schedules/",
"roles": "/api/v2/roles/",
"notification_templates": "/api/v2/notification_templates/",
"notifications": "/api/v2/notifications/",
"labels": "/api/v2/labels/",
"unified_job_templates": "/api/v2/unified_job_templates/",
"unified_jobs": "/api/v2/unified_jobs/",
"activity_stream": "/api/v2/activity_stream/",
"workflow_job_templates": "/api/v2/workflow_job_templates/",
"workflow_jobs": "/api/v2/workflow_jobs/",
"workflow_approvals": "/api/v2/workflow_approvals/",
"workflow_job_template_nodes": "/api/v2/workflow_job_template_nodes/",
"workflow_job_nodes": "/api/v2/workflow_job_nodes/"
}
Conventions#
- Requests should end in
/
otherwise they are redirected with a301
Querying#
Getting data
GET http://<Tower server name>/api/v2/groups/
Getting data in order
Use
order_by
query parameter
http://<Tower server name>/api/v2/groups?order_by={{ order_field }}
- To sort in reverse order prefix with a
-
- Multiple sorting is seperated with a
,
Searching#
Use the
search
query parameter
http://<Tower server name>/api/v2/groups?search={{ query_term }}
Search accross related fields with related__search
http://<Tower server name>/api/v2/model_verbose_name?related__search={{ query_term }}
Filtering#
Contains: use field__contains={{ term }}
http://<Tower server name>/api/v2/groups/?name__contains=foo
Exact match: use field={{ term }}
http://<Tower server name>/api/v2/groups/?name=foo
Casting to integer
http://<Tower server name>/api/v2/groups/?x__int=5
Related resources: All users that contain kim
in name
http://<Tower server name>/api/v2/users/?first_name__icontains=kim
Filter on multiple fields
http://<Tower server name>/api/v2/groups/?name__icontains=test&has_active_failures=false
It uses the django queryset filtering conventions
Special characters should be url encoded:
?field=value%20xyz
fields (in the db) can span relationships:
?other__field=value
Exclude criteria
?not__field=value
Using and
and or
:
?or__field=value&or__field=othervalue
?or__not__field=value&or__field=othervalue
Chain related:
?chain__related__field=value&chain__related__field2=othervalue
?chain__not__related__field=value&chain__related__field2=othervalue
Field Lookups#
?field__lookup=value
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. (comma seperated)
Boolean values may be specified as 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.
Test filtering on a certain user’s role level:
role_level
: Level of role to filter on, such as admin_role
Pagination#
Responses are paginated you get back something like this:
{'count': 25, 'next': 'http://testserver/api/v2/some_resource?page=2', 'previous': None, 'results': [ ... ] }
To get the next page, make a query to the next
link
Use page_size=XX
to change the number of results for each request - with a defualt max of 200
. That max can be changed in config.
Retrieve a particular page with the page
query parameter:
http://<Tower server name>/api/v2/model_verbose_name?page_size=100&page=2
Accessing Resources#
In Tower 3.1 and 3.2 you could only access resources with their pk
:
/api/v2/hosts/2/
In newer versions you can access resources with their names:
/api/v2/hosts/host_name++inv_name++org_name/
The configuration is accessible at:
/api/v2/settings/named-url/
More info on named resource configuration in the docs
API Reference#
The awx api reference is available
Authenticating#
There are various methods for authenticating on ansible tower / awx:
- Session Authentication
- Basic Authentication
- OAuth 2 Token Authentication
- SSO (single sign on) - SAML, LDAP (SSO), github, Azure AD, Radius, Google oAuth
Under Oauth there is the following methods for obtaining an access token:
- Personal access tokens (PAT)
- Application Token: Password grant type
- Application Token: Implicit grant type
- Application Token: Authorization Code grant type
If another application is interfacing with Tower/AWX - but you want users in AWX/Tower to allow permission to the app - then you want to use OAuth and the authorization code flow.
To set that up look at the admin docs on token based authnetication
A B2B application using Ansible#
Usually you would use the OAuth Client Credentials flow. However this flow is not Oauth. It is simple personal access Tokens - token auth. Or am I wrong?
After creating a user on awx. Make a request for a token:
http -a username:password POST https://<tower-host>/api/v2/tokens/
Response:
HTTP/1.1 201 Created
Allow: GET, POST, HEAD, OPTIONS
Connection: keep-alive
Content-Language: en
Content-Length: 486
Content-Security-Policy: default-src 'self'; connect-src 'self' ws: wss:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' *.pendo.io; img-src 'self' *.pendo.io data:; report-uri /csp-violation/
Content-Type: application/json
Date: Wed, 27 May 2020 10:22:33 GMT
Location: /api/v2/tokens/1/
Server: openresty/1.15.8.1
Strict-Transport-Security: max-age=15724800; includeSubDomains
Vary: Accept, Accept-Language, Origin, Cookie
X-API-Node: awx-bd8bbc7-79rq5
X-API-Time: 0.766s
X-API-Total-Time: 1.206s
X-Content-Security-Policy: default-src 'self'; connect-src 'self' ws: wss:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' *.pendo.io; img-src 'self' *.pendo.io data:; report-uri /csp-violation/
X-Frame-Options: DENY
{
"application": null,
"created": "2020-05-27T10:22:32.433229Z",
"description": "",
"expires": "3019-09-28T10:22:32.425120Z",
"id": 1,
"modified": "2020-05-27T10:22:32.499876Z",
"refresh_token": null,
"related": {
"activity_stream": "/api/v2/tokens/1/activity_stream/",
"user": "/api/v2/users/13/"
},
"scope": "write",
"summary_fields": {
"user": {
"first_name": "",
"id": 13,
"last_name": "",
"username": "api"
}
},
"token": "MgsDkwXRP9bX4NQmh4cIoQomVn2ax9",
"type": "o_auth2_access_token",
"url": "/api/v2/tokens/1/",
"user": 13
}
Use the token
in the response for further requests, like getting all jobs:
http GET https://<tower>/api/v2/jobs/ Authorization:"Bearer MgsDkwXRP9bX4NQmh4cIoQomVn2ax9"
Launching a Job#
To launch a job
Get the specific job template launch:
http GET https://<tower>/api/v2/job_templates/12/launch/ Authorization:"Bearer MgsDkwXRP9bX4NQmh4cIoQomVn2ax9"
Inspect the response for the required variables:
passwords_needed_to_start
: List of passwords neededcredential_needed_to_start
: Booleaninventory_needed_to_start
: Booleanvariables_needed_to_start
: List of fields that need to be passed inside of the extra_vars dictionaryask_variables_on_launch
: Boolean specifying whether to prompt the user for additional variables to pass to Ansible inside of extra_varsask_tags_on_launch
: Boolean specifying whether to prompt the user for job_tags on launch (allow allows use of skip_tags for convienience)ask_job_type_on_launch
: Boolean specifying whether to prompt the user for job_type on launchask_limit_on_launch
: Boolean specifying whether to prompt the user for limit on launchask_inventory_on_launch
: Boolean specifying whether to prompt the user for the related field inventory on launchask_credential_on_launch
: Boolean specifying whether to prompt the user for the related field credential on launchsurvey_enabled
: Boolean specifying whether to prompt the user for additional extra_vars, following the job template’s survey_spec Q&A format
Ensure that you have gathered all the required variables then launch the job:
http POST https://<tower>/api/v2/job_templates/<your job template id>/launch/
with the required variables:
extra_vars
: A string that represents a JSON or YAML formatted dictionary (with escaped parentheses) which includes variables given by the user, including answers to survey questionsjob_tags
: A string that represents a comma-separated list of tags in the playbook to runlimit
: A string that represents a comma-separated list of hosts or groups to operate oninventory
: A integer value for the foreign key of an inventory to use in this job runcredential
: A integer value for the foreign key of a credential to use in this job run