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 a 301

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=
  • 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=

Search accross related fields with related__search

http://<Tower server name>/api/v2/model_verbose_name?related__search=

Filtering

Contains: use field__contains=

http://<Tower server name>/api/v2/groups/?name__contains=foo

Exact match: use field=

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:

  1. Session Authentication
  2. Basic Authentication
  3. OAuth 2 Token Authentication
  4. 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

An 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 needed
  • credential_needed_to_start: Boolean
  • inventory_needed_to_start: Boolean
  • variables_needed_to_start: List of fields that need to be passed inside of the extra_vars dictionary
  • ask_variables_on_launch: Boolean specifying whether to prompt the user for additional variables to pass to Ansible inside of extra_vars
  • ask_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 launch
  • ask_limit_on_launch: Boolean specifying whether to prompt the user for limit on launch
  • ask_inventory_on_launch: Boolean specifying whether to prompt the user for the related field inventory on launch
  • ask_credential_on_launch: Boolean specifying whether to prompt the user for the related field credential on launch
  • survey_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 questions
  • job_tags: A string that represents a comma-separated list of tags in the playbook to run
  • limit: A string that represents a comma-separated list of hosts or groups to operate on
  • inventory: A integer value for the foreign key of an inventory to use in this job run
  • credential: A integer value for the foreign key of a credential to use in this job run

Source