Problems with AWX REST API schema definition

First of all i am not sure if i am in the correct place but since i was a little lost in api specs: (Sorry your system didnt allow me to post links)

  • Readhat api-catalog ansible-automation-controller
  • AWX REST API
  • Automation Controller API
  • Ansible TOWER API (redirected from deployed Ansible Automation Platform in browseable API)

i’ll try my luck here. I try to use the AWX REST API in a java based application to call a job template of the Ansible Automation Platform. So first i tried “to find” the schema definition to generate my stubs.
In some Thread here someone pointed out it could be obtained via s3.amazonaws.com/awx-public-ci-files/devel/schema.json (maybe a possibility to download it directly in the docs would be handy).

As first test i call the /api/v2/job_templates/{id}/launch/ (POST) Endpoint and was a little confused about the specification.

  • First i need to provide a version but its not defined in any way. Is the purpose to use it as /api/{version}/job_templates/{id}/launch/ ?
  • Further i got exceptions after receiving the response because passwords_needed_to_start is defined as String in the JobLaunch but in reality (in my case) the Ansible Automation Platform returns an (empty) array. Also in the description it is mentioned that it would be an array so i guess the current definition is faulty? (Maybe this also effects JobDetail, JobList and JobRelaunch)
  • In the end i tried to get the id from my call for further operations but i found out i couldn’t. That’s since the response is defined as #/definitions/JobLaunch which doesn’t contain the information. But in reality i get following response structure:
{
	"job": 1,
	"ignored_fields": {
		
	},
	"id": 1,
	"type": "job",
	"url": "/api/v2/jobs/1/",
	"related": {
		"created_by": "/api/v2/users/2/",
		"modified_by": "/api/v2/users/2/",
		"labels": "/api/v2/jobs/1/labels/",
		"inventory": "/api/v2/inventories/57/",
		"project": "/api/v2/projects/3/",
		"organization": "/api/v2/organizations/11/",
		"credentials": "/api/v2/jobs/1/credentials/",
		"unified_job_template": "/api/v2/job_templates/8452/",
		"stdout": "/api/v2/jobs/1/stdout/",
		"execution_environment": "/api/v2/execution_environments/3/",
		"job_events": "/api/v2/jobs/1/job_events/",
		"job_host_summaries": "/api/v2/jobs/1/job_host_summaries/",
		"activity_stream": "/api/v2/jobs/1/activity_stream/",
		"notifications": "/api/v2/jobs/1/notifications/",
		"create_schedule": "/api/v2/jobs/1/create_schedule/",
		"job_template": "/api/v2/job_templates/8452/",
		"cancel": "/api/v2/jobs/1/cancel/",
		"relaunch": "/api/v2/jobs/1/relaunch/"
	},
	"summary_fields": {
		"organization": {
			"id": 11,
			"name": "name",
			"description": "description"
		},
		"inventory": {
			"id": 57,
			"name": "name",
			"description": "description",
			"has_active_failures": true,
			"total_hosts": 5,
			"hosts_with_active_failures": 1,
			"total_groups": 0,
			"has_inventory_sources": false,
			"total_inventory_sources": 0,
			"inventory_sources_with_failures": 0,
			"organization_id": 11,
			"kind": ""
		},
		"execution_environment": {
			"id": 3,
			"name": "1 DEFAULT | RedHat ee-supported-rhel8",
			"description": "Ansible Engine v2.15. configuration_as_code managed.",
			"image": "ansible-automation-platform-24/ee-supported-rhel8:latest"
		},
		"project": {
			"id": 3,
			"name": "1",
			"description": "2",
			"status": "successful",
			"scm_type": "git",
			"allow_override": true
		},
		"job_template": {
			"id": 8452,
			"name": "name",
			"description": "description"
		},
		"unified_job_template": {
			"id": 8452,
			"name": "name",
			"description": "description",
			"unified_job_type": "job"
		},
		"created_by": {
			"id": 2,
			"username": "user",
			"first_name": "first",
			"last_name": "last"
		},
		"modified_by": {
			"id": 2,
			"username": "user",
			"first_name": "first",
			"last_name": "last"
		},
		"user_capabilities": {
			"delete": false,
			"start": true
		},
		"labels": {
			"count": 0,
			"results": []
		},
		"credentials": [
			{
				"id": 1583,
				"name": "name",
				"description": "description",
				"kind": "ssh",
				"cloud": false
			},
			{
				"id": 1948,
				"name": "name",
				"description": "",
				"kind": "vault",
				"cloud": false
			},
			{
				"id": 1686,
				"name": "name",
				"description": "description",
				"kind": "vault",
				"cloud": false
			},
			{
				"id": 1928,
				"name": "name",
				"description": "descp",
				"kind": "vault",
				"cloud": false
			}
		]
	},
	"created": "2024-08-08T09:49:53.994483Z",
	"modified": "2024-08-08T09:49:54.036005Z",
	"name": "name",
	"description": "description",
	"job_type": "run",
	"inventory": 57,
	"project": 3,
	"playbook": "playbook.yml",
	"scm_branch": "1.2.3.4",
	"forks": 0,
	"limit": "host",
	"verbosity": 0,
	"extra_vars": "{\"version\": \"1\"}",
	"job_tags": "tags",
	"force_handlers": false,
	"skip_tags": "",
	"start_at_task": "",
	"timeout": 0,
	"use_fact_cache": false,
	"organization": 11,
	"unified_job_template": 8452,
	"launch_type": "manual",
	"status": "pending",
	"execution_environment": 3,
	"failed": false,
	"started": null,
	"finished": null,
	"canceled_on": null,
	"elapsed": 0.0,
	"job_args": "",
	"job_cwd": "",
	"job_env": {
		
	},
	"job_explanation": "",
	"execution_node": "",
	"controller_node": "",
	"result_traceback": "",
	"event_processing_finished": false,
	"launched_by": {
		"id": 2,
		"name": "someuser",
		"type": "user",
		"url": "/api/v2/users/2/"
	},
	"work_unit_id": null,
	"job_template": 8452,
	"passwords_needed_to_start": [],
	"allow_simultaneous": false,
	"artifacts": {
		
	},
	"scm_revision": "",
	"instance_group": null,
	"diff_mode": false,
	"job_slice_number": 0,
	"job_slice_count": 1,
	"webhook_service": "",
	"webhook_credential": null,
	"webhook_guid": ""
}

All informations i need would be present but not accessible.

  • Is my assumption correct that the AWX REST API is the point of truth? Or is the API changed extended in Ansible Automation Controller/Ansible Tower?
  • Is it even correct to assume that only one “v2” API exists and any little change would result in “v3”?
  • If not how can i find out which exactly version of the AWX REST API the Ansible Automation Platform is using (Can’t find any hint in any docs)
  • Am i using the API correctly? Since i am not familiar with all aspects of the products/api i am not sure if i use it as intended?

Current Endpoint Definition:

"/api/v2/job_templates/{id}/launch/": {
  "get": {
	"description": "...",
	"operationId": "api_job_templates_launch_read",
	"parameters": [],
	"responses": {
	  "200": {
		"description": "",
		"schema": {
		  "$ref": "#/definitions/JobLaunch"
		}
	  }
	},
	"summary": "Make a GET request to this resource to determine if the job_template can be",
	"tags": [
	  "api"
	]
  },
  "parameters": [
	{
	  "in": "path",
	  "name": "version",
	  "required": true,
	  "type": "string"
	},
	{
	  "in": "path",
	  "name": "id",
	  "required": true,
	  "type": "string"
	}
  ],
  "post": {
	"description": "...",
	"operationId": "api_job_templates_launch_create",
	"parameters": [
	  {
		"in": "body",
		"name": "data",
		"required": true,
		"schema": {
		  "$ref": "#/definitions/JobLaunch"
		}
	  }
	],
	"responses": {
	  "201": {
		"description": "",
		"schema": {
		  "$ref": "#/definitions/JobLaunch"
		}
	  }
	},
	"summary": "Make a GET request to this resource to determine if the job_template can be",
	"tags": [
	  "api"
	]
  }
}

Schema Definition of JobLaunch:

"JobLaunch": {
      "properties": {
        "ask_credential_on_launch": {
          "readOnly": true,
          "title": "Ask credential on launch",
          "type": "boolean",
          "x-nullable": true
        },
        "ask_diff_mode_on_launch": {
          "readOnly": true,
          "title": "Ask diff mode on launch",
          "type": "boolean",
          "x-nullable": true
        },
        "ask_execution_environment_on_launch": {
          "readOnly": true,
          "title": "Ask execution environment on launch",
          "type": "boolean",
          "x-nullable": true
        },
        "ask_forks_on_launch": {
          "readOnly": true,
          "title": "Ask forks on launch",
          "type": "boolean",
          "x-nullable": true
        },
        "ask_instance_groups_on_launch": {
          "readOnly": true,
          "title": "Ask instance groups on launch",
          "type": "boolean",
          "x-nullable": true
        },
        "ask_inventory_on_launch": {
          "readOnly": true,
          "title": "Ask inventory on launch",
          "type": "boolean",
          "x-nullable": true
        },
        "ask_job_slice_count_on_launch": {
          "readOnly": true,
          "title": "Ask job slice count on launch",
          "type": "boolean",
          "x-nullable": true
        },
        "ask_job_type_on_launch": {
          "readOnly": true,
          "title": "Ask job type on launch",
          "type": "boolean",
          "x-nullable": true
        },
        "ask_labels_on_launch": {
          "readOnly": true,
          "title": "Ask labels on launch",
          "type": "boolean",
          "x-nullable": true
        },
        "ask_limit_on_launch": {
          "readOnly": true,
          "title": "Ask limit on launch",
          "type": "boolean",
          "x-nullable": true
        },
        "ask_scm_branch_on_launch": {
          "readOnly": true,
          "title": "Ask scm branch on launch",
          "type": "boolean",
          "x-nullable": true
        },
        "ask_skip_tags_on_launch": {
          "readOnly": true,
          "title": "Ask skip tags on launch",
          "type": "boolean",
          "x-nullable": true
        },
        "ask_tags_on_launch": {
          "readOnly": true,
          "title": "Ask tags on launch",
          "type": "boolean",
          "x-nullable": true
        },
        "ask_timeout_on_launch": {
          "readOnly": true,
          "title": "Ask timeout on launch",
          "type": "boolean",
          "x-nullable": true
        },
        "ask_variables_on_launch": {
          "readOnly": true,
          "title": "Ask variables on launch",
          "type": "boolean",
          "x-nullable": true
        },
        "ask_verbosity_on_launch": {
          "readOnly": true,
          "title": "Ask verbosity on launch",
          "type": "boolean",
          "x-nullable": true
        },
        "can_start_without_user_input": {
          "readOnly": true,
          "title": "Can start without user input",
          "type": "boolean"
        },
        "credential_needed_to_start": {
          "readOnly": true,
          "title": "Credential needed to start",
          "type": "string"
        },
        "credential_passwords": {
          "title": "Credential passwords",
          "type": "string"
        },
        "credentials": {
          "items": {
            "type": "integer"
          },
          "type": "array",
          "uniqueItems": true
        },
        "defaults": {
          "readOnly": true,
          "title": "Defaults",
          "type": "string"
        },
        "diff_mode": {
          "title": "Diff mode",
          "type": "boolean"
        },
        "execution_environment": {
          "title": "Execution environment",
          "type": "integer"
        },
        "extra_vars": {
          "title": "Extra vars",
          "type": "object"
        },
        "forks": {
          "minimum": 0,
          "title": "Forks",
          "type": "integer"
        },
        "instance_groups": {
          "items": {
            "type": "integer"
          },
          "type": "array",
          "uniqueItems": true
        },
        "inventory": {
          "title": "Inventory",
          "type": "integer"
        },
        "inventory_needed_to_start": {
          "readOnly": true,
          "title": "Inventory needed to start",
          "type": "string"
        },
        "job_slice_count": {
          "minimum": 0,
          "title": "Job slice count",
          "type": "integer"
        },
        "job_tags": {
          "title": "Job tags",
          "type": "string"
        },
        "job_template_data": {
          "readOnly": true,
          "title": "Job template data",
          "type": "string"
        },
        "job_type": {
          "enum": [
            "run",
            "check"
          ],
          "title": "Job type",
          "type": "string"
        },
        "labels": {
          "items": {
            "type": "integer"
          },
          "type": "array",
          "uniqueItems": true
        },
        "limit": {
          "title": "Limit",
          "type": "string"
        },
        "passwords_needed_to_start": {
          "readOnly": true,
          "title": "Passwords needed to start",
          "type": "string"
        },
        "scm_branch": {
          "title": "Scm branch",
          "type": "string"
        },
        "skip_tags": {
          "title": "Skip tags",
          "type": "string"
        },
        "survey_enabled": {
          "readOnly": true,
          "title": "Survey enabled",
          "type": "string"
        },
        "timeout": {
          "title": "Timeout",
          "type": "integer"
        },
        "variables_needed_to_start": {
          "readOnly": true,
          "title": "Variables needed to start",
          "type": "string"
        },
        "verbosity": {
          "enum": [
            0,
            1,
            2,
            3,
            4,
            5
          ],
          "title": "Verbosity",
          "type": "integer"
        }
      },
      "type": "object"
    }

I would happy if anybody could help me with this or point me to the correct direction.

Welcome to the forum, @TimS .

I’m no authority on AWX, REST, or API schemas, but I fumbled my way through what I needed to know by pointing my browser at our AWX instance to get logged in, then exploring the API directly in the browser.

For example, if you hit https://{your.awx.instance}/api/ it will return a page showing (among other things, in our case)

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
X-API-Node: […]
X-API-Product-Name: AWX
X-API-Product-Version: 24.6.0
X-API-Time: 0.019s

{
    "description": "AWX REST API",
    "current_version": "/api/v2/",
    "available_versions": {
        "v2": "/api/v2/"
    },
    "oauth2": "/api/o/",
    "custom_logo": "data:image/png;base64,[…]",
    "custom_login_info": "[…]",
    "login_redirect_override": "[…]"
}

That answers one of your questions: how to find out which version(s) of the API are available. In our case, there’s only that one: “v2”.

In the actual page, that “/api/v2/” is a link which, if you follow it, will take you to a page listing all the top-level API mid-points/end-points, each of which are themselves links to similar pages etc.

I believe exploring that will give you the insights you need to answer most of your other questions. As I said, I’m no expert on this stuff. I’ve just used what I’ve found through the above procedure to be able to do what I’ve needed to do.

And I’m hoping someone else will clarify my glaring omissions or misstatements. :slight_smile:

Thanks @utoddl,

for trying to help. I checked again but in my case it’s

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
X-API-Node: [...]
X-API-Product-Name: Red Hat Ansible Automation Platform
X-API-Product-Version: 4.5.8
X-API-Time: 0.183s

{
    "description": "AWX REST API",
    "current_version": "/api/v2/",
    "available_versions": {
        "v2": "/api/v2/"
    },
    "custom_logo": "data:image/png;base64,[…]",
    "custom_login_info": "[…]",
    "login_redirect_override": "[…]"
}

So the Ansible Automation Platform states it’s using the AWX REST API (In the description) in the API-Product-Version 4.5.8? That’s what i ment with i was a little lost in api specs:

  • AWX REST API doesn’t exist in this version
  • Ansible Tower API doesn’t exist in this version
    ** link\docs.ansible.com\ansible-tower\4.5.8\html\towerapi\index.html (404)
    ** link\docs.ansible.com\ansible-tower\latest\html\towerapi\index.html (Still latest points to 3.8.6 so this couldn’t be either)
  • Ansible Automation Platform (from the API-Product -Name) doesn’t exist in this version either (latest is 2.4)
  • Automation Controller - latest is 4.5 (currently best match i guess)
    ** Documentation moved to link\docs.redhat.com\en\documentation\red_hat_ansible_automation_platform\2.4\html\automation_controller_user_guide\index
    ** link\developers.redhat.com\api-catalog\api\ansible-automation-controller (looks little bit different)
    ** But documentation also points to the community Documentation of AWX (loop back to point 1)

So i wondered who defines the API they all have in common and is the REST API identically overall? Since the only schema definition i found was AWX i started with it but it doesn’t seem to match.

Of course i can fix all of those issues on client side and handle them how it should work but i am still interested in the real source i should be using and why it’s so hard to find it :slight_smile:

I’d ignore the headers. Truth - to the extent there is any - is in the json body.
(Unless I’m wrong. But I’m not in a json body, so…)

API Catalog is the most recently-published controller API guide. Is that pointing to AWX documentation somewhere?

See Automation Controller API Guide v4.5 — Automation Controller API Guide v4.5

It looks like the Ansible Automation Platform controller API you mentioned “lost” some information. For example the referenced request/response schemas are missing. Any chance i can get the schema file which is rendered there?

Ah so the old controller page points to the AAP API guide, and also a pointer for the AWX API guide. That probably needs to stay because it’s only recently (in awx time) that we’ve had the AWX API guide available.

But good catch on the lost info on the AAP controller API guide! I’ll open a jira ticket for that one. Are the request/response schemas in the AWX API guide or are they missing from both? (sorry, don’t really know AWX/controller so not sure what I’m looking for)

doh! okay looks like there is an AAP Controller API overview guide that’s separate from the actuall API details… Does THAT have the missing info?

Although @samccann addressed the documentation issue I wanted to clarify the versioning issue:

  • AWX is the upstream project of “automation controller” (formerly Ansible Tower), a single component of Ansible Automation Platform (AAP), which includes several other (Hub, EDA, navigator, etc.). You will see references to AWX and Tower in source code and documentation due to legacy or internal naming needs (“AWX REST API”).
  • “automation controller” has it’s own version, different from AAP and AWX. In this case, automation controller is version 4.5.8, while AAP is version 2.4. There is no direct AWX version to AAP controller version match. You can see the internal components of AAP and their versions in the AAP life cycle page.
  • The API is version 2.

Of course, all these things are related in some way during releases, but as “automation controller” is a stable component of AAP there might be differences with AWX, which is a faster moving project (and incidentally going through some changes, see: awx-modernization), so you should always check with AAP documentation or Red Hat support if in doubt. Specially if you are integrating it with other systems.