AWX
AWX connections, automation templates, execution requests, webhook receiver, and reference data — endpoints under /api/awx/.
Eight ViewSets plus three webhook endpoints under /api/awx/. This is where network automation lives: connect Fabrik to AWX/Tower, define templates that turn Fabrik query results into playbook runs, and stream job status back over WebSocket.
Connections
GET /api/awx/connections/
List AWX connection records.
Resource shape:
{
"id": "…",
"name": "Production AWX",
"base_url": "https://awx.example.com",
"username": "fabrik-svc",
"token_configured": true,
"is_default": false,
"last_tested_at": "…",
"last_test_status": "success"
}OAuth2 tokens are write-only and Fernet-encrypted.
POST /api/awx/connections/
Create.
{
"name": "Production AWX",
"base_url": "https://awx.example.com",
"username": "fabrik-svc",
"oauth_token": "…",
"is_default": true
}POST /api/awx/connections/<id>/test/
Test reachability and auth against the AWX/Tower instance.
The connection ViewSet also exposes discovery actions used by the template wizard, all keyed off a saved connection: job-templates/, job-templates/<template_id>/, workflow-templates/, workflow-templates/<template_id>/, credentials/, and credential-types/.
Automation templates
Templates describe how Fabrik passes data to an AWX job template. They carry a schema (the columns the table needs), optional validation rules, and the execution mode.
GET /api/awx/templates/
List templates visible to the user. Permission-filtered via FabrikModelPermissions.
Filters: ?category=<id>, ?search=<term> (matches name/description/tags), ?ordering=<field>.
POST /api/awx/templates/
Create a template.
Request:
{
"name": "Tenant cleanup",
"category": 3,
"awx_connection": "<id>",
"awx_job_template_id": 42,
"execution_mode": "bulk",
"schema": [
{ "name": "tenant", "field_type": "text", "required": true },
{ "name": "action", "field_type": "enum", "choices": ["shutdown", "delete"] }
],
"validation_lists": [],
"allowed_groups": [2, 3]
}PATCH / DELETE /api/awx/templates/<id>/
Update or remove a template.
The template ViewSet also exposes data-validation actions used before a run is submitted: validate-input/, validate-sheets/, and validation-status/<task_id>/ (validation runs async — poll the status endpoint with the returned task ID).
There is no launch action on templates. To run a template, create an AutomationRequest (POST /api/awx/requests/) and then execute it — see below.
Automation requests
A request is the user's intent to run a template against a set of input rows. Execution is bulk only — one request produces a single AWX job (the historical per_row and hybrid modes were removed).
GET /api/awx/requests/
Paginated list.
Resource shape (list):
{
"id": "…",
"title": "Clean up pre-decomm tenants",
"description": "…",
"status": "running",
"template": "<id>",
"template_name": "Tenant cleanup",
"awx_connection": "<id>",
"awx_connection_name": "Lab AWX",
"target_apic": "<id>",
"target_apic_name": "lab-aci",
"awx_credential_id": 12,
"awx_credential_name": "lab-machine-cred",
"input_data": [ /* the rows */ ],
"requested_by": "alice",
"requested_at": "…",
"awx_job_id": 8472,
"check_mode": false,
"scheduled_for": null,
"approved_by": null,
"approved_at": null,
"rejection_reason": null
}Request actions
All are detail-level POST:
execute/— submit the request to AWX (launches the job).retry/— re-submit a failed request.approve//reject/— approval workflow for templates that require it.rollback/— trigger the configured rollback for a completed request.
Automation executions
Each launched AWX job is tracked as an AutomationExecution. Since requests are bulk-only, a request maps to one execution (plus any relaunches).
GET /api/awx/executions/
Read-only list/detail.
Resource shape (list):
{
"id": "…",
"automation_request": "<id>",
"automation_request_title": "Clean up pre-decomm tenants",
"template_name": "Tenant cleanup",
"awx_job_id": 8472,
"awx_job_url": "https://awx.example.com/#/jobs/playbook/8472/output",
"status": "successful",
"progress_percentage": 100,
"current_task": null,
"playbook_counts": { "ok": 12, "changed": 3, "failed": 0 },
"started_at": "…",
"finished_at": "…",
"elapsed_seconds": 47,
"relaunch_of": null,
"relaunch_count": 0,
"created_at": "…",
"updated_at": "…"
}Execution actions
POST /api/awx/executions/<id>/cancel/— cancel a running job.POST /api/awx/executions/<id>/relaunch/— relaunch the job as a new execution.GET /api/awx/executions/<id>/output/— full job stdout. Prefer the WebSocket stream for live runs.GET /api/awx/executions/<id>/download-output/— stdout as a downloadable file.GET /api/awx/executions/<id>/workflow-nodes/— for workflow-template jobs, the per-node breakdown.GET /api/awx/executions/<id>/node-output/<awx_job_id>/— stdout for one workflow node.GET /api/awx/executions/<id>/row-results/— per-input-row results for the run.
Reference data
Three small ViewSets that power template authoring:
/api/awx/categories/
Flat categories for organizing templates (name, description, color, icon, display_order). No nesting.
/api/awx/column-templates/
Reusable column definitions (e.g. "IPv4 address", "VLAN ID"). Reference them by ID from template schemas instead of re-defining.
/api/awx/validation-lists/
Named lists of allowed values (e.g. valid tenant names). Reference from a schema column's validation_list field.
/api/awx/regex-patterns/
Named regex patterns for column validation.
All four support standard CRUD.
Webhook receiver
AWX calls these when job state changes. Not for manual use — documented for firewall and debugging visibility.
POST /api/awx/webhooks/receiver/
AWX → Fabrik webhook. Requires the X-AWX-Webhook-Signature header matching AWX_WEBHOOK_SECRET. The receiver validates the signature, then calls JobMonitor.sync_job_status() directly to reconcile the execution row with AWX. A 30-second Celery beat task polls AWX as a safety net for missed webhooks.
GET /api/awx/webhooks/health/
Anonymous health check for AWX notification templates. Always returns { "status": "ok" }.
POST /api/awx/webhooks/test/
Admin-only. Sends a synthetic event through the receiver to verify the chain is wired up.
If webhook events stop arriving, check three things in order: AWX's own notification delivery log, docker compose logs backend | grep awx_webhook for receiver errors, and whether the 30-second awx.sync_running_jobs Celery task is also failing (which would point at the AWX connection rather than the webhook path).