From f288b09e564bfffccbad601b6935f67c84534b43 Mon Sep 17 00:00:00 2001 From: Michael Elrom Date: Fri, 28 Aug 2026 11:15:44 -0400 Subject: [PATCH] feat(f5): add F5 Insight Integration Model and Studio Project Curated OpenAPI spec (227 of 281 upstream operations) covering device fleet management, device templates, software distribution/installation, upgrade orchestration, backup/storage, and licensing, plus a Studio Project with 227 ready-to-import workflows across 27 folders. --- F5/Insight/OpenAPIs/f5_insight-latest.json | 25864 ++++++++++ F5/Insight/OpenAPIs/f5_insight-v1.2.2.json | 33461 +++++++++++++ F5/Insight/README.md | 132 + .../Studio Projects/F5 Insight.project.json | 40897 ++++++++++++++++ README.md | 2 +- 5 files changed, 100355 insertions(+), 1 deletion(-) create mode 100644 F5/Insight/OpenAPIs/f5_insight-latest.json create mode 100644 F5/Insight/OpenAPIs/f5_insight-v1.2.2.json create mode 100644 F5/Insight/README.md create mode 100644 F5/Insight/Studio Projects/F5 Insight.project.json diff --git a/F5/Insight/OpenAPIs/f5_insight-latest.json b/F5/Insight/OpenAPIs/f5_insight-latest.json new file mode 100644 index 0000000..32d56e7 --- /dev/null +++ b/F5/Insight/OpenAPIs/f5_insight-latest.json @@ -0,0 +1,25864 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "F5 Insight", + "description": "Unified API for F5 Insight monitoring and analytics platform including device management, system operations, and AI-powered insights", + "version": "latest", + "x-vendor-api-version": "v1.2.2", + "x-itential-curated": "Trimmed to 227 of 281 upstream operations covering device management, device templates, inventory, cloud environments/providers, infrastructure discovery, jobs, observability, backup, software distribution/installation, upgrade orchestration, configuration, licensing, images, scheduling, VM tasks, compatibility checks, flight checks, health/readiness, storage, audit events, workflows, and validation. Dropped: authentication/authorization/identity-provider administration (one-time setup, not routine automation), AI-assistant chat history and insights, feature flags, and other internal admin tooling, plus operations requiring multipart file uploads (image/backup/upgrade-bundle uploads, device migration bundles), which are outside this repo's REST/JSON automation scope. See the repo README for the full breakdown and the full spec." + }, + "servers": [ + { + "url": "/" + } + ], + "security": [ + { + "basicAuth": [] + } + ], + "paths": { + "/api/ai-integrations/aidf": { + "get": { + "x-mode": "lite", + "tags": [ + "Configuration" + ], + "summary": "Get current AIDF configuration", + "operationId": "getCurrentAIDFConfig", + "responses": { + "200": { + "description": "Current AIDF configuration", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AIDFConfigResponse" + } + } + } + }, + "204": { + "description": "No configuration found" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + }, + "parameters": [] + }, + "post": { + "x-mode": "lite", + "tags": [ + "Configuration" + ], + "summary": "Save AIDF configuration", + "operationId": "saveAIDFConfig", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConfigAIDFRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Configuration saved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StatusResponse" + } + } + } + }, + "400": { + "description": "Validation error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + }, + "parameters": [] + }, + "delete": { + "x-mode": "lite", + "tags": [ + "Configuration" + ], + "summary": "Delete AIDF configuration", + "operationId": "deleteAIDFConfig", + "responses": { + "200": { + "description": "Configuration deleted successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StatusResponse" + } + } + } + }, + "404": { + "description": "Configuration not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/ai-integrations/llm-provider": { + "get": { + "tags": [ + "Configuration" + ], + "summary": "Get current AI provider configuration", + "operationId": "getCurrentAIProvider", + "responses": { + "200": { + "description": "Current AI provider configuration", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AIProviderResponse" + } + } + } + }, + "204": { + "description": "No configuration found" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + }, + "parameters": [] + }, + "post": { + "tags": [ + "Configuration" + ], + "summary": "Save AI provider configuration", + "operationId": "saveAIProviderConfig", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConfigAIProviderRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Configuration saved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StatusResponse" + } + } + } + }, + "400": { + "description": "Validation error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + }, + "parameters": [] + }, + "delete": { + "tags": [ + "Configuration" + ], + "summary": "Delete AI provider configuration", + "operationId": "deleteAIProviderConfig", + "responses": { + "200": { + "description": "Configuration deleted successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StatusResponse" + } + } + } + }, + "404": { + "description": "Configuration not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/audit/events": { + "get": { + "tags": [ + "AuditConsole" + ], + "summary": "List AI assistant audit events", + "description": "Returns a paginated, filterable list of AI assistant audit events from ClickHouse. Each row represents one agent action (user message, assistant response, tool call, tool result, error, data access, or PDF export). Requires the `audit.read` permission. PII fields (ip_address, user_agent, message, tool_arguments, tool_result) are masked unless the caller also holds the `audit.view_sensitive` permission and passes `view_sensitive=true`.\n", + "operationId": "listAuditEvents", + "parameters": [ + { + "name": "page", + "in": "query", + "required": false, + "description": "Page number (1-based).", + "schema": { + "type": "integer", + "minimum": 1, + "default": 1 + } + }, + { + "name": "size", + "in": "query", + "required": false, + "description": "Results per page (max 100).", + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 20 + } + }, + { + "name": "username", + "in": "query", + "required": false, + "description": "Case-insensitive substring match on the username field.", + "schema": { + "type": "string" + } + }, + { + "name": "event_type", + "in": "query", + "required": false, + "description": "Exact match on event_type.", + "schema": { + "type": "string", + "enum": [ + "user_message", + "assistant_response", + "tool_call", + "tool_result", + "error", + "data_access", + "pdf_export" + ] + } + }, + { + "name": "tool", + "in": "query", + "required": false, + "description": "Case-insensitive substring match on tool_name.", + "schema": { + "type": "string" + } + }, + { + "name": "keyword", + "in": "query", + "required": false, + "description": "Case-insensitive substring match on message OR tool_name.", + "schema": { + "type": "string" + } + }, + { + "name": "thread_id", + "in": "query", + "required": false, + "description": "Exact match on thread_id (conversation ID).", + "schema": { + "type": "string" + } + }, + { + "name": "interaction_id", + "in": "query", + "required": false, + "description": "Exact match on interaction_id.", + "schema": { + "type": "string" + } + }, + { + "name": "session_id", + "in": "query", + "required": false, + "description": "Exact match on session_id.", + "schema": { + "type": "string" + } + }, + { + "name": "date_from", + "in": "query", + "required": false, + "description": "Return events at or after this timestamp (RFC 3339).", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "date_to", + "in": "query", + "required": false, + "description": "Return events at or before this timestamp (RFC 3339).", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "view_sensitive", + "in": "query", + "required": false, + "description": "When `true` (and the caller has `audit.view_sensitive` permission), PII fields are returned unmasked.\n", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "Paginated list of audit events", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuditEventsResponse" + } + } + } + }, + "401": { + "$ref": "#/components/responses/UnauthorizedError" + }, + "403": { + "description": "Insufficient permissions (requires audit.read)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + }, + "503": { + "description": "Audit storage (ClickHouse) unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "status": 503, + "message": "audit storage unavailable" + } + } + } + } + } + } + }, + "/api/audit/export": { + "post": { + "tags": [ + "AuditConsole" + ], + "summary": "Request an audit export (CSV)", + "description": "Generates a CSV export of audit events matching the supplied filters. For \u226410 000 matching rows the export is generated synchronously and the response includes a `download_url`. For >10 000 rows the job is queued asynchronously; the response is `202 Accepted` with `status: processing` and a `status_url` to poll. Exports are cached on disk for 30 minutes and deleted after download. A per-user limit of 5 concurrent exports is enforced.\n", + "operationId": "requestAuditExport", + "parameters": [ + { + "name": "view_sensitive", + "in": "query", + "required": false, + "description": "Include unmasked PII in the CSV (requires audit.view_sensitive permission).", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuditExportRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Export ready for download (synchronous path, \u226410 000 rows)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuditExportResponse" + }, + "example": { + "export_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "ready", + "download_url": "/api/audit/export/3fa85f64-5717-4562-b3fc-2c963f66afa6", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "row_count": 42 + } + } + } + }, + "202": { + "description": "Export queued for background processing (>10 000 rows)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuditExportResponse" + }, + "example": { + "export_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "processing", + "status_url": "/api/audit/export/3fa85f64-5717-4562-b3fc-2c963f66afa6/status", + "download_url": "/api/audit/export/3fa85f64-5717-4562-b3fc-2c963f66afa6", + "row_count": 15000 + } + } + } + }, + "401": { + "$ref": "#/components/responses/UnauthorizedError" + }, + "403": { + "description": "Insufficient permissions (requires audit.export)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "413": { + "description": "Export exceeds the maximum row limit (5 000 000 rows)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "status": 413, + "message": "export exceeds maximum row limit" + } + } + } + }, + "429": { + "description": "Per-user concurrent export limit reached (max 5)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "status": 429, + "message": "export limit reached" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + }, + "503": { + "description": "Audit storage unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/audit/export/{id}": { + "get": { + "tags": [ + "AuditConsole" + ], + "summary": "Download an audit export CSV", + "description": "Streams the CSV file for the given export ID. The file is deleted from the server after a successful download. If the export is still being processed, returns `202`. If the export has expired (TTL 30 min), returns `410 Gone`.\n", + "operationId": "downloadAuditExport", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Export ID returned by POST /audit/export.", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "CSV file download", + "headers": { + "Content-Disposition": { + "required": true, + "schema": { + "type": "string" + }, + "example": "attachment; filename=\"audit-export-3fa85f64.csv\"" + }, + "X-Content-SHA256": { + "required": true, + "schema": { + "type": "string" + }, + "description": "SHA-256 hex digest of the file for integrity verification" + } + }, + "content": { + "application/octet-stream": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "401": { + "$ref": "#/components/responses/UnauthorizedError" + }, + "404": { + "description": "Export not found or already downloaded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "status": 404, + "message": "export not found or expired" + } + } + } + }, + "410": { + "description": "Export has expired (TTL exceeded)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "status": 410, + "message": "export expired" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/api/device-management/data-centers": { + "post": { + "x-mode": "lite", + "operationId": "AddDataCenter", + "description": "Add a new data center to F5 Insights fleet.", + "requestBody": { + "description": "Details of the data center to be added.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataCenter" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Data center added successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddDataCenterResponse" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ], + "parameters": [] + }, + "get": { + "x-mode": "lite", + "operationId": "GetDataCenters", + "description": "Retrieve all Data Centers.", + "responses": { + "200": { + "description": "List of all data centers.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListOfDataCenters" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ], + "parameters": [] + } + }, + "/api/device-management/data-centers/devices": { + "get": { + "x-mode": "lite", + "operationId": "GetDataCentersRegisteredDevices", + "description": "Retrieve all data centers with their registered devices.", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "deviceType", + "in": "query", + "required": false, + "description": "Filter by device kind. One of all, bigip, f5os. Defaults to all.", + "schema": { + "type": "string", + "enum": [ + "all", + "bigip", + "f5os" + ], + "default": "all" + } + } + ], + "responses": { + "200": { + "description": "List of all data centers with their devices.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataCentersWithDevicesResponse" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/data-centers/{id}": { + "delete": { + "x-mode": "lite", + "operationId": "DeleteDataCenter", + "description": "Delete a specific data center by its ID.", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Unique identifier of the data center to delete.", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Data center deleted successfully." + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Data center not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "409": { + "description": "Cannot delete data center with associated devices.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices": { + "post": { + "x-mode": "lite", + "operationId": "AddDevice", + "description": "Onboard a device (BIG-IP or F5OS) to F5 Insights fleet. The deviceType field selects the kind; defaults to bigip.", + "requestBody": { + "description": "Details of the device to be added (BIG-IP or F5OS).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddDeviceRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Device added successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddDeviceResponse" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ], + "parameters": [] + }, + "get": { + "x-mode": "lite", + "operationId": "GetDevices", + "description": "Retrieve all devices (BIG-IP and F5OS) onboarded to F5 Insights with pagination and filtering support. Use deviceType to filter by kind.", + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/SizeParam" + }, + { + "$ref": "#/components/parameters/SinceParam" + }, + { + "$ref": "#/components/parameters/SearchParam" + }, + { + "$ref": "#/components/parameters/SortParam" + }, + { + "name": "deviceType", + "in": "query", + "required": false, + "description": "Filter by device kind. One of all, bigip, f5os. Defaults to all.", + "schema": { + "type": "string", + "enum": [ + "all", + "bigip", + "f5os" + ], + "default": "all" + } + } + ], + "responses": { + "200": { + "description": "List of devices (BIG-IP and F5OS) with pagination metadata.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListOfDevices" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + } + }, + "/api/device-management/devices/auto-scale/{autoScaleGroupId}": { + "get": { + "operationId": "GetDevicesByAutoScaleGroup", + "description": "Retrieve all the devices that belong to a specific auto-scale group.", + "parameters": [ + { + "name": "autoScaleGroupId", + "in": "path", + "required": true, + "description": "Unique identifier of the auto-scale group.", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/SizeParam" + }, + { + "$ref": "#/components/parameters/SinceParam" + }, + { + "$ref": "#/components/parameters/SortParam" + } + ], + "responses": { + "200": { + "description": "List of devices belonging to the specified auto-scale group.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListOfDevices" + }, + "example": { + "devices": [ + { + "id": "123e4567-e89b-12d3-a456-426614174000", + "alias_name": "bigip-prod-01", + "description": "Production BIG-IP device", + "username": "admin", + "data_center": "US-EAST-1", + "endpoint": "192.168.1.100:443", + "tls_enabled": true, + "collection_interval": 60, + "max_concurrent_connections": 5, + "deviceName": "bigip1.example.com", + "retention": "30D", + "modules": { + "apm": false, + "cgnat": false, + "dns": false, + "dos": false, + "firewall": false, + "gtm": false, + "policy_api_protection": false, + "policy_asm": false, + "policy_firewall": false, + "policy_ip_intelligence": false, + "policy_nat": false, + "profile_dos": false + } + }, + { + "id": "223e4567-e89b-12d3-a456-426614174001", + "alias_name": "bigip-prod-02", + "description": "Production BIG-IP device 2", + "username": "admin", + "data_center": "US-EAST-1", + "endpoint": "192.168.1.101:443", + "tls_enabled": true, + "collection_interval": 60, + "max_concurrent_connections": 5, + "deviceName": "bigip2.example.com", + "retention": "30D", + "modules": { + "apm": false, + "cgnat": false, + "dns": false, + "dos": false, + "firewall": false, + "gtm": false, + "policy_api_protection": false, + "policy_asm": false, + "policy_firewall": false, + "policy_ip_intelligence": false, + "policy_nat": false, + "profile_dos": false + } + } + ], + "pagination": { + "page": 1, + "pageSize": 20, + "totalDevices": 2, + "totalPages": 1 + } + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Auto-scale group not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + } + }, + "/api/device-management/devices/bulk-import": { + "post": { + "x-mode": "lite", + "operationId": "BulkImportDevices", + "description": "Import multiple devices (BIG-IP and/or F5OS) to F5 Insights in a single operation.", + "tags": [ + "Device Management" + ], + "requestBody": { + "description": "Array of devices to be imported (mixed BIG-IP and F5OS allowed).", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "devices" + ], + "properties": { + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AddDeviceRequest" + }, + "minItems": 1, + "description": "List of devices to import (BIG-IP or F5OS per item)" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Bulk import completed with summary of results.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkImportResponse" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/device-management/devices/connection/validate": { + "post": { + "x-mode": "lite", + "operationId": "ValidateDeviceConnection", + "description": "Validate connectivity from F5 Insights to a BIG-IP device using provided credentials.", + "requestBody": { + "description": "Device details required for connection validation.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Connection validation result.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConnectionValidationResponse" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ], + "parameters": [] + } + }, + "/api/device-management/devices/import": { + "get": { + "x-mode": "lite", + "operationId": "GetCurrentImportTask", + "description": "Get the currently running or most recent import task.\nReturns the active import task if one is in progress, otherwise returns the most recent completed/failed task.\n", + "tags": [ + "Device Management" + ], + "responses": { + "200": { + "description": "Import task state and per-device results.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImportTaskStatus" + } + } + } + }, + "404": { + "description": "No import tasks found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [] + }, + "post": { + "x-mode": "lite", + "operationId": "ImportDevicesAsync", + "description": "Asynchronously import a batch of devices (BIG-IP and/or F5OS) and track the result as a task. Accepts the same `devices[]` body as `bulk-import`; in addition `Content-Type: application/yaml` is supported so a YAML file from disk can be POSTed directly. Returns a task id immediately; poll the status endpoint for per-device outcomes once items start completing.", + "tags": [ + "Device Management" + ], + "requestBody": { + "description": "Array of devices to import (mixed BIG-IP and F5OS allowed).", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "devices" + ], + "properties": { + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AddDeviceRequest" + }, + "minItems": 1, + "maxItems": 1000, + "description": "List of devices to import (BIG-IP or F5OS per item)." + } + } + } + }, + "application/yaml": { + "schema": { + "type": "object", + "required": [ + "devices" + ], + "properties": { + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AddDeviceRequest" + }, + "minItems": 1, + "maxItems": 1000, + "description": "List of devices to import (BIG-IP or F5OS per item)." + } + } + } + } + } + }, + "responses": { + "202": { + "description": "Import task accepted. Poll the status endpoint with the returned task_id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImportTaskAccepted" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/device-management/devices/import/cleanup/{task_id}": { + "delete": { + "x-mode": "lite", + "operationId": "CleanupImportTask", + "description": "Clean up an async import task and its tracked results.\nRemoves the task record (including the per-device results stored in status_json).\nDevices that were successfully onboarded remain intact in the main tables.\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "The import task ID to clean up", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "force", + "in": "query", + "required": false, + "description": "Force cleanup even if the task is still running.\nWARNING: Use with extreme caution - only when a task is stuck for a very long time.\nForcing cleanup of a running task may lead to inconsistent state.\n", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "Cleanup completed successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CleanupImportTaskResponse" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/import/status/{task_id}": { + "get": { + "x-mode": "lite", + "operationId": "GetImportTaskStatus", + "description": "Returns the current state of an async import task plus the full per-device result list. `items[]` is updated as workers finish each device, so polling shows progress without a separate per-device endpoint.", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "Task id returned by POST /device-management/devices/import.", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Task state and per-device results.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImportTaskStatus" + } + } + } + }, + "404": { + "description": "Task not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/migrate-ast": { + "get": { + "x-mode": "lite", + "operationId": "GetCurrentMigrationTask", + "description": "Get the currently running or most recent migration task.\nReturns the active migration task if one is in progress, otherwise returns the most recent completed/failed task.\n", + "tags": [ + "Device Management" + ], + "responses": { + "200": { + "description": "Migration task information retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MigrationTaskResponse" + } + } + } + }, + "404": { + "description": "No migration tasks found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/device-management/devices/migrate-ast/cleanup/{task_id}": { + "delete": { + "x-mode": "lite", + "operationId": "CleanupMigrationTask", + "description": "Clean up all staging data associated with a migration task.\nThis removes all staging devices and trust store entries that have not been committed.\nSuccessfully committed devices and trust stores remain intact.\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "The task ID to clean up", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "force", + "in": "query", + "required": false, + "description": "Force cleanup even if task is still running.\nWARNING: Use with extreme caution - only when a task is stuck for a very long time.\nForcing cleanup of a running task may lead to inconsistent state.\n", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "Cleanup completed successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CleanupMigrationTaskResponse" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/migrate-ast/retry/{task_id}": { + "post": { + "x-mode": "lite", + "operationId": "RetryFailedMigrationDevices", + "description": "Retry failed devices from an existing migration task.\nThis endpoint reuses the same task ID and only retries devices with validation_status = 'FAILED'.\nFailed devices are reset to 'PENDING' and the task state is reset to 'IN_PROGRESS'.\n\nRequirements:\n- Task must exist and be a MIGRATION task\n- No other migration task can be currently running\n- Task must have at least one failed device\n\nThe retry process:\n1. Validates the task exists and is a migration task\n2. Checks no concurrent migration tasks are running\n3. Resets failed devices to PENDING status\n4. Resets task state to IN_PROGRESS\n5. Reprocesses only the failed devices through the validation workflow\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "The task ID to retry failed devices for", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "202": { + "description": "Retry initiated successfully. Use the same task_id to query status.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RetryFailedMigrationDevicesResponse" + } + } + } + }, + "400": { + "description": "No failed devices to retry", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "409": { + "description": "A migration task is already running", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/migrate-ast/staging-ca-bundles/{staging_ca_id}": { + "patch": { + "x-mode": "lite", + "operationId": "PatchStagingCABundle", + "summary": "Update and commit a staging CA bundle", + "description": "Updates a single staging CA bundle with provided fields, validates certificate\nformat, and commits the certificate to the trust_store table. If a certificate\nwith the same content already exists, it will be linked instead of creating a duplicate.\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "staging_ca_id", + "in": "path", + "required": true, + "description": "UUID of the staging CA bundle to update", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddTrustStoreRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Staging CA bundle updated and committed successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PatchStagingCABundleResponse" + } + } + } + }, + "400": { + "description": "Invalid certificate data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Staging CA bundle not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/migrate-ast/staging-devices/{staging_device_id}": { + "get": { + "x-mode": "lite", + "operationId": "GetStagingDevice", + "summary": "Get a staging device by ID", + "description": "Retrieve details of a specific staging device including its validation status,\nconfiguration, and error messages if any.\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "staging_device_id", + "in": "path", + "required": true, + "description": "UUID of the staging device to retrieve", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Staging device retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StagingDeviceResponse" + } + } + } + }, + "404": { + "description": "Staging device not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "patch": { + "x-mode": "lite", + "operationId": "PatchStagingDevice", + "summary": "Update and commit a staging device", + "description": "Updates a single staging device with provided fields, validates connectivity,\nand commits the device to the main devices table. If a device with the same\nendpoint exists, it will be updated instead of creating a new one.\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "staging_device_id", + "in": "path", + "required": true, + "description": "UUID of the staging device to update", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DevicePatchRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Staging device updated and committed successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PatchStagingDeviceResponse" + } + } + } + }, + "400": { + "description": "Device validation failed or invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Staging device not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/migrate-ast/status/{task_id}": { + "get": { + "x-mode": "lite", + "operationId": "GetMigrationStatus", + "description": "Get the status of a device migration task including overall progress and individual device status.\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "The task ID returned from the migration request", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "include_devices", + "in": "query", + "required": false, + "description": "Include individual device status details", + "schema": { + "type": "boolean", + "default": true + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "description": "Maximum number of device details to return", + "schema": { + "type": "integer", + "default": 100, + "minimum": 1, + "maximum": 1000 + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "description": "Offset for pagination of device details", + "schema": { + "type": "integer", + "default": 0, + "minimum": 0 + } + }, + { + "name": "updated_since", + "in": "query", + "required": false, + "description": "Filter devices updated since this timestamp (ISO 8601 format, e.g., 2026-01-30T08:00:00Z)", + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "Migration status retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MigrationStatusResponse" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/migrate-ast/status/{task_id}/ca-bundles": { + "get": { + "x-mode": "lite", + "operationId": "GetCABundleProgress", + "summary": "Get staging CA certificates for a migration task", + "description": "Retrieve all staging CA certificates associated with a migration task.\nReturns the list of CA bundles that were extracted during the migration process\nand are available for validation and commit operations.\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "The task ID returned from the migration request", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/SizeParam" + } + ], + "responses": { + "200": { + "description": "CA bundle list retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CABundleListResponse" + } + } + } + }, + "400": { + "description": "Invalid request parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/migrate-ast/status/{task_id}/devices": { + "get": { + "x-mode": "lite", + "operationId": "GetDeviceProgress", + "description": "Get paginated device-level progress for a migration task with delta update support.\nUse this for live UI updates showing per-device status (Connected/Failed/In Progress).\nSupports polling with 'since' parameter to fetch only recently updated devices.\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "The task ID returned from the migration request", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/SizeParam" + }, + { + "$ref": "#/components/parameters/SinceParam" + }, + { + "$ref": "#/components/parameters/SearchParam" + }, + { + "$ref": "#/components/parameters/SortParam" + } + ], + "responses": { + "200": { + "description": "Device progress retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceProgressResponse" + } + } + } + }, + "400": { + "description": "Invalid request parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/{id}": { + "put": { + "x-mode": "lite", + "operationId": "UpdateDevice", + "description": "Updates configuration of a device (BIG-IP or F5OS). The device kind is auto-detected from the id.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Unique identifier of the device to update (BIG-IP or F5OS).", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "Updated details of the device.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Device updated successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateDeviceResponse" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + }, + "patch": { + "x-mode": "lite", + "operationId": "PartialUpdateDevice", + "description": "Partially updates configuration of a device (BIG-IP or F5OS). Only provided fields are updated. The device kind is auto-detected from the id.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Unique identifier of the device to update (BIG-IP or F5OS).", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "Partial device update. Only include fields that should be updated.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DevicePatchRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Device partially updated successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceResponse" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Device not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + }, + "get": { + "x-mode": "lite", + "operationId": "GetDevice", + "description": "Fetch details of a specific device (BIG-IP or F5OS). The device kind is auto-detected from the id.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Unique identifier of the device (BIG-IP or F5OS).", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Device fetched successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceResponse" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + }, + "delete": { + "x-mode": "lite", + "operationId": "DeleteDevice", + "description": "Delete a specific device (BIG-IP or F5OS). The device kind is auto-detected from the id.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Unique identifier of the device (BIG-IP or F5OS).", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Device deleted successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + } + }, + "/api/device-management/devices/{id}/refresh": { + "post": { + "x-mode": "lite", + "operationId": "RefreshDevice", + "description": "Re-discover a device and refresh its inventory details (hardware model, serial number, OS version/build, status, last-seen). Supported for F5OS devices only; returns 400 for BIG-IP. The device kind is auto-detected from the id. This operation is synchronous.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Unique identifier of the device to refresh (F5OS).", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Device refreshed successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceResponse" + } + } + } + }, + "400": { + "description": "Validation error (e.g. refresh not supported for BIG-IP devices).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Device not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + } + }, + "/api/device-management/trust-store": { + "post": { + "x-mode": "lite", + "operationId": "AddTrustStore", + "description": "certificate for TLS connections.", + "requestBody": { + "description": "Certificate details and content.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddTrustStoreRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Certificate uploaded successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TrustStoreResponse" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ], + "parameters": [] + }, + "get": { + "x-mode": "lite", + "operationId": "GetTrustStores", + "description": "Retrieve all certificates from trust store.", + "responses": { + "200": { + "description": "List of certificates.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListOfTrustStores" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ], + "parameters": [] + } + }, + "/api/device-management/trust-store/{id}": { + "get": { + "x-mode": "lite", + "operationId": "GetTrustStore", + "description": "Retrieve a specific certificate by ID from trust store.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "Certificate ID" + } + ], + "responses": { + "200": { + "description": "Certificate details.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TrustStore" + } + } + } + }, + "404": { + "description": "Certificate not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + }, + "delete": { + "x-mode": "lite", + "operationId": "DeleteTrustStore", + "description": "Delete a certificate from trust store.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "Certificate ID" + } + ], + "responses": { + "200": { + "description": "Certificate deleted successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MessageResponse" + } + } + } + }, + "404": { + "description": "Certificate not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "409": { + "description": "Certificate is in use by devices.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + } + }, + "/api/license/activate": { + "post": { + "x-mode": "lite", + "summary": "Activate license", + "description": "Activates the license for the service and returns activation status, digital asset ID, entitlements, and subscription details", + "operationId": "activateLicense", + "tags": [ + "License" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseActivationRequest" + } + } + } + }, + "responses": { + "200": { + "description": "License activated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseActivationResponse" + } + } + } + }, + "400": { + "description": "Invalid activation request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized activation attempt", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "503": { + "description": "Service unavailable - unable to connect to licensing server", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/license/deactivate": { + "post": { + "x-mode": "lite", + "summary": "Deactivate license", + "description": "Deactivates the license for the service and returns deactivation status", + "operationId": "deactivateLicense", + "tags": [ + "License" + ], + "responses": { + "200": { + "description": "License deactivated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseDeactivationResponse" + } + } + } + }, + "400": { + "description": "Invalid deactivation request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseDeactivationResponse" + } + } + } + }, + "401": { + "description": "Unauthorized deactivation attempt", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseDeactivationResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseDeactivationResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/license/entitlements": { + "get": { + "x-mode": "lite", + "summary": "Get license entitlements", + "description": "Retrieves license entitlements from llm sdk", + "operationId": "getLicenseEntitlements", + "tags": [ + "License" + ], + "responses": { + "200": { + "description": "License entitlements retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseEntitlementsResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/license/health": { + "get": { + "x-mode": "lite", + "summary": "Check license service health status", + "description": "Returns the health status of the license service including activation status, storage metrics, and license information", + "operationId": "getLicenseHealth", + "tags": [ + "License" + ], + "responses": { + "200": { + "description": "License service is healthy", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseHealthResponse" + } + } + } + }, + "503": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseHealthResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/license/report": { + "get": { + "x-mode": "lite", + "summary": "Download license report", + "description": "Downloads the license report in disconnected mode (base64 encoded)", + "operationId": "downloadReport", + "tags": [ + "License" + ], + "responses": { + "200": { + "description": "License report downloaded successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseReportResponse" + } + } + } + }, + "403": { + "description": "Operation not allowed in connected mode", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [] + }, + "put": { + "summary": "Verify license report", + "description": "Verifies a signed license report acknowledgment from F5 TEEM in disconnected mode", + "operationId": "verifyReport", + "tags": [ + "License" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VerifyReportRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Report verification initiated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MessageResponse" + } + } + } + }, + "400": { + "description": "Invalid request body", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Operation not allowed in connected mode", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/provisioning/v1/cloud/clusters": { + "get": { + "tags": [ + "Infrastructure Discovery" + ], + "summary": "List clusters", + "description": "Lists all clusters in a datacenter.\n", + "operationId": "listClusters", + "parameters": [ + { + "name": "connId", + "in": "query", + "required": true, + "description": "Connection ID from /cloud/connect endpoint", + "schema": { + "type": "string" + } + }, + { + "name": "datacenter", + "in": "query", + "required": true, + "description": "Name of the datacenter", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of clusters", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ClusterInfo" + } + } + } + } + }, + "400": { + "description": "Bad request - missing required parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Environment or datacenter not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/connect": { + "post": { + "tags": [ + "Infrastructure Discovery" + ], + "summary": "Establish vSphere connection", + "description": "Establishes a connection to vSphere using provider credentials.\nReturns a connection ID that can be used for subsequent discovery API calls.\n", + "operationId": "connectToVSphere", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConnectRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Connection established successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConnectResponse" + } + } + } + }, + "400": { + "description": "Bad request - missing required parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Provider not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error or connection failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/provisioning/v1/cloud/datacenters": { + "get": { + "tags": [ + "Infrastructure Discovery" + ], + "summary": "List datacenters", + "description": "Lists all available datacenters in the vSphere environment.\n", + "operationId": "listDatacenters", + "parameters": [ + { + "name": "connId", + "in": "query", + "required": true, + "description": "Connection ID from /cloud/connect endpoint", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of datacenters", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DatacenterInfo" + } + } + } + } + }, + "400": { + "description": "Bad request - missing required parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Environment not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/datastores": { + "get": { + "tags": [ + "Infrastructure Discovery" + ], + "summary": "List datastores", + "description": "Lists all datastores in a datacenter.\n", + "operationId": "listDatastores", + "parameters": [ + { + "name": "connId", + "in": "query", + "required": true, + "description": "Connection ID from /cloud/connect endpoint", + "schema": { + "type": "string" + } + }, + { + "name": "datacenter", + "in": "query", + "required": true, + "description": "Name of the datacenter", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of datastores", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DatastoreInfo" + } + } + } + } + }, + "400": { + "description": "Bad request - missing required parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Environment or datacenter not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/environments": { + "get": { + "tags": [ + "Cloud Environments" + ], + "summary": "List all VMware environments", + "description": "List all VMware cloud environments for auto-scaling.", + "operationId": "getCloudEnvironments", + "responses": { + "200": { + "description": "Cloud environment listed successfully", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CloudEnvironment" + } + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [] + }, + "post": { + "tags": [ + "Cloud Environments" + ], + "summary": "Create VMware environment", + "description": "Creates a new VMware cloud environment for auto-scaling.", + "operationId": "createCloudEnvironment", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateCloudEnvironmentRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Cloud environment created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CloudEnvironment" + } + } + } + }, + "400": { + "description": "Bad request - validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationError" + } + } + } + }, + "404": { + "description": "Provider or device template not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "409": { + "description": "Conflict - environment with same name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/provisioning/v1/cloud/environments/{environmentId}": { + "get": { + "tags": [ + "Cloud Environments" + ], + "summary": "Get VMware environment by ID", + "operationId": "getCloudEnvironmentByID", + "parameters": [ + { + "name": "environmentId", + "in": "path", + "required": true, + "description": "UUID of the cloud environment", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Cloud environment returned successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CloudEnvironment" + } + } + } + }, + "404": { + "description": "Cloud environment not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Cloud Environments" + ], + "summary": "Edit VMware environment", + "operationId": "updateCloudEnvironment", + "parameters": [ + { + "name": "environmentId", + "in": "path", + "required": true, + "description": "UUID of the cloud environment", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateCloudEnvironmentRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Cloud environment updated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CloudEnvironment" + } + } + } + }, + "400": { + "description": "Bad request - validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationError" + } + } + } + }, + "404": { + "description": "Cloud environment not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "409": { + "description": "Conflict - environment with same name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Cloud Environments" + ], + "summary": "Delete VMware environment", + "description": "Deletes an existing VMware cloud environment.", + "operationId": "deleteCloudEnvironment", + "parameters": [ + { + "name": "environmentId", + "in": "path", + "required": true, + "description": "UUID of the cloud environment", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "204": { + "description": "Cloud environment deleted successfully" + }, + "400": { + "description": "Bad request - environment is in use", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Cloud environment not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/hosts": { + "get": { + "tags": [ + "Infrastructure Discovery" + ], + "summary": "List hosts", + "description": "Lists hosts in a datacenter or cluster. If cluster is provided, lists only hosts\nin that cluster; otherwise lists all hosts in the datacenter.\n", + "operationId": "listHosts", + "parameters": [ + { + "name": "connId", + "in": "query", + "required": true, + "description": "Connection ID from /cloud/connect endpoint", + "schema": { + "type": "string" + } + }, + { + "name": "datacenter", + "in": "query", + "required": true, + "description": "Name of the datacenter", + "schema": { + "type": "string" + } + }, + { + "name": "cluster", + "in": "query", + "required": false, + "description": "Name of the cluster (optional - if omitted, lists all hosts in datacenter)", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of hosts", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HostInfo" + } + } + } + } + }, + "400": { + "description": "Bad request - missing required parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Environment, datacenter, or cluster not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/networks": { + "get": { + "tags": [ + "Infrastructure Discovery" + ], + "summary": "List networks", + "description": "Lists all networks in a datacenter.\n", + "operationId": "listNetworks", + "parameters": [ + { + "name": "connId", + "in": "query", + "required": true, + "description": "Connection ID from /cloud/connect endpoint", + "schema": { + "type": "string" + } + }, + { + "name": "datacenter", + "in": "query", + "required": true, + "description": "Name of the datacenter", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of networks", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NetworkInfo" + } + } + } + } + }, + "400": { + "description": "Bad request - missing required parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Environment or datacenter not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/providers": { + "get": { + "tags": [ + "Cloud Providers" + ], + "summary": "List all cloud providers", + "operationId": "getCloudProviders", + "responses": { + "200": { + "description": "List of cloud providers retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CloudProvider" + } + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "parameters": [] + }, + "post": { + "tags": [ + "Cloud Providers" + ], + "summary": "Create a cloud provider", + "operationId": "createCloudProvider", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateCloudProviderRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Cloud provider created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CloudProvider" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "409": { + "description": "Conflict - provider with same name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "parameters": [] + } + }, + "/api/provisioning/v1/cloud/providers/{providerId}": { + "get": { + "tags": [ + "Cloud Providers" + ], + "summary": "Get cloud provider by ID", + "operationId": "getCloudProvider", + "responses": { + "200": { + "description": "Cloud provider retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CloudProvider" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/ProviderId" + } + ] + }, + "patch": { + "tags": [ + "Cloud Providers" + ], + "summary": "Edit cloud provider", + "operationId": "updateCloudProvider", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateCloudProviderRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Cloud provider updated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CloudProvider" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Conflict - provider with same name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/ProviderId" + } + ] + }, + "delete": { + "tags": [ + "Cloud Providers" + ], + "summary": "Delete cloud provider", + "operationId": "deleteCloudProvider", + "responses": { + "204": { + "description": "Provider deleted successfully" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/ProviderId" + } + ] + } + }, + "/api/provisioning/v1/cloud/tasks/create-vm": { + "post": { + "tags": [ + "VM Tasks" + ], + "summary": "Create a VM", + "description": "Kicks off an asynchronous VM creation task in the referenced\ncloud environment. Returns 202 Accepted with task tracking info.\n", + "operationId": "createVMTask", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VMTaskRequest" + } + } + } + }, + "responses": { + "202": { + "description": "VM creation task accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VMTaskResponse" + } + } + } + }, + "400": { + "description": "Bad request - validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Referenced environment not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/provisioning/v1/cloud/tasks/create-vm/{taskId}": { + "get": { + "tags": [ + "VM Tasks" + ], + "summary": "Get create-vm task status", + "operationId": "getCreateVMTask", + "parameters": [ + { + "name": "taskId", + "in": "path", + "required": true, + "description": "UUID of the VM task", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Task status returned", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VMTaskResponse" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/tasks/delete-vm": { + "post": { + "tags": [ + "VM Tasks" + ], + "summary": "Delete a VM", + "description": "Kicks off an asynchronous VM deletion task in the referenced\ncloud environment. Returns 202 Accepted with task tracking info.\n", + "operationId": "deleteVMTask", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VMTaskRequest" + } + } + } + }, + "responses": { + "202": { + "description": "VM deletion task accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VMTaskResponse" + } + } + } + }, + "400": { + "description": "Bad request - validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Referenced environment not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/provisioning/v1/cloud/tasks/delete-vm/{taskId}": { + "get": { + "tags": [ + "VM Tasks" + ], + "summary": "Get delete-vm task status", + "operationId": "getDeleteVMTask", + "parameters": [ + { + "name": "taskId", + "in": "path", + "required": true, + "description": "UUID of the VM task", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Task status returned", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VMTaskResponse" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/vm-images": { + "get": { + "tags": [ + "Infrastructure Discovery" + ], + "summary": "List VM images", + "description": "Lists all VM images (templates) available in a datacenter.\n", + "operationId": "listVMImages", + "parameters": [ + { + "name": "connId", + "in": "query", + "required": true, + "description": "Connection ID from /cloud/connect endpoint", + "schema": { + "type": "string" + } + }, + { + "name": "datacenter", + "in": "query", + "required": true, + "description": "Name of the datacenter", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of VM images", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/VMInfo" + } + } + } + } + }, + "400": { + "description": "Bad request - missing required parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Environment or datacenter not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/device-templates": { + "get": { + "summary": "List device templates", + "description": "Returns a paginated list of device templates.\n\nSupports OData-style query parameters for filtering, sorting,\npagination, field selection, and total count:\n\n| Parameter | Example |\n|------------|----------------------------------------------|\n| `$filter` | `state eq 'DEPLOYED'` |\n| `$orderby` | `name asc` |\n| `$top` | `10` |\n| `$skip` | `20` |\n| `$select` | `id,name,state` |\n| `$count` | `true` |\n", + "operationId": "ListDeviceTemplates", + "tags": [ + "Device Templates" + ], + "parameters": [], + "responses": { + "200": { + "description": "Paginated list of device templates", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateListResponse" + }, + "example": { + "status": 200, + "count": 2, + "totalItems": 2, + "items": [ + { + "id": "550e8400-e29b-41d4-a716-446655440000", + "name": "BIG-IP Standard Template", + "provider": "VMware", + "description": "Standard VMware configuration", + "state": "DEPLOYED", + "locked": false, + "lockReason": "NONE", + "createdAt": "2026-01-15T09:23:41Z", + "updatedAt": "2026-03-22T14:45:10Z" + }, + { + "id": "660e8400-e29b-41d4-a716-446655440001", + "name": "BIG-IP HA Template", + "provider": "AWS", + "description": "High availability configuration", + "state": "DRAFT", + "locked": false, + "lockReason": "NONE", + "createdAt": "2026-02-10T11:00:00Z", + "updatedAt": "2026-02-10T11:00:00Z" + } + ], + "selfLink": "/api/device-templates" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": null + } + } + } + } + } + }, + "post": { + "summary": "Create a device template", + "description": "Creates a new device template.\n\nThe optional `draft` flag controls the initial state:\n\n| `draft` | Initial state | Response |\n|---------|---------------|----------|\n| `true` | `DRAFT` | **201 Created** |\n| `false` / omitted | `NEW` | **200 OK** |\n\nTo deploy a template, use the separate `POST /device-templates/{id}/deploy` endpoint.\n", + "operationId": "CreateDeviceTemplate", + "tags": [ + "Device Templates" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateWriteRequest" + }, + "example": { + "name": "BIG-IP Standard Template", + "provider": "VMware", + "description": "Standard VMware configuration for production workloads", + "definition": { + "rootPassword": "s3cur3P@ss!", + "timeZone": "America/Los_Angeles", + "defaultRoute": "10.0.0.1", + "managementSslPort": 443, + "hostnameComponents": [ + { + "type": "STATIC_TEXT", + "value": "bigip-" + }, + { + "type": "SERIAL_NUMBER", + "value": null + } + ], + "lookupServerList": [ + "8.8.8.8", + "8.8.4.4" + ], + "ntpServerList": [ + "0.pool.ntp.org" + ], + "userAccountList": [ + { + "username": "admin", + "password": "adminP@ss!", + "role": "administrator", + "shell": "bash" + } + ], + "provisionedModuleList": [ + { + "module": "LTM", + "level": "NOMINAL" + } + ], + "networkRouteList": [ + { + "name": "default", + "gatewayAddress": "10.0.0.1", + "destination": "0.0.0.0/0" + } + ], + "vlanList": [ + { + "name": "external", + "nic": "1.1", + "mtu": 1500, + "tag": 100 + } + ], + "selfIpList": [ + { + "name": "external-self", + "ipPoolReference": "c3d4e5f6-a7b8-4890-8bcd-ef1234567892", + "vlanName": "external", + "portLockdown": "default", + "allowServices": null + } + ] + } + } + } + } + }, + "responses": { + "200": { + "description": "OK \u2014 device template created in NEW state (`draft=false` or omitted)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateMutationResponse" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "state": "NEW", + "status": 200, + "selfLink": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000", + "createdAt": "2026-01-15T09:23:41Z", + "updatedAt": "2026-01-15T09:23:41Z" + } + } + } + }, + "201": { + "description": "Created \u2014 device template created in DRAFT state (`draft=true`)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateMutationResponse" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "state": "DRAFT", + "status": 201, + "selfLink": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000", + "createdAt": "2026-01-15T09:23:41Z", + "updatedAt": "2026-01-15T09:23:41Z" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 400, + "message": "Bad Request \u2014 request validation failed", + "details": "Field 'name' is required and must be between 1 and 255 characters" + } + } + } + }, + "409": { + "description": "Conflict \u2014 name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "A device template with name 'BIG-IP Standard Template' already exists" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": "failed to create device template" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/provisioning/v1/device-templates/tasks/{taskId}": { + "get": { + "summary": "Get a device template task by ID", + "description": "Retrieves a specific task by its ID.\nFor active tasks (PENDING, RUNNING), this endpoint polls the external service\nfor the latest status before returning.\n", + "operationId": "GetDeviceTemplateTask", + "tags": [ + "Device Templates" + ], + "responses": { + "200": { + "description": "OK \u2014 task retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateTask" + }, + "example": { + "id": "660e8400-e29b-41d4-a716-446655440001", + "deviceTemplateId": "550e8400-e29b-41d4-a716-446655440000", + "externalTaskId": "ext-task-12345", + "type": "DEPLOYMENT", + "status": 200, + "taskStatus": "RUNNING", + "state": "onboarding", + "createdAt": "2026-04-20T12:00:00Z", + "updatedAt": "2026-04-20T12:05:00Z", + "selfLink": "/api/device-templates/tasks/660e8400-e29b-41d4-a716-446655440001" + } + } + } + }, + "400": { + "description": "Bad Request \u2014 invalid UUID format", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 400, + "message": "Bad Request \u2014 request validation failed", + "details": "Task ID 'invalid-uuid' is not a valid UUID format" + } + } + } + }, + "404": { + "description": "Not Found \u2014 task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Task with ID '660e8400-e29b-41d4-a716-446655440001' not found" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": null + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/TaskIdParam" + } + ] + } + }, + "/api/provisioning/v1/device-templates/{id}": { + "get": { + "summary": "Get a device template by ID", + "description": "Returns a single device template identified by its ID.\n\nSupports the OData `$select` parameter to return only specific fields:\n```\nGET /device-templates/{id}?$select=id,name,state\nGET /device-templates/{id}?$select=id,name,locked,lockReason,definition\n```\n", + "operationId": "GetDeviceTemplate", + "tags": [ + "Device Templates" + ], + "parameters": [ + { + "$ref": "#/components/parameters/DeviceTemplateIdParam" + } + ], + "responses": { + "200": { + "description": "Device template returned successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateGetResponse" + }, + "example": { + "status": 200, + "id": "550e8400-e29b-41d4-a716-446655440000", + "name": "BIG-IP Standard Template", + "provider": "VMware", + "description": "Standard VMware configuration for production workloads", + "state": "DEPLOYED", + "locked": true, + "lockReason": "READ_ONLY", + "definition": { + "rootPassword": "s3cur3P@ss!", + "timeZone": "America/Los_Angeles", + "defaultRoute": "10.0.0.1", + "managementSslPort": 443, + "hostnameComponents": [ + { + "type": "STATIC_TEXT", + "value": "bigip-" + }, + { + "type": "SERIAL_NUMBER", + "value": null + } + ], + "lookupServerList": [ + "8.8.8.8", + "8.8.4.4" + ], + "ntpServerList": [ + "0.pool.ntp.org" + ], + "userAccountList": [ + { + "username": "admin", + "password": "adminP@ss!", + "role": "administrator", + "shell": "bash" + } + ], + "provisionedModuleList": [ + { + "module": "LTM", + "level": "NOMINAL" + } + ], + "networkRouteList": [ + { + "name": "default", + "gatewayAddress": "10.0.0.1", + "destination": "0.0.0.0/0" + } + ], + "vlanList": [ + { + "name": "external", + "nic": "1.1", + "mtu": 1500, + "tag": 100 + } + ], + "selfIpList": [ + { + "name": "external-self", + "ipPoolReference": "c3d4e5f6-a7b8-4890-8bcd-ef1234567892", + "vlanName": "external", + "portLockdown": "default", + "allowServices": null + } + ] + }, + "lastValidatedAt": "2026-03-10T08:00:00Z", + "validatedAgainstLiveVm": false, + "lastDeployedVersion": null, + "selfLink": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000", + "createdAt": "2026-01-15T09:23:41Z", + "updatedAt": "2026-04-01T14:30:00Z" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": null + } + } + } + } + } + }, + "put": { + "summary": "Update a device template (full replace)", + "description": "Replaces all fields of an existing device template.\n\n**Precondition:** The device template must not be locked (`locked=true` \u2192 409).\nTemplates in `DEPLOYING` state are system-locked and cannot be modified.\n\nThe optional `draft` flag controls state transitions:\n\n| Current state | `draft` | New state | Response |\n|---------------|---------|-----------|----------|\n| `DRAFT` | `true` | `DRAFT` | **200 OK** |\n| `DRAFT` | `false` / omitted | `NEW` | **200 OK** |\n| `NEW` | \u2014 | `NEW` | **200 OK** |\n| `DEPLOYED` | \u2014 | `DEPLOYED` | **200 OK** |\n| `DEPLOYING` | any | \u2014 | **409 Conflict** |\n| Any (locked) | any | \u2014 | **409 Conflict** |\n\nTo deploy a template, use the separate `POST /device-templates/{id}/deploy` endpoint.\n", + "operationId": "UpdateDeviceTemplate", + "tags": [ + "Device Templates" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateWriteRequest" + }, + "example": { + "name": "BIG-IP Standard Template v2", + "provider": "VMware", + "description": "Updated VMware configuration with HA support", + "definition": { + "rootPassword": "n3wS3cur3P@ss!", + "timeZone": "America/Los_Angeles", + "defaultRoute": "10.0.0.1", + "managementSslPort": 443, + "hostnameComponents": [ + { + "type": "STATIC_TEXT", + "value": "bigip-" + }, + { + "type": "SERIAL_NUMBER", + "value": null + } + ], + "lookupServerList": [ + "8.8.8.8", + "8.8.4.4" + ], + "ntpServerList": [ + "0.pool.ntp.org" + ], + "userAccountList": [ + { + "username": "admin", + "password": "adminP@ss!", + "role": "administrator", + "shell": "bash" + } + ], + "provisionedModuleList": [ + { + "module": "LTM", + "level": "NOMINAL" + }, + { + "module": "ASM", + "level": "NOMINAL" + } + ], + "networkRouteList": [ + { + "name": "default", + "gatewayAddress": "10.0.0.1", + "destination": "0.0.0.0/0" + } + ], + "vlanList": [ + { + "name": "external", + "nic": "1.1", + "mtu": 1500, + "tag": 100 + }, + { + "name": "internal", + "nic": "1.2", + "mtu": 1500, + "tag": 200 + } + ], + "selfIpList": [ + { + "name": "external-self", + "ipPoolReference": "c3d4e5f6-a7b8-4890-8bcd-ef1234567892", + "vlanName": "external", + "portLockdown": "default", + "allowServices": null + }, + { + "name": "internal-self", + "ipPoolReference": "d4e5f6a7-b8c9-4890-8bcd-ef1234567893", + "vlanName": "internal", + "portLockdown": "none", + "allowServices": null + } + ] + } + } + } + } + }, + "responses": { + "200": { + "description": "OK \u2014 device template updated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateMutationResponse" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "state": "NEW", + "status": 200, + "selfLink": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000", + "createdAt": "2026-01-15T09:23:41Z", + "updatedAt": "2026-03-22T14:45:10Z" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 400, + "message": "Bad Request \u2014 request validation failed", + "details": "Field 'definition.rootPassword' must be at least 8 characters" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "409": { + "description": "Conflict \u2014 locked, deploying, or name collision", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "template is locked and cannot be modified" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": "failed to update device template" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/DeviceTemplateIdParam" + } + ] + }, + "patch": { + "summary": "Partially update a device template", + "description": "Partially updates an existing device template. Only the provided fields\nare modified; omitted fields retain their current values.\n\n**Precondition:** The device template must not be locked.\nTemplates in `DEPLOYING` state cannot be patched.\n\nFor the `definition` object, merge-patch semantics apply:\n- Provided keys are updated.\n- Omitted keys are left unchanged.\n- Keys set to `null` are cleared.\n- Array fields (e.g. `vlanList`, `selfIpList`) are replaced wholesale.\n", + "operationId": "PatchDeviceTemplate", + "tags": [ + "Device Templates" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplatePatchRequest" + }, + "example": { + "description": "Updated description with HA failover notes", + "definition": { + "managementSslPort": 8443 + } + } + } + } + }, + "responses": { + "200": { + "description": "OK \u2014 device template patched successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateMutationResponse" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "state": "NEW", + "status": 200, + "selfLink": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000", + "createdAt": "2026-01-15T09:23:41Z", + "updatedAt": "2026-04-01T16:20:00Z" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 400, + "message": "Bad Request \u2014 request validation failed", + "details": "Invalid value for 'definition.managementSslPort': must be between 1 and 65535" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "409": { + "description": "Conflict \u2014 locked or deploying", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "examples": { + "locked": { + "summary": "Template is locked", + "value": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "template is locked and cannot be modified" + } + }, + "deploying": { + "summary": "Template is deploying", + "value": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "template is currently deploying and cannot be modified" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": "failed to update device template" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/DeviceTemplateIdParam" + } + ] + }, + "delete": { + "summary": "Delete a device template", + "description": "Deletes a device template by ID.\n\n**Precondition:** The device template must not be locked.\nTemplates in `DEPLOYING` state cannot be deleted.\n", + "operationId": "DeleteDeviceTemplate", + "tags": [ + "Device Templates" + ], + "responses": { + "200": { + "description": "OK \u2014 device template deleted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateDeleteResponse" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "status": 200, + "deletedAt": "2026-04-10T16:00:00Z" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "409": { + "description": "Conflict \u2014 locked or deploying", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "template is locked and cannot be modified" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": "failed to delete device template" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/DeviceTemplateIdParam" + } + ] + } + }, + "/api/provisioning/v1/device-templates/{id}/clone": { + "post": { + "summary": "Clone a device template", + "description": "Creates a deep copy of an existing device template with a new name.\nThe clone is always created in `DRAFT` state, unlocked.\n", + "operationId": "CloneDeviceTemplate", + "tags": [ + "Device Templates" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateCloneRequest" + }, + "example": { + "name": "BIG-IP Standard Template (Copy)" + } + } + } + }, + "responses": { + "201": { + "description": "Created \u2014 clone created in DRAFT state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateMutationResponse" + }, + "example": { + "id": "770e8400-e29b-41d4-a716-446655440002", + "state": "DRAFT", + "status": 201, + "selfLink": "/api/device-templates/770e8400-e29b-41d4-a716-446655440002", + "createdAt": "2026-04-20T12:00:00Z", + "updatedAt": "2026-04-20T12:00:00Z" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 400, + "message": "Bad Request \u2014 request validation failed", + "details": "Field 'name' is required for cloning" + } + } + } + }, + "404": { + "description": "Not Found \u2014 source template not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Source device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "409": { + "description": "Conflict \u2014 clone name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "A device template with name 'BIG-IP Standard Template (Copy)' already exists" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": "failed to create device template" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/DeviceTemplateIdParam" + } + ] + } + }, + "/api/provisioning/v1/device-templates/{id}/deploy": { + "post": { + "summary": "Deploy a device template", + "description": "Triggers deployment of a device template to target infrastructure.\n\n**Preconditions:**\n- Template must be in `NEW` or `DEPLOYED` state\n- Template must not be locked\n- Template must pass validation\n\nReturns 202 Accepted with a task object for tracking deployment progress.\n", + "operationId": "DeployDeviceTemplate", + "tags": [ + "Device Templates" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateDeployRequest" + }, + "example": { + "mgmtIp": "192.168.1.100", + "username": "admin", + "encodedBasicAuth": "YWRtaW46YWRtaW5QYXNzd29yZDEyMw==" + } + } + } + }, + "responses": { + "202": { + "description": "Accepted \u2014 deployment task queued", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateDeployResponse" + }, + "example": { + "status": 202, + "deviceTemplateId": "550e8400-e29b-41d4-a716-446655440000", + "deploymentTaskId": "c3d4e5f6-a7b8-4012-8def-123456789012", + "selfLink": "/api/device-templates/tasks/c3d4e5f6-a7b8-4012-8def-123456789012" + } + } + } + }, + "400": { + "description": "Bad Request \u2014 invalid request payload", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 400, + "message": "Bad Request \u2014 request validation failed", + "details": "Field 'mgmtIp' is required and must be a valid IPv4 address" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "409": { + "description": "Conflict \u2014 locked or already deploying", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "template is currently deploying and cannot be modified" + } + } + } + }, + "422": { + "description": "Unprocessable Entity \u2014 template not in deployable state or validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 422, + "message": "Unprocessable Entity \u2014 template validation failed", + "details": "Template must pass validation before deployment" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": null + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/DeviceTemplateIdParam" + } + ] + } + }, + "/api/provisioning/v1/device-templates/{id}/lock": { + "post": { + "summary": "Lock a device template", + "description": "Locks a device template to prevent modifications.\nSets `locked=true` and `lockReason=READ_ONLY`.\n\n**Precondition:** Template must not already be locked.\n", + "operationId": "LockDeviceTemplate", + "tags": [ + "Device Templates" + ], + "responses": { + "200": { + "description": "OK \u2014 device template locked", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateLockResponse" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "locked": true, + "lockReason": "READ_ONLY", + "status": 200, + "selfLink": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000", + "updatedAt": "2026-04-15T08:20:00Z" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "409": { + "description": "Conflict \u2014 already locked", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "template is locked and cannot be modified" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": null + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/DeviceTemplateIdParam" + } + ] + }, + "delete": { + "summary": "Unlock a device template", + "description": "Unlocks a device template to allow modifications.\nSets `locked=false` and `lockReason=NONE`.\n\n**Precondition:** Template must be locked with `lockReason=READ_ONLY`.\nSystem locks (`DEPLOYMENT`) cannot be manually unlocked.\n", + "operationId": "UnlockDeviceTemplate", + "tags": [ + "Device Templates" + ], + "responses": { + "200": { + "description": "OK \u2014 device template unlocked", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateLockResponse" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "locked": false, + "lockReason": "NONE", + "status": 200, + "selfLink": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000", + "updatedAt": "2026-04-15T09:00:00Z" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "409": { + "description": "Conflict \u2014 not locked or system-locked", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "template is currently deploying and cannot be modified" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": null + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/DeviceTemplateIdParam" + } + ] + } + }, + "/api/provisioning/v1/device-templates/{id}/validate": { + "post": { + "summary": "Validate a device template", + "description": "Runs multi-tier validation on a device template:\n\n- **Tier 1 \u2014 Data & Sanity:** Required fields, value ranges, cross-field rules.\n- **Tier 2 \u2014 Template / Schema:** Validates the definition against the default template schema.\n- **Tier 3 \u2014 Live VM (future):** Validates against a live BIG-IP VM.\n\nAlways returns HTTP 200. Inspect `valid` and each tier's result for pass/fail.\n", + "operationId": "ValidateDeviceTemplate", + "tags": [ + "Device Templates" + ], + "responses": { + "200": { + "description": "Validation completed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateValidationResponse" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "status": 200, + "valid": false, + "validatedAt": "2026-04-15T10:30:00Z", + "dataSanity": { + "valid": true, + "errors": [], + "warnings": [] + }, + "templateSchema": { + "valid": false, + "errors": [ + { + "field": "definition.managementSslPort", + "message": "Value must be between 1 and 65535" + } + ], + "warnings": [] + }, + "selfLink": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": null + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/DeviceTemplateIdParam" + } + ] + } + }, + "/api/provisioning/v1/executions": { + "get": { + "tags": [ + "Observability" + ], + "summary": "List executions across all workflows and jobs", + "description": "Global execution timeline across the entire platform.\nSupports filtering by workflow, job, execution mode, trigger, and time window.\n", + "operationId": "listAllExecutions", + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/LimitParam" + }, + { + "name": "workflowId", + "in": "query", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "jobId", + "in": "query", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "type", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + } + }, + { + "name": "executionMode", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "CONTINUOUS", + "ON_DEMAND" + ] + } + }, + { + "name": "status", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED", + "CANCELLED", + "TIMEOUT" + ] + } + }, + { + "name": "trigger", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "USER", + "ALERT", + "SYSTEM", + "SCHEDULE" + ] + } + }, + { + "name": "since", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "until", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "List of executions", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecutionListResponse" + }, + "example": { + "items": [ + { + "id": "2f2f8b64-91d2-4d4f-9aa8-03b8a9238ea1", + "jobId": "220f0b6b-87e7-4e5f-bcc2-9f2d26786ac6", + "trigger": "SYSTEM", + "status": "RUNNING", + "reason": "Continuous controller active", + "startedAt": "2026-05-18T08:10:00.000Z", + "activityCount": 37 + }, + { + "id": "7d8f5576-6414-410f-8f5a-0c34f95df3b0", + "jobId": "114ca9f9-88a3-49e1-92f2-757d7fedde98", + "trigger": "USER", + "status": "COMPLETED", + "reason": "Manual emergency run", + "startedAt": "2026-05-18T12:10:00.000Z", + "completedAt": "2026-05-18T12:17:00.000Z", + "activityCount": 1 + } + ], + "total": 2, + "page": 1, + "limit": 50 + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + } + } + } + }, + "/api/provisioning/v1/ip-pools": { + "get": { + "summary": "List IP pools", + "description": "Retrieve IP pools with optional pagination.", + "operationId": "getIpPools", + "parameters": [ + { + "name": "$top", + "in": "query", + "description": "Maximum number of records to return.", + "required": false, + "schema": { + "type": "integer", + "minimum": 1 + } + }, + { + "name": "$skip", + "in": "query", + "description": "Number of records to skip before returning results.", + "required": false, + "schema": { + "type": "integer", + "minimum": 0 + } + } + ], + "responses": { + "200": { + "description": "A paginated collection of IP pools.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPPoolListResponse" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ] + }, + "post": { + "summary": "Create IP pool", + "description": "Create a new IP pool with CIDR definition and address ranges.", + "operationId": "postIpPools", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPPoolCreateRequest" + } + } + } + }, + "responses": { + "201": { + "description": "IP pool created successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPPool" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ], + "parameters": [] + } + }, + "/api/provisioning/v1/ip-pools/leases": { + "post": { + "summary": "Create manual lease", + "description": "Manually create a lease for a specific address in a pool. Validates address belongs to pool ranges and enforces uniqueness.", + "operationId": "postIpPoolsLeases", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPLease" + } + } + } + }, + "responses": { + "200": { + "description": "Lease created successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPLease" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "409": { + "description": "Lease creation failed due to conflicts (address already allocated or allocationId in use).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ], + "parameters": [] + } + }, + "/api/provisioning/v1/ip-pools/release": { + "post": { + "summary": "Release IP address(es) globally across all pools", + "description": "Release one or more leases across all IP pools that match the provided allocation ID and optional lease tags.", + "operationId": "postRelease", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GlobalReleaseRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Leases successfully released (if any matched the criteria).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ], + "parameters": [] + } + }, + "/api/provisioning/v1/ip-pools/{poolId}": { + "get": { + "summary": "Get IP pool", + "description": "Fetch an IP pool by its identifier.", + "operationId": "getIpPoolsPoolId", + "responses": { + "200": { + "description": "IP pool details.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPPool" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PoolId" + } + ] + }, + "put": { + "summary": "Update IP pool", + "description": "Replace the configuration of an existing IP pool.", + "operationId": "putIpPoolsPoolId", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPPoolUpdateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Updated IP pool.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPPool" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PoolId" + } + ] + }, + "delete": { + "summary": "Delete IP pool", + "description": "Permanently remove an IP pool. The operation fails if the pool still has active leases.", + "operationId": "deleteIpPoolsPoolId", + "responses": { + "204": { + "description": "Pool deleted successfully." + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "409": { + "description": "Pool cannot be deleted because of active leases or validation errors.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PoolId" + } + ] + } + }, + "/api/provisioning/v1/ip-pools/{poolId}/allocate": { + "post": { + "summary": "Allocate IP address", + "description": "Allocate an IP address from the specified pool. The request is idempotent on `allocationId`.", + "operationId": "postIpPoolsPoolIdAllocate", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AllocationRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Allocation succeeded and returns the resulting lease.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AllocationResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "409": { + "description": "Allocation failed due to conflicts such as exhausted address space.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PoolId" + } + ] + } + }, + "/api/provisioning/v1/ip-pools/{poolId}/leases": { + "get": { + "summary": "List leases for pool", + "description": "Retrieve all active leases belonging to the specified pool.", + "operationId": "getIpPoolsPoolIdLeases", + "responses": { + "200": { + "description": "Collection of leases for the pool.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPLeaseListResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PoolId" + } + ] + } + }, + "/api/provisioning/v1/ip-pools/{poolId}/leases/{leaseId}": { + "get": { + "summary": "Get lease by ID", + "description": "Retrieve a specific lease by its identifier.", + "operationId": "getIpPoolsPoolIdLeasesLeaseId", + "responses": { + "200": { + "description": "Lease details.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPLease" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PoolId" + }, + { + "name": "leaseId", + "in": "path", + "description": "UUID of the IP lease.", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ] + } + }, + "/api/provisioning/v1/ip-pools/{poolId}/release": { + "post": { + "summary": "Release IP address(es)", + "description": "Release one or more leases that match the provided criteria (allocation ID, address, or tags).", + "operationId": "postIpPoolsPoolIdRelease", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Leases successfully released (if any matched the filters).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PoolId" + } + ] + } + }, + "/api/provisioning/v1/jobs": { + "get": { + "tags": [ + "Observability" + ], + "summary": "List jobs across all workflows", + "description": "Global jobs listing endpoint across workflow templates.\nUseful for platform views, tenant operations dashboards, and central search.\n", + "operationId": "listAllJobs", + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/LimitParam" + }, + { + "name": "workflowId", + "in": "query", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "type", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + } + }, + { + "name": "executionMode", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "CONTINUOUS", + "ON_DEMAND" + ] + } + }, + { + "name": "status", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSED", + "INACTIVE", + "ERROR", + "DELETING" + ] + } + } + ], + "responses": { + "200": { + "description": "List of jobs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobListPaginatedResponse" + }, + "example": { + "items": [ + { + "id": "220f0b6b-87e7-4e5f-bcc2-9f2d26786ac6", + "workflowId": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "name": "tenant-a-autoscale", + "status": "ACTIVE", + "createdAt": "2026-05-18T12:00:00.000Z", + "updatedAt": "2026-05-18T14:45:00.000Z" + } + ], + "pagination": { + "page": 1, + "page_size": 50, + "total": 1, + "total_pages": 1 + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + } + } + } + }, + "/api/provisioning/v1/jobs/bulk-delete": { + "post": { + "tags": [ + "Jobs" + ], + "summary": "Bulk delete jobs", + "description": "Delete multiple jobs in a single request. Each job is processed\nindependently \u2014 partial success is possible. Jobs that are in an\nactive lifecycle state (RUNNING, ACTIVE, PAUSING, PAUSED, CANCELLING)\ncannot be deleted and will be reported as FAILED in the response.\nThe deletion propagates to feature-specific tables (software installation,\nsoftware distribution) via the pg_notify mechanism.\n", + "operationId": "bulkDeleteJobs", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkDeleteJobsRequest" + }, + "example": { + "job_ids": [ + "550e8400-e29b-41d4-a716-446655440001", + "550e8400-e29b-41d4-a716-446655440002" + ] + } + } + } + }, + "responses": { + "200": { + "description": "Bulk delete results (partial success possible)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkDeleteJobsResponse" + }, + "example": { + "results": [ + { + "job_id": "550e8400-e29b-41d4-a716-446655440001", + "status": "DELETED" + }, + { + "job_id": "550e8400-e29b-41d4-a716-446655440002", + "status": "FAILED", + "error": "job cannot be deleted while it has live work \u2014 abort the job first" + } + ] + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + } + }, + "parameters": [] + } + }, + "/api/provisioning/v1/licensing/pool/regkey/licenses": { + "get": { + "tags": [ + "License Pool" + ], + "summary": "Fetches all available license pools", + "description": "Fetches all available license pools in the system.", + "operationId": "getLicensePools", + "parameters": [ + { + "name": "$select", + "in": "query", + "required": false, + "description": "Fields to select in the response", + "schema": { + "type": "string" + }, + "example": "id" + } + ], + "responses": { + "200": { + "description": "returns list of all License pools successfully", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/LicensePool" + } + } + } + } + }, + "400": { + "description": "Bad request - invalid input", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "post": { + "tags": [ + "License Pool" + ], + "summary": "Create a new license pool", + "description": "Creates a new license pool that can hold multiple license offerings", + "operationId": "createLicensePool", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the license pool", + "example": "test" + }, + "description": { + "type": "string", + "description": "Description of the license pool", + "example": "" + } + } + }, + "examples": { + "createPool": { + "summary": "Create license pool example", + "value": { + "name": "test", + "description": "" + } + } + } + } + } + }, + "responses": { + "201": { + "description": "License pool created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicensePool" + } + } + } + }, + "400": { + "description": "Bad request - invalid input", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/provisioning/v1/licensing/pool/regkey/licenses/{poolId}": { + "get": { + "tags": [ + "License Pool" + ], + "summary": "Get license pool by ID", + "description": "Get license pool by given ID in the path parameter", + "operationId": "getLicensePool", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + } + ], + "responses": { + "200": { + "description": "Returns the License pool successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicensePool" + } + } + } + }, + "400": { + "description": "Bad request - invalid input", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool not found" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "delete": { + "tags": [ + "License Pool" + ], + "summary": "Delete a license pool", + "description": "Deletes a license pool. If licenses are added and activated but not assigned to any device, deleting the pool will invalidate all associated registration keys. If any license from the pool is already assigned to a member, returns 400 error.\n", + "operationId": "deleteLicensePool", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + } + ], + "responses": { + "204": { + "description": "License pool deleted successfully" + }, + "400": { + "description": "Bad request - pool has outstanding grants", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "code": 400, + "message": "Found 1 outstanding grant(s). They must be removed before this license can be deleted." + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool not found" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/provisioning/v1/licensing/pool/regkey/licenses/{poolId}/assign": { + "post": { + "tags": [ + "License Pool" + ], + "summary": "Assign an available license from the pool to a device", + "description": "Automatically assigns an available license from the pool to the specified BIG-IP device.\n\nThis is a convenience endpoint that:\n1. Finds all offerings in the pool that are READY and not already assigned to any member\n2. Picks the first available offering\n3. Assigns the license to the specified device\n\nThis is an **asynchronous operation** that returns a TaskReference for polling.\n", + "operationId": "assignPoolLicense", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoolLicenseOperationRequest" + }, + "examples": { + "assignLicense": { + "summary": "Assign license to device", + "value": { + "deviceAddress": "192.168.1.100", + "deviceUsername": "admin", + "devicePassword": "admin" + } + } + } + } + } + }, + "responses": { + "202": { + "description": "License assignment initiated (async operation)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskReference" + } + } + } + }, + "400": { + "description": "Bad request - no available licenses or invalid parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "noAvailableLicenses": { + "summary": "No available licenses in the pool", + "value": { + "code": 400, + "message": "No available licenses in the pool" + } + }, + "invalidDeviceAddress": { + "summary": "Invalid device address", + "value": { + "code": 400, + "message": "Invalid device address" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool not found" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/provisioning/v1/licensing/pool/regkey/licenses/{poolId}/offerings": { + "post": { + "tags": [ + "License Offering" + ], + "summary": "Add license offering to the pool", + "description": "Adds a license offering to an existing pool by activating a registration key. Steps - 1. Generate public/private keys and dossier. 2. Check the MODE of activation (AUTOMATIC, MANUAL, CCN) and trigger corresponding flow. 3. Contact F5 License Server at https://authem.f5net.com/license/services/. 4. F5 License server returns license_text if activation is successful.\n", + "operationId": "addLicenseOffering", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "regKey", + "status" + ], + "properties": { + "regKey": { + "type": "string", + "description": "F5 registration key", + "example": "U5939-99933-49705-74523-4841009" + }, + "status": { + "type": "string", + "enum": [ + "ACTIVATING_AUTOMATIC", + "ACTIVATING_MANUAL" + ], + "description": "Activation mode to use when adding the offering. ACTIVATING_AUTOMATIC - contacts F5 license server automatically. ACTIVATING_MANUAL - begins manual activation flow.\n", + "example": "ACTIVATING_AUTOMATIC" + }, + "name": { + "type": "string", + "description": "Optional name for the license offering", + "example": "" + }, + "description": { + "type": "string", + "description": "Optional description for the license offering", + "example": "" + } + } + }, + "examples": { + "automaticActivation": { + "summary": "Automatic activation example", + "value": { + "regKey": "U5939-99933-49705-74523-4841009", + "status": "ACTIVATING_AUTOMATIC", + "name": "", + "description": "" + } + }, + "manualActivation": { + "summary": "Manual activation example", + "value": { + "regKey": "U5939-99933-49705-74523-4841009", + "status": "ACTIVATING_MANUAL", + "name": "", + "description": "" + } + } + } + } + } + }, + "responses": { + "202": { + "description": "License offering activation initiated (async operation)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskReference" + } + } + } + }, + "400": { + "description": "Bad request - invalid registration key or activation failure", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool not found" + }, + "500": { + "description": "Internal server error" + } + } + }, + "get": { + "tags": [ + "License Offering" + ], + "summary": "Get all license offerings in the pool", + "description": "Retrieves all license offerings associated with a specific license pool", + "operationId": "getLicenseOfferings", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "$select", + "in": "query", + "required": false, + "description": "Fields to select in the response", + "schema": { + "type": "string" + }, + "example": "selfLink" + }, + { + "name": "$filter", + "in": "query", + "required": false, + "description": "OData filter expression to filter offerings.\nSupported fields: status, isAssigned, regKey\nExamples:\n- `isAssigned eq false` - Get only available (unassigned) offerings\n- `isAssigned eq true` - Get only assigned offerings\n- `status eq 'READY'` - Get only offerings with READY status\n- `status eq 'READY' and isAssigned eq false` - Get available READY offerings\n", + "schema": { + "type": "string" + }, + "examples": { + "available": { + "summary": "Get available offerings", + "value": "isAssigned eq false" + }, + "assigned": { + "summary": "Get assigned offerings", + "value": "isAssigned eq true" + }, + "readyAndAvailable": { + "summary": "Get ready and available offerings", + "value": "status eq 'READY' and isAssigned eq false" + } + } + } + ], + "responses": { + "200": { + "description": "List of license offerings retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/LicenseOffering" + } + }, + "totalItems": { + "type": "integer", + "description": "Total number of offerings" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool not found" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/provisioning/v1/licensing/pool/regkey/licenses/{poolId}/offerings/{regKey}": { + "get": { + "tags": [ + "License Offering" + ], + "summary": "Get license offering by registration key", + "description": "Retrieves a specific license offering from the pool by its registration key. Returns the full offering details including activation status, license text, and license count information.\n", + "operationId": "getLicenseOffering", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "regKey", + "in": "path", + "required": true, + "description": "Registration key of the license offering", + "schema": { + "type": "string" + }, + "example": "U5939-99933-49705-74523-4841009" + } + ], + "responses": { + "200": { + "description": "License offering retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseOffering" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool or offering not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "code": 404, + "message": "License offering with regKey U5939-99933-49705-74523-4841009 not found in pool 7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + } + } + } + }, + "500": { + "description": "Internal server error" + } + } + }, + "patch": { + "tags": [ + "License Offering" + ], + "summary": "Update or reactivate a license offering", + "description": "Updates an existing license offering in the pool. This endpoint supports three distinct operations\nbased on the `status` field in the request body:\n\n---\n## Operation 1: Automatic Reactivation (Async)\n**Request:** `{\"status\": \"ACTIVATING_AUTOMATIC\"}`\n**Response:** `202 Accepted` with TaskReference\n\nTriggers automatic reactivation via F5 license server. This is an **asynchronous operation**.\n\nSteps:\n1. Validate the offering exists and belongs to the specified pool.\n2. Generate a new dossier for the existing registration key.\n3. Contact F5 License Server at https://authem.f5net.com/license/services/ for reactivation.\n4. F5 License Server returns updated license_text if reactivation is successful.\n5. Update the offering status to READY upon successful reactivation.\n\nPoll the returned task link to check completion status.\n\n---\n## Operation 2: Manual Reactivation - Get New Dossier (Sync)\n**Request:** `{\"status\": \"ACTIVATING_MANUAL\"}`\n**Response:** `200 OK` with LicenseOffering (containing new dossier)\n\nTriggers manual reactivation flow. This is a **synchronous operation** that returns immediately\nwith a new dossier. The offering status will be set to `ACTIVATING_MANUAL_NEED_LICENSE_TEXT`.\n\nSteps:\n1. Validate the offering exists and belongs to the specified pool.\n2. Regenerate dossier (reuses existing keys).\n3. Return the updated offering with the new dossier.\n\nUser should then submit the dossier to F5 license server UI to obtain license text.\n\n---\n## Operation 3: Complete Manual Activation with License Text (Sync)\n**Request:** `{\"status\": \"ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED\", \"licenseText\": \"...\"}`\n**Response:** `200 OK` with LicenseOffering\n\nCompletes manual activation by providing the license text. This is a **synchronous operation**.\nThe offering must be in `ACTIVATING_MANUAL_NEED_LICENSE_TEXT` status.\n\nSteps:\n1. Validate the offering exists and is in ACTIVATING_MANUAL_NEED_LICENSE_TEXT status.\n2. Validate the provided license text format.\n3. Store the license text and parse license state.\n4. Update the offering status to READY.\n", + "operationId": "updateLicenseOffering", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "regKey", + "in": "path", + "required": true, + "description": "Registration key of the license offering to update", + "schema": { + "type": "string" + }, + "example": "U5939-99933-49705-74523-4841009" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateLicenseOfferingRequest" + }, + "examples": { + "reactivateAutomatic": { + "summary": "Operation 1: Automatic Reactivation (Async) \u2192 Returns 202 with TaskReference", + "value": { + "status": "ACTIVATING_AUTOMATIC" + } + }, + "reactivateManual": { + "summary": "Operation 2: Manual Reactivation (Sync) \u2192 Returns 200 with new dossier", + "value": { + "status": "ACTIVATING_MANUAL" + } + }, + "completeManualActivation": { + "summary": "Operation 3: Complete Manual Activation (Sync) \u2192 Returns 200 with activated offering", + "value": { + "status": "ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED", + "licenseText": "Auth vers : 5b\nRegistration key : W5778-33088-84412-26046-5913991\nLicensed date : 20260525\nLicense start : 20260524\nLicense end : 20260625\nService check date : 20260525\nPlatform ID : Z100\nUsage : F5 Internal Product Development\nVendor : F5 Networks, Inc.\n..." + } + } + } + } + } + }, + "responses": { + "200": { + "description": "License offering updated successfully. Returned for **synchronous operations**:\n- `ACTIVATING_MANUAL`: Returns offering with new dossier (status: ACTIVATING_MANUAL_NEED_LICENSE_TEXT)\n- `ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED`: Returns fully activated offering (status: READY)\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseOffering" + }, + "examples": { + "manualReactivationResponse": { + "summary": "Response for ACTIVATING_MANUAL - new dossier generated", + "value": { + "id": "f1e2d3c4-b5a6-7890-cdef-123456789abc", + "regKey": "U5939-99933-49705-74523-4841009", + "name": "", + "status": "ACTIVATING_MANUAL_NEED_LICENSE_TEXT", + "dossier": "1ac56379204d679f59524f2e64300d03b91b4b9ff08225ce0087d91b6cf061227610", + "message": "Dossier generated. Submit this dossier to F5 license server to obtain license text, then call this endpoint with status ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED.", + "selfLink": "https://localhost/api/licensing/pool/regkey/licenses/7dd7b971-6eb8-4b9e-995b-1dcb1287d65f/offerings/U5939-99933-49705-74523-4841009", + "createdAt": "2024-01-15T10:30:00Z" + } + }, + "licenseTextProvidedResponse": { + "summary": "Response for ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED - activation complete", + "value": { + "id": "f1e2d3c4-b5a6-7890-cdef-123456789abc", + "regKey": "U5939-99933-49705-74523-4841009", + "name": "", + "status": "READY", + "licenseText": "Auth vers : 5b\nRegistration key : W5778-33088-84412-26046-5913991\n...", + "licenseState": { + "registrationKey": "W5778-33088-84412-26046-5913991", + "licensedDateTime": "2024-01-15T10:30:00Z", + "licenseEndDateTime": "2025-01-15T10:30:00Z" + }, + "selfLink": "https://localhost/api/licensing/pool/regkey/licenses/7dd7b971-6eb8-4b9e-995b-1dcb1287d65f/offerings/U5939-99933-49705-74523-4841009", + "createdAt": "2024-01-15T10:30:00Z", + "activatedAt": "2024-01-15T10:35:00Z" + } + } + } + } + } + }, + "202": { + "description": "License offering reactivation initiated. Returned for **asynchronous operation**:\n- `ACTIVATING_AUTOMATIC`: Returns task reference for polling\n\nPoll the `taskLink` to check the status of the reactivation operation.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskReference" + }, + "example": { + "taskLink": "https://localhost/api/licensing/pool/tasks/d4e5f6a7-b8c9-0123-defg-456789abcdef" + } + } + } + }, + "400": { + "description": "Bad request - invalid status, missing license text, or operation not allowed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "invalidStatus": { + "summary": "Invalid status for current offering state", + "value": { + "code": 400, + "message": "Cannot complete manual activation: offering is not in ACTIVATING_MANUAL_NEED_LICENSE_TEXT status" + } + }, + "missingLicenseText": { + "summary": "Missing license text for manual completion", + "value": { + "code": 400, + "message": "License text is required when status is ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED" + } + }, + "invalidLicenseText": { + "summary": "Invalid license text format", + "value": { + "code": 400, + "message": "Invalid license text format: missing required fields" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool or offering not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "code": 404, + "message": "License offering with regKey U5939-99933-49705-74523-4841009 not found in pool 7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + } + } + } + }, + "500": { + "description": "Internal server error" + } + } + }, + "delete": { + "tags": [ + "License Offering" + ], + "summary": "Delete license offering from the pool", + "description": "Deletes a specific license offering from the pool. If the license has already been granted to a member, returns 400 error.\n", + "operationId": "deleteLicenseOffering", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "regKey", + "in": "path", + "required": true, + "description": "Registration key of the license offering", + "schema": { + "type": "string" + }, + "example": "U5939-99933-49705-74523-4841009" + } + ], + "responses": { + "204": { + "description": "License offering deleted successfully" + }, + "400": { + "description": "Bad request - license has been granted to a device", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "code": 400, + "message": "The license U5939-99933-49705-74523-4841009 has been granted to a device" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License offering not found" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/provisioning/v1/licensing/pool/regkey/licenses/{poolId}/offerings/{regKey}/members": { + "post": { + "tags": [ + "License Members" + ], + "summary": "Assign license offering to member", + "description": "Assign a license from the pool to a specific BIG-IP device member", + "operationId": "assignLicenseMember", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "regKey", + "in": "path", + "required": true, + "description": "Registration key of the license offering", + "schema": { + "type": "string" + }, + "example": "U5939-99933-49705-74523-4841009" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "deviceAddress", + "deviceUsername", + "devicePassword" + ], + "properties": { + "deviceAddress": { + "type": "string", + "format": "ipv4", + "description": "IP address of the BIG-IP device", + "example": "192.168.1.100" + }, + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + }, + "examples": { + "assignMember": { + "summary": "Assign license to member example", + "value": { + "deviceAddress": "192.168.1.100", + "deviceUsername": "admin", + "devicePassword": "admin" + } + } + } + } + } + }, + "responses": { + "202": { + "description": "License assignment initiated (async operation)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskReference" + } + } + } + }, + "400": { + "description": "Bad request - invalid parameters, no available licenses, or license already granted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "licenseAlreadyGranted": { + "summary": "License already assigned to another device", + "value": { + "code": 400, + "message": "This license has already been granted to a BIG-IP - bigip-ve-001.local" + } + }, + "invalidDeviceAddress": { + "summary": "Invalid device address", + "value": { + "code": 400, + "message": "Invalid device address" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool or offering not found" + }, + "500": { + "description": "Internal server error" + } + } + }, + "get": { + "tags": [ + "License Members" + ], + "summary": "Get all license offering members", + "description": "Retrieves all members (BIG-IP devices) that have been assigned licenses from a specific offering", + "operationId": "getLicenseMembers", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "regKey", + "in": "path", + "required": true, + "description": "Registration key of the license offering", + "schema": { + "type": "string" + }, + "example": "U5939-99933-49705-74523-4841009" + } + ], + "responses": { + "200": { + "description": "List of license members retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/LicenseMember" + } + }, + "totalItems": { + "type": "integer", + "description": "Total number of members" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool or offering not found" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/provisioning/v1/licensing/pool/regkey/licenses/{poolId}/offerings/{regKey}/members/{memberId}": { + "delete": { + "tags": [ + "License Members" + ], + "summary": "Revoke license from member", + "description": "Revokes a license assignment from a specific BIG-IP device member and returns the license to the pool. This is a synchronous operation that contacts the device to deactivate the license. If force=true is specified, the license will be revoked from the pool without contacting the device.\n", + "operationId": "revokeLicenseMember", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "regKey", + "in": "path", + "required": true, + "description": "Registration key of the license offering", + "schema": { + "type": "string" + }, + "example": "U5939-99933-49705-74523-4841009" + }, + { + "name": "memberId", + "in": "path", + "required": true, + "description": "UUID of the license member", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" + }, + { + "name": "force", + "in": "query", + "required": false, + "description": "If true, skip device reachability check and delete the license assignment from the pool without contacting the BIG-IP device. Useful when the device is unreachable or destroyed.\n", + "schema": { + "type": "boolean", + "default": false + }, + "example": true + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "deviceUsername", + "devicePassword" + ], + "properties": { + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + }, + "examples": { + "revokeMember": { + "summary": "Revoke license from member example", + "value": { + "deviceUsername": "admin", + "devicePassword": "admin" + } + } + } + } + } + }, + "responses": { + "204": { + "description": "License successfully revoked from the device" + }, + "400": { + "description": "Bad request - revocation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License member not found" + }, + "500": { + "description": "Internal server error" + } + } + }, + "patch": { + "tags": [ + "License Members" + ], + "summary": "Reactivating license key on member", + "description": "Updates the details of a license member, such as device information. This can be used to correct device information or update the member record after a device change.\n", + "operationId": "reactivateLicenseMember", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "regKey", + "in": "path", + "required": true, + "description": "Registration key of the license offering", + "schema": { + "type": "string" + }, + "example": "U5939-99933-49705-74523-4841009" + }, + { + "name": "memberId", + "in": "path", + "required": true, + "description": "UUID of the license member to update", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + } + } + } + }, + "responses": { + "202": { + "description": "License member update initiated (async operation)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskReference" + } + } + } + }, + "400": { + "description": "Bad request - invalid input or update failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License member not found" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/provisioning/v1/licensing/pool/regkey/licenses/{poolId}/revoke": { + "delete": { + "tags": [ + "License Pool" + ], + "summary": "Revoke license from a device in the pool", + "description": "Revokes the license from a device that has a license assigned from this pool.\n\nThis is a convenience endpoint that:\n1. Finds the member record by device address\n2. Revokes the license from the device (unless force=true)\n3. Removes the member record from the pool\n\nIf `force=true`, the license will be revoked from the pool without contacting the device.\nThis is useful when the device is unreachable or destroyed.\n", + "operationId": "revokePoolLicense", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "force", + "in": "query", + "required": false, + "description": "If true, skip device communication and delete the license assignment from the pool\nwithout contacting the BIG-IP device. Useful when the device is unreachable or destroyed.\n", + "schema": { + "type": "boolean", + "default": false + }, + "example": true + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoolLicenseOperationRequest" + }, + "examples": { + "revokeLicense": { + "summary": "Revoke license from device", + "value": { + "deviceAddress": "192.168.1.100", + "deviceUsername": "admin", + "devicePassword": "admin" + } + } + } + } + } + }, + "responses": { + "204": { + "description": "License successfully revoked from the device" + }, + "400": { + "description": "Bad request - revocation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool not found or device not found in pool", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "deviceNotFound": { + "summary": "Device not found in pool", + "value": { + "code": 404, + "message": "Device 192.168.1.100 not found in pool" + } + } + } + } + } + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/provisioning/v1/licensing/pool/tasks": { + "get": { + "tags": [ + "Tasks" + ], + "summary": "List all tasks", + "description": "Retrieves a paginated list of all async tasks with optional filtering.\nUseful for monitoring and debugging async operations.\n", + "operationId": "listTasks", + "parameters": [ + { + "name": "status", + "in": "query", + "required": false, + "description": "Filter tasks by status", + "schema": { + "type": "string", + "enum": [ + "PENDING", + "IN_PROGRESS", + "COMPLETED", + "FAILED" + ] + }, + "example": "IN_PROGRESS" + }, + { + "name": "type", + "in": "query", + "required": false, + "description": "Filter tasks by type", + "schema": { + "type": "string", + "enum": [ + "ADD_OFFERING", + "REACTIVATE_OFFERING", + "ASSIGN_LICENSE", + "REVOKE_LICENSE" + ] + }, + "example": "ASSIGN_LICENSE" + }, + { + "name": "resourceType", + "in": "query", + "required": false, + "description": "Filter tasks by resource type", + "schema": { + "type": "string", + "enum": [ + "LicenseOffering", + "LicenseMember" + ] + }, + "example": "LicenseMember" + }, + { + "name": "resourceId", + "in": "query", + "required": false, + "description": "Filter tasks by resource ID", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" + }, + { + "name": "page", + "in": "query", + "required": false, + "description": "Page number for pagination (1-based)", + "schema": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "example": 1 + }, + { + "name": "size", + "in": "query", + "required": false, + "description": "Number of items per page", + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 20 + }, + "example": 20 + }, + { + "name": "sort", + "in": "query", + "required": false, + "description": "Sort order for results. Format: field:direction\nSupported fields: createdAt, startedAt, completedAt, status\nDirection: asc or desc\n", + "schema": { + "type": "string", + "default": "createdAt:desc" + }, + "example": "createdAt:desc" + } + ], + "responses": { + "200": { + "description": "List of tasks retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskListResponse" + } + } + } + }, + "400": { + "description": "Bad request - invalid filter parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/licensing/pool/tasks/{taskId}": { + "get": { + "tags": [ + "Tasks" + ], + "summary": "Get task status by ID", + "description": "Retrieves the current status and details of an async task.\nUse this endpoint to poll for task completion after initiating async operations\nlike license activation, assignment, or revocation.\n", + "operationId": "getTaskStatus", + "parameters": [ + { + "name": "taskId", + "in": "path", + "required": true, + "description": "UUID of the task to retrieve", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "d4e5f6a7-b8c9-0123-defg-456789abcdef" + } + ], + "responses": { + "200": { + "description": "Task status retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Task" + }, + "examples": { + "pendingTask": { + "summary": "Task pending", + "value": { + "id": "d4e5f6a7-b8c9-0123-defg-456789abcdef", + "type": "ASSIGN_LICENSE", + "status": "PENDING", + "progress": 0, + "resourceType": "LicenseMember", + "resourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "selfLink": "https://localhost/api/licensing/pool/tasks/d4e5f6a7-b8c9-0123-defg-456789abcdef", + "createdAt": "2024-01-15T10:30:00Z" + } + }, + "inProgressTask": { + "summary": "Task in progress", + "value": { + "id": "d4e5f6a7-b8c9-0123-defg-456789abcdef", + "type": "ADD_OFFERING", + "status": "IN_PROGRESS", + "progress": 50, + "resourceType": "LicenseOffering", + "resourceId": "f1e2d3c4-b5a6-7890-cdef-123456789abc", + "selfLink": "https://localhost/api/licensing/pool/tasks/d4e5f6a7-b8c9-0123-defg-456789abcdef", + "createdAt": "2024-01-15T10:30:00Z", + "startedAt": "2024-01-15T10:30:05Z" + } + }, + "completedTask": { + "summary": "Task completed successfully", + "value": { + "id": "d4e5f6a7-b8c9-0123-defg-456789abcdef", + "type": "ASSIGN_LICENSE", + "status": "COMPLETED", + "progress": 100, + "resourceType": "LicenseMember", + "resourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "resourceLink": "https://localhost/api/licensing/pool/regkey/licenses/7dd7b971-6eb8-4b9e-995b-1dcb1287d65f/offerings/U5939-99933-49705-74523-4841009/members/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "selfLink": "https://localhost/api/licensing/pool/tasks/d4e5f6a7-b8c9-0123-defg-456789abcdef", + "createdAt": "2024-01-15T10:30:00Z", + "startedAt": "2024-01-15T10:30:05Z", + "completedAt": "2024-01-15T10:30:15Z" + } + }, + "failedTask": { + "summary": "Task failed", + "value": { + "id": "d4e5f6a7-b8c9-0123-defg-456789abcdef", + "type": "ADD_OFFERING", + "status": "FAILED", + "progress": 25, + "resourceType": "LicenseOffering", + "resourceId": "f1e2d3c4-b5a6-7890-cdef-123456789abc", + "error": { + "code": 500, + "message": "Failed to contact F5 license server", + "details": "Connection timeout after 30 seconds", + "timestamp": "2024-01-15T10:30:35Z" + }, + "selfLink": "https://localhost/api/licensing/pool/tasks/d4e5f6a7-b8c9-0123-defg-456789abcdef", + "createdAt": "2024-01-15T10:30:00Z", + "startedAt": "2024-01-15T10:30:05Z", + "completedAt": "2024-01-15T10:30:35Z" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "code": 404, + "message": "Task with ID d4e5f6a7-b8c9-0123-defg-456789abcdef not found" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/workflows": { + "get": { + "tags": [ + "Workflows" + ], + "summary": "List workflow templates", + "description": "Returns workflow templates that define reusable workflow behavior.\nSupports filtering by workflow type, execution mode, and template lifecycle status.\nUse this endpoint for catalog/discovery before creating Jobs.\n", + "operationId": "listWorkflows", + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/LimitParam" + }, + { + "name": "type", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + } + }, + { + "name": "executionMode", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "CONTINUOUS", + "ON_DEMAND" + ] + } + }, + { + "name": "status", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "DRAFT", + "ACTIVE", + "DEPRECATED" + ] + } + } + ], + "responses": { + "200": { + "description": "List of workflow templates", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkflowListResponse" + }, + "example": { + "items": [ + { + "id": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "name": "autoscale-default", + "description": "Autoscale default template", + "type": "AUTO_SCALE", + "executionMode": "CONTINUOUS", + "createdAt": "2026-05-18T10:00:00.000Z" + } + ], + "total": 1, + "page": 1, + "limit": 50 + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}": { + "get": { + "tags": [ + "Workflows" + ], + "summary": "Get a workflow template", + "description": "Returns a single workflow template by ID including type, execution mode,\nversioning metadata, and default configuration.\n", + "operationId": "getWorkflow", + "responses": { + "200": { + "description": "Workflow template", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Workflow" + }, + "example": { + "id": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "name": "autoscale-template-prod", + "description": "Production autoscale template for monitoring and scaling", + "type": "AUTO_SCALE", + "executionMode": "CONTINUOUS", + "createdAt": "2026-05-18T10:10:00.000Z" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + } + ] + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs": { + "get": { + "tags": [ + "Jobs" + ], + "summary": "List jobs for a workflow", + "description": "Lists runtime Jobs created from a workflow template.\nJobs represent environment- or tenant-specific instantiations of the template.\nSupports status filtering and pagination.\n", + "operationId": "listJobs", + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/LimitParam" + }, + { + "name": "status", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSED", + "INACTIVE", + "ERROR", + "DELETING" + ] + } + }, + { + "$ref": "#/components/parameters/WorkflowId" + } + ], + "responses": { + "200": { + "description": "List of jobs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobListResponse" + }, + "example": { + "items": [ + { + "id": "114ca9f9-88a3-49e1-92f2-757d7fedde98", + "workflowId": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "name": "tenant-a-autoscale", + "status": "ACTIVE", + "createdAt": "2026-05-18T11:00:00.000Z", + "updatedAt": "2026-05-18T11:00:00.000Z" + } + ], + "total": 1, + "page": 1, + "limit": 50 + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + }, + "post": { + "tags": [ + "Jobs" + ], + "summary": "Create a job (runtime instance of a workflow)", + "description": "Creates a new runtime Job under a workflow template.\nJob-level `config` overrides are merged with template `defaultConfig`\nto produce `effectiveConfig` used during execution.\n", + "operationId": "createJob", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobCreateRequest" + }, + "examples": { + "autoscale": { + "summary": "Create AutoScale job", + "value": { + "type": "AUTO_SCALE", + "name": "tenant-a-autoscale", + "status": "READY", + "config": { + "configType": "AUTO_SCALE", + "environmentReference": "550e8400-e29b-41d4-a716-446655440000", + "templateReference": "550e8400-e29b-41d4-a716-446655440001", + "licensePoolReference": "550e8400-e29b-41d4-a716-446655440003", + "minSize": 2, + "maxSize": 8, + "desiredSize": 3, + "evaluationPeriod": 300, + "scaleInMethod": "NEWEST_FIRST", + "scaleOutCooldownSeconds": 600, + "scaleInCooldownSeconds": 900 + } + } + }, + "autoscaleBurst": { + "summary": "Create burst-capable AutoScale job", + "value": { + "type": "AUTO_SCALE", + "name": "tenant-b-autoscale-burst", + "config": { + "configType": "AUTO_SCALE", + "environmentReference": "550e8400-e29b-41d4-a716-446655440020", + "templateReference": "550e8400-e29b-41d4-a716-446655440021", + "licensePoolReference": "550e8400-e29b-41d4-a716-446655440023", + "minSize": 3, + "maxSize": 15, + "desiredSize": 5, + "evaluationPeriod": 120, + "scaleInMethod": "NEWEST_FIRST", + "scaleOutCooldownSeconds": 300, + "scaleInCooldownSeconds": 600 + } + } + } + } + } + } + }, + "responses": { + "201": { + "description": "Job created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + }, + "example": { + "id": "114ca9f9-88a3-49e1-92f2-757d7fedde98", + "workflowId": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "name": "tenant-a-autoscale", + "type": "AUTO_SCALE", + "status": "READY", + "version": "v1", + "createdAt": "2026-05-18T11:00:00.000Z", + "updatedAt": "2026-05-18T11:00:00.000Z" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + } + ] + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}": { + "get": { + "tags": [ + "Jobs" + ], + "summary": "Get a job", + "description": "Returns one Job including resolved configuration (`effectiveConfig`),\nlifecycle status, and runtime/schedule state when applicable.\n", + "operationId": "getJob", + "responses": { + "200": { + "description": "Job", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + }, + "example": { + "id": "114ca9f9-88a3-49e1-92f2-757d7fedde98", + "workflowId": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "name": "tenant-a-autoscale", + "type": "AUTO_SCALE", + "status": "ACTIVE", + "config": { + "configType": "AUTO_SCALE", + "minSize": 2, + "maxSize": 8, + "desiredSize": 4, + "scaleOutCooldownSeconds": 600, + "scaleInCooldownSeconds": 900 + }, + "runtime": { + "currentSize": 4, + "lastEvaluatedAt": "2026-05-18T11:09:30.000Z" + }, + "createdAt": "2026-05-18T11:00:00.000Z", + "updatedAt": "2026-05-18T11:10:00.000Z" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ] + }, + "patch": { + "tags": [ + "Jobs" + ], + "summary": "Partially update a job config", + "description": "Not allowed while a CONTINUOUS job is ACTIVE or an ON_DEMAND execution is RUNNING.", + "operationId": "patchJob", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobPatchRequest" + }, + "examples": { + "updateName": { + "summary": "Update job name", + "value": { + "name": "tenant-a-autoscale-prod" + } + }, + "updateStatus": { + "summary": "Pause job updates during maintenance", + "value": { + "status": "PAUSED" + } + }, + "updateDesiredSize": { + "summary": "Update desired size for AutoScale job", + "value": { + "config": { + "configType": "AUTO_SCALE", + "desiredSize": 5 + } + } + }, + "updateAutoScaleConfig": { + "summary": "Update AutoScale configuration", + "value": { + "config": { + "configType": "AUTO_SCALE", + "licensePoolReference": "550e8400-e29b-41d4-a716-446655440003", + "minSize": 2, + "maxSize": 12, + "desiredSize": 4, + "scaleOutCooldownSeconds": 300 + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Updated job", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + }, + "example": { + "id": "114ca9f9-88a3-49e1-92f2-757d7fedde98", + "workflowId": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "name": "tenant-a-autoscale-prod", + "type": "AUTO_SCALE", + "status": "ACTIVE", + "updatedAt": "2026-05-18T11:20:00.000Z" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "$ref": "#/components/responses/Conflict" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ] + }, + "delete": { + "tags": [ + "Jobs" + ], + "summary": "Delete a job", + "description": "Terminates any running executions before deletion.", + "operationId": "deleteJob", + "responses": { + "204": { + "description": "Deleted" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "$ref": "#/components/responses/Conflict" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ] + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/activate": { + "post": { + "tags": [ + "Lifecycle - Continuous" + ], + "summary": "Activate a CONTINUOUS job", + "description": "Transitions job from READY/PAUSED \u2192 ACTIVE.\nOnly valid for jobs whose parent Workflow has executionMode=CONTINUOUS.\nStarts (or reuses) the long-lived continuous execution container for activity generation.\n", + "operationId": "activateJob", + "responses": { + "200": { + "description": "Job activated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + }, + "example": { + "id": "2f2f8b64-91d2-4d4f-9aa8-03b8a9238ea1", + "jobId": "220f0b6b-87e7-4e5f-bcc2-9f2d26786ac6", + "workflowId": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "status": "RUNNING", + "startedAt": "2026-05-18T12:00:00.000Z" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "$ref": "#/components/responses/Conflict" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ] + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/devices": { + "get": { + "tags": [ + "Jobs" + ], + "summary": "List autoscale devices for a job", + "description": "Returns all autoscale device rows associated with the job.\n", + "operationId": "listDevices", + "responses": { + "200": { + "description": "Devices for the job", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InstanceListResponse" + }, + "example": { + "items": [ + { + "id": "65b1c38e-44b9-48e3-9fd3-38ffab1b6da1", + "workflowId": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "jobId": "114ca9f9-88a3-49e1-92f2-757d7fedde98", + "hostname": "bigip-tenant-a-01", + "ip": "10.145.134.204", + "status": "READY", + "managementAddr": "10.145.134.204", + "providerGuestRef": "vm-stub-65b1c38e-44b9-48e3-9fd3-38ffab1b6da1", + "createdAt": "2026-05-18T11:20:00.000Z", + "updatedAt": "2026-05-18T11:20:00.000Z", + "deletedAt": null + } + ], + "totalItems": 1 + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ] + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/events": { + "get": { + "tags": [ + "Observability" + ], + "summary": "List audit events for a job", + "description": "Returns audit/event stream entries related to the Job lifecycle and execution processing.\nEvents are useful for timeline reconstruction and correlation across components.\n", + "operationId": "listEvents", + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/LimitParam" + }, + { + "name": "source", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "eventType", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "correlationId", + "in": "query", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "since", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ], + "responses": { + "200": { + "description": "List of events", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EventListResponse" + }, + "example": { + "items": [ + { + "id": "dfee47f7-5e66-4ff2-91ea-e7f7052d6d76", + "jobId": "220f0b6b-87e7-4e5f-bcc2-9f2d26786ac6", + "source": "autoscale-engine", + "eventType": "SCALE_OUT_TRIGGERED", + "message": "CPU threshold exceeded", + "payload": { + "metricName": "cpu_utilization", + "metricValue": 91 + }, + "eventTime": "2026-05-18T12:19:59.000Z", + "correlationId": "9f7224ff-f108-4284-a80e-5f31135606fe" + } + ], + "total": 1, + "page": 1, + "limit": 50 + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/executions": { + "get": { + "tags": [ + "Observability" + ], + "summary": "List executions for a job", + "description": "Execution cardinality depends on the parent workflow executionMode:\n\n- CONTINUOUS: at most one long-lived execution exists for a job.\n- ON_DEMAND: one execution per trigger (user/schedule/system), returned as history.\nUse filters (`status`, `trigger`, `since`, `until`) for timeline and troubleshooting use-cases.\n", + "operationId": "listExecutions", + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/LimitParam" + }, + { + "name": "status", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED", + "CANCELLED", + "TIMEOUT" + ] + } + }, + { + "name": "trigger", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "USER", + "ALERT", + "SYSTEM", + "SCHEDULE" + ] + } + }, + { + "name": "since", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "until", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ], + "responses": { + "200": { + "description": "List of executions", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecutionListResponse" + }, + "examples": { + "continuousMode": { + "summary": "CONTINUOUS job (single execution)", + "value": { + "items": [ + { + "id": "2f2f8b64-91d2-4d4f-9aa8-03b8a9238ea1", + "jobId": "b4b9a9a0-4ecb-4f9a-b9ab-8a25fdca0db8", + "trigger": "SYSTEM", + "status": "RUNNING", + "reason": "Continuous controller active", + "startedAt": "2026-05-18T08:10:00.000Z", + "activityCount": 37 + } + ], + "total": 1, + "page": 1, + "limit": 50 + } + }, + "onDemandMode": { + "summary": "ON_DEMAND simulation job (multiple runs)", + "value": { + "items": [ + { + "id": "7d8f5576-6414-410f-8f5a-0c34f95df3b0", + "jobId": "b4b9a9a0-4ecb-4f9a-b9ab-8a25fdca0db8", + "trigger": "USER", + "status": "COMPLETED", + "reason": "Manual autoscale simulation run", + "startedAt": "2026-05-18T10:00:00.000Z", + "completedAt": "2026-05-18T10:07:31.000Z", + "activityCount": 1 + }, + { + "id": "0e6ea02f-d03c-4cf4-8434-feb23a9f9eb6", + "jobId": "b4b9a9a0-4ecb-4f9a-b9ab-8a25fdca0db8", + "trigger": "SCHEDULE", + "status": "FAILED", + "reason": "Nightly run", + "startedAt": "2026-05-17T02:00:00.000Z", + "completedAt": "2026-05-17T02:02:10.000Z", + "activityCount": 1 + } + ], + "total": 2, + "page": 1, + "limit": 50 + } + } + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/executions/{executionId}": { + "get": { + "tags": [ + "Observability" + ], + "summary": "Get execution detail including activity summary", + "description": "Returns execution metadata and activity-level summary.\n\n- For CONTINUOUS jobs, this is the single long-lived execution that accumulates many activities.\n- For ON_DEMAND jobs, this is one triggered run.\n\nUse `/executions/{executionId}/activities` to page through activities.\nThis endpoint is summary-focused and avoids returning unbounded activity step payloads.\n", + "operationId": "getExecution", + "responses": { + "200": { + "description": "Execution detail with activity summary", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecutionDetail" + }, + "example": { + "id": "2f2f8b64-91d2-4d4f-9aa8-03b8a9238ea1", + "jobId": "220f0b6b-87e7-4e5f-bcc2-9f2d26786ac6", + "trigger": "SYSTEM", + "status": "RUNNING", + "reason": "Continuous controller active", + "startedAt": "2026-05-18T08:10:00.000Z", + "activityCount": 37, + "activitySummary": { + "total": 37, + "running": 1, + "completed": 35, + "failed": 1 + }, + "latestActivityId": "0c4208f9-f7bf-4891-a2a3-df08eb7720d8", + "latestActivityType": "SCALE_OUT" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + }, + { + "$ref": "#/components/parameters/ExecutionId" + } + ] + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/executions/{executionId}/activities": { + "get": { + "tags": [ + "Observability" + ], + "summary": "List activities for an execution", + "description": "Activities are action units inside an execution.\nExamples: `SCALE_OUT`, `SCALE_IN`, `UPGRADE`, `PRECHECK`, `POSTCHECK`.\n\n- CONTINUOUS: this list grows over the life of the single execution.\n- ON_DEMAND: this list typically contains one or a small fixed set of activities.\nUse this endpoint to inspect action-level outcomes before drilling into step-level detail.\n", + "operationId": "listExecutionActivities", + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/LimitParam" + }, + { + "name": "activityType", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "COMPLETED", + "FAILED", + "SKIPPED", + "CANCELLED" + ] + } + }, + { + "name": "since", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + }, + { + "$ref": "#/components/parameters/ExecutionId" + } + ], + "responses": { + "200": { + "description": "List of activities", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivityListResponse" + }, + "example": { + "items": [ + { + "id": "0c4208f9-f7bf-4891-a2a3-df08eb7720d8", + "executionId": "2f2f8b64-91d2-4d4f-9aa8-03b8a9238ea1", + "activityType": "SCALE_OUT", + "status": "COMPLETED", + "trigger": "ALERT", + "reason": "cpu_utilization > 90", + "startedAt": "2026-05-18T12:20:00.000Z", + "completedAt": "2026-05-18T12:21:15.000Z", + "durationMs": 75000, + "stepCount": 4 + }, + { + "id": "2729938f-ae9c-4d6b-8d93-2852fc7f4c8c", + "executionId": "2f2f8b64-91d2-4d4f-9aa8-03b8a9238ea1", + "activityType": "SCALE_IN", + "status": "RUNNING", + "trigger": "SYSTEM", + "reason": "low utilization evaluation", + "startedAt": "2026-05-18T12:30:00.000Z", + "stepCount": 3 + } + ], + "total": 2, + "page": 1, + "limit": 50 + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/executions/{executionId}/activities/{activityId}": { + "get": { + "tags": [ + "Observability" + ], + "summary": "Get activity detail including steps", + "description": "Returns one activity with full step breakdown, retries, timing, and error details.\nUse this as the primary endpoint for root-cause analysis of a failed activity.\n", + "operationId": "getExecutionActivity", + "responses": { + "200": { + "description": "Activity with steps", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivityDetail" + }, + "example": { + "id": "0c4208f9-f7bf-4891-a2a3-df08eb7720d8", + "executionId": "2f2f8b64-91d2-4d4f-9aa8-03b8a9238ea1", + "activityType": "SCALE_OUT", + "status": "COMPLETED", + "trigger": "ALERT", + "reason": "cpu_utilization > 90", + "startedAt": "2026-05-18T12:20:00.000Z", + "completedAt": "2026-05-18T12:21:15.000Z", + "durationMs": 75000, + "currentStep": "FINISHED", + "stepCount": 4, + "steps": [ + { + "id": "67b5f8ad-a992-46da-af82-38f5d9a0a4ee", + "activityId": "0c4208f9-f7bf-4891-a2a3-df08eb7720d8", + "stepName": "validate-pools", + "sequence": 1, + "status": "COMPLETED", + "startedAt": "2026-05-18T12:20:00.000Z", + "completedAt": "2026-05-18T12:20:10.000Z", + "durationMs": 10000 + }, + { + "id": "94aab872-52a5-4b8a-8a95-ffcb2ac5d41a", + "activityId": "0c4208f9-f7bf-4891-a2a3-df08eb7720d8", + "stepName": "provision-instance", + "sequence": 2, + "status": "COMPLETED", + "startedAt": "2026-05-18T12:20:10.000Z", + "completedAt": "2026-05-18T12:20:55.000Z", + "durationMs": 45000 + }, + { + "id": "20f06e25-48ca-41a9-b6bd-ef517f4ca886", + "activityId": "0c4208f9-f7bf-4891-a2a3-df08eb7720d8", + "stepName": "register-instance", + "sequence": 3, + "status": "COMPLETED", + "startedAt": "2026-05-18T12:20:55.000Z", + "completedAt": "2026-05-18T12:21:05.000Z", + "durationMs": 10000 + }, + { + "id": "2969654c-f790-4a60-8e0f-cfb75a97f6c8", + "activityId": "0c4208f9-f7bf-4891-a2a3-df08eb7720d8", + "stepName": "post-check", + "sequence": 4, + "status": "COMPLETED", + "startedAt": "2026-05-18T12:21:05.000Z", + "completedAt": "2026-05-18T12:21:15.000Z", + "durationMs": 10000 + } + ] + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + }, + { + "$ref": "#/components/parameters/ExecutionId" + }, + { + "$ref": "#/components/parameters/ActivityId" + } + ] + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/pause": { + "post": { + "tags": [ + "Lifecycle - Continuous" + ], + "summary": "Pause a CONTINUOUS job", + "description": "Halts automatic evaluation for CONTINUOUS execution.\nNo new activities are triggered while paused.\nIn-flight activity processing may complete before full pause takes effect.\n", + "operationId": "pauseJob", + "responses": { + "200": { + "description": "Job paused", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + }, + "example": { + "message": "job paused" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "$ref": "#/components/responses/Conflict" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ] + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/resume": { + "post": { + "tags": [ + "Lifecycle - Continuous" + ], + "summary": "Resume a paused CONTINUOUS job", + "description": "Resumes automatic evaluation for a previously paused CONTINUOUS job.\nNew activities can be generated again based on policy/signal conditions.\n", + "operationId": "resumeJob", + "responses": { + "200": { + "description": "Job resumed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + }, + "example": { + "message": "job resumed" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "$ref": "#/components/responses/Conflict" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ] + } + }, + "/api/storage/config": { + "get": { + "tags": [ + "Storage" + ], + "summary": "Get storage allocation configuration", + "description": "Retrieve the current storage allocation configuration including percentages, TTL settings, and cleanup thresholds", + "operationId": "getStorageConfig", + "responses": { + "200": { + "description": "Storage configuration retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageAllocationConfigResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + }, + "parameters": [] + }, + "post": { + "tags": [ + "Storage" + ], + "summary": "Update storage allocation configuration", + "description": "Update storage allocation percentages, TTL settings, and cleanup thresholds", + "operationId": "updateStorageConfig", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageAllocationConfigRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Storage configuration updated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageAllocationConfigResponse" + } + } + } + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/backup-schedules": { + "get": { + "summary": "List backup schedules", + "description": "Returns all configured backup schedules. Multiple schedules are allowed (one per backup type).", + "operationId": "getBackupSchedule", + "tags": [ + "Schedule" + ], + "responses": { + "200": { + "description": "Configured schedules", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleListResponse" + } + } + } + }, + "500": { + "description": "Failed to list backup schedules", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Scheduler is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + }, + "parameters": [] + }, + "post": { + "summary": "Create backup schedule", + "description": "Create a named backup schedule. Multiple schedules allowed. Duplicate names rejected.", + "operationId": "createBackupSchedule", + "tags": [ + "Schedule" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateScheduleRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Schedule created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleResponse" + } + } + } + }, + "400": { + "description": "Invalid request, e.g. a full backup schedule without a remote storage target", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Schedule already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to create the backup schedule", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Scheduler or Vault is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/backup-schedules/{id}": { + "get": { + "summary": "Get backup schedule by ID", + "operationId": "getBackupScheduleById", + "tags": [ + "Schedule" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Schedule details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleResponse" + } + } + } + }, + "404": { + "description": "Schedule not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Scheduler is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + }, + "put": { + "summary": "Update backup schedule", + "operationId": "updateBackupSchedule", + "tags": [ + "Schedule" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Schedule updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleResponse" + } + } + } + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Schedule not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Conflicting schedule for this backup type", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to update the backup schedule", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Scheduler is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + }, + "delete": { + "summary": "Delete backup schedule", + "operationId": "deleteBackupSchedule", + "tags": [ + "Schedule" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Schedule deleted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SuccessResponse" + } + } + } + }, + "404": { + "description": "Schedule not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Scheduler is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/backups": { + "get": { + "summary": "List backups", + "description": "Returns a list of all backup and restore jobs", + "operationId": "listBackups", + "tags": [ + "Backup" + ], + "responses": { + "200": { + "description": "List of jobs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackupListResponse" + } + } + } + }, + "500": { + "description": "Failed to list backups", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + }, + "parameters": [] + }, + "post": { + "summary": "Create a backup", + "description": "Triggers a backup operation. Returns a job ID to track progress.", + "operationId": "createBackup", + "tags": [ + "Backup" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateBackupRequest" + } + } + } + }, + "responses": { + "202": { + "description": "Backup started", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackupJobResponse" + } + } + } + }, + "400": { + "description": "Invalid request. Includes SYSTEM-0003 when a full backup is requested without a remote storage target (full backups are not supported on local storage), an invalid backup name/passphrase, or an unknown storage target.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Another backup/restore is in progress", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to create the backup job", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Platform manager is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/backups/analysis": { + "get": { + "summary": "Backup size anomaly analysis", + "description": "Compares the most recent completed backup size against the rolling\naverage of the previous 3 completed backups. Returns is_anomalous=true\nwhen the latest backup is more than 30% smaller than the rolling average\n(pct_of_avg < 70).\n", + "operationId": "getBackupsAnalysis", + "tags": [ + "Backup" + ], + "responses": { + "200": { + "description": "Analysis result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackupSizeAnalysisResponse" + } + } + } + }, + "500": { + "description": "Failed to calculate backup analysis", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/backups/import": { + "post": { + "summary": "Import backup from path", + "description": "Import a backup file from a local path or remote storage target.\nReads the manifest via platform-manager to validate and extract metadata.\nCreates a DB record referencing the file location without copying.\n", + "operationId": "importBackup", + "tags": [ + "Backup" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImportBackupRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Backup imported", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackupJobResponse" + } + } + } + }, + "400": { + "description": "Invalid request or file not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Backup already imported", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to import the backup", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Storage target or platform manager unreachable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/backups/{id}": { + "get": { + "summary": "Get backup details", + "description": "Returns details of a specific backup job including live progress", + "operationId": "getBackup", + "tags": [ + "Backup" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Backup details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackupJobResponse" + } + } + } + }, + "404": { + "description": "Backup not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + }, + "delete": { + "summary": "Delete a backup", + "description": "Deletes a backup file and its job record", + "operationId": "deleteBackup", + "tags": [ + "Backup" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Backup deleted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SuccessResponse" + } + } + } + }, + "404": { + "description": "Backup not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to delete the backup", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/backups/{id}/download": { + "get": { + "summary": "Download backup file", + "description": "Downloads the backup archive file", + "operationId": "downloadBackup", + "tags": [ + "Backup" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Backup file stream", + "content": { + "application/octet-stream": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "404": { + "description": "Backup not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/backups/{id}/restore": { + "post": { + "summary": "Restore from backup", + "description": "Triggers a restore from the specified backup", + "operationId": "createRestore", + "tags": [ + "Backup" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "passphrase" + ], + "properties": { + "passphrase": { + "type": "string", + "description": "Encryption passphrase used when backup was created" + }, + "components": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "data", + "config", + "network", + "dns", + "hostname", + "ntp", + "proxy", + "ssh" + ] + }, + "description": "Components to restore. Valid values data, config, network, dns, hostname, ntp, proxy, ssh. 'data' covers databases, 'config' covers configuration; system settings (dns, ntp, proxy, ssh, network, hostname) must be selected individually." + }, + "force": { + "type": "boolean", + "description": "Skip pre-restore state preservation (no rollback possible)" + } + } + } + } + } + }, + "responses": { + "202": { + "description": "Restore started", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackupJobResponse" + } + } + } + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Backup, backup file, or referenced storage target not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Another operation is in progress", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to start the restore job", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Platform manager is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/fqdn": { + "post": { + "summary": "Configure external FQDN", + "description": "Configure the canonical external FQDN used by F5 Insight and Zitadel.\nThe operation runs asynchronously because it performs a Helm upgrade and\nreruns Zitadel bootstrap to refresh the registered OIDC callback URL.\n", + "operationId": "configureFqdn", + "tags": [ + "FQDN Configuration" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FqdnConfigRequest" + } + } + } + }, + "responses": { + "202": { + "description": "FQDN configuration task submitted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FqdnConfigResponse" + } + } + } + }, + "400": { + "description": "Invalid FQDN target", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Another FQDN configuration task is already running", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/fqdn/status/{task_id}": { + "get": { + "summary": "Get FQDN configuration status", + "description": "Query the progress of an FQDN configuration task by task_id.", + "operationId": "getFqdnStatus", + "tags": [ + "FQDN Configuration" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "UUID of the FQDN configuration task", + "schema": { + "type": "string", + "format": "uuid", + "example": "123e4567-e89b-12d3-a456-426614174000" + } + } + ], + "responses": { + "200": { + "description": "FQDN configuration status retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FqdnStatusResponse" + } + } + } + }, + "400": { + "description": "Invalid task_id format", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/health": { + "get": { + "summary": "Health check endpoint", + "description": "Returns the health status of the system manager service", + "operationId": "getHealth", + "tags": [ + "Health" + ], + "responses": { + "200": { + "description": "Service is healthy", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HealthResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/storage-targets": { + "get": { + "summary": "List storage targets", + "description": "Returns all configured storage targets", + "operationId": "listStorageTargets", + "tags": [ + "Storage" + ], + "responses": { + "200": { + "description": "List of storage targets", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageTargetListResponse" + } + } + } + }, + "500": { + "description": "Failed to list storage targets", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + }, + "parameters": [] + }, + "post": { + "summary": "Create storage target", + "description": "Create a new NFS or SMB storage target", + "operationId": "createStorageTarget", + "tags": [ + "Storage" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStorageTargetRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Storage target created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageTargetResponse" + } + } + } + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to create the storage target", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Vault is unavailable and the credential could not be stored", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/storage-targets/test": { + "post": { + "summary": "Test storage connectivity without creating", + "description": "Tests connectivity to a storage target using the provided config. Does not save anything.", + "operationId": "testStorageConnectivity", + "tags": [ + "Storage" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestStorageTargetRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Test result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageTestResponse" + } + } + } + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Platform manager is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/storage-targets/{id}": { + "get": { + "summary": "Get storage target", + "operationId": "getStorageTarget", + "tags": [ + "Storage" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Storage target details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageTargetResponse" + } + } + } + }, + "404": { + "description": "Not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + }, + "put": { + "summary": "Update storage target", + "operationId": "updateStorageTarget", + "tags": [ + "Storage" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStorageTargetRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Storage target updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageTargetResponse" + } + } + } + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Storage target not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to update the storage target", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Vault is unavailable and the credential could not be updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + }, + "delete": { + "summary": "Delete storage target", + "operationId": "deleteStorageTarget", + "tags": [ + "Storage" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Storage target deleted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SuccessResponse" + } + } + } + }, + "400": { + "description": "Cannot delete default local target", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Storage target not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to delete the storage target", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/storage-targets/{id}/test": { + "post": { + "summary": "Test storage connectivity", + "description": "Mount, write test file, unmount. Returns success with latency.", + "operationId": "testStorageTarget", + "tags": [ + "Storage" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Test result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageTestResponse" + } + } + } + }, + "404": { + "description": "Storage target not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Platform manager is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/active-job": { + "get": { + "summary": "Get active upgrade job", + "description": "Returns the single pending/running job. When no active job exists, returns 200 with data set to null. Failed dirty-state jobs are available through history; patch deployment failures trigger automatic rollback.", + "operationId": "getUpgradeActiveJob", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Active job result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActiveJobResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/upgrade/apply": { + "post": { + "summary": "Apply upgrade", + "description": "Starts an upgrade job for an uploaded/local bundle or an online F5\nDownloads catalog entry.\nRuns backend preflight validation before creating the upgrade job so\ndirect API callers cannot bypass failed checks.\nThe request is persisted in upgrade_history and handed to\nplatform-manager over the Unix domain socket. For online entries,\nsystem-manager downloads the selected bundle to disk, verifies SHA256\nand any provided signature, then applies the same local bundle path.\n", + "operationId": "postUpgradeApply", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApplyUpgradeRequest" + } + } + } + }, + "responses": { + "202": { + "description": "Upgrade initiated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApplyAcceptedResponse" + } + } + } + }, + "400": { + "description": "Invalid request or validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Upgrade already in progress or preflight checks failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Platform manager unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/upgrade/catalog": { + "get": { + "summary": "Get upgrade catalog", + "description": "Returns only the latest available patch and latest available full\nupgrade for the selected source. Use mode=online to return only F5\nDownloads entries, or mode=offline to return only offline local/uploaded\nbundle entries. The mode query parameter is required.\n", + "operationId": "getUpgradeCatalog", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "mode", + "in": "query", + "required": true, + "description": "Catalog source filter.", + "schema": { + "type": "string", + "enum": [ + "online", + "offline" + ] + } + } + ], + "responses": { + "200": { + "description": "Catalog retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeCatalogResponse" + } + } + } + }, + "400": { + "description": "Missing or invalid mode query parameter", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/current": { + "get": { + "summary": "Get current running version", + "description": "Returns the APP_VERSION environment variable from the running system-manager pod.", + "operationId": "getUpgradeCurrent", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Current version returned", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CurrentVersionResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/upgrade/history": { + "get": { + "summary": "Get upgrade history", + "description": "Returns the last 50 upgrade jobs, newest first, with top-level dirty_state.", + "operationId": "getUpgradeHistory", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Patch history", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeHistoryResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/upgrade/history/stats": { + "get": { + "summary": "Get all-time upgrade stats", + "description": "Returns aggregate statistics across all historical upgrade jobs.", + "operationId": "getUpgradeHistoryStats", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Aggregate stats", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeHistoryStatsResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/upgrade/jobs/{job_id}": { + "get": { + "summary": "Get upgrade job status", + "description": "Unified polling endpoint for upgrade status, rollback state, rollback\njob status, and postflight checks.\n", + "operationId": "getUpgradeJob", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "description": "Upgrade history record ID", + "schema": { + "type": "string", + "format": "uuid", + "example": "550e8400-e29b-41d4-a716-446655440000" + } + } + ], + "responses": { + "200": { + "description": "Job status retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobStatusResponse" + } + } + } + }, + "404": { + "description": "Job not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/jobs/{job_id}/cancel": { + "post": { + "summary": "Cancel patch upgrade job", + "description": "Cancels a pending/running patch job. Full upgrade jobs cannot be cancelled. If patch deployment has already started, automatic rollback is triggered; jobs cancelled before deployment are marked clean.", + "operationId": "postUpgradeJobCancel", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "description": "Upgrade history record ID", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "202": { + "description": "Cancel accepted" + }, + "400": { + "description": "Cancel is only supported for patch upgrade jobs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Job not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "No active job to cancel", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/jobs/{job_id}/confirm-clean": { + "post": { + "summary": "Confirm upgrade state is clean", + "description": "Admin-only override that clears unresolved dirty-state for a failed upgrade after admin review and records rollback_history status admin_confirmed. Only available when the job is failed and dirty_state is true.", + "operationId": "postUpgradeJobConfirmClean", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "description": "Upgrade history record ID", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Dirty state cleared" + }, + "403": { + "description": "Admin role required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Job not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Job is already clean or is not an unresolved failed upgrade", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/jobs/{job_id}/postflight": { + "get": { + "summary": "Run post-flight health checks", + "description": "Runs post-deployment health checks for a completed upgrade job.", + "operationId": "getUpgradeJobPostflight", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "description": "Upgrade history record ID", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Post-flight results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PostflightResponse" + } + } + } + }, + "404": { + "description": "Job not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/jobs/{job_id}/rollback": { + "post": { + "summary": "Roll back upgrade job", + "description": "Manually starts rollback for the latest successful patch job within 72 hours of completion. Failed patch jobs trigger automatic rollback when deployment has started.", + "operationId": "postUpgradeJobRollback", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "description": "Upgrade history record ID", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "202": { + "description": "Rollback started", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RollbackAcceptedResponse" + } + } + } + }, + "400": { + "description": "Rollback is not available for this job", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Job not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Another operation is already in progress", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/jobs/{job_id}/rollback-state": { + "get": { + "summary": "Check rollback state availability", + "description": "Returns whether manual rollback is currently available for this job. Manual rollback is available for the latest successful patch job within 72 hours of completion; failed patch jobs use automatic rollback.", + "operationId": "getUpgradeJobRollbackState", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "description": "Upgrade history record ID", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Rollback state checked", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RollbackStateResponse" + } + } + } + }, + "404": { + "description": "Job not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/preflight": { + "get": { + "summary": "Run preflight checks for upgrade", + "description": "Runs preflight checks before a patch or full_upgrade can be applied.\nChecks include no_active_job, disk_space, pod_health, dr_pair,\nversion_compatibility, and bundle_signature for online upgrades.\n", + "operationId": "getUpgradePreflight", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "kind", + "in": "query", + "required": true, + "description": "Upgrade kind to validate preflight for", + "schema": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "example": "patch" + } + }, + { + "name": "version", + "in": "query", + "required": true, + "description": "Target version to validate (e.g., f5-insight-patch-1.2.3)", + "schema": { + "type": "string", + "example": "f5-insight-patch-1.2.3" + } + } + ], + "responses": { + "200": { + "description": "Preflight checks completed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PreflightResponse" + } + } + } + }, + "400": { + "description": "Invalid version parameter", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Version not found in catalog", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/rollback/{rollback_id}": { + "get": { + "summary": "Poll rollback job status", + "description": "Returns rollback status, progress, and structured log lines.", + "operationId": "getUpgradeRollback", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "rollback_id", + "in": "path", + "required": true, + "description": "Rollback history record ID", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Rollback status", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RollbackStatusResponse" + } + } + } + }, + "404": { + "description": "Rollback job not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/schedule": { + "post": { + "summary": "Schedule an upgrade", + "description": "Schedules a patch or full_upgrade to run at a future UTC timestamp.", + "operationId": "postUpgradeSchedule", + "tags": [ + "Upgrade" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleUpgradeRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Schedule created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduledUpgradeCreatedResponse" + } + } + } + }, + "400": { + "description": "scheduled_at must be a future timestamp", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/upgrade/schedule/recommendation": { + "get": { + "summary": "Get recommended scheduling window", + "description": "Analyses upgrade history to find the best 2-hour UTC scheduling window.", + "operationId": "getUpgradeScheduleRecommendation", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Recommendation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleRecommendationResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/upgrade/scheduled": { + "get": { + "summary": "List pending scheduled upgrade jobs", + "description": "Returns all scheduled upgrade jobs with status pending.", + "operationId": "getUpgradeScheduled", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Scheduled jobs list", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduledUpgradeListResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/upgrade/scheduled/history": { + "get": { + "summary": "List completed scheduled upgrade jobs", + "description": "Returns scheduled jobs in terminal states done, failed, and cancelled. Pending jobs are excluded.", + "operationId": "getUpgradeScheduledHistory", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Scheduled job history", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduledUpgradeListResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/upgrade/scheduled/{sched_id}": { + "delete": { + "summary": "Cancel a pending scheduled upgrade job", + "description": "Cancels a pending scheduled job. Has no effect on jobs already triggered.", + "operationId": "deleteUpgradeScheduled", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "sched_id", + "in": "path", + "required": true, + "description": "Scheduled upgrade job ID", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Scheduled job cancelled" + }, + "404": { + "description": "Scheduled job not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/start": { + "post": { + "summary": "Start upgrade", + "description": "Not supported since F5 Insight 1.2.0.\nUse POST /api/system/upgrade/apply instead.\n", + "operationId": "startUpgrade", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "responses": { + "410": { + "description": "Endpoint is not supported", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/upgrade/status": { + "get": { + "summary": "Get upgrade status", + "description": "Returns the current status of the upgrade operation", + "operationId": "getUpgradeStatus", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Status retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeStatusResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/system/upgrade/upload": { + "get": { + "summary": "Get uploaded bundle info", + "description": "Returns information about the currently uploaded bundle, if any", + "operationId": "getUploadedBundle", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Bundle info retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadInfoResponse" + } + } + } + } + }, + "parameters": [] + }, + "delete": { + "summary": "Delete uploaded upgrade bundle", + "description": "Deletes uploaded offline upgrade bundles from local bundle storage.\nWhen version and/or kind are provided, only matching bundles are removed.\nWhen no filters are provided, all uploaded offline bundles are removed.\n", + "operationId": "deleteUploadedBundle", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "version", + "in": "query", + "required": false, + "description": "Uploaded bundle version to delete", + "schema": { + "type": "string", + "example": "1.2.1-3" + } + }, + { + "name": "kind", + "in": "query", + "required": false, + "description": "Uploaded bundle kind to delete", + "schema": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "example": "patch" + } + } + ], + "responses": { + "200": { + "description": "Uploaded bundle deleted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SuccessResponse" + } + } + } + }, + "400": { + "description": "No matching uploaded bundle found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Upgrade operation already in progress", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to delete uploaded bundle", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/version": { + "get": { + "summary": "Get system version", + "description": "Returns the current F5 Insight version information", + "operationId": "getVersion", + "tags": [ + "Health" + ], + "responses": { + "200": { + "description": "Version information retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VersionResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/telemetry/types": { + "get": { + "x-mode": "lite", + "tags": [ + "Telemetry Configuration" + ], + "summary": "List all telemetry types", + "description": "Get all available telemetry types and their enabled status for AIDF forwarding", + "operationId": "getTelemetryTypes", + "responses": { + "200": { + "description": "List of all telemetry types with their configuration", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TelemetryTypesResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + }, + "parameters": [] + }, + "put": { + "x-mode": "lite", + "tags": [ + "Telemetry Configuration" + ], + "summary": "Update enabled telemetry types", + "description": "Bulk update which telemetry types are enabled for AIDF forwarding. Triggers OTEL configuration reload.", + "operationId": "updateTelemetryTypes", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateTelemetryTypesRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Telemetry types updated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StatusResponse" + } + } + } + }, + "400": { + "description": "Validation error - invalid telemetry type names", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/telemetry/types/{type}": { + "get": { + "x-mode": "lite", + "tags": [ + "Telemetry Configuration" + ], + "summary": "Get specific telemetry type configuration", + "description": "Get the configuration for a specific telemetry type", + "operationId": "getTelemetryType", + "parameters": [ + { + "name": "type", + "in": "path", + "required": true, + "description": "Telemetry type name (API_Discovery or Application_Telemetry)", + "schema": { + "type": "string", + "enum": [ + "API_Discovery", + "Application_Telemetry" + ] + } + } + ], + "responses": { + "200": { + "description": "Telemetry type configuration", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TelemetryTypeConfig" + } + } + } + }, + "400": { + "description": "Invalid telemetry type name", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Telemetry type not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/compat/upgrade-paths": { + "get": { + "operationId": "listCompatUpgradePaths", + "summary": "List BIG-IP upgrade path rules (K13845)", + "description": "Returns all rows in upgrade.bigip_upgrade_paths.\nIncludes both YAML-seeded rows (is_operator_override=false) and\noperator-managed rows (is_operator_override=true).\n", + "tags": [ + "CompatMatrix" + ], + "responses": { + "200": { + "description": "List of upgrade path rules", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CompatUpgradePathListResponse" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + }, + "parameters": [] + }, + "post": { + "operationId": "upsertCompatUpgradePath", + "summary": "Add or update a BIG-IP upgrade path rule (K13845 operator override)", + "description": "Inserts or updates a row in upgrade.bigip_upgrade_paths using the\nnatural key `(target_major_version, min_source_version)`.\nThe row is always marked `is_operator_override=true` \u2014 the CompatSeeder\nwill never overwrite it on service restart.\n\n**Why upsert (not separate POST/PATCH)?**\nThe natural business key is `(target_major_version, min_source_version)`,\nnot the UUID. Operators think in terms of rules, not opaque IDs. The\nupsert pattern lets operators:\n- Add a new rule without checking whether it already exists\n- Update an existing rule (including YAML-seeded rows) without needing to look up its UUID first\n- Use the same idempotent script to enforce desired state across environments\n\n**Response codes:**\n- `201 Created` \u2014 a new row was inserted (the natural key did not previously exist)\n- `200 OK` \u2014 an existing row was updated (the natural key already existed)\n", + "tags": [ + "CompatMatrix" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpsertCompatUpgradePathRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Existing row updated (natural key already existed)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CompatUpgradePath" + } + } + } + }, + "201": { + "description": "New row created (natural key did not previously exist)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CompatUpgradePath" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + }, + "parameters": [] + } + }, + "/api/v1/fleet/upgrade/compat/upgrade-paths/{compatId}": { + "get": { + "operationId": "getCompatUpgradePath", + "summary": "Get a BIG-IP upgrade path rule by ID", + "description": "Returns a single row from upgrade.bigip_upgrade_paths addressed by its UUID.\nIncludes both YAML-seeded rows (is_operator_override=false) and\noperator-managed rows (is_operator_override=true).\n", + "tags": [ + "CompatMatrix" + ], + "responses": { + "200": { + "description": "Upgrade path rule", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CompatUpgradePath" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/CompatIdParam" + } + ] + }, + "delete": { + "operationId": "deleteCompatUpgradePath", + "summary": "Delete a BIG-IP upgrade path rule by ID", + "tags": [ + "CompatMatrix" + ], + "responses": { + "204": { + "description": "Row deleted" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/CompatIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/devices": { + "get": { + "operationId": "listFleetDevices", + "summary": "List all fleet devices (BIG-IP + F5OS)", + "tags": [ + "Inventory" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/PageSizeParam" + }, + { + "name": "type", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "BIGIP", + "RSERIES", + "VELOS" + ] + } + }, + { + "name": "search", + "in": "query", + "schema": { + "type": "string" + }, + "description": "Search by hostname, IP, version" + }, + { + "name": "$filter", + "in": "query", + "schema": { + "type": "string" + }, + "description": "OData-style filter expression. Supported fields and operators:\n endpoint eq 'https://10.145.135.45'\n hostname eq 'rseries-lab-01'\n device_type eq 'BIGIP'\nCombine with 'and': endpoint eq '...' and device_type eq 'BIGIP'\n" + }, + { + "name": "$orderby", + "in": "query", + "schema": { + "type": "string" + }, + "description": "OData-style ordering expression.\nSupported fields: hostname, endpoint, current_version, last_refresh_at, device_type\nFormat: ' asc' or ' desc' (default: hostname asc)\n" + } + ], + "responses": { + "200": { + "description": "Paginated fleet device list", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FleetDeviceListResponse" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/devices/disk-analysis": { + "post": { + "operationId": "createDevicesDiskAnalysisTask", + "summary": "Create asynchronous disk space analysis task for multiple devices", + "description": "Starts a background task that checks available disk space on each device\nand compares it against the requested `required_size_bytes` threshold.\n\n**BIG-IP devices** \u2014 calls the iControl REST bash endpoint\n(`POST /mgmt/tm/util/bash`) to run `df -k /shared/images` directly on\nthe device. The reported `available_disk_bytes` reflects free space on\nthe `/shared/images` filesystem, which is where software images are\nstaged before installation.\n\n**F5OS devices (RSERIES / VELOS)** \u2014 queries the F5OS platform REST API\nfor storage metrics.\n\nResults are returned via `GET /devices/disk-analysis/{taskId}`.\n", + "tags": [ + "Inventory" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DiskAnalysisBatchRequest" + } + } + } + }, + "responses": { + "202": { + "description": "Disk space analysis task accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DiskAnalysisTaskAcceptedResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + } + }, + "parameters": [] + } + }, + "/api/v1/fleet/upgrade/devices/disk-analysis/{taskId}": { + "get": { + "operationId": "getDevicesDiskAnalysisTask", + "summary": "Get asynchronous disk space analysis task status and results", + "tags": [ + "Inventory" + ], + "responses": { + "200": { + "description": "Disk analysis task details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DiskAnalysisTaskStatusResponse" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "name": "taskId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ] + } + }, + "/api/v1/fleet/upgrade/devices/{deviceId}": { + "get": { + "operationId": "getFleetDevice", + "summary": "Get fleet device details", + "tags": [ + "Inventory" + ], + "responses": { + "200": { + "description": "Fleet device details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FleetDevice" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/DeviceIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/devices/{deviceId}/refresh": { + "post": { + "operationId": "refreshFleetDevice", + "summary": "Trigger on-demand metadata refresh for a device", + "tags": [ + "Inventory" + ], + "responses": { + "200": { + "description": "Device metadata refreshed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FleetDevice" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/DeviceIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/flight-checks/diffs": { + "get": { + "operationId": "listFlightDiffs", + "summary": "List PRE-vs-POST flight-check diffs", + "description": "Returns a paginated list of PRE-vs-POST flight-check diffs. Because a fleet\naccumulates many diffs over time, callers should scope the query with the\n`jobId` and/or `deviceId` filters (e.g. all diffs for a given installation\njob, or the diff history for one device).\n", + "tags": [ + "FlightChecks" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/PageSizeParam" + }, + { + "name": "jobId", + "in": "query", + "description": "Filter to diffs computed under this installation job.", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "deviceId", + "in": "query", + "description": "Filter to diffs computed for this device.", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Paginated list of flight-check diffs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FlightCheckDiffListResponse" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + } + }, + "/api/v1/fleet/upgrade/flight-checks/diffs/{diffId}": { + "get": { + "operationId": "getFlightDiff", + "summary": "Get a single PRE-vs-POST flight-check diff by ID", + "description": "Returns one PRE-vs-POST flight-check diff, addressed by its own ID. The\nresponse includes the per-check diff entries plus the diff's deviceId,\njobId, computedAt timestamp, and back-links to the PRE and POST snapshots\nit was computed from (preSnapshotUrl / postSnapshotUrl \u2014 each resolvable via\nGET /api/v1/fleet/upgrade/flight-checks/snapshots/{snapshotId}).\n", + "tags": [ + "FlightChecks" + ], + "responses": { + "200": { + "description": "Flight-check diff", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FlightCheckDiff" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/DiffIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/flight-checks/snapshots": { + "get": { + "operationId": "listFlightSnapshots", + "summary": "List flight-check snapshots", + "description": "Returns a paginated list of flight-check snapshots. Because a fleet\naccumulates many snapshots over time, callers should scope the query with\nthe `jobId`, `deviceId` and/or `phase` filters (e.g. all snapshots for a\ngiven installation job, or both phases for one device in one job).\n", + "tags": [ + "FlightChecks" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/PageSizeParam" + }, + { + "name": "jobId", + "in": "query", + "description": "Filter to snapshots captured under this installation job.", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "deviceId", + "in": "query", + "description": "Filter to snapshots captured from this device.", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "phase", + "in": "query", + "description": "Filter to a single phase (PRE or POST).", + "schema": { + "type": "string", + "enum": [ + "PRE", + "POST" + ] + } + } + ], + "responses": { + "200": { + "description": "Paginated list of flight-check snapshots", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FlightSnapshotListResponse" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + } + }, + "/api/v1/fleet/upgrade/flight-checks/snapshots/{snapshotId}": { + "get": { + "operationId": "getFlightSnapshot", + "summary": "Get a single flight-check snapshot by ID", + "description": "Returns one PRE or POST flight-check snapshot, addressed by its own ID.\nThe response includes the captured core-check results plus the snapshot's\ndeviceId, jobId, phase (PRE/POST) and capturedAt timestamp.\n", + "tags": [ + "FlightChecks" + ], + "responses": { + "200": { + "description": "Flight-check snapshot", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FlightSnapshot" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/SnapshotIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/images": { + "get": { + "operationId": "listImages", + "summary": "List software images", + "tags": [ + "Images" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/PageSizeParam" + }, + { + "name": "product_family", + "in": "query", + "schema": { + "$ref": "#/components/schemas/ProductFamily" + } + }, + { + "name": "sort_by", + "in": "query", + "schema": { + "$ref": "#/components/schemas/SortByImages" + } + }, + { + "name": "sort_order", + "in": "query", + "description": "Sort direction; only applied when sort_by is also provided.", + "schema": { + "$ref": "#/components/schemas/SortOrder" + } + } + ], + "responses": { + "200": { + "description": "List of software images", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImageListResponse" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + } + }, + "/api/v1/fleet/upgrade/images/bulk-delete": { + "post": { + "operationId": "bulkDeleteImages", + "summary": "Delete multiple software images in a single request", + "tags": [ + "Images" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkDeleteImagesRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Per-image deletion results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkDeleteImagesResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + }, + "parameters": [] + } + }, + "/api/v1/fleet/upgrade/images/{imageId}": { + "get": { + "operationId": "getImage", + "summary": "Get a software image by ID", + "tags": [ + "Images" + ], + "responses": { + "200": { + "description": "Software image details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareImage" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/ImageIdParam" + } + ] + }, + "delete": { + "operationId": "deleteImage", + "summary": "Delete a software image", + "tags": [ + "Images" + ], + "responses": { + "204": { + "description": "Image deleted" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Image is associated with one or more upgrade jobs and cannot be\ndeleted. The error message lists the offending job types and names.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/ImageIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution": { + "get": { + "operationId": "listSoftwareDistributionJobs", + "summary": "List software distribution jobs", + "tags": [ + "SoftwareDistribution" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/PageSizeParam" + }, + { + "name": "status", + "in": "query", + "description": "Filter by job lifecycle status", + "schema": { + "$ref": "#/components/schemas/UpgradeJobStatus" + } + } + ], + "responses": { + "200": { + "description": "Paginated list of software distribution jobs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareDistributionJobListResponse" + }, + "example": { + "data": [ + { + "id": "a1b2c3d4-0000-0000-0000-000000000001", + "workflowId": "wf-0000-0000-0000-000000000001", + "name": "distribute-bigip-17.1.2-to-prod", + "status": "COMPLETED", + "deviceCount": 3, + "createdAt": "2026-05-29T09:00:00Z", + "updatedAt": "2026-05-29T09:30:00Z" + } + ], + "pagination": { + "page": 1, + "page_size": 20, + "total": 1, + "total_pages": 1 + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + }, + "post": { + "operationId": "createSoftwareDistributionJob", + "summary": "Create a software distribution job", + "description": "Creates a new software distribution job. The job starts in DRAFT state and\ncan be edited before activation.\n\nCopies a software image to one or more target devices in parallel batches.\nConfig requires: `imageId`, `deviceTargets`\nConfig optional: `batchSize` (default 10)\n\nOnce created, activate the job with `POST /jobs/{jobId}/activate`.\n", + "tags": [ + "SoftwareDistribution" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSoftwareDistributionJobRequest" + }, + "example": { + "name": "distribute-bigip-17.1.2-to-prod", + "description": "Push BIGIP-17.1.2-0.0.13.iso to 3 production devices before install", + "config": { + "images": [ + { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso" + } + ], + "batchSize": 10, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + }, + { + "deviceId": "cccccccc-cccc-cccc-cccc-cccccccccccc" + } + ] + } + } + } + } + }, + "responses": { + "201": { + "description": "Software distribution job created (in DRAFT state)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareDistributionJob" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "409": { + "description": "Job name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}": { + "get": { + "operationId": "getSoftwareDistributionJob", + "summary": "Get software distribution job details", + "description": "Returns full job details including configuration, current lifecycle status,\nand execution state.\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "200": { + "description": "Software distribution job details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareDistributionJob" + }, + "example": { + "id": "a1b2c3d4-0000-0000-0000-000000000001", + "workflowId": "wf-0000-0000-0000-000000000001", + "name": "distribute-bigip-17.1.2-to-prod", + "description": "Push image to prod devices", + "status": "COMPLETED", + "config": { + "images": [ + { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso" + } + ], + "batchSize": 10, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + }, + { + "deviceId": "cccccccc-cccc-cccc-cccc-cccccccccccc" + } + ] + }, + "execution": { + "executionId": "exec-0000-0000-0000-000000000001", + "status": "COMPLETED", + "startedAt": "2026-05-29T09:00:00Z", + "endedAt": "2026-05-29T09:28:00Z", + "currentBatch": 1, + "totalBatches": 1, + "batches": [ + { + "batchNumber": 1, + "status": "COMPLETED", + "currentStep": "COMPLETE", + "deviceIds": [ + "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", + "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", + "cccccccc-cccc-cccc-cccc-cccccccccccc" + ] + } + ] + }, + "createdAt": "2026-05-29T08:55:00Z", + "updatedAt": "2026-05-29T09:28:00Z" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + }, + "patch": { + "operationId": "updateSoftwareDistributionJob", + "summary": "Update software distribution job configuration", + "description": "Replaces the job configuration.\nOnly allowed when the job is in DRAFT or READY state.\n", + "tags": [ + "SoftwareDistribution" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSoftwareDistributionJobRequest" + }, + "example": { + "name": "distribute-bigip-17.1.2-to-prod-v2", + "description": "Updated device list", + "config": { + "images": [ + { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso" + } + ], + "batchSize": 5, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + } + ] + } + } + } + } + }, + "responses": { + "200": { + "description": "Job updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareDistributionJob" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job cannot be updated in its current state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + }, + "delete": { + "operationId": "deleteSoftwareDistributionJob", + "summary": "Delete a software distribution job", + "description": "Permanently deletes a software distribution job.\nOnly allowed when the job is not in RUNNING state.\nTerminates any in-progress execution before deletion.\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "204": { + "description": "Job deleted" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job cannot be deleted in its current state (e.g. RUNNING)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}/activate": { + "post": { + "operationId": "activateSoftwareDistributionJob", + "summary": "Start a software distribution job", + "description": "Transitions a software distribution job from DRAFT/READY \u2192 RUNNING and begins\ndistributing the image to target devices in batches.\n\n**Pre-execution checks:**\n- Image must exist and be accessible in the image registry\n- All target devices must be reachable\n", + "tags": [ + "SoftwareDistribution" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivateDistributionJobRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Job activated and distribution started", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeJob" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job cannot be activated (wrong state or image not accessible)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}/cancel": { + "post": { + "operationId": "cancelSoftwareDistributionJob", + "summary": "Cancel a running or paused software distribution job", + "description": "Durably signals job cancellation by transitioning to CANCELLING.\n- The claim gate immediately stops the worker pool from picking\n new devices.\n- In-flight workers run to completion of their current device\n (no mid-stream kill \u2014 chunked uploads can't be safely\n interrupted).\n- When the pool drains, remaining non-terminal per-device rows\n are marked CANCELLED and the job returns to READY (re-activatable);\n the CANCELLED outcome is recorded on the EXECUTION row, not\n the job, because the job is a long-lived re-activatable\n definition.\n- Safe across pods and pod restarts: CANCELLING is durable in\n the DB so a different pod / a restarted pod converges to\n READY at the job level without operator intervention.\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "202": { + "description": "Cancel accepted \u2014 job is CANCELLING; converges to READY at the job level (CANCELLED on the execution row)" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job is not in a cancellable state (e.g. already COMPLETED or in a non-cancellable lifecycle state)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}/executions": { + "get": { + "operationId": "listSoftwareDistributionJobExecutions", + "summary": "List executions of a software distribution job", + "description": "Returns all executions of a job ordered by `startedAt` descending\n(newest first). Same item shape as the generic workflow executions\nlist (`GET /workflows/{wfId}/jobs/{jobId}/executions`) so the\ncross-feature UI can render distribution + autoscale + installation\nexecution lists with the same component.\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "200": { + "description": "List of executions", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "items" + ], + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SoftwareDistributionExecution" + } + }, + "totalItems": { + "type": "integer" + } + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}/executions/{executionId}": { + "get": { + "operationId": "getSoftwareDistributionJobExecution", + "summary": "Get a single execution of a software distribution job", + "description": "Returns the execution record in the same shape as the generic\nworkflows API (`GET /workflows/{wfId}/jobs/{jobId}/executions/{execId}`)\nso the cross-feature UI can render distribution executions with the\nsame panel it uses for autoscale / installation. Per-device runtime\nprogress is embedded inline via the `instanceProgress` field \u2014 only\non this single-execution GET, not on the executions LIST.\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "200": { + "description": "Execution detail", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareDistributionExecution" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + }, + { + "name": "executionId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ] + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}/pause": { + "post": { + "operationId": "pauseSoftwareDistributionJob", + "summary": "Pause a running software distribution job", + "description": "Pauses the distribution job at the queue level. The worker pool\nstops claiming new PENDING devices; devices already TRANSFERRING\nor VERIFYING run to completion (chunked uploads cannot be safely\ninterrupted mid-stream). Job transitions to PAUSING immediately;\nonce all in-flight devices finish, the service flips to PAUSED.\nOperator then calls /resume or /cancel.\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "202": { + "description": "Pause accepted \u2014 job is PAUSING (draining in-flight)" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job is not in a pausable state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}/resume": { + "post": { + "operationId": "resumeSoftwareDistributionJob", + "summary": "Resume a paused software distribution job", + "description": "Resumes a PAUSED distribution job. Job transitions back to\nRUNNING; a fresh worker pool is spawned to pick up the PENDING\ndevices that were held back during the pause. Devices already\nCOMPLETED stay COMPLETED \u2014 no rework. Returns 409 if the job\nis still PAUSING (drain in progress); wait for PAUSED first.\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "202": { + "description": "Resume accepted \u2014 job is back to RUNNING" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job is not in a resumable state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}/status": { + "get": { + "operationId": "getSoftwareDistributionJobStatus", + "summary": "Get per-device runtime status for a software distribution job", + "description": "Returns the per-device runtime status of a software distribution job\nplus a rolled-up summary (counts per status + overall transfer percent).\nDistinct from `GET /jobs/software-distribution/{jobId}`, which returns\nthe saved job record only.\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "200": { + "description": "Per-device + roll-up status", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DistributionJobAggregate" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}/targets/{deviceId}": { + "delete": { + "operationId": "cancelSoftwareDistributionTarget", + "summary": "Cancel distribution for one device in a running job", + "description": "Cancels in-flight distribution for a single device within a running job.\nOrthogonal to the job-level cancel \u2014 the rest of the job continues.\n\n- Device's distribution_state row transitions to CANCELLED\n- The device lock for this job is released\n- If the device is currently TRANSFERRING, the next chunk boundary\n observes the cancel and the goroutine returns\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "202": { + "description": "Per-target cancel accepted" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Device is already in a terminal state for this job (COMPLETED / FAILED / CANCELLED / SKIPPED)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + }, + { + "$ref": "#/components/parameters/DeviceIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/jobs/software-installation": { + "get": { + "operationId": "listSoftwareInstallationJobs", + "summary": "List software installation jobs", + "tags": [ + "SoftwareInstallation" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/PageSizeParam" + }, + { + "name": "status", + "in": "query", + "description": "Filter by job lifecycle status", + "schema": { + "$ref": "#/components/schemas/UpgradeJobStatus" + } + }, + { + "name": "installationType", + "in": "query", + "description": "Filter by installation type", + "schema": { + "$ref": "#/components/schemas/InstallationType" + } + } + ], + "responses": { + "200": { + "description": "Paginated list of software installation jobs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareInstallationJobListResponse" + }, + "example": { + "data": [ + { + "id": "b2c3d4e5-0000-0000-0000-000000000002", + "workflowId": "wf-0000-0000-0000-000000000001", + "name": "install-bigip-17.1.2-standalone-batch", + "status": "RUNNING", + "installationType": "STANDALONE", + "batchSize": 10, + "deviceCount": 5, + "createdAt": "2026-05-29T10:00:00Z", + "updatedAt": "2026-05-29T10:45:00Z" + } + ], + "pagination": { + "page": 1, + "page_size": 20, + "total": 1, + "total_pages": 1 + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + }, + "post": { + "operationId": "createSoftwareInstallationJob", + "summary": "Create a software installation job", + "description": "Creates a new software installation job. The job starts in DRAFT state and\ncan be edited before activation.\n\n**installationType controls device targeting mode:**\n- `STANDALONE` \u2014 upgrades independent BIG-IP or F5OS devices\n- `HA` \u2014 upgrades HA pairs, maintaining service continuity\n\n**batchSize controls serial vs batch execution:**\n- `batchSize=1` \u2014 serial: upgrades one device (or HA pair) at a time\n- `batchSize>1` \u2014 batch: upgrades multiple devices (or HA pairs) in parallel\n\nConfig requires: `imageId`, `installationType`, `deviceTargets`\nConfig optional: `batchSize` (default 10), `execution` controls (default true)\n\nVolume selection is **job-level** via `volumeStrategy`; a per-device `volumeOverride`\non a device target takes precedence for that device only.\n\n**At most 5 installation jobs may be in RUNNING state simultaneously.**\n", + "tags": [ + "SoftwareInstallation" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSoftwareInstallationJobRequest" + }, + "examples": { + "standaloneSerial": { + "summary": "Upgrade 3 independent devices serially, device C uses a specific volume (STANDALONE, batchSize=1)", + "value": { + "name": "install-bigip-17.1.2-standalone-serial", + "description": "Upgrade 3 devices one at a time", + "config": { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso", + "installationType": "STANDALONE", + "batchSize": 1, + "volumeStrategy": "NEXT_SEQUENTIAL_NEW", + "execution": { + "hitlPauseBetweenBatches": true, + "hitlPauseBeforeReboot": true, + "reboot": true + }, + "flightChecks": { + "enabled": true + }, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + }, + { + "deviceId": "cccccccc-cccc-cccc-cccc-cccccccccccc", + "volumeOverride": "HD1.3" + } + ] + } + } + }, + "standaloneBatch": { + "summary": "Upgrade 5 independent devices in batches (STANDALONE, batchSize=10), device D uses a specific volume", + "value": { + "name": "install-bigip-17.1.2-standalone-batch", + "description": "Upgrade 5 production BIG-IPs in parallel batches", + "config": { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso", + "installationType": "STANDALONE", + "batchSize": 10, + "volumeStrategy": "NEXT_SEQUENTIAL_NEW", + "execution": { + "hitlPauseBetweenBatches": true, + "reboot": true + }, + "installConfig": true, + "flightChecks": { + "enabled": true, + "coreChecks": { + "trunkStatus": true, + "interfaceStatus": true, + "virtualServerState": true, + "poolHealth": true, + "poolMemberHealth": true + } + }, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + }, + { + "deviceId": "cccccccc-cccc-cccc-cccc-cccccccccccc" + }, + { + "deviceId": "dddddddd-dddd-dddd-dddd-dddddddddddd", + "volumeOverride": "HD1.2" + }, + { + "deviceId": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee" + } + ] + } + } + }, + "haSerial": { + "summary": "Upgrade HA pairs one at a time (HA, batchSize=1) [E7 scope \u2014 not yet implemented]", + "value": { + "name": "install-bigip-17.1.2-ha-serial", + "description": "Upgrade HA pairs one pair at a time", + "config": { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso", + "installationType": "HA", + "batchSize": 1, + "volumeStrategy": "NEXT_SEQUENTIAL_NEW", + "execution": { + "hitlPauseBetweenBatches": true, + "hitlPauseAfterStandbyInstallBeforeReboot": true, + "reboot": false + }, + "installConfig": false, + "flightChecks": { + "enabled": false + }, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + } + ] + } + } + }, + "haBatch": { + "summary": "Upgrade HA pairs in parallel batches (HA, batchSize>1) [E7 scope \u2014 not yet implemented]", + "value": { + "name": "install-bigip-17.1.2-ha-batch", + "description": "Upgrade HA pairs in batches of 2", + "config": { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso", + "installationType": "HA", + "batchSize": 10, + "volumeStrategy": "NEXT_SEQUENTIAL_NEW", + "execution": { + "hitlPauseBetweenBatches": true, + "hitlPauseBeforeReboot": true, + "reboot": true + }, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + }, + { + "deviceId": "cccccccc-cccc-cccc-cccc-cccccccccccc" + }, + { + "deviceId": "dddddddd-dddd-dddd-dddd-dddddddddddd" + } + ] + } + } + } + } + } + } + }, + "responses": { + "201": { + "description": "Software installation job created (in DRAFT state)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareInstallationJob" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "409": { + "description": "Job name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/v1/fleet/upgrade/jobs/software-installation/{jobId}": { + "get": { + "operationId": "getSoftwareInstallationJob", + "summary": "Get software installation job details", + "description": "Returns full job details including configuration, current lifecycle status,\nand per-device install state for any devices that have started execution.\n", + "tags": [ + "SoftwareInstallation" + ], + "responses": { + "200": { + "description": "Software installation job details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareInstallationJob" + }, + "example": { + "id": "b2c3d4e5-0000-0000-0000-000000000002", + "workflowId": "wf-0000-0000-0000-000000000001", + "name": "install-bigip-17.1.2-standalone-batch", + "description": "Upgrade 5 production BIG-IPs in parallel batches of 2", + "status": "RUNNING", + "config": { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso", + "installationType": "STANDALONE", + "batchSize": 10, + "volumeStrategy": "NEXT_SEQUENTIAL_NEW", + "execution": { + "hitlPauseBetweenBatches": true, + "hitlPauseBeforeReboot": true, + "reboot": true + }, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + }, + { + "deviceId": "cccccccc-cccc-cccc-cccc-cccccccccccc", + "volumeOverride": "HD1.3" + } + ] + }, + "execution": { + "executionId": "exec-0000-0000-0000-000000000002", + "status": "RUNNING", + "startedAt": "2026-05-29T10:00:00Z", + "currentBatch": 2, + "totalBatches": 3, + "batches": [ + { + "batchNumber": 1, + "status": "COMPLETED", + "currentStep": "COMPLETE", + "deviceIds": [ + "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", + "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + ] + } + ] + }, + "deviceInstallStates": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", + "hostname": "bigip-prod-01", + "currentVersion": "17.1.1", + "targetVersion": "17.1.2", + "plannedVolume": "HD1.2", + "status": "COMPLETED", + "currentStep": "COMPLETE", + "startedAt": "2026-05-29T10:00:00Z", + "completedAt": "2026-05-29T10:44:30Z" + } + ], + "createdAt": "2026-05-29T09:55:00Z", + "updatedAt": "2026-05-29T10:45:00Z" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + }, + "patch": { + "operationId": "updateSoftwareInstallationJob", + "summary": "Update software installation job configuration", + "description": "Replaces the job configuration.\nOnly allowed when the job is in DRAFT or READY state.\n", + "tags": [ + "SoftwareInstallation" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSoftwareInstallationJobRequest" + }, + "examples": { + "updateStandaloneBatch": { + "summary": "Update batch size and device list (STANDALONE, batchSize=10 for parallel batch), device B uses a specific volume", + "value": { + "name": "install-bigip-17.1.2-batch-v2", + "description": "Updated batch size", + "config": { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso", + "installationType": "STANDALONE", + "batchSize": 10, + "volumeStrategy": "NEXT_SEQUENTIAL_NEW", + "execution": { + "hitlPauseBetweenBatches": false, + "hitlPauseBeforeReboot": false, + "reboot": true + }, + "flightChecks": { + "enabled": true, + "coreChecks": { + "trunkStatus": true, + "interfaceStatus": true, + "virtualServerState": true, + "poolHealth": true, + "poolMemberHealth": false + } + }, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", + "volumeOverride": "HD1.2" + } + ] + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Job updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareInstallationJob" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job cannot be updated in its current state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + }, + "delete": { + "operationId": "deleteSoftwareInstallationJob", + "summary": "Delete a software installation job", + "description": "Permanently deletes a software installation job.\nOnly allowed when the job is not in RUNNING state.\nTerminates any in-progress execution before deletion.\n", + "tags": [ + "SoftwareInstallation" + ], + "responses": { + "204": { + "description": "Job deleted" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job cannot be deleted in its current state (e.g. RUNNING)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/jobs/software-installation/{jobId}/activate": { + "post": { + "operationId": "activateSoftwareInstallationJob", + "summary": "Start a software installation job", + "description": "Transitions a software installation job from DRAFT/READY \u2192 RUNNING and begins\nthe installation pipeline.\n\n**Pre-execution checks:**\n- Image must be in VERIFIED state\n- All target devices must be reachable\n- No target device may be locked by another running job\n- Total running software installation jobs must be fewer than 5\n\nExecution creates batches based on `batchSize` and processes devices one\nbatch at a time. If `hitlPauseBetweenBatches` is true, execution pauses\nbetween batches for operator confirmation.\n", + "tags": [ + "SoftwareInstallation" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivateInstallationJobRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Job activated and installation started", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeJob" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job cannot be activated (wrong state, image not verified, device locked, or max concurrent jobs reached)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/jobs/software-installation/{jobId}/cancel": { + "post": { + "operationId": "cancelSoftwareInstallationJob", + "summary": "Cancel a running or paused software installation job", + "description": "Cancels the installation job gracefully.\n- Any in-progress batch is allowed to complete its current step (no mid-step kill)\n- All pending devices transition to CANCELLED state\n- Device locks are released\n- Job returns to READY (re-activatable); the CANCELLED outcome\n is recorded on the EXECUTION row, not the job, because the\n job is a long-lived re-activatable definition\n", + "tags": [ + "SoftwareInstallation" + ], + "responses": { + "200": { + "description": "Job cancelled", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeJob" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job is not in a cancellable state (e.g. already COMPLETED or in a non-cancellable lifecycle state)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/jobs/software-installation/{jobId}/executions": { + "get": { + "operationId": "listSoftwareInstallationJobExecutions", + "summary": "List executions of a software installation job", + "description": "Returns all executions of a job ordered by `startedAt` descending\n(newest first). Same item shape as the generic workflow executions\nlist (`GET /workflows/{wfId}/jobs/{jobId}/executions`) so the\ncross-feature UI can render distribution + autoscale + installation\nexecution lists with the same component.\n", + "tags": [ + "SoftwareInstallation" + ], + "responses": { + "200": { + "description": "List of executions", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "items" + ], + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SoftwareInstallationExecutionRecord" + } + }, + "totalItems": { + "type": "integer" + } + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/jobs/software-installation/{jobId}/executions/{executionId}": { + "get": { + "operationId": "getSoftwareInstallationJobExecution", + "summary": "Get a single execution of a software installation job", + "description": "Returns the execution record in the same shape as the generic\nworkflows API (`GET /workflows/{wfId}/jobs/{jobId}/executions/{execId}`)\nso the cross-feature UI can render installation executions with the\nsame panel it uses for distribution / autoscale. Per-device runtime\nprogress is embedded inline via the `instanceProgress` field \u2014 only\non this single-execution GET, not on the executions LIST.\n", + "tags": [ + "SoftwareInstallation" + ], + "responses": { + "200": { + "description": "Execution detail", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareInstallationExecutionRecord" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + }, + { + "name": "executionId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ] + } + }, + "/api/v1/fleet/upgrade/jobs/software-installation/{jobId}/pause": { + "post": { + "operationId": "pauseSoftwareInstallationJob", + "summary": "Pause a running software installation job (HITL)", + "description": "Pauses the installation job at the next available HITL checkpoint (between batches).\nThe current batch in progress will complete before the pause takes effect.\nJob transitions to PAUSED state and waits for operator to call /resume or /cancel.\nOnly applicable to software installation jobs with hitlPauseBetweenBatches=true.\n", + "tags": [ + "SoftwareInstallation" + ], + "responses": { + "200": { + "description": "Pause requested \u2014 job will pause at the next batch boundary", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeJob" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job is not in a pausable state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/jobs/software-installation/{jobId}/resume": { + "post": { + "operationId": "resumeSoftwareInstallationJob", + "summary": "Resume a paused software installation job", + "description": "Resumes a PAUSED software installation job. Execution continues with the next\npending batch. Job transitions back to RUNNING state.\n", + "tags": [ + "SoftwareInstallation" + ], + "responses": { + "200": { + "description": "Job resumed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeJob" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job is not in a resumable state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ] + } + }, + "/api/v1/fleet/upgrade/readiness": { + "get": { + "operationId": "listReadinessRuns", + "summary": "List readiness check runs", + "description": "Returns a paginated list of readiness check runs with rollup summaries.\nEach item contains the run status, device counts, and timestamps \u2014 but\nnot the full per-device results. Use `GET /readiness/{runId}` for the\ndetailed per-device breakdown.\n", + "tags": [ + "Readiness" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/PageSizeParam" + }, + { + "name": "status", + "in": "query", + "description": "Filter runs by rolled-up status.", + "schema": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "PASSED", + "WARNING", + "FAILED", + "ERROR" + ] + } + } + ], + "responses": { + "200": { + "description": "Paginated list of readiness runs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadinessRunListResponse" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + }, + "post": { + "operationId": "triggerReadinessChecks", + "summary": "Trigger async pre-distribution readiness checks for target devices", + "description": "Runs the requested readiness checks against the specified target devices.\nThis is a pre-distribution gate \u2014 call before distributing images to verify\nthat target devices are ready to receive the distribution.\n\nThe request envelope holds shared context (device targets and image IDs)\nand a list of check types to run. Image metadata is resolved once and\nshared across all checks.\n\nReturns `202 Accepted` with a `run_id`. Poll `GET /readiness/{runId}`\nuntil `status` is no longer `PENDING` or `RUNNING`.\n\n---\n\n### Supported check types\n\n| Type | What it checks | Severity |\n|------|----------------|----------|\n| `base_image_presence` | For each hotfix image, verifies the required base OS image is present on the device's image catalog (or co-distributed). | SOFT/WARN |\n| `disk_space` | Sums image file sizes and verifies the device has enough free space in its image filesystem. Also updates `disk_available_gb` in device metadata. | SOFT/WARN |\n| `image_compatibility` | Verifies each image's product family is compatible with the target device type (e.g. BIG-IP images cannot target F5OS devices and vice versa). | HARD/FAIL |\n\n---\n\n### Adding a new check type (internal)\n\n1. Implement the `Check` interface.\n2. Register a `ReadinessDescriptor` in `DefaultReadinessRegistry`.\n3. Add the type to the enum in this schema.\n\nNo API envelope changes are required.\n", + "tags": [ + "Readiness" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadinessTriggerRequest" + } + } + } + }, + "responses": { + "202": { + "description": "Readiness checks triggered \u2014 poll GET /readiness/{runId} for results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadinessTriggeredResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + }, + "parameters": [] + } + }, + "/api/v1/fleet/upgrade/readiness/{runId}": { + "get": { + "operationId": "getReadinessResults", + "summary": "Get results for a readiness check run", + "description": "Returns persisted per-device readiness results for a run.\nPoll until `status` is no longer `PENDING` or `RUNNING`.\n`can_proceed: true` means no hard-blocking failures exist.\n", + "tags": [ + "Readiness" + ], + "responses": { + "200": { + "description": "Readiness check results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadinessSummary" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "name": "runId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "The readiness run ID returned by POST /readiness" + } + ] + } + }, + "/api/v1/fleet/upgrade/summary": { + "get": { + "operationId": "getFleetSummary", + "summary": "Get fleet summary (device counts by type, version, status)", + "tags": [ + "Inventory" + ], + "responses": { + "200": { + "description": "Fleet summary", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FleetSummary" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/v1/fleet/upgrade/validate": { + "post": { + "operationId": "triggerValidation", + "summary": "Trigger async pre-job validation for a list of devices against an image", + "description": "Starts the pluggable validation engine for the supplied devices against the\ngiven target image. No job needs to exist \u2014 this endpoint is called **before**\njob creation to confirm all selected devices are eligible for the upgrade.\n\nReturns `202 Accepted` immediately with a `validation_run_id`.\nPoll `GET /validate/{validationRunId}` until `status` is no longer `PENDING` or `RUNNING`.\n\nBefore the validation checks run, the engine performs a **live metadata refresh**\nfor each device so that all checks operate on up-to-date data (current version,\nservice check date, license check date, available disk, etc.). The refresh result\nis best-effort \u2014 a refresh failure logs a warning but does not abort validation.\n\n---\n\n### Soft checks \u2014 warn operator; job may still proceed (`can_proceed: true`)\n\n| Check | Source | Threshold |\n|-------|--------|-----------|\n| `disk_space` | Cached `disk_available_gb` from last device refresh | < 15 GB for new volume slot; < 2 GB for existing slot |\n| `cpu_utilization` | Stage 1: always **SKIP** \u2014 Stage 2: 5-min avg via iControl REST | > 80% |\n| `memory_utilization` | Stage 1: always **SKIP** \u2014 Stage 2: 5-min avg via iControl REST | > 90% |\n| `license_date` | `service_check_date` (from `bigip.license`) vs `license_check_date` (from `/etc/version_date` on device, falls back to K7727 static table) | Service check date must be \u2265 license check date of the target version |\n\n### Hard checks \u2014 block upgrade; job cannot proceed (`can_proceed: false`)\n\n| Check | Source | Rule |\n|-------|--------|------|\n| `upgrade_path` | `upgrade.bigip_upgrade_paths` table (seeded from F5 KB K13845) | Current version must satisfy the minimum-source-version rule for the target major version (BIG-IP only) |\n| `license_compatibility` | `bigip.license` active-modules (fetched live or cached) | License edition must not have an \"Exclusive Version\" ceiling below the target version (BIG-IP only) |\n| `f5os_version_support` | `upgrade.f5os_supported_versions` table (seeded from F5 KB K86001294) | Target F5OS version must be explicitly listed as supported for the device's hardware platform (F5OS only) |\n\n---\n\n### License Date check detail (`license_date`)\n\nBIG-IP will refuse to load its configuration after booting into a newly-upgraded\nvolume if the **service check date** in `bigip.license` predates the\n**license check date** (LCD) baked into that version's build\n(published in F5 KB K7727, stored in `/etc/version_date` on the device).\n\nThe engine reads the LCD in the following order:\n1. Live read of `/etc/version_date` via the iControl REST bash endpoint\n (`POST /mgmt/tm/util/bash`), populated into `device_upgrade_metadata.license_check_date`\n during the pre-validation refresh.\n2. Fallback to the static K7727 lookup table keyed by `major.minor` of the\n **target** image version, when the live read is unavailable.\n\nA `WARN` result means the device's service contract should be re-activated before\nupgrading (see F5 KB K7727: *License activation may be required before a software\nupgrade for BIG-IP*). The check is **SOFT** \u2014 the operator can proceed, but F5\nstrongly recommends reactivating the license first.\n\n---\n\nRe-triggering with the same inputs creates a fresh validation run (a new\n`validation_run_id` is returned each time).\n", + "tags": [ + "Validation" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationTriggerRequest" + } + } + } + }, + "responses": { + "202": { + "description": "Validation triggered \u2014 poll GET /validate/{validationRunId} for results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationTriggeredResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + }, + "parameters": [] + } + }, + "/api/v1/fleet/upgrade/validate/{validationRunId}": { + "get": { + "operationId": "getValidationResults", + "summary": "Get results for a validation run", + "description": "Returns persisted per-device validation results for a run.\nPoll until `status` is no longer `PENDING` or `RUNNING`.\n`can_proceed: true` means no HARD check failures exist across any device.\n", + "tags": [ + "Validation" + ], + "responses": { + "200": { + "description": "Validation results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationSummary" + }, + "example": { + "validation_run_id": "a1b2c3d4-0000-0000-0000-000000000001", + "image_id": "img-uuid-0000-0000-0000-000000000001", + "status": "WARNING", + "device_count": 3, + "pass_count": 2, + "warn_count": 1, + "fail_count": 0, + "error_count": 0, + "can_proceed": true, + "triggered_at": "2026-08-06T10:00:00Z", + "completed_at": "2026-08-06T10:00:05Z", + "devices": [ + { + "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", + "hostname": "bigip-prod-01", + "status": "PASSED", + "current_step": "COMPLETE", + "blocking_check": "", + "check_results": [ + { + "check_name": "disk_space", + "severity": "SOFT", + "status": "PASS" + }, + { + "check_name": "cpu_utilization", + "severity": "SOFT", + "status": "SKIP", + "message": "CPU check not yet implemented (Stage 2)" + }, + { + "check_name": "memory_utilization", + "severity": "SOFT", + "status": "SKIP", + "message": "Memory check not yet implemented (Stage 2)" + }, + { + "check_name": "upgrade_path", + "severity": "HARD", + "status": "PASS" + }, + { + "check_name": "license_compatibility", + "severity": "HARD", + "status": "PASS" + }, + { + "check_name": "license_date", + "severity": "SOFT", + "status": "PASS" + } + ] + }, + { + "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", + "hostname": "bigip-prod-02", + "status": "WARNING", + "current_step": "COMPLETE", + "blocking_check": "", + "check_results": [ + { + "check_name": "disk_space", + "severity": "SOFT", + "status": "WARN", + "message": "disk space 8.2 GB is below recommended 15 GB threshold", + "detail": { + "available_gb": 8.2, + "threshold_gb": 15 + } + }, + { + "check_name": "upgrade_path", + "severity": "HARD", + "status": "PASS" + }, + { + "check_name": "license_compatibility", + "severity": "HARD", + "status": "PASS" + }, + { + "check_name": "license_date", + "severity": "SOFT", + "status": "PASS" + } + ] + }, + { + "device_id": "cccccccc-cccc-cccc-cccc-cccccccccccc", + "hostname": "bigip-prod-03", + "status": "FAILED", + "current_step": "COMPLETE", + "blocking_check": "upgrade_path", + "check_results": [ + { + "check_name": "disk_space", + "severity": "SOFT", + "status": "PASS" + }, + { + "check_name": "upgrade_path", + "severity": "HARD", + "status": "FAIL", + "message": "Current version 15.1.2 is not compatible with target image BIGIP-17.1.5. Minimum source version required: 16.1.0", + "detail": { + "current_version": "15.1.2", + "target_version": "17.1.5", + "min_source_version": "16.1.0" + } + } + ] + } + ] + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "name": "validationRunId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "The validation run ID returned by POST /validate" + } + ] + } + }, + "/api/validate/aidf": { + "post": { + "x-mode": "lite", + "tags": [ + "Validators" + ], + "summary": "Validate AIDF configuration", + "operationId": "validateAIDF", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidateAIDFRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Validation successful", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationResponse" + } + } + } + }, + "400": { + "description": "Validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationResponse" + } + } + } + } + }, + "parameters": [] + } + }, + "/api/validate/inference_provider": { + "post": { + "tags": [ + "Validators" + ], + "summary": "Validate AI provider configuration", + "operationId": "validateAIProvider", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidateAIProviderRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Validation successful", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationResponse" + } + } + } + }, + "400": { + "description": "Validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationResponse" + } + } + } + } + }, + "parameters": [] + } + } + }, + "components": { + "schemas": { + "ImportBackupRequest": { + "type": "object", + "required": [ + "file_path" + ], + "properties": { + "storage_target": { + "type": "string", + "description": "Name of the storage target where the file resides. If omitted, looks in local backup directory." + }, + "file_path": { + "type": "string", + "description": "Filename on the remote share, or filename in local backup directory." + } + } + }, + "StatusResponse": { + "type": "object", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "validation_success", + "validation_error", + "save_successful", + "save_error", + "internal_error", + "healthy", + "unhealthy" + ] + } + } + }, + "StorageTargetResponse": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "$ref": "#/components/schemas/StorageTarget" + } + } + }, + "VMwareProviderProperties": { + "type": "object", + "required": [ + "vCenterHostname" + ], + "properties": { + "vCenterHostname": { + "type": "string", + "format": "hostname", + "description": "Hostname or IP address of vCenter server" + } + } + }, + "ScheduleListResponse": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ScheduledTask" + } + } + } + }, + "JobStatusResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "$ref": "#/components/schemas/JobStatusData" + } + } + }, + "ValidationResponse": { + "type": "object", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "validation_success", + "validation_error", + "internal_error" + ] + }, + "error": { + "type": "string" + } + } + }, + "VolumeStrategy": { + "type": "string", + "description": "Determines which boot volume to install the new software on.\nThis is a job-level setting applied to all devices.\nA per-device volumeOverride takes precedence over this field for that specific device.\n- NEXT_INACTIVE: install on the next available inactive volume numerically\n- LAST_INACTIVE: install on the last available inactive volume numerically\n- NEXT_SEQUENTIAL_NEW: create a new volume with the next sequential identifier\n", + "enum": [ + "NEXT_INACTIVE", + "LAST_INACTIVE", + "NEXT_SEQUENTIAL_NEW" + ] + }, + "ClusterInfo": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the cluster" + }, + "cluster": { + "type": "string", + "description": "Managed Object Reference (cluster ID)" + } + } + }, + "DeviceTemplateTask": { + "type": "object", + "description": "A task associated with a device template lifecycle operation (e.g., deployment).\n", + "required": [ + "id", + "deviceTemplateId", + "type", + "status", + "taskStatus", + "createdAt", + "selfLink" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Server-generated UUID of the task.", + "example": "660e8400-e29b-41d4-a716-446655440001" + }, + "deviceTemplateId": { + "type": "string", + "format": "uuid", + "description": "UUID of the device template this task belongs to.", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "type": { + "type": "string", + "description": "Type of task operation.", + "enum": [ + "DEPLOYMENT" + ], + "example": "DEPLOYMENT" + }, + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 200 + }, + "taskStatus": { + "type": "string", + "description": "Current status of the task.", + "enum": [ + "PENDING", + "IN_PROGRESS", + "COMPLETED", + "FAILED", + "UNKNOWN" + ], + "example": "IN_PROGRESS" + }, + "state": { + "type": "string", + "description": "Current state from the external service (e.g., \"onboarding\", \"licensing\").", + "nullable": true, + "example": "onboarding" + }, + "failureReason": { + "type": "string", + "description": "Reason for task failure. Only present when taskStatus is FAILED.", + "nullable": true, + "example": null + }, + "startedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task started execution.", + "nullable": true, + "example": "2026-04-20T12:00:00Z" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created.", + "example": "2026-04-20T12:00:00Z" + }, + "completedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task completed.", + "nullable": true, + "example": "2026-04-20T12:05:00Z" + }, + "selfLink": { + "type": "string", + "description": "URI path to this task resource.", + "example": "/api/device-templates/tasks/660e8400-e29b-41d4-a716-446655440001" + } + } + }, + "ActivateDistributionJobRequest": { + "type": "object", + "description": "Optional request body for POST /jobs/software-distribution/{jobId}/activate.\nAll fields are optional; the endpoint may be called with no body at all.\n", + "properties": { + "changeRequest": { + "type": "string", + "nullable": true, + "maxLength": 255, + "description": "Optional change-request identifier (e.g. \"CHG0012345\") associated with\nthis specific activation/run. Persisted on the execution record so the\nUI can display it in the execution drawer. Each activation of the same\njob may carry a different change request.\n" + } + } + }, + "TelemetryTypeConfig": { + "type": "object", + "required": [ + "name", + "enabled" + ], + "properties": { + "name": { + "type": "string", + "enum": [ + "API_Discovery", + "Application_Telemetry" + ], + "description": "Telemetry type name", + "example": "API_Discovery" + }, + "enabled": { + "type": "boolean", + "description": "Whether this telemetry type is enabled for AIDF forwarding", + "example": true + }, + "description": { + "type": "string", + "description": "Human-readable description of the telemetry type", + "example": "API discovery telemetry from iRule" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of last update", + "example": "2026-05-13T10:30:00Z" + } + } + }, + "CleanupMigrationTaskResponse": { + "type": "object", + "required": [ + "task_id", + "deleted_devices", + "deleted_trust_stores", + "message" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "The task ID that was cleaned up", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "deleted_devices": { + "type": "integer", + "description": "Number of staging devices deleted", + "example": 10 + }, + "deleted_trust_stores": { + "type": "integer", + "description": "Number of staging trust store entries deleted", + "example": 5 + }, + "message": { + "type": "string", + "description": "Success message", + "example": "Successfully cleaned up migration task staging data" + } + } + }, + "RetryFailedMigrationDevicesResponse": { + "type": "object", + "required": [ + "message", + "task_id" + ], + "properties": { + "message": { + "type": "string", + "description": "Success message", + "example": "Retry task initiated successfully" + }, + "task_id": { + "type": "string", + "format": "uuid", + "description": "The same task ID (reused for retry)", + "example": "123e4567-e89b-12d3-a456-426614174000" + } + } + }, + "DiskAnalysisBatchDeviceInput": { + "type": "object", + "required": [ + "device_id" + ], + "properties": { + "device_id": { + "type": "string", + "format": "uuid" + } + } + }, + "ServiceStatus": { + "type": "object", + "required": [ + "health", + "message", + "errors" + ], + "properties": { + "health": { + "type": "string", + "enum": [ + "green", + "yellow", + "red" + ], + "description": "Overall system health determined by used_percent thresholds (green <75%, yellow 75\u201390%, red >90%)", + "example": "green" + }, + "message": { + "type": "string", + "description": "Additional details about the present license status of the device", + "example": "Activation service healthy" + }, + "errors": { + "type": "array", + "items": { + "type": "string" + }, + "description": "If any occurred while licensing the device", + "example": [] + } + } + }, + "IPPoolCreateRequest": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z_][a-zA-Z0-9_.\\-]*$", + "description": "Pool name. Rules:\n- Minimum length: 1 character\n- Maximum length: 255 characters\n- First character must be a letter (a-z, A-Z) or underscore (_)\n- Remaining characters may be letters, digits, hyphens (-), underscores (_), or dots (.)\n- The following reserved words are not allowed: all, delete, disable, enable, help, list, none, show, None\n" + }, + "description": { + "type": "string" + }, + "addressFamily": { + "type": "string", + "enum": [ + "IPv4", + "IPv6" + ], + "description": "Address family of the pool. When omitted, it is inferred from the CIDR (IPv4 or IPv6)." + }, + "address": { + "type": "string", + "example": "10.0.0.0/24" + }, + "gateway": { + "type": "string", + "nullable": true + }, + "addressRanges": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/AddressRange" + } + } + }, + "required": [ + "name", + "address", + "addressRanges" + ] + }, + "SoftwareInstallationJobPayload": { + "type": "object", + "description": "Shared payload fields for creating or updating a software installation job.\nAll fields are optional at this level; required constraints are applied by the\nCreate/Update wrappers that reference this schema via allOf.\n", + "properties": { + "name": { + "type": "string", + "description": "Unique name for this installation job.", + "minLength": 1, + "maxLength": 255 + }, + "description": { + "type": "string", + "description": "Optional human-readable description." + }, + "enabled": { + "type": "boolean", + "description": "Whether this job is enabled. Set to false to disable the job.\nA disabled job cannot be activated, paused, or resumed.\nOmit on create to default to true.\n" + }, + "config": { + "$ref": "#/components/schemas/SoftwareInstallationConfig" + } + } + }, + "EventListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Event" + } + }, + "total": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "limit": { + "type": "integer" + } + } + }, + "PaginationMetadata": { + "type": "object", + "required": [ + "page", + "page_size", + "total", + "total_pages" + ], + "properties": { + "page": { + "type": "integer", + "minimum": 1 + }, + "page_size": { + "type": "integer", + "minimum": 1 + }, + "total": { + "type": "integer", + "minimum": 0 + }, + "total_pages": { + "type": "integer", + "minimum": 0 + } + } + }, + "TelemetryTypesResponse": { + "type": "object", + "required": [ + "types" + ], + "properties": { + "types": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TelemetryTypeConfig" + }, + "description": "List of all telemetry types with their configuration" + } + } + }, + "ReadinessSummary": { + "type": "object", + "description": "Aggregated readiness check results for a full run.\nReturned by GET /readiness/{runId}. Poll until status is no longer PENDING or RUNNING.\n", + "required": [ + "run_id", + "status", + "device_count", + "pass_count", + "warn_count", + "fail_count", + "error_count", + "can_proceed", + "devices" + ], + "properties": { + "run_id": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "description": "Rolled-up status across all devices:\n- RUNNING \u2014 at least one device is still being checked\n- PASSED \u2014 all devices pass cleanly\n- WARNING \u2014 at least one soft warning; no hard failures\n- FAILED \u2014 at least one hard check failed\n- ERROR \u2014 at least one device errored (unreachable, etc.)\n", + "enum": [ + "PENDING", + "RUNNING", + "PASSED", + "WARNING", + "FAILED", + "ERROR" + ] + }, + "device_count": { + "type": "integer" + }, + "pass_count": { + "type": "integer" + }, + "warn_count": { + "type": "integer" + }, + "fail_count": { + "type": "integer" + }, + "error_count": { + "type": "integer" + }, + "can_proceed": { + "type": "boolean", + "description": "True when no device has a HARD-severity FAIL. Always true for soft-only checks." + }, + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReadinessDeviceResult" + } + }, + "triggered_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "completed_at": { + "type": "string", + "format": "date-time", + "nullable": true + } + } + }, + "VolumeInfo": { + "type": "object", + "description": "A single non-active BIG-IP software boot volume. Always represents an inactive volume.", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "Volume slot name (e.g. \"HD1.2\")" + }, + "version": { + "type": "string", + "description": "Software version installed on this volume (e.g. \"17.1.2\")" + }, + "build": { + "type": "string", + "description": "Build number (e.g. \"0.0.13\")" + }, + "status": { + "type": "string", + "description": "Volume status (e.g. \"complete\", \"installing\")" + } + } + }, + "ReadinessRunListItem": { + "type": "object", + "description": "Lightweight summary of a single readiness run (no per-device details).\nUse GET /readiness/{runId} for full per-device results.\n", + "required": [ + "run_id", + "status", + "device_count", + "pass_count", + "warn_count", + "fail_count", + "error_count", + "can_proceed" + ], + "properties": { + "run_id": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "description": "Rolled-up status across all devices in this run.", + "enum": [ + "PENDING", + "RUNNING", + "PASSED", + "WARNING", + "FAILED", + "ERROR" + ] + }, + "device_count": { + "type": "integer" + }, + "pass_count": { + "type": "integer" + }, + "warn_count": { + "type": "integer" + }, + "fail_count": { + "type": "integer" + }, + "error_count": { + "type": "integer" + }, + "can_proceed": { + "type": "boolean", + "description": "True when no device has a HARD-severity FAIL." + }, + "triggered_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "completed_at": { + "type": "string", + "format": "date-time", + "nullable": true + } + } + }, + "ActivityDetail": { + "allOf": [ + { + "$ref": "#/components/schemas/Activity" + }, + { + "type": "object", + "properties": { + "steps": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ActivityStep" + } + } + } + } + ] + }, + "AddDeviceRequest": { + "description": "Unified add-device request. The `deviceType` field selects how the\nbody is interpreted. For `bigip` (default) the existing flat BIG-IP\nfields apply (backward compatible). For `f5os` the `f5os` object is\nrequired. Exactly one variant applies per request.\n", + "oneOf": [ + { + "$ref": "#/components/schemas/BigIPAddRequest" + }, + { + "$ref": "#/components/schemas/F5OSAddRequest" + } + ], + "discriminator": { + "propertyName": "deviceType", + "mapping": { + "bigip": "#/components/schemas/BigIPAddRequest", + "f5os": "#/components/schemas/F5OSAddRequest" + } + } + }, + "ApplyAcceptedResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "202" + }, + "data": { + "type": "object", + "required": [ + "id", + "status" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "example": "d4e5f6a7-b8c9-4000-8000-000000000001" + }, + "status": { + "type": "string", + "enum": [ + "pending", + "running", + "done", + "failed" + ], + "example": "pending" + } + } + } + } + }, + "LicenseReportResponse": { + "type": "object", + "required": [ + "report" + ], + "properties": { + "report": { + "type": "string", + "description": "Base64 encoded license report (JSON content)", + "example": "eyJyZXBvcnROYW1lIjoibXktcmVwb3J0IiwidGVsZW1ldHJ5UmVjb3JkcyI6W119" + } + } + }, + "PreflightCheck": { + "type": "object", + "required": [ + "name", + "status", + "message", + "bypass_allowed" + ], + "properties": { + "name": { + "type": "string", + "example": "no_active_job" + }, + "status": { + "type": "string", + "enum": [ + "pass", + "fail" + ], + "example": "pass" + }, + "message": { + "type": "string", + "example": "No active patch job running" + }, + "bypass_allowed": { + "type": "boolean", + "description": "True when a failed check can be bypassed by an explicit user override. Always false for no_active_job, disk_space, and version_compatibility.", + "example": false + } + } + }, + "DataCentersWithDevicesResponse": { + "type": "object", + "additionalProperties": false, + "properties": { + "data_centers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DataCenterWithDevices" + } + }, + "total_data_centers": { + "type": "integer", + "description": "Total number of data centers", + "minimum": 0 + }, + "total_devices": { + "type": "integer", + "description": "Total number of devices across all data centers", + "minimum": 0 + } + } + }, + "DeviceTemplateDeployResponse": { + "type": "object", + "description": "Response returned after initiating deployment.", + "required": [ + "status", + "deviceTemplateId", + "deploymentTaskId", + "selfLink" + ], + "properties": { + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 202 + }, + "deviceTemplateId": { + "type": "string", + "format": "uuid", + "description": "UUID of the device template being deployed.", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "deploymentTaskId": { + "type": "string", + "format": "uuid", + "description": "UUID of the deployment task for tracking progress.", + "example": "c3d4e5f6-a7b8-4012-8def-123456789012" + }, + "selfLink": { + "type": "string", + "description": "URI path to the deployment task resource.", + "example": "/api/device-templates/tasks/c3d4e5f6-a7b8-4012-8def-123456789012" + }, + "warning": { + "type": "string", + "description": "Optional warning from the onboarding service. Present when the declaration\ncontains restart-causing resources (e.g., sys:license, sys:provision,\nshared:licensing:registration).\n", + "nullable": true, + "example": "Onboarding operation might cause a BIG-IP system restart." + } + } + }, + "UpgradeHistoryStatsResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "object", + "required": [ + "total_applied", + "total_failed", + "total_rollbacks", + "avg_duration_sec", + "security_patches" + ], + "properties": { + "total_applied": { + "type": "integer", + "example": 19 + }, + "total_failed": { + "type": "integer", + "example": 2 + }, + "total_rollbacks": { + "type": "integer", + "example": 2 + }, + "avg_duration_sec": { + "type": "integer", + "example": 514 + }, + "security_patches": { + "type": "integer", + "example": 3 + } + } + } + } + }, + "Workflow": { + "type": "object", + "required": [ + "id", + "name", + "type", + "executionMode", + "createdAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "name": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "executionMode": { + "type": "string", + "enum": [ + "CONTINUOUS", + "ON_DEMAND" + ], + "description": "CONTINUOUS \u2014 self-repeating, driven by policies/conditions (e.g. AutoScale).\nON_DEMAND \u2014 discrete runs triggered by user or scheduler (e.g. SOFTWARE_DISTRIBUTION, SOFTWARE_INSTALLATION, Backup).\n" + }, + "description": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + } + } + }, + "GlobalSettings": { + "type": "object", + "properties": { + "retention": { + "$ref": "#/components/schemas/Retention" + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "collection_interval": { + "type": "integer", + "minimum": 1, + "description": "Collection interval in seconds" + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean", + "default": false + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from trust store" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean", + "default": false + }, + "cgnat": { + "type": "boolean", + "default": false + }, + "dns": { + "type": "boolean", + "default": false + }, + "dos": { + "type": "boolean", + "default": false + }, + "firewall": { + "type": "boolean", + "default": false + }, + "gtm": { + "type": "boolean", + "default": false + }, + "policy_api_protection": { + "type": "boolean", + "default": false + }, + "policy_asm": { + "type": "boolean", + "default": false + }, + "policy_firewall": { + "type": "boolean", + "default": false + }, + "policy_ip_intelligence": { + "type": "boolean", + "default": false + }, + "policy_nat": { + "type": "boolean", + "default": false + }, + "profile_dos": { + "type": "boolean", + "default": false + } + } + } + } + }, + "UpgradeHistoryEntry": { + "type": "object", + "required": [ + "job_id", + "version", + "kind", + "status", + "started_by", + "started_at", + "services", + "security_fix", + "rollback_available" + ], + "properties": { + "job_id": { + "type": "string", + "format": "uuid", + "example": "d4e5f6a7-b8c9-4000-8000-000000000001" + }, + "version": { + "type": "string", + "example": "f5-insight-patch-3.19" + }, + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "example": "patch" + }, + "status": { + "type": "string", + "enum": [ + "pending", + "running", + "done", + "failed" + ], + "example": "done" + }, + "started_by": { + "type": "string", + "example": "admin@f5.com" + }, + "started_at": { + "type": "string", + "format": "date-time" + }, + "finished_at": { + "type": "string", + "format": "date-time" + }, + "services": { + "type": "array", + "items": { + "type": "string" + } + }, + "security_fix": { + "type": "boolean", + "example": false + }, + "rollback_available": { + "type": "boolean", + "description": "True when this patch job can currently be rolled back manually. Manual rollback is available only for the latest successful patch completed within the last 72 hours; failed patch jobs use automatic rollback.", + "example": true + } + } + }, + "UpdateTelemetryTypesRequest": { + "type": "object", + "required": [ + "enabled_types" + ], + "properties": { + "enabled_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "API_Discovery", + "Application_Telemetry" + ] + }, + "description": "List of telemetry types to enable (all others will be disabled)", + "example": [ + "API_Discovery", + "Application_Telemetry" + ], + "minItems": 0 + } + } + }, + "BackupSizeAnalysis": { + "type": "object", + "required": [ + "is_anomalous", + "recent_size_bytes", + "rolling_avg_bytes", + "pct_of_avg", + "sample_size" + ], + "properties": { + "is_anomalous": { + "type": "boolean", + "description": "True when the latest backup is more than 30% smaller than the rolling average.", + "example": false + }, + "recent_size_bytes": { + "type": "integer", + "format": "int64", + "description": "Size of the most recent completed backup.", + "example": 104857600 + }, + "rolling_avg_bytes": { + "type": "integer", + "format": "int64", + "description": "Average size of up to 3 completed backups before the most recent one.", + "example": 99614720 + }, + "pct_of_avg": { + "type": "integer", + "description": "Latest backup size as a percentage of rolling_avg_bytes.", + "example": 105 + }, + "sample_size": { + "type": "integer", + "description": "Number of previous backups used to calculate rolling_avg_bytes.", + "example": 3 + } + } + }, + "ConnectResponse": { + "type": "object", + "properties": { + "connId": { + "type": "string", + "description": "Connection ID to use for subsequent discovery API calls" + }, + "message": { + "type": "string", + "description": "Connection status message" + } + } + }, + "DeviceTemplateValidationResponse": { + "type": "object", + "description": "Response returned after validating a device template.\nAlways HTTP 200 \u2014 inspect `valid` and each tier's result for pass/fail.\n", + "required": [ + "id", + "status", + "valid", + "validatedAt", + "dataSanity", + "templateSchema", + "selfLink" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "UUID of the validated device template.", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 200 + }, + "valid": { + "type": "boolean", + "description": "Overall validation result \u2014 `true` only if all tiers pass.", + "example": false + }, + "validatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp (UTC) when validation was performed.", + "example": "2026-04-15T10:30:00Z" + }, + "dataSanity": { + "type": "object", + "description": "Tier 1 \u2014 Data & Sanity validation results.", + "required": [ + "valid", + "errors", + "warnings" + ], + "properties": { + "valid": { + "type": "boolean", + "example": true + }, + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ValidationIssue" + } + }, + "warnings": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ValidationIssue" + } + } + } + }, + "templateSchema": { + "type": "object", + "description": "Tier 2 \u2014 Template / Schema validation results.", + "required": [ + "valid", + "errors", + "warnings" + ], + "properties": { + "valid": { + "type": "boolean", + "example": false + }, + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ValidationIssue" + } + }, + "warnings": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ValidationIssue" + } + } + } + }, + "selfLink": { + "type": "string", + "description": "URI path to the validated device template resource.", + "example": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000" + } + } + }, + "HostInfo": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the host" + }, + "host": { + "type": "string", + "description": "Managed Object Reference (host ID)" + } + } + }, + "Task": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier of the task", + "example": "d4e5f6a7-b8c9-0123-defg-456789abcdef" + }, + "type": { + "type": "string", + "enum": [ + "ADD_OFFERING", + "REACTIVATE_OFFERING", + "ASSIGN_LICENSE", + "REVOKE_LICENSE" + ], + "description": "Type of the async operation", + "example": "ASSIGN_LICENSE" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "IN_PROGRESS", + "COMPLETED", + "FAILED" + ], + "description": "Current status of the task", + "example": "IN_PROGRESS" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Progress percentage (0-100)", + "example": 50 + }, + "resourceType": { + "type": "string", + "enum": [ + "LicenseOffering", + "LicenseMember" + ], + "description": "Type of resource this task operates on", + "example": "LicenseMember" + }, + "resourceId": { + "type": "string", + "format": "uuid", + "description": "ID of the resource being operated on", + "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" + }, + "resourceLink": { + "type": "string", + "format": "uri", + "description": "Link to the resource once task completes", + "example": "https://localhost/api/licensing/pool/regkey/licenses/7dd7b971-6eb8-4b9e-995b-1dcb1287d65f/offerings/U5939-99933-49705-74523-4841009/members/a1b2c3d4-e5f6-7890-abcd-ef1234567890" + }, + "error": { + "$ref": "#/components/schemas/Error" + }, + "selfLink": { + "type": "string", + "format": "uri", + "description": "Self-referencing link to this task", + "example": "https://localhost/api/licensing/pool/tasks/d4e5f6a7-b8c9-0123-defg-456789abcdef" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + }, + "startedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task started processing" + }, + "completedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task completed (success or failure)" + } + } + }, + "EntitledFeature": { + "type": "object", + "description": "A single entitled feature within the license", + "properties": { + "featureId": { + "type": "string", + "description": "Unique feature identifier", + "example": "FEAT-001" + }, + "featureName": { + "type": "string", + "description": "Human-readable feature name", + "example": "AI-Driven Forecasting" + }, + "featurePermitted": { + "type": "integer", + "description": "Maximum permitted usage for this feature", + "example": 1000 + }, + "featureRemain": { + "type": "integer", + "description": "Remaining usage available", + "example": 750 + }, + "featureUnlimited": { + "type": "boolean", + "description": "Whether this feature has unlimited usage", + "example": false + }, + "featureUsed": { + "type": "integer", + "description": "Amount of feature already consumed", + "example": 250 + }, + "featureValueType": { + "type": "string", + "description": "Type of the feature value", + "enum": [ + "integral", + "boolean", + "string" + ], + "example": "integral" + }, + "uomCode": { + "type": "string", + "description": "Unit of measure code", + "example": "GB" + }, + "uomTerm": { + "type": "string", + "description": "Unit of measure term", + "example": "gigabytes" + }, + "uomTermStart": { + "type": "integer", + "description": "Starting value for unit of measure", + "example": 0 + } + } + }, + "DataCenterWithDevices": { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the data center" + }, + "name": { + "type": "string", + "description": "Name of the data center", + "maxLength": 255 + }, + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DeviceResponse" + } + }, + "device_count": { + "type": "integer", + "description": "Total number of devices in this data center", + "minimum": 0 + } + } + }, + "APIErrorResponse": { + "type": "object", + "required": [ + "success", + "error" + ], + "properties": { + "success": { + "type": "boolean", + "example": false + }, + "error": { + "$ref": "#/components/schemas/APIError" + } + } + }, + "StorageAllocationConfigResponse": { + "type": "object", + "required": [ + "id", + "clickhouse_allocation_percent", + "victoriametrics_allocation_percent", + "cleanup_threshold_percent", + "cleanup_data_percent", + "sslo_logs_ttl_days", + "irule_logs_ttl_days", + "victoriametrics_retention", + "created_at", + "updated_at" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Configuration ID" + }, + "clickhouse_allocation_percent": { + "type": "number", + "format": "double", + "description": "Percentage of total storage allocated to ClickHouse. Supports up to 2 decimal places.", + "example": 70.5 + }, + "victoriametrics_allocation_percent": { + "type": "number", + "format": "double", + "description": "Percentage of total storage allocated to VictoriaMetrics. Supports up to 2 decimal places.", + "example": 29.5 + }, + "cleanup_threshold_percent": { + "type": "number", + "format": "double", + "description": "Threshold percentage at which cleanup is triggered. Supports up to 2 decimal places.", + "example": 80 + }, + "cleanup_data_percent": { + "type": "number", + "format": "double", + "description": "Percentage of data to delete during cleanup. Supports up to 2 decimal places.", + "example": 70 + }, + "sslo_logs_ttl_days": { + "type": "integer", + "description": "TTL for SSLO logs in days", + "example": 7 + }, + "irule_logs_ttl_days": { + "type": "integer", + "description": "TTL for iRule logs in days", + "example": 7 + }, + "victoriametrics_retention": { + "type": "string", + "description": "VictoriaMetrics retention period", + "example": "12M" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Configuration creation timestamp" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Last update timestamp" + } + } + }, + "ValidationIssue": { + "type": "object", + "description": "A single validation error or warning.", + "required": [ + "field", + "message" + ], + "properties": { + "field": { + "type": "string", + "description": "Dot-notation path to the problematic field.", + "example": "definition.managementSslPort" + }, + "message": { + "type": "string", + "description": "Human-readable description of the issue.", + "example": "Value must be between 1 and 65535" + } + } + }, + "CreateSoftwareDistributionJobRequest": { + "description": "Request body for creating a new software distribution job. Name is required.", + "allOf": [ + { + "$ref": "#/components/schemas/SoftwareDistributionJobPayload" + }, + { + "required": [ + "name" + ] + } + ] + }, + "FlightCheckDiff": { + "type": "object", + "description": "A first-class, independently-addressable result of comparing a device's PRE\nsnapshot with its matching POST snapshot. Addressed by its own `id` via\nGET /flight-checks/diffs/{diffId}. Carries back-links to the two snapshots it\nwas computed from (preSnapshotUrl / postSnapshotUrl), each resolvable via\nGET /api/v1/fleet/upgrade/flight-checks/snapshots/{snapshotId}.\n\npreSnapshotUrl / postSnapshotUrl are optional: a diff is its own\nfirst-class entity and outlives the snapshots it was derived from, so a\nback-link is omitted once the corresponding snapshot has been pruned.\n", + "required": [ + "id", + "jobId", + "deviceId", + "computedAt", + "degraded" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique diff ID (addressing key)." + }, + "jobId": { + "type": "string", + "format": "uuid", + "description": "Installation job execution this diff belongs to." + }, + "deviceId": { + "type": "string", + "format": "uuid", + "description": "Device this diff was computed for." + }, + "degraded": { + "type": "boolean", + "description": "Quick \"needs attention\" flag: true when any entry has a DEGRADED\noutcome (POST is worse than PRE). Always present; materialized from\nthe diff entries at compute time.\n" + }, + "preSnapshotUrl": { + "type": "string", + "description": "Optional back-link to the PRE snapshot used in the comparison.\nOmitted when that snapshot has been pruned. Resolves via\nGET /api/v1/fleet/upgrade/flight-checks/snapshots/{snapshotId}.\n" + }, + "postSnapshotUrl": { + "type": "string", + "description": "Optional back-link to the POST snapshot used in the comparison.\nOmitted when that snapshot has been pruned. Resolves via\nGET /api/v1/fleet/upgrade/flight-checks/snapshots/{snapshotId}.\n" + }, + "computedAt": { + "type": "string", + "format": "date-time", + "description": "When the diff was computed." + }, + "entries": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FlightCheckDiffEntry" + } + } + } + }, + "SoftwareDistributionJobPayload": { + "type": "object", + "description": "Shared payload fields for creating or updating a software distribution job.\nAll fields are optional at this level; required constraints are applied by the\nCreate/Update wrappers that reference this schema via allOf.\n", + "properties": { + "name": { + "type": "string", + "description": "Unique name for this distribution job.", + "minLength": 1, + "maxLength": 255 + }, + "description": { + "type": "string", + "description": "Optional human-readable description." + }, + "enabled": { + "type": "boolean", + "description": "Whether this job is enabled. Set to false to disable the job.\nA disabled job cannot be activated, paused, or resumed.\nOmit on create to default to true.\n" + }, + "config": { + "$ref": "#/components/schemas/SoftwareDistributionConfig" + } + } + }, + "ListOfTrustStores": { + "type": "object", + "additionalProperties": false, + "properties": { + "trust_stores": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TrustStore" + } + } + } + }, + "NetworkRoute": { + "type": "object", + "description": "A network route definition.", + "required": [ + "name", + "gatewayAddress", + "destination" + ], + "properties": { + "name": { + "type": "string", + "example": "default" + }, + "gatewayAddress": { + "type": "string", + "example": "10.0.0.1" + }, + "destination": { + "type": "string", + "example": "0.0.0.0/0" + } + } + }, + "ReadinessTriggerRequest": { + "type": "object", + "description": "Request body for POST /readiness.\nThe `context` object holds shared parameters (device targets and image IDs)\napplied to all checks. The `checks` array specifies which readiness check\ntypes to run.\n", + "required": [ + "context", + "checks" + ], + "properties": { + "context": { + "$ref": "#/components/schemas/ReadinessContext" + }, + "checks": { + "type": "array", + "description": "List of readiness check types to run.", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/ReadinessCheckEntry" + } + } + } + }, + "ActivityStep": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "activityId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "stepName": { + "type": "string" + }, + "sequence": { + "type": "integer" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "COMPLETED", + "FAILED", + "SKIPPED" + ] + }, + "attempt": { + "type": "integer" + }, + "retryCount": { + "type": "integer" + }, + "previousAttempts": { + "type": "array", + "readOnly": true, + "description": "Earlier attempts for this same logical step. The top-level step represents the latest attempt.", + "items": { + "$ref": "#/components/schemas/ActivityStep" + } + }, + "startedAt": { + "type": "string", + "format": "date-time" + }, + "completedAt": { + "type": "string", + "format": "date-time" + }, + "durationMs": { + "type": "integer" + }, + "errorCode": { + "type": "string" + }, + "errorMessage": { + "type": "string" + }, + "metadata": { + "type": "object", + "additionalProperties": true + } + } + }, + "SoftwareInstallationJob": { + "type": "object", + "description": "Full software installation job resource including config, execution state,\nand per-device install tracking.\n", + "required": [ + "id", + "name", + "status", + "enabled", + "config", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique job identifier." + }, + "workflowId": { + "type": "string", + "format": "uuid", + "description": "Parent workflow entity ID." + }, + "name": { + "type": "string", + "description": "Unique human-readable job name." + }, + "description": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/UpgradeJobStatus" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether this job is enabled. A disabled job (false) cannot be activated,\npaused, or resumed. Defaults to true on creation.\n" + }, + "config": { + "$ref": "#/components/schemas/SoftwareInstallationConfig" + }, + "execution": { + "$ref": "#/components/schemas/JobExecution", + "description": "Present once the job has been activated at least once." + }, + "deviceInstallStates": { + "type": "array", + "description": "Per-device install tracking. Populated once a device's batch starts.", + "items": { + "$ref": "#/components/schemas/DeviceInstallState" + } + }, + "createdBy": { + "type": "string", + "nullable": true, + "description": "Username of the operator who created the job." + }, + "modifiedBy": { + "type": "string", + "nullable": true, + "description": "Username of the operator who last modified the job." + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "warnings": { + "type": "array", + "description": "Informational (non-blocking) warnings about the job configuration.\nPresent when HA-paired devices are included in a STANDALONE job.\nDoes not affect job status.\n\n**Availability:** Only populated on single-job GET responses\n(`GET /jobs/software-installation/{id}`). Not returned in list\nresponses (`GET /jobs/software-installation`). Use the single-job\nGET endpoint to retrieve warnings for a specific job.\n", + "items": { + "$ref": "#/components/schemas/JobWarning" + } + } + } + }, + "LicenseMember": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier of the license member", + "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" + }, + "deviceAddress": { + "type": "string", + "format": "ipv4", + "description": "IP address of the BIG-IP device", + "example": "192.168.1.100" + }, + "deviceName": { + "type": "string", + "description": "Hostname/name of the BIG-IP device", + "example": "bigip-ve-001.local" + }, + "deviceMacAddress": { + "type": "string", + "pattern": "^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$", + "description": "MAC address of the BIG-IP device", + "example": "00:1A:2B:3C:4D:5E" + }, + "deviceLicenseText": { + "type": "string", + "description": "License text that was installed on the BIG-IP device" + }, + "status": { + "type": "string", + "enum": [ + "INSTALLING", + "INSTALLATION_FAILED", + "LICENSED" + ], + "description": "Current status of the license assignment to the member device. INSTALLING - license installation on the BIG-IP device is in progress. INSTALLATION_FAILED - license installation on the device failed. LICENSED - license has been successfully installed and the device is licensed.\n", + "example": "LICENSED" + }, + "taskId": { + "type": "string", + "format": "uuid", + "description": "ID of the async task processing this member assignment", + "example": "d4e5f6a7-b8c9-0123-defg-456789abcdef" + }, + "selfLink": { + "type": "string", + "format": "uri", + "description": "Self-referencing link", + "example": "https://localhost/api/licensing/pool/regkey/licenses/7dd7b971-6eb8-4b9e-995b-1dcb1287d65f/offerings/U5939-99933-49705-74523-4841009/members/a1b2c3d4-e5f6-7890-abcd-ef1234567890" + }, + "assignedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the license was assigned" + }, + "revokedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the license was revoked (if applicable)" + } + } + }, + "FleetDeviceListResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FleetDevice" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + } + }, + "UpgradeEntry": { + "type": "object", + "required": [ + "version", + "kind" + ], + "properties": { + "version": { + "type": "string", + "description": "Version string (e.g., f5-insight-patch-1.2.1)", + "example": "f5-insight-patch-1.2.1" + }, + "base_version": { + "type": "string", + "description": "Minimum required version for this patch", + "example": "f5-insight-1.2.0" + }, + "minimum_supported_version": { + "type": "string", + "description": "Minimum installed version required by this bundle manifest", + "example": "1.1.0" + }, + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade", + "release" + ], + "description": "Bundle type", + "example": "patch" + }, + "is_latest": { + "type": "boolean", + "description": "Whether this entry matches the latest version for its upgrade type", + "example": true + }, + "built_at": { + "type": "string", + "format": "date-time", + "description": "Build timestamp", + "example": "2026-05-15T10:30:00Z" + }, + "release_date": { + "type": "string", + "format": "date", + "description": "Release date for this catalog entry", + "example": "2026-05-15" + }, + "services": { + "type": "array", + "description": "Services included in this bundle", + "items": { + "type": "string" + }, + "example": [ + "backend", + "frontend", + "auth-service" + ] + }, + "filename": { + "type": "string", + "description": "Bundle filename", + "example": "f5insight-patch-1.2.1.tar.gz" + }, + "size_bytes": { + "type": "integer", + "format": "int64", + "description": "Bundle size in bytes", + "example": 41943040 + }, + "sha256": { + "type": "string", + "description": "SHA256 checksum", + "example": "abc123def456..." + }, + "cosign_signature": { + "type": "string", + "description": "Cosign signature for the bundle", + "example": "MEUCIQD..." + }, + "download_url": { + "type": "string", + "description": "Download URL used by system-manager for online F5 Downloads entries. Empty for offline bundles.", + "example": "" + }, + "security_fix": { + "type": "boolean", + "description": "Whether this bundle contains security fixes", + "example": true + }, + "severity": { + "type": "string", + "enum": [ + "critical", + "high", + "medium", + "low", + "" + ], + "description": "Security severity level", + "example": "high" + }, + "mrs": { + "type": "array", + "description": "Merge requests included in this bundle", + "items": { + "$ref": "#/components/schemas/MergeRequest" + } + }, + "cumulative_mrs": { + "type": "array", + "description": "All MRs since base_version (for patches)", + "items": { + "$ref": "#/components/schemas/MergeRequest" + } + } + } + }, + "CreateScheduleRequest": { + "type": "object", + "required": [ + "name", + "cron", + "passphrase" + ], + "properties": { + "name": { + "type": "string", + "description": "Schedule name (e.g., \"daily-config\", \"weekly-full\")" + }, + "cron": { + "type": "string", + "description": "Standard 5-field cron expression", + "example": "0 2 * * *" + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ], + "default": "full" + }, + "storage_target": { + "type": "string" + }, + "passphrase": { + "type": "string", + "minLength": 12, + "description": "Encryption passphrase (stored in Vault). Must be at least 12 characters with uppercase, lowercase, digit, and special character. Max 2 consecutive identical characters." + } + } + }, + "PostflightCheck": { + "type": "object", + "required": [ + "name", + "status", + "message" + ], + "properties": { + "name": { + "type": "string", + "example": "deployments_ready" + }, + "status": { + "type": "string", + "enum": [ + "pass", + "fail" + ], + "example": "pass" + }, + "message": { + "type": "string", + "example": "All deployments are Ready" + } + } + }, + "FleetSummary": { + "type": "object", + "properties": { + "total_devices": { + "type": "integer" + }, + "bigip_count": { + "type": "integer" + }, + "f5os_count": { + "type": "integer" + }, + "version_distribution": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "status_distribution": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + } + } + }, + "ConnectionValidationResponse": { + "type": "object", + "required": [ + "reachable", + "authenticated" + ], + "properties": { + "reachable": { + "type": "boolean", + "description": "Indicates if the device is reachable." + }, + "authenticated": { + "type": "boolean", + "description": "Indicates if authentication succeeded." + }, + "message": { + "type": "string", + "description": "Additional details about the validation result." + } + } + }, + "StorageInfo": { + "type": "object", + "required": [ + "used_percent", + "used_gb", + "entitled_gb" + ], + "properties": { + "used_percent": { + "type": "number", + "format": "float", + "description": "Percentage of storage currently consumed", + "example": 15.7 + }, + "used_gb": { + "type": "integer", + "description": "Actual used storage in gigabytes", + "example": 500 + }, + "entitled_gb": { + "type": "integer", + "description": "Licensed storage capacity allowed", + "example": 300 + } + } + }, + "FlightCheckResult": { + "type": "object", + "description": "Generic result envelope for a single core check within a snapshot.", + "properties": { + "status": { + "$ref": "#/components/schemas/FlightCheckStatus" + }, + "details": { + "type": "object", + "additionalProperties": true, + "description": "Check-specific structured details (raw collected state)." + }, + "error": { + "type": "string", + "description": "Collection error message, when status is ERROR." + } + } + }, + "ReadinessRunListResponse": { + "type": "object", + "description": "Paginated list of readiness check runs.", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReadinessRunListItem" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + } + }, + "InstanceListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Instance" + } + }, + "totalItems": { + "type": "integer" + } + } + }, + "RollbackLogEntry": { + "type": "object", + "required": [ + "ts", + "level", + "message" + ], + "properties": { + "ts": { + "type": "string", + "format": "date-time", + "example": "2026-05-11T14:30:00Z" + }, + "level": { + "type": "string", + "enum": [ + "info", + "success", + "warn", + "error" + ], + "example": "success" + }, + "message": { + "type": "string", + "example": "Rolled back backend to f5-insight-patch/backend:3.19" + } + } + }, + "SortOrder": { + "type": "string", + "enum": [ + "asc", + "desc" + ], + "description": "Sort direction (shared schema, reusable across endpoints)" + }, + "MessageResponse": { + "type": "object", + "properties": { + "message": { + "type": "string", + "example": "Operation successful" + } + } + }, + "DeviceType": { + "type": "string", + "enum": [ + "bigip", + "f5os" + ], + "default": "bigip", + "description": "Discriminates the kind of device. `bigip` (default) is a BIG-IP device;\n`f5os` is an F5OS platform provider (e.g. rSeries). When omitted the\ndevice is treated as a BIG-IP for backward compatibility.\n" + }, + "IPPoolUpdateRequest": { + "allOf": [ + { + "$ref": "#/components/schemas/IPPoolCreateRequest" + } + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Should match the path parameter; the server overwrites mismatched values." + } + } + }, + "DeviceTemplateMutationResponse": { + "type": "object", + "description": "Response returned after creating, updating, or cloning a device template.\n- **200**: Synchronous save completed.\n- **201**: Created in DRAFT state.\n", + "required": [ + "id", + "state", + "status", + "selfLink", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "UUID of the device template.", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "state": { + "type": "string", + "description": "Current lifecycle state after the operation.", + "enum": [ + "DRAFT", + "NEW", + "DEPLOYED" + ], + "example": "NEW" + }, + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 200 + }, + "selfLink": { + "type": "string", + "description": "URI path to the device template resource.", + "example": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp (UTC) when the template was created.", + "example": "2026-01-15T09:23:41Z" + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp (UTC) when the template was last modified.", + "example": "2026-03-22T14:45:10Z" + } + } + }, + "TaskListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Task" + } + }, + "totalItems": { + "type": "integer", + "description": "Total number of tasks matching the filter criteria", + "example": 42 + }, + "page": { + "type": "integer", + "description": "Current page number", + "example": 1 + }, + "size": { + "type": "integer", + "description": "Number of items per page", + "example": 20 + }, + "totalPages": { + "type": "integer", + "description": "Total number of pages", + "example": 3 + } + } + }, + "DeviceTemplateDefinition": { + "type": "object", + "description": "Template definition containing all BIG-IP device configuration parameters.", + "required": [ + "rootPassword" + ], + "properties": { + "rootPassword": { + "type": "string", + "description": "BIG-IP root password. Must be at least 8 characters.", + "minLength": 8, + "example": "s3cur3P@ss!" + }, + "timeZone": { + "type": "string", + "description": "NTP timezone string applied to the BIG-IP device.", + "nullable": true, + "maxLength": 100, + "example": "America/Los_Angeles" + }, + "defaultRoute": { + "type": "string", + "description": "Default network gateway route for the BIG-IP device. Must be a valid IP address without prefix.", + "nullable": true, + "example": "10.0.0.1" + }, + "managementSslPort": { + "type": "integer", + "description": "BIG-IP management SSL port. If omitted, the device default is used.", + "nullable": true, + "minimum": 0, + "maximum": 65535, + "example": 443 + }, + "managementIp": { + "$ref": "#/components/schemas/ManagementIp" + }, + "hostnameComponents": { + "type": "array", + "description": "Ordered array of hostname building blocks.", + "items": { + "$ref": "#/components/schemas/HostnameComponent" + }, + "example": [ + { + "type": "STATIC_TEXT", + "value": "bigip-" + }, + { + "type": "SERIAL_NUMBER", + "value": null + } + ] + }, + "lookupServerList": { + "type": "array", + "description": "List of DNS lookup server addresses.", + "items": { + "type": "string" + }, + "example": [ + "8.8.8.8", + "8.8.4.4" + ] + }, + "ntpServerList": { + "type": "array", + "description": "List of NTP server addresses.", + "items": { + "type": "string" + }, + "example": [ + "0.pool.ntp.org" + ] + }, + "userAccountList": { + "type": "array", + "description": "Array of BIG-IP user accounts to create.", + "items": { + "$ref": "#/components/schemas/UserAccount" + } + }, + "provisionedModuleList": { + "type": "array", + "description": "Array of BIG-IP modules to provision.", + "items": { + "$ref": "#/components/schemas/ProvisionedModule" + } + }, + "networkRouteList": { + "type": "array", + "description": "Array of network interface routes.", + "items": { + "$ref": "#/components/schemas/NetworkRoute" + } + }, + "vlanList": { + "type": "array", + "description": "Array of VLAN definitions.", + "items": { + "$ref": "#/components/schemas/VlanDefinition" + } + }, + "selfIpList": { + "type": "array", + "description": "Array of self-IP definitions for the BIG-IP device.", + "items": { + "$ref": "#/components/schemas/SelfIpDefinition" + } + }, + "bgpConfig": { + "$ref": "#/components/schemas/BgpConfig" + } + } + }, + "SoftwareDistributionJobListResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SoftwareDistributionJobSummary" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + } + }, + "AddDeviceResponse": { + "type": "object", + "required": [ + "message", + "id" + ], + "properties": { + "message": { + "type": "string", + "description": "Success message", + "example": "Device added successfully" + }, + "id": { + "type": "string", + "format": "uuid", + "description": "UUID of the device that was created" + } + } + }, + "DiskAnalysisTaskStatusResponse": { + "type": "object", + "required": [ + "task_id", + "status", + "created_at" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "status": { + "$ref": "#/components/schemas/DiskAnalysisTaskStatus" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "started_at": { + "type": "string", + "format": "date-time" + }, + "completed_at": { + "type": "string", + "format": "date-time" + }, + "progress": { + "$ref": "#/components/schemas/DiskAnalysisTaskProgress" + }, + "result": { + "$ref": "#/components/schemas/DiskAnalysisTaskResult" + }, + "error": { + "$ref": "#/components/schemas/Error" + } + } + }, + "BackupSizeAnalysisResponse": { + "type": "object", + "required": [ + "success", + "data" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "$ref": "#/components/schemas/BackupSizeAnalysis" + } + } + }, + "MergeRequest": { + "type": "object", + "required": [ + "id", + "title" + ], + "properties": { + "id": { + "type": "string", + "description": "MR identifier (e.g., !847)", + "example": "!847" + }, + "title": { + "type": "string", + "description": "MR title", + "example": "Fix authentication timeout issue" + } + } + }, + "AddDataCenterResponse": { + "type": "object", + "required": [ + "message", + "id" + ], + "properties": { + "message": { + "type": "string", + "description": "Success message", + "example": "Data center added successfully" + }, + "id": { + "type": "string", + "format": "uuid", + "description": "UUID of the data center that was created" + } + } + }, + "BFDTimers": { + "type": "object", + "description": "Bidirectional Forwarding Detection (BFD) timer configuration.\nAll values are specified in milliseconds (ms).\n", + "required": [ + "transmitInterval", + "receiveInterval", + "detectionMultiplier" + ], + "properties": { + "transmitInterval": { + "type": "integer", + "description": "BFD transmission interval in milliseconds.\nThe time interval between BFD control packets sent to the peer.\n", + "minimum": 1, + "maximum": 60000, + "example": 300 + }, + "receiveInterval": { + "type": "integer", + "description": "BFD reception interval in milliseconds.\nThe time interval expected between BFD control packets received from the peer.\n", + "minimum": 1, + "maximum": 60000, + "example": 300 + }, + "detectionMultiplier": { + "type": "integer", + "description": "BFD detection multiplier.\nThe number of BFD packets that must be missed to declare the session down.\nDetection time = transmitInterval \u00d7 detectionMultiplier.\n", + "minimum": 1, + "maximum": 50, + "example": 3 + } + } + }, + "UpdateCloudProviderRequest": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "Name of the cloud provider" + }, + "vmwProperties": { + "$ref": "#/components/schemas/VMwareProviderProperties" + } + } + }, + "StorageAllocationConfigRequest": { + "type": "object", + "required": [ + "clickhouse_allocation_percent", + "victoriametrics_allocation_percent" + ], + "description": "Request body for updating storage allocation config. Only accepts 4 fields - allocation percentages (mandatory) and cleanup percentages (optional). All percentages support up to 2 decimal places (e.g., 70.50).", + "properties": { + "clickhouse_allocation_percent": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 100, + "description": "Percentage of total storage allocated to ClickHouse (mandatory, must sum to 100 with victoriametrics_allocation_percent). Supports up to 2 decimal places.", + "example": 70.5 + }, + "victoriametrics_allocation_percent": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 100, + "description": "Percentage of total storage allocated to VictoriaMetrics (mandatory, must sum to 100 with clickhouse_allocation_percent). Supports up to 2 decimal places.", + "example": 29.5 + }, + "cleanup_threshold_percent": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 100, + "description": "Threshold percentage at which cleanup is triggered (optional). Supports up to 2 decimal places.", + "example": 80 + }, + "cleanup_data_percent": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 100, + "description": "Percentage of data to delete during cleanup (optional). Supports up to 2 decimal places.", + "example": 70 + } + } + }, + "DeviceTemplatePatchRequest": { + "type": "object", + "description": "Payload for partially updating a device template (PATCH).\nAll fields are optional \u2014 only provided fields are modified.\nFor `definition`, merge-patch semantics apply.\n", + "properties": { + "name": { + "type": "string", + "description": "Human-readable name. Must be unique.", + "minLength": 1, + "maxLength": 255, + "example": "BIG-IP Standard Template v2" + }, + "provider": { + "type": "string", + "description": "Provider or vendor.", + "minLength": 1, + "maxLength": 255, + "example": "VMware" + }, + "description": { + "type": "string", + "description": "Optional description. Set to `null` to clear.", + "nullable": true, + "maxLength": 1000, + "example": "Updated description" + }, + "draft": { + "type": "boolean", + "description": "Controls DRAFT state on partial update." + }, + "definition": { + "$ref": "#/components/schemas/PatchDeviceTemplateDefinition" + } + } + }, + "VersionResponse": { + "type": "object", + "required": [ + "success", + "data" + ], + "properties": { + "success": { + "type": "boolean", + "example": true + }, + "data": { + "type": "object", + "properties": { + "version": { + "type": "string", + "example": "1.2.0" + }, + "build_date": { + "type": "string", + "example": "2025-01-14" + }, + "git_commit": { + "type": "string", + "example": "abc1234" + } + } + } + } + }, + "MigrationStatusResponse": { + "type": "object", + "required": [ + "task_id", + "task_type", + "state", + "status", + "progress", + "total_devices", + "pending_devices", + "validated_devices", + "failed_devices", + "created_at", + "updated_at" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the migration task", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "task_type": { + "type": "string", + "enum": [ + "DEVICE_IMPORT", + "MIGRATION", + "BULK_IMPORT", + "SYNC" + ], + "description": "Type of the task", + "example": "MIGRATION" + }, + "state": { + "type": "string", + "enum": [ + "INIT", + "IN_PROGRESS", + "COMPLETED", + "FAILED" + ], + "description": "Current state of the task", + "example": "IN_PROGRESS" + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "SUCCESS", + "ERROR" + ], + "description": "Overall status of the task", + "example": "RUNNING" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Overall progress percentage", + "example": 45 + }, + "total_devices": { + "type": "integer", + "description": "Total number of devices in the migration", + "example": 100 + }, + "pending_devices": { + "type": "integer", + "description": "Number of devices pending validation", + "example": 55 + }, + "validated_devices": { + "type": "integer", + "description": "Number of devices successfully validated", + "example": 40 + }, + "failed_devices": { + "type": "integer", + "description": "Number of devices that failed validation", + "example": 5 + }, + "error_message": { + "type": "string", + "nullable": true, + "description": "Error message if the task failed", + "example": null + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "When the task was created", + "example": "2026-01-29T10:30:00Z" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "When the task was last updated", + "example": "2026-01-29T10:35:00Z" + }, + "devices": { + "type": "array", + "description": "Individual device status details (included if include_devices=true)", + "items": { + "$ref": "#/components/schemas/DeviceStatusDetail" + } + } + } + }, + "BulkDeleteJobsResponse": { + "type": "object", + "required": [ + "results" + ], + "properties": { + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkDeleteJobResult" + }, + "description": "Per-job deletion outcome" + } + } + }, + "FeatureFlag": { + "type": "object", + "description": "A feature flag with name and value", + "properties": { + "featureName": { + "type": "string", + "description": "Name of the feature", + "example": "perf_SSL_Mbps" + }, + "featureValue": { + "type": "string", + "description": "Value of the feature (can be numeric or \"enabled\"/\"disabled\")", + "example": "2000" + } + } + }, + "VMwareEnvironmentPropertiesResponse": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "datacenter": { + "type": "string" + }, + "user": { + "type": "string" + }, + "password": { + "type": "string", + "description": "Encrypted password (base64-encoded). Frontend should pass this through as-is without decrypting." + }, + "vmImage": { + "type": "string" + }, + "networkInterfaceMapping": { + "type": "array", + "items": { + "type": "object", + "properties": { + "network": { + "type": "string" + } + } + } + }, + "ipPoolAliasMapping": { + "type": "array", + "items": { + "type": "object", + "properties": { + "alias": { + "type": "string" + }, + "ipPoolReference": { + "type": "string" + } + } + } + } + } + }, + "TrustStoreResponse": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the certificate" + }, + "name": { + "type": "string", + "description": "Name of the certificate" + }, + "description": { + "type": "string", + "description": "Description of the certificate" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp" + } + } + }, + "ValidateAIProviderRequest": { + "type": "object", + "required": [ + "provider_name" + ], + "properties": { + "provider_name": { + "type": "string", + "description": "AI provider name (e.g., openai, claude, local)" + }, + "api_token": { + "type": "string", + "description": "API token for the provider. Required for 'openai' and 'claude' providers, optional for 'local' provider." + }, + "base_url": { + "type": "string", + "description": "Base URL for the provider. Required for 'local' provider, optional for 'openai' and 'claude'." + }, + "model": { + "type": "string", + "description": "Model name to use. Required for 'local' provider, optional for others." + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "Optional CA certificate UUID from trust store" + }, + "skip_tls_verify": { + "type": "boolean", + "description": "Indicates if TLS verification should be skipped for this provider" + } + } + }, + "ManagementIp": { + "type": "object", + "description": "Management IP configuration.\n\nThe management IP is configured via DHCP. This field is reserved for future use.\n\nThe field should be omitted or set to `null`.\n", + "properties": {} + }, + "ReadinessContext": { + "type": "object", + "description": "Shared context for all readiness checks in a single run.", + "required": [ + "device_targets", + "image_ids" + ], + "properties": { + "device_targets": { + "type": "array", + "description": "Target devices to run readiness checks against.", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/ReadinessDeviceTarget" + } + }, + "image_ids": { + "type": "array", + "description": "UUIDs of the software images being distributed. Used by all checks to resolve image metadata.", + "minItems": 1, + "items": { + "type": "string", + "format": "uuid" + } + } + } + }, + "Instance": { + "type": "object", + "required": [ + "id", + "workflowId", + "jobId", + "status", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "workflowId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "jobId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "hostname": { + "type": "string" + }, + "ip": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "PROVISIONING", + "READY", + "ERROR", + "DEPROVISIONING", + "UNKNOWN" + ] + }, + "managementAddr": { + "type": "string" + }, + "providerGuestRef": { + "type": "string" + }, + "vmName": { + "type": "string", + "description": "Cloud provider VM name returned by create-vm." + }, + "statsDeviceId": { + "type": "string", + "format": "uuid", + "description": "Device identifier returned by stats collection/device management." + }, + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "deletedAt": { + "type": "string", + "format": "date-time", + "nullable": true, + "readOnly": true + } + } + }, + "DeviceTemplateDeployRequest": { + "type": "object", + "description": "Payload for deploying a device template to a target BIG-IP device.", + "required": [ + "mgmtIp", + "encodedBasicAuth" + ], + "properties": { + "mgmtIp": { + "type": "string", + "format": "ipv4", + "description": "Management IP address of the target BIG-IP device.", + "example": "192.168.1.100" + }, + "username": { + "type": "string", + "description": "Username for the BIG-IP device (optional, for display/logging purposes).", + "minLength": 1, + "maxLength": 255, + "example": "admin" + }, + "encodedBasicAuth": { + "type": "string", + "description": "Base64-encoded basic authentication credentials (username:password).", + "minLength": 1, + "example": "YWRtaW46YWRtaW5QYXNzd29yZDEyMw==" + } + } + }, + "PatchStagingCABundleResponse": { + "type": "object", + "required": [ + "message", + "staging_ca_id" + ], + "properties": { + "message": { + "type": "string", + "description": "Success message", + "example": "Staging CA bundle updated and committed successfully" + }, + "staging_ca_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the staging CA bundle that was updated" + } + } + }, + "JobListPaginatedResponse": { + "type": "object", + "required": [ + "items", + "pagination" + ], + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Job" + } + }, + "pagination": { + "$ref": "#/components/schemas/PaginationMetadata" + } + } + }, + "StorageTarget": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "storage_type": { + "type": "string", + "enum": [ + "local", + "nfs", + "smb" + ] + }, + "server": { + "type": "string" + }, + "share_path": { + "type": "string" + }, + "mount_options": { + "type": "string" + }, + "username": { + "type": "string" + }, + "is_default": { + "type": "boolean" + }, + "status": { + "type": "string", + "description": "Health-check status of the target (active, unreachable, unknown). Local targets are always active. Populated by background connectivity checks.", + "enum": [ + "active", + "unreachable", + "unknown" + ] + }, + "last_checked_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent health check (null until first check)." + }, + "latency": { + "type": "string", + "description": "Round-trip latency measured during the last successful health check, e.g. \"45ms\"." + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "last_modified": { + "type": "string", + "format": "date-time" + } + } + }, + "HAPhase": { + "type": "string", + "description": "A pair-level phase walked by the HA coordinator. These belong to the\nPAIR (not to either node alone): VALIDATE_PAIR validates both nodes\ntogether, the AWAIT_* phases are durable HITL gates the coordinator\nPAUSES on, FAILOVER/FAILBACK move traffic between nodes, and STANDBY/\nACTIVE are the per-node install phases surfaced here so the pair\ntimeline reads end-to-end. DONE/FAILED are terminal cursor states.\n", + "enum": [ + "VALIDATE_PAIR", + "DISABLE_SYNC", + "STANDBY", + "AWAIT_FAILOVER_GATE", + "FAILOVER", + "AWAIT_SECOND_INSTALL_GATE", + "ACTIVE", + "AWAIT_FAILBACK_GATE", + "FAILBACK", + "RESTORE_SYNC", + "DONE", + "FAILED" + ] + }, + "ListOfDataCenters": { + "type": "object", + "additionalProperties": false, + "properties": { + "data_centers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DataCenter" + } + } + } + }, + "ScheduledUpgradeCreatedResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "201" + }, + "data": { + "type": "object", + "required": [ + "id", + "status", + "scheduled_at" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "example": "770e8400-e29b-41d4-a716-446655440010" + }, + "status": { + "type": "string", + "example": "pending" + }, + "scheduled_at": { + "type": "string", + "format": "date-time", + "example": "2026-05-12T02:00:00Z" + } + } + } + } + }, + "ReleaseResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IPLease" + } + }, + "totalItems": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "items", + "totalItems" + ] + }, + "BackupListResponse": { + "type": "object", + "required": [ + "success", + "data" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BackupJob" + } + } + } + }, + "SoftwareInstallationConfig": { + "type": "object", + "required": [ + "configType" + ], + "properties": { + "configType": { + "type": "string", + "enum": [ + "SOFTWARE_INSTALLATION" + ], + "description": "Config type discriminator" + } + } + }, + "Pagination": { + "type": "object", + "properties": { + "page": { + "type": "integer" + }, + "page_size": { + "type": "integer" + }, + "total": { + "type": "integer" + }, + "total_pages": { + "type": "integer" + } + } + }, + "IPPool": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z_][a-zA-Z0-9_.\\-]*$", + "description": "Pool name. Rules:\n- Minimum length: 1 character\n- Maximum length: 255 characters\n- First character must be a letter (a-z, A-Z) or underscore (_)\n- Remaining characters may be letters, digits, hyphens (-), underscores (_), or dots (.)\n- The following reserved words are not allowed: all, delete, disable, enable, help, list, none, show, None\n" + }, + "description": { + "type": "string" + }, + "addressFamily": { + "type": "string", + "enum": [ + "IPv4", + "IPv6" + ] + }, + "address": { + "type": "string", + "description": "Pool network expressed in CIDR notation.", + "example": "10.0.0.0/24" + }, + "gateway": { + "type": "string", + "nullable": true, + "example": "10.0.0.1" + }, + "addressRanges": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AddressRange" + } + }, + "totalAddressCount": { + "type": "integer", + "minimum": 0 + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "deletedAt": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "required": [ + "id", + "name", + "addressFamily", + "address", + "addressRanges", + "totalAddressCount", + "createdAt", + "updatedAt" + ] + }, + "UpdateLicenseOfferingRequest": { + "type": "object", + "description": "Request to update or reactivate a license offering. The operation performed depends on the `status` field:\n\n- `ACTIVATING_AUTOMATIC`: Triggers automatic reactivation (async, returns 202 with TaskReference)\n- `ACTIVATING_MANUAL`: Triggers manual reactivation (sync, returns 200 with new dossier)\n- `ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED`: Completes manual activation with license text (sync, returns 200)\n", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "ACTIVATING_AUTOMATIC", + "ACTIVATING_MANUAL", + "ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED" + ], + "description": "The operation to perform:\n- `ACTIVATING_AUTOMATIC`: Trigger automatic reactivation via F5 license server (async)\n- `ACTIVATING_MANUAL`: Trigger manual reactivation, regenerates dossier (sync)\n- `ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED`: Complete manual activation with provided license text (sync)\n", + "example": "ACTIVATING_AUTOMATIC" + }, + "licenseText": { + "type": "string", + "description": "License text obtained from F5 license server. \n**Required** when status is `ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED`.\nThe user obtains this by submitting the dossier to the F5 license server UI.\n", + "example": "Auth vers : 5b\nRegistration key : W5778-33088-84412-26046-5913991\nLicensed date : 20260525\n..." + } + } + }, + "AuditEvent": { + "type": "object", + "description": "A single AI assistant audit event row from ClickHouse.", + "properties": { + "event_id": { + "type": "string", + "format": "uuid", + "description": "Unique event identifier", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "session_id": { + "type": "string", + "description": "Browser/session identifier", + "example": "sess-abc123" + }, + "thread_id": { + "type": "string", + "description": "Conversation/thread identifier (maps to chat history conversation_id)", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "interaction_id": { + "type": "string", + "description": "Single request-response cycle identifier within a thread", + "example": "interact-xyz" + }, + "user_id": { + "type": "string", + "description": "Authenticated user ID", + "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" + }, + "username": { + "type": "string", + "description": "Authenticated username", + "example": "admin" + }, + "event_type": { + "type": "string", + "enum": [ + "user_message", + "assistant_response", + "tool_call", + "tool_result", + "error", + "data_access", + "pdf_export" + ], + "description": "Type of agent action that generated this event" + }, + "message": { + "type": "string", + "description": "User message text, assistant response text, or error message. Masked as `[MASKED]` unless caller has `audit.view_sensitive`.\n" + }, + "tool_name": { + "type": "string", + "description": "Name of the tool invoked (populated for tool_call/tool_result events)", + "example": "list_pools" + }, + "tool_arguments": { + "type": "string", + "description": "JSON-encoded tool arguments. PII masked unless view_sensitive.", + "example": "{\"device_name\":\"bigip-01\"}" + }, + "tool_result": { + "type": "string", + "description": "JSON-encoded tool result. PII masked unless view_sensitive." + }, + "error_message": { + "type": "string", + "description": "Error details for error-type events." + }, + "provider": { + "type": "string", + "description": "LLM provider name", + "example": "openai" + }, + "model": { + "type": "string", + "description": "LLM model name", + "example": "gpt-4o" + }, + "ip_address": { + "type": "string", + "description": "Client IP address. Masked unless view_sensitive.", + "example": "192.168.1.***" + }, + "user_agent": { + "type": "string", + "description": "Client user agent. Always `[MASKED]` unless view_sensitive." + }, + "timestamp": { + "type": "string", + "format": "date-time", + "description": "Event timestamp (UTC)", + "example": "2026-06-01T10:30:00Z" + }, + "duration_ms": { + "type": "integer", + "description": "Duration of the operation in milliseconds (populated for tool_result events)", + "example": 342 + }, + "outcome": { + "type": "string", + "enum": [ + "success", + "failure", + "pending" + ], + "description": "Outcome of the agent action" + }, + "extra": { + "type": "string", + "description": "Additional JSON metadata" + } + } + }, + "InstallStepStatus": { + "type": "string", + "description": "Lifecycle status of a single step within a device's installation\ntimeline. Distinct from InstallStep (which names *which* step) and from\nthe device-level status. Used to render the completed/current/upcoming\nper-device step timeline.\n", + "enum": [ + "PENDING", + "RUNNING", + "COMPLETED", + "FAILED", + "CANCELLED", + "SKIPPED" + ] + }, + "SoftwareDistributionExecution": { + "type": "object", + "description": "Software distribution execution record. Field names + types match\nthe generic workflow Execution schema so the cross-feature UI can\nrender distribution and autoscale / installation executions with\nthe same panel.\n\nOn single-execution GET (`/executions/{executionId}`) the response\nadditionally embeds `instanceProgress` \u2014 the per-device runtime\nrollup scoped to this execution. The executions LIST endpoint\nstays lean and never populates that field.\n", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "jobId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "jobName": { + "type": "string", + "readOnly": true, + "description": "Parent software distribution job name." + }, + "jobDescription": { + "type": "string", + "readOnly": true, + "description": "Parent software distribution job description." + }, + "trigger": { + "type": "string", + "enum": [ + "USER", + "ALERT", + "SYSTEM", + "SCHEDULE" + ], + "readOnly": true + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED", + "CANCELLED", + "TIMEOUT" + ], + "readOnly": true + }, + "reason": { + "type": "string", + "description": "Human-readable trigger reason" + }, + "startedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "completedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "durationMs": { + "type": "integer", + "readOnly": true + }, + "activityCount": { + "type": "integer", + "readOnly": true, + "description": "Number of activities (per-device rows) recorded under this execution" + }, + "retryCount": { + "type": "integer", + "readOnly": true + }, + "currentStep": { + "type": "string", + "readOnly": true + }, + "lastError": { + "type": "string", + "readOnly": true + }, + "changeRequest": { + "type": "string", + "nullable": true, + "maxLength": 255, + "description": "Optional change-request identifier supplied at activation time.\nNull when no change request was provided.\n", + "readOnly": true + }, + "correlationId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "createdBy": { + "type": "string", + "nullable": true, + "readOnly": true, + "description": "Username of the operator who created (activated) this execution." + }, + "modifiedBy": { + "type": "string", + "nullable": true, + "readOnly": true, + "description": "Username of the operator who last modified this execution." + }, + "instanceProgress": { + "$ref": "#/components/schemas/InstanceProgress", + "description": "Per-device runtime rollup scoped to this execution. Populated\nonly on the single-execution GET; absent on the executions LIST.\n" + } + } + }, + "ImageStatus": { + "type": "string", + "description": "Lifecycle status of a software image during upload and verification", + "enum": [ + "UPLOADING", + "PENDING_VERIFICATION", + "VERIFYING", + "AVAILABLE", + "VERIFICATION_FAILED" + ], + "default": "UPLOADING" + }, + "HACoordination": { + "type": "object", + "description": "Cross-node HA orchestration rollup for an execution. Holds one entry\nper HA pair participating in the execution. This is a derived READ\nMODEL (the pair-level analogue of the per-device step timeline), not a\nnew source of truth: it is projected from the persisted pair cursors.\n", + "required": [ + "pairs" + ], + "properties": { + "pairs": { + "type": "array", + "description": "One coordination timeline per HA pair in this execution.", + "items": { + "$ref": "#/components/schemas/HAPairCoordination" + } + } + } + }, + "VMInfo": { + "type": "object", + "properties": { + "vm": { + "type": "string", + "description": "Managed Object Reference (VM ID)" + }, + "name": { + "type": "string", + "description": "Name of the virtual machine" + } + } + }, + "HostnameComponent": { + "type": "object", + "description": "A hostname building block.", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "description": "Component type.", + "enum": [ + "STATIC_TEXT", + "SERIAL_NUMBER" + ], + "example": "STATIC_TEXT" + }, + "value": { + "type": "string", + "description": "Value for the component. Required for STATIC_TEXT, null for SERIAL_NUMBER.", + "nullable": true, + "example": "bigip-" + } + } + }, + "UpgradeOperationStatus": { + "type": "object", + "required": [ + "action", + "status" + ], + "properties": { + "action": { + "type": "string", + "enum": [ + "upgrade" + ], + "example": "upgrade" + }, + "status": { + "type": "string", + "enum": [ + "in_progress", + "completed", + "failed", + "rebooting" + ], + "x-enum-varnames": [ + "UpgradeOperationStatusStatusInProgress", + "UpgradeOperationStatusStatusCompleted", + "UpgradeOperationStatusStatusFailed", + "UpgradeOperationStatusStatusRebooting" + ], + "example": "in_progress" + }, + "phase": { + "type": "string", + "description": "Current phase of the upgrade", + "enum": [ + "init", + "platform_manager", + "k3s", + "images", + "helm", + "cleanup", + "complete" + ], + "example": "helm" + }, + "message": { + "type": "string", + "example": "Deploying application updates..." + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "example": 75 + }, + "started_at": { + "type": "string", + "format": "date-time", + "example": "2025-01-14T10:30:00Z" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "example": "2025-01-14T10:35:00Z" + }, + "result": { + "type": "object", + "properties": { + "version": { + "type": "string", + "description": "New version after successful upgrade", + "example": "1.2.0" + } + } + } + } + }, + "VMTaskRequest": { + "type": "object", + "required": [ + "envReference" + ], + "properties": { + "envReference": { + "type": "string", + "description": "ID (UUID) or name of the cloud environment to use for this VM task.\n" + }, + "vmName": { + "type": "string", + "description": "For create-vm only: optional name for the created VM. If omitted,\na name is generated automatically using the configured naming\nprefix (default: \"autoscale-bigip-\"). Ignored by delete-vm.\n" + }, + "vmIP": { + "type": "string", + "description": "IP address of the VM. For delete-vm, either vmIP or vmUuid must be\nsupplied; vmIP takes precedence when both are present.\n" + }, + "vmUuid": { + "type": "string", + "description": "vCenter Managed Object Reference (MoRef) of the VM. For delete-vm,\neither vmIP or vmUuid must be supplied. Recommended for cleaning up\norphaned clones that never acquired an IP \u2014 the create-vm response\nreturns vmUuid as soon as the clone succeeds.\n" + } + } + }, + "MigrationTaskResponse": { + "type": "object", + "required": [ + "task_id", + "status", + "message" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the migration task", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "status": { + "type": "string", + "enum": [ + "INIT", + "IN_PROGRESS" + ], + "description": "Initial status of the task", + "example": "INIT" + }, + "message": { + "type": "string", + "description": "Human-readable message about the task", + "example": "Migration task created successfully. Use the task_id to query status." + } + } + }, + "DeviceTemplateCloneRequest": { + "type": "object", + "description": "Payload for cloning an existing device template.", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "Name for the cloned template. Must be unique.", + "minLength": 1, + "maxLength": 255, + "example": "BIG-IP Standard Template (Copy)" + } + } + }, + "DeviceProgressItem": { + "type": "object", + "required": [ + "id", + "device_name", + "status", + "last_modified" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the staging device", + "example": "660e8400-e29b-41d4-a716-446655440001" + }, + "device_name": { + "type": "string", + "description": "Name of the device being migrated", + "example": "bigip-prod-01.example.com" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "VALIDATING", + "SUCCESS", + "FAILED", + "SKIPPED", + "SKIPPED" + ], + "description": "Current validation status of the device", + "example": "SUCCESS" + }, + "error_message": { + "type": "string", + "nullable": true, + "description": "Error message if status is FAILED", + "example": "Invalid credentials" + }, + "last_modified": { + "type": "string", + "format": "date-time", + "description": "Timestamp when this device was last updated", + "example": "2026-01-30T12:12:00Z" + } + } + }, + "FlightSnapshot": { + "type": "object", + "description": "A first-class, independently-addressable capture of device state for one\nphase (PRE or POST), holding the core check results. Addressed by its own\n\n`id` via GET /flight-checks/snapshots/{snapshotId}. A device accumulates many\nsnapshots over time (one PRE + one POST per installation job it participates\nin), so each snapshot carries its own deviceId, jobId, phase and capturedAt.\n\nCore-check result fields are a flat UNION across platforms: BIG-IP snapshots\npopulate trunkStatus/interfaceStatus/virtualServerState/poolHealth/\npoolMemberHealth; F5OS snapshots populate interfaceStatus (shared)/lagStatus/\nalarms/healthSummary/cluster/firmwareStatus/fpgaStatus/cores/tenantStatus/\nservicePods. Fields not relevant to the captured device's type are omitted.\n", + "required": [ + "id", + "jobId", + "deviceId", + "phase", + "capturedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique snapshot ID (addressing key)." + }, + "jobId": { + "type": "string", + "format": "uuid", + "description": "Installation job execution this snapshot was captured under." + }, + "deviceId": { + "type": "string", + "format": "uuid", + "description": "Device this snapshot was captured from." + }, + "phase": { + "type": "string", + "enum": [ + "PRE", + "POST" + ], + "description": "Whether captured before (PRE) or after (POST) install." + }, + "capturedAt": { + "type": "string", + "format": "date-time", + "description": "When the snapshot was captured." + }, + "trunkStatus": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "interfaceStatus": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "virtualServerState": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "poolHealth": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "poolMemberHealth": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "performanceAllStats": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "lagStatus": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "alarms": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "healthSummary": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "cluster": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "firmwareStatus": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "fpgaStatus": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "cores": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "tenantStatus": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "servicePods": { + "$ref": "#/components/schemas/FlightCheckResult" + } + } + }, + "ValidationSummary": { + "type": "object", + "description": "Aggregated validation results for a validation run.\nReturned by GET /validate/{validationRunId}.\nPoll until `status` is no longer PENDING or RUNNING.\n`can_proceed: true` means no HARD check failures exist across any device.\n", + "required": [ + "validation_run_id", + "image_id", + "status", + "device_count", + "pass_count", + "warn_count", + "fail_count", + "error_count", + "can_proceed", + "devices" + ], + "properties": { + "validation_run_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for this validation run." + }, + "image_id": { + "type": "string", + "format": "uuid", + "description": "The target image UUID this run validated against." + }, + "status": { + "$ref": "#/components/schemas/ValidationStatus", + "description": "Rolled-up status across all devices.\nFAILED if any device has a HARD failure; WARNING if any device has a SOFT warning and no\nHARD failures; PASSED if all devices pass cleanly; ERROR if any device errored.\n" + }, + "device_count": { + "type": "integer", + "description": "Total number of devices being validated." + }, + "pass_count": { + "type": "integer", + "description": "Devices with status PASSED." + }, + "warn_count": { + "type": "integer", + "description": "Devices with status WARNING." + }, + "fail_count": { + "type": "integer", + "description": "Devices with status FAILED." + }, + "error_count": { + "type": "integer", + "description": "Devices with status ERROR." + }, + "can_proceed": { + "type": "boolean", + "description": "True when no device has a HARD-severity FAIL.\nThe operator may still choose to proceed despite SOFT warnings.\n" + }, + "devices": { + "type": "array", + "description": "Per-device validation results.", + "items": { + "$ref": "#/components/schemas/DeviceValidationResult" + } + }, + "triggered_at": { + "type": "string", + "format": "date-time", + "description": "When this validation run was triggered." + }, + "completed_at": { + "type": "string", + "format": "date-time", + "description": "When all devices finished (or errored). Null while status is PENDING or RUNNING." + } + } + }, + "ReadinessDeviceTarget": { + "type": "object", + "description": "A single device target for readiness checks.", + "required": [ + "device_id" + ], + "properties": { + "device_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the device to check." + } + } + }, + "JobWarning": { + "type": "object", + "description": "An informational warning produced during job validation.", + "required": [ + "code", + "message", + "severity" + ], + "properties": { + "code": { + "type": "string", + "description": "Machine-readable warning code.", + "example": "HA_DEVICES_IN_STANDALONE_JOB" + }, + "message": { + "type": "string", + "description": "Human-readable warning description.", + "example": "Device bigip/10.0.0.1.bigip is the active node of an HA pair but will be installed independently without automatic failover sequencing." + }, + "severity": { + "type": "string", + "description": "Severity level of the warning.", + "enum": [ + "INFO" + ], + "example": "INFO" + } + } + }, + "CurrentVersionResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "object", + "required": [ + "version" + ], + "properties": { + "version": { + "type": "string", + "example": "f5-insight-patch-3.19" + } + } + } + } + }, + "VerifyReportRequest": { + "type": "object", + "required": [ + "manifest" + ], + "properties": { + "manifest": { + "type": "string", + "description": "Base64 encoded signed report acknowledgment from F5 TEEM", + "example": "eyJzaWduZWRBY2siOiJ0ZXN0In0=" + } + } + }, + "FqdnConfigResponse": { + "type": "object", + "required": [ + "task_id", + "target", + "status" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the FQDN configuration task", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "target": { + "type": "string", + "description": "Normalized FQDN target submitted to the configuration script", + "example": "https://f5insights.example.com" + }, + "status": { + "type": "string", + "enum": [ + "submitted" + ], + "description": "Initial status of the task", + "example": "submitted" + } + } + }, + "IPPoolListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IPPool" + } + }, + "totalItems": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "items", + "totalItems" + ] + }, + "ImageType": { + "type": "string", + "enum": [ + "FULL_ISO", + "FULL_VE", + "HOTFIX" + ], + "default": "FULL_ISO" + }, + "HAPhaseStep": { + "type": "object", + "description": "One coordination phase in a pair's timeline, classified against the\nlive cursor using the same vocabulary as the per-device step timeline\n(COMPLETED / RUNNING / FAILED / PENDING), plus PAUSED for an AWAIT gate\nthe coordinator is currently holding for HITL confirmation.\n", + "required": [ + "phase", + "status" + ], + "properties": { + "phase": { + "$ref": "#/components/schemas/HAPhase", + "description": "Which coordination phase this entry represents." + }, + "status": { + "$ref": "#/components/schemas/InstallStepStatus", + "description": "Lifecycle status of this phase against the live cursor. PAUSED is\nadditionally used for an AWAIT gate the coordinator is holding on.\n" + }, + "sequence": { + "type": "integer", + "description": "0-based position of this phase within the pair's IN-PLAN timeline,\nmirroring InstallStepDetail.sequence on the per-device step timeline.\nLets the UI render phases in coordinator order without hardcoding the\nHAPhase ordering. Because disabled HITL gates are omitted from the\nplan, sequence is contiguous over the phases actually present (it is\nNOT the device's position in the full HAPhase enum).\n" + } + } + }, + "APIError": { + "type": "object", + "required": [ + "code", + "status", + "message" + ], + "properties": { + "code": { + "type": "string", + "description": "Error code (SYSTEM-XXXX format)", + "example": "SYSTEM-0002" + }, + "status": { + "type": "integer", + "description": "HTTP status code", + "example": 409 + }, + "message": { + "type": "string", + "description": "Human-readable error message", + "example": "An upgrade is already in progress" + }, + "help": { + "type": "string", + "description": "Guidance for resolving the error", + "example": "Wait for the current upgrade to complete or check status at /api/system/upgrade/status" + } + } + }, + "SuccessResponse": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "ValidationTriggerRequest": { + "type": "object", + "description": "Request body for POST /validate.\nThe caller provides the list of device targets to validate and the target image UUID.\nNo job needs to exist \u2014 this is a pre-job eligibility check.\n", + "required": [ + "device_targets", + "image_id" + ], + "properties": { + "device_targets": { + "type": "array", + "description": "List of device targets (with optional per-device volume_override) to validate against the target image.", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/ValidationDeviceTarget" + } + }, + "image_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the target software image to validate against." + }, + "volume_strategy": { + "$ref": "#/components/schemas/VolumeStrategy", + "description": "Volume selection strategy applied to all devices in this validation request.\nA per-device volume_override (explicit slot name, e.g. \"HD1.2\") takes precedence\nover this field for that device. Defaults to NEXT_SEQUENTIAL_NEW when omitted.\n" + }, + "install_config": { + "type": "boolean", + "default": true, + "description": "Controls config carry-forward (BIG-IP cpcfg) for all devices in this\nvalidation request. Mirrors SoftwareInstallationConfig.installConfig.\nWhen true (or omitted), the install_config readiness check warns if the\ntarget version is older than the active version (a downgrade causes cpcfg\nto skip config copy). When false, the install_config check is skipped.\n" + } + } + }, + "AddTrustStoreRequest": { + "type": "object", + "required": [ + "name", + "certificate_content" + ], + "properties": { + "name": { + "type": "string", + "maxLength": 255, + "description": "Name of the certificate" + }, + "description": { + "type": "string", + "description": "Description of the certificate" + }, + "certificate_content": { + "type": "string", + "description": "PEM encoded certificate content" + } + } + }, + "HostLicenseDetails": { + "type": "object", + "description": "Detailed information about the host license", + "properties": { + "licenseId": { + "type": "string", + "description": "Unique license identifier", + "example": "LIC-12345-ABCDE" + }, + "subscriptionType": { + "type": "string", + "description": "Subscription type", + "example": "trial" + }, + "orderType": { + "type": "string", + "description": "Order type", + "example": "subscription" + }, + "expiryDate": { + "type": "string", + "format": "date-time", + "description": "License expiry date", + "example": "2026-11-29T00:00:32Z" + }, + "isActive": { + "type": "boolean", + "description": "Whether the license is currently active", + "example": true + } + } + }, + "CloudProvider": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier of the cloud provider" + }, + "providerType": { + "type": "string", + "enum": [ + "VMware" + ], + "description": "Type of cloud provider" + }, + "name": { + "type": "string", + "description": "Name of the cloud provider" + }, + "vmwProperties": { + "$ref": "#/components/schemas/VMwareProviderProperties" + }, + "selfLink": { + "type": "string", + "format": "uri", + "description": "Self-referencing link to the cloud provider" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the provider was created" + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the provider was last updated" + } + } + }, + "FqdnConfigRequest": { + "type": "object", + "required": [ + "target" + ], + "properties": { + "target": { + "type": "string", + "description": "External FQDN target. May include https scheme and port.", + "example": "f5insights.example.com" + } + } + }, + "DeviceTemplateListResponse": { + "type": "object", + "description": "Paginated list response for device templates.", + "required": [ + "status", + "count", + "items", + "selfLink" + ], + "properties": { + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 200 + }, + "count": { + "type": "integer", + "description": "Number of items in the current response.", + "example": 2 + }, + "totalItems": { + "type": "integer", + "description": "Total matching records. Only present when `$count=true`.", + "example": 2 + }, + "items": { + "type": "array", + "description": "Array of device template resources.", + "items": { + "$ref": "#/components/schemas/DeviceTemplate" + } + }, + "selfLink": { + "type": "string", + "description": "URI path to this list resource.", + "example": "/api/device-templates" + } + } + }, + "ApplyUpgradeRequest": { + "type": "object", + "required": [ + "version", + "kind" + ], + "properties": { + "version": { + "type": "string", + "description": "Target version to upgrade to", + "example": "3.2.1" + }, + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "description": "Upgrade kind to apply", + "example": "patch" + }, + "skip_backup": { + "type": "boolean", + "default": false, + "example": false + }, + "backup_passphrase": { + "type": "string", + "format": "password", + "description": "Required when skip_backup is false. Used only to create the pre-upgrade backup and never persisted in plaintext.", + "example": "MyStr0ng!Pass" + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ], + "description": "Required when skip_backup is false. Determines whether the pre-upgrade backup captures all components or config-only.", + "example": "full" + }, + "storage_target": { + "type": "string", + "description": "Required when skip_backup is false. Use \"local\" for local appliance storage or a configured storage target name.", + "example": "local" + }, + "bypass_preflight_checks": { + "type": "boolean", + "default": false, + "description": "Explicit user override for failed preflight checks that have bypass_allowed=true. no_active_job, disk_space, and version_compatibility failures always block apply.", + "example": false + } + } + }, + "Tag": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "Tag name. Duplicate names and special characters are allowed." + }, + "value": { + "type": "string", + "nullable": true + } + }, + "required": [ + "name" + ] + }, + "InstallStepDetail": { + "type": "object", + "description": "One step in a device's installation timeline. The ORDERED list of steps\nis derived from the per-device FSM plan (identical for standalone and for\neach node of an HA pair) and enriched with live persisted runtime state\n(upgrade.activity_steps + the device's current step/progress). This lets\nthe UI render every step \u2014 those already DONE, the one IN PROGRESS, and\nthe upcoming/PENDING ones \u2014 on a single per-device timeline.\n\nStatus semantics:\n * COMPLETED \u2014 step ran and finished (carries startedAt/completedAt).\n * RUNNING \u2014 the device's current step (carries startedAt).\n * PENDING \u2014 planned but not yet reached (\"next/upcoming\"); no times.\n * FAILED \u2014 this step errored; carries errorCode/errorMessage.\n * CANCELLED \u2014 the device terminated (FAILED/CANCELLED) before reaching\n this planned step, so it will never run.\n * SKIPPED \u2014 intentionally omitted for this device's plan (rare on the\n per-device timeline since plan() already omits skipped steps).\n", + "required": [ + "step", + "status" + ], + "properties": { + "step": { + "allOf": [ + { + "$ref": "#/components/schemas/InstallStep" + } + ], + "description": "Which FSM step this row represents." + }, + "status": { + "$ref": "#/components/schemas/InstallStepStatus" + }, + "sequence": { + "type": "integer", + "description": "0-based position of this step within the device's plan." + }, + "startedAt": { + "type": "string", + "format": "date-time", + "description": "When the step entered RUNNING. Omitted for PENDING steps." + }, + "completedAt": { + "type": "string", + "format": "date-time", + "description": "When the step left RUNNING (COMPLETED/FAILED). Omitted otherwise." + }, + "durationMs": { + "type": "integer", + "format": "int64", + "description": "Step duration in milliseconds, when known." + }, + "retryCount": { + "type": "integer", + "description": "Number of retries recorded for this step." + }, + "errorCode": { + "type": "string", + "description": "Machine-readable error category, present on FAILED steps." + }, + "errorMessage": { + "type": "string", + "description": "Human-readable error detail, present on FAILED steps." + } + } + }, + "DistributionJobAggregate": { + "type": "object", + "description": "Per-device runtime status plus a roll-up summary for a software distribution job.", + "required": [ + "jobId", + "status", + "totalDevices", + "overallPercent", + "devices" + ], + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "description": "Roll-up job status derived from per-device states.", + "enum": [ + "RUNNING", + "COMPLETED", + "FAILED", + "CANCELLED" + ] + }, + "totalDevices": { + "type": "integer" + }, + "pending": { + "type": "integer" + }, + "transferring": { + "type": "integer" + }, + "verifying": { + "type": "integer" + }, + "completed": { + "type": "integer" + }, + "failed": { + "type": "integer" + }, + "cancelled": { + "type": "integer" + }, + "skipped": { + "type": "integer" + }, + "overallPercent": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Mean of per-device transferProgress." + }, + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PerDeviceDistributionStatus" + } + } + } + }, + "LicenseActivationRequest": { + "type": "object", + "required": [ + "jwt", + "modeOfOperation" + ], + "properties": { + "jwt": { + "type": "string", + "description": "JWT token for license activation", + "example": "your-jwt-token" + }, + "customId": { + "type": "string", + "description": "Optional custom identifier for the device" + }, + "modeOfOperation": { + "type": "string", + "description": "Mode of operation for license activation", + "enum": [ + "connected", + "disconnected" + ], + "example": "connected" + } + } + }, + "PatchStagingDeviceResponse": { + "type": "object", + "required": [ + "message", + "staging_device_id" + ], + "properties": { + "message": { + "type": "string", + "description": "Success message", + "example": "Staging device updated and committed successfully" + }, + "staging_device_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the staging device that was updated" + } + } + }, + "DevicePatchRequest": { + "type": "object", + "description": "Partial device update - only include fields you want to update.", + "properties": { + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string" + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "retention": { + "$ref": "#/components/schemas/Retention" + }, + "collection_interval": { + "type": "integer", + "minimum": 1 + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean" + }, + "ca": { + "type": "string", + "format": "uuid" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean" + }, + "cgnat": { + "type": "boolean" + }, + "dns": { + "type": "boolean" + }, + "dos": { + "type": "boolean" + }, + "firewall": { + "type": "boolean" + }, + "gtm": { + "type": "boolean" + }, + "profile_dos": { + "type": "boolean" + }, + "policy_api_protection": { + "type": "boolean" + }, + "policy_asm": { + "type": "boolean" + }, + "policy_firewall": { + "type": "boolean" + }, + "policy_ip_intelligence": { + "type": "boolean" + }, + "policy_nat": { + "type": "boolean" + } + } + } + } + }, + "FlightCheckDiffListResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FlightCheckDiff" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + } + }, + "Event": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "jobId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "source": { + "type": "string", + "description": "Component that generated the event (e.g. \"autoscale-engine\", \"user-api\")" + }, + "eventType": { + "type": "string", + "description": "Event classification (e.g. \"SCALE_OUT_TRIGGERED\", \"JOB_ACTIVATED\")" + }, + "message": { + "type": "string" + }, + "payload": { + "type": "object", + "additionalProperties": true + }, + "eventTime": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "correlationId": { + "type": "string", + "format": "uuid", + "description": "Links event to the Execution that caused it" + } + } + }, + "IPLeaseListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IPLease" + } + }, + "totalItems": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "items", + "totalItems" + ] + }, + "RollbackStateResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "object", + "required": [ + "available", + "prev_images" + ], + "properties": { + "available": { + "type": "boolean", + "example": true + }, + "prev_images": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "example": { + "backend": "f5-insight-patch/backend:3.19", + "system-manager": "f5-insight-patch/system-manager:3.19", + "frontend": "f5-insight-patch/frontend:3.19" + } + } + } + } + } + }, + "ValidationStatus": { + "type": "string", + "description": "Rolled-up validation status for a device or a job.", + "enum": [ + "PENDING", + "RUNNING", + "PASSED", + "WARNING", + "FAILED", + "ERROR" + ] + }, + "AllocationResponse": { + "type": "object", + "properties": { + "lease": { + "$ref": "#/components/schemas/IPLease" + }, + "poolId": { + "type": "string", + "format": "uuid" + }, + "allocationId": { + "type": "string" + } + }, + "required": [ + "lease", + "poolId", + "allocationId" + ] + }, + "DeviceTemplateError": { + "type": "object", + "description": "Error response returned by the Device Template API.", + "required": [ + "status", + "message" + ], + "properties": { + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 400 + }, + "message": { + "type": "string", + "description": "Short human-readable error summary.", + "example": "Bad Request \u2014 request validation failed" + }, + "details": { + "type": "string", + "description": "Detailed explanation of the error cause and suggested resolution.", + "nullable": true, + "example": "failed to create device template" + } + } + }, + "StagingCABundle": { + "type": "object", + "required": [ + "id", + "name", + "certificate_content" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the staging CA bundle", + "example": "660e8400-e29b-41d4-a716-446655440000" + }, + "name": { + "type": "string", + "description": "Name of the CA certificate", + "example": "Production Root CA" + }, + "description": { + "type": "string", + "nullable": true, + "description": "Description of the CA certificate", + "example": "Root CA for production environment" + }, + "certificate_content": { + "type": "string", + "description": "PEM-encoded certificate content", + "example": "-----BEGIN CERTIFICATE-----\nMIIDXTCCAkWgA...\n-----END CERTIFICATE-----" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp", + "example": "2026-01-30T10:00:00Z" + }, + "last_modified": { + "type": "string", + "format": "date-time", + "description": "Last modification timestamp", + "example": "2026-01-30T12:00:00Z" + } + } + }, + "ReleaseRequest": { + "type": "object", + "description": "At least one criterion must be supplied (allocationId, address, or leaseTags). When leaseTags are used as a release filter, each tag must include a non-empty name and value.", + "properties": { + "allocationId": { + "type": "string", + "nullable": true + }, + "address": { + "type": "string", + "nullable": true, + "example": "10.0.0.10" + }, + "leaseTags": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Tag" + } + } + }, + "anyOf": [ + { + "required": [ + "allocationId" + ] + }, + { + "required": [ + "address" + ] + }, + { + "required": [ + "leaseTags" + ] + } + ] + }, + "CreateStorageTargetRequest": { + "type": "object", + "required": [ + "name", + "storage_type" + ], + "properties": { + "name": { + "type": "string" + }, + "storage_type": { + "type": "string", + "enum": [ + "nfs", + "smb" + ] + }, + "server": { + "type": "string" + }, + "share_path": { + "type": "string" + }, + "mount_options": { + "type": "string" + }, + "username": { + "type": "string" + }, + "password": { + "type": "string", + "description": "SMB password (stored securely in Vault, never in DB)" + } + } + }, + "PerDeviceInstallStatus": { + "type": "object", + "description": "Runtime status of one device within a software installation job execution.\nThis is the per-device row returned under\ninstanceProgress.devices[] on the single-execution GET\n(GET /jobs/software-installation/{jobId}/executions/{executionId}).\nFor an HA pair, each node appears as its own row here.\n", + "required": [ + "deviceId", + "status" + ], + "properties": { + "deviceId": { + "type": "string", + "format": "uuid" + }, + "deviceName": { + "type": "string", + "description": "Display name resolved from `upgrade.device_upgrade_metadata.device_name`\n(mirrored from `public.devices.device_name` for BIG-IP and\n`public.f5os_providers.name` for F5OS). Empty when the metadata row\nis missing or has no name \u2014 clients should fall back to `deviceId`\nfor display.\n" + }, + "deviceKind": { + "$ref": "#/components/schemas/DeviceKind" + }, + "haRole": { + "type": "string", + "description": "HA role resolved from `upgrade.device_upgrade_metadata.ha_state`\nfor this device within the execution rollup. Omitted when the\ndevice has no metadata row or no HA role is known.\n", + "enum": [ + "ACTIVE", + "STANDBY", + "STANDALONE", + "UNKNOWN" + ] + }, + "haPeerId": { + "type": "string", + "format": "uuid", + "description": "Peer device identifier resolved from\n`upgrade.device_upgrade_metadata.ha_peer_device_id`. Omitted for\nstandalone devices or when the peer is not onboarded / unknown.\n" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "COMPLETED", + "FAILED", + "CANCELLED" + ] + }, + "currentStep": { + "allOf": [ + { + "$ref": "#/components/schemas/InstallStep" + } + ], + "description": "Current step of this device's installation FSM. For an HA pair this is\nthe per-node step; pair-level coordination phases (failover/failback/\ncross-node gates) are not reflected here.\n" + }, + "steps": { + "type": "array", + "description": "Ordered per-device step timeline. Derived from the device's FSM plan\n(plan() \u2014 identical for standalone and for each node of an HA pair)\nand enriched with live persisted runtime state (upgrade.activity_steps\n+ the device's current step/progress). Each entry carries the step\nname plus its own status (COMPLETED / RUNNING / PENDING / FAILED /\nCANCELLED) so the UI can render the DONE steps, the IN-PROGRESS step,\nand the upcoming/PENDING steps on a single timeline. Populated only on\nthe single-execution GET; may be empty before the device's plan is\nknown.\n", + "items": { + "$ref": "#/components/schemas/InstallStepDetail" + } + }, + "retryCount": { + "type": "integer" + }, + "progressPct": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Live install-monitoring percentage (0\u2013100) for this device within\n*this* execution (ARGUSTELEM-5223). Read back from\nupgrade.installation_device_state.progress_pct, written by the install\nengine as the per-device install advances. Defaults to 0 when the\ndevice has no progress row yet (PENDING, before install starts), so\nclients can always render a progress bar. For an HA pair, each node\nreports its own percentage.\n" + }, + "lastError": { + "type": "string" + }, + "startedAt": { + "type": "string", + "format": "date-time" + }, + "completedAt": { + "type": "string", + "format": "date-time" + }, + "preSnapshotUrl": { + "type": "string", + "description": "API back-link to the PRE-install flight-check snapshot captured for\nthis device during *this* execution. The snapshot ID is embedded in\nthe URL (GET /flight-checks/snapshots/{snapshotId}). Omitted when no\nPRE snapshot was captured.\n" + }, + "postSnapshotUrl": { + "type": "string", + "description": "API back-link to the POST-install flight-check snapshot captured for\nthis device during *this* execution. The snapshot ID is embedded in\nthe URL (GET /flight-checks/snapshots/{snapshotId}). Omitted when no\nPOST snapshot was captured.\n" + }, + "diffUrl": { + "type": "string", + "description": "API back-link to the PRE-vs-POST flight-check diff\n(GET /flight-checks/diffs/{diffId}). Omitted when no diff was computed.\n" + }, + "readinessWarnings": { + "type": "array", + "description": "Post-upgrade readiness warning findings roll-up computed at POST_FLIGHT\n(F5OS devices only). Omitted when none or non-F5OS device.\n", + "items": { + "$ref": "#/components/schemas/ReadinessWarning" + } + } + } + }, + "BatchStatus": { + "type": "object", + "description": "Per-batch execution summary.", + "properties": { + "batchNumber": { + "type": "integer", + "description": "Batch sequence number (1-based)." + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "COMPLETED", + "FAILED", + "CANCELLED" + ] + }, + "currentStep": { + "allOf": [ + { + "$ref": "#/components/schemas/InstallStep" + } + ], + "description": "Current pipeline step for this batch." + }, + "deviceIds": { + "type": "array", + "description": "IDs of devices in this batch.", + "items": { + "type": "string", + "format": "uuid" + } + }, + "startedAt": { + "type": "string", + "format": "date-time" + }, + "endedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "BackupJob": { + "type": "object", + "required": [ + "id", + "operation", + "backup_type", + "status" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string", + "description": "User-given or auto-generated backup name" + }, + "operation": { + "type": "string", + "enum": [ + "backup", + "restore" + ] + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ] + }, + "status": { + "type": "string", + "enum": [ + "pending", + "running", + "completed", + "failed", + "uploaded", + "imported" + ] + }, + "phase": { + "type": "string", + "description": "Current phase of the operation" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Progress percentage" + }, + "message": { + "type": "string", + "description": "Human-readable status message" + }, + "file_name": { + "type": "string" + }, + "file_size": { + "type": "integer", + "format": "int64" + }, + "storage_target_id": { + "type": "string", + "format": "uuid", + "description": "ID of the storage target where the backup is stored (null for local)" + }, + "storage_target_name": { + "type": "string", + "description": "Name of the storage target where the backup is stored" + }, + "encrypted": { + "type": "boolean" + }, + "error_message": { + "type": "string" + }, + "started_at": { + "type": "string", + "format": "date-time" + }, + "completed_at": { + "type": "string", + "format": "date-time" + }, + "created_at": { + "type": "string", + "format": "date-time" + } + } + }, + "LicenseDeactivationResponse": { + "type": "object", + "required": [ + "status", + "message" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "Deactivation status", + "example": "success" + }, + "message": { + "type": "string", + "description": "Deactivation result message", + "example": "License deactivated successfully" + }, + "digitalAssetId": { + "type": "string", + "description": "Digital asset ID" + }, + "licenseStatus": { + "type": "string", + "description": "License status", + "example": "Terminated" + }, + "deactivatedAt": { + "type": "string", + "format": "date-time", + "description": "Deactivation timestamp" + } + } + }, + "JobLogEntry": { + "type": "object", + "required": [ + "ts", + "level", + "message" + ], + "properties": { + "ts": { + "type": "string", + "format": "date-time" + }, + "level": { + "type": "string", + "enum": [ + "info", + "success", + "warn", + "error" + ], + "example": "info" + }, + "message": { + "type": "string", + "example": "Starting patch job for f5-insight-patch-3.20" + } + } + }, + "DiskAnalysisBatchSummary": { + "type": "object", + "required": [ + "sufficient_count", + "insufficient_count" + ], + "properties": { + "sufficient_count": { + "type": "integer", + "minimum": 0 + }, + "insufficient_count": { + "type": "integer", + "minimum": 0 + } + } + }, + "ReadinessCheckResult": { + "type": "object", + "description": "Outcome of a single readiness check for a device.", + "required": [ + "check_name", + "severity", + "status" + ], + "properties": { + "check_name": { + "type": "string", + "description": "Name of the check (e.g. \"base_image_pre_distribution\", \"disk_space\")." + }, + "severity": { + "type": "string", + "enum": [ + "SOFT", + "HARD" + ] + }, + "status": { + "type": "string", + "enum": [ + "PASS", + "WARN", + "FAIL", + "SKIP" + ] + }, + "message": { + "type": "string", + "description": "Human-readable explanation." + }, + "detail": { + "description": "Structured extra data relevant to the check outcome." + } + } + }, + "ScheduledUpgradeEntry": { + "type": "object", + "required": [ + "id", + "version", + "scheduled_at", + "skip_backup", + "status" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "example": "770e8400-e29b-41d4-a716-446655440010" + }, + "version": { + "type": "string", + "example": "f5-insight-patch-3.20" + }, + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "example": "patch" + }, + "scheduled_at": { + "type": "string", + "format": "date-time", + "example": "2026-05-12T02:00:00Z" + }, + "skip_backup": { + "type": "boolean", + "example": false + }, + "status": { + "type": "string", + "enum": [ + "pending", + "triggered", + "done", + "failed", + "cancelled" + ], + "example": "pending" + }, + "upgrade_job_id": { + "type": "string", + "format": "uuid", + "description": "Created upgrade_history job ID after the schedule fires" + } + } + }, + "AIDFConfigResponse": { + "type": "object", + "properties": { + "endpoint": { + "type": "string" + }, + "tenant_id": { + "type": "string" + }, + "data_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "logs", + "metrics" + ] + }, + "description": "Data types being sent to AIDF" + } + } + }, + "TestStorageTargetRequest": { + "type": "object", + "description": "Ad-hoc connectivity test for a storage target that has not been saved.\nNo name is required because nothing is persisted.\n", + "required": [ + "storage_type" + ], + "properties": { + "storage_type": { + "type": "string", + "enum": [ + "local", + "nfs", + "smb" + ] + }, + "server": { + "type": "string" + }, + "share_path": { + "type": "string" + }, + "mount_options": { + "type": "string" + }, + "username": { + "type": "string" + }, + "password": { + "type": "string", + "description": "SMB password (used only for the test, never persisted)" + } + } + }, + "UserAccount": { + "type": "object", + "description": "A BIG-IP user account definition with required credentials and role assignment.", + "required": [ + "username", + "password", + "role" + ], + "properties": { + "username": { + "type": "string", + "description": "Username for the BIG-IP account. Must start with a letter or underscore,\nand contain only letters, digits, hyphens, dots, or underscores.\n", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z_][-a-zA-Z_.0-9]*$", + "example": "admin" + }, + "password": { + "type": "string", + "description": "Password for the BIG-IP account. Must be at least 8 characters.", + "minLength": 8, + "maxLength": 255, + "example": "adminP@ss!" + }, + "role": { + "type": "string", + "description": "User role on the BIG-IP device. Defines the access level and permissions\nfor the user account. Common roles include 'admin', 'operator', 'guest', etc.\n", + "minLength": 1, + "maxLength": 255, + "example": "admin" + }, + "shell": { + "type": "string", + "description": "Shell access level for the user (e.g., 'bash', 'tmsh', 'none').", + "example": "bash" + } + } + }, + "LicenseState": { + "type": "object", + "description": "Parsed license state information from the F5 license server", + "properties": { + "usage": { + "type": "string", + "description": "License usage description", + "example": "F5 Internal Product Development" + }, + "vendor": { + "type": "string", + "description": "License vendor", + "example": "F5 Networks, Inc." + }, + "dossier": { + "type": "string", + "description": "Dossier string used for license activation", + "example": "1a6806020f683204a3bbb8f3b0cf93c8f61be328908e76b0a570d2b992b0fb300e0c" + }, + "authVers": { + "type": "string", + "description": "Authorization version", + "example": "5b" + }, + "generation": { + "type": "integer", + "description": "License generation number", + "example": 0 + }, + "platformId": { + "type": "string", + "description": "Platform identifier", + "example": "Z100" + }, + "skipLicense": { + "type": "boolean", + "description": "Whether to skip license check", + "example": false + }, + "featureFlags": { + "type": "array", + "description": "List of licensed feature flags", + "items": { + "$ref": "#/components/schemas/FeatureFlag" + } + }, + "activeModules": { + "type": "array", + "description": "List of active licensed modules", + "items": { + "type": "string" + }, + "example": [ + "BIG-IP, LAB (LTM,APM,ASM,AM, GTM), VE|D826541-4208201|IPV6 Gateway|Rate Shaping", + "CGN, VE (LAB)|T172156-2328256|Routing Bundle, VE", + "DNSSEC|M275558-6506420" + ] + }, + "authorization": { + "type": "string", + "description": "License authorization signature" + }, + "serviceStatus": { + "type": "string", + "description": "Current service contract status", + "example": "As of 2026-05-14 there is no active service contract." + }, + "licensedVersion": { + "type": "string", + "description": "Licensed software version", + "example": "8.4.1" + }, + "optionalModules": { + "type": "array", + "description": "List of optional modules available for licensing", + "items": { + "type": "string" + }, + "example": [ + "App Mode (TMSH Only, No Root/Bash)", + "BIG-IP VE, Multicast Routing", + "PEM, VE", + "Routing Bundle, VE" + ] + }, + "registrationKey": { + "type": "string", + "description": "Registration key associated with this license", + "example": "W5778-33088-84412-26046-5913991" + }, + "lastUpdateMicros": { + "type": "integer", + "format": "int64", + "description": "Last update timestamp in microseconds", + "example": 0 + }, + "licensedDateTime": { + "type": "string", + "format": "date-time", + "description": "Date and time when license was issued" + }, + "exclusivePlatform": { + "type": "array", + "description": "List of exclusive platform identifiers", + "items": { + "type": "string" + }, + "example": [ + "Z100", + "Z100A", + "Z100H", + "Z100K", + "Z100x" + ] + }, + "licenseEndDateTime": { + "type": "string", + "format": "date-time", + "description": "License end date and time" + }, + "licenseStartDateTime": { + "type": "string", + "format": "date-time", + "description": "License start date and time" + }, + "serviceCheckDateTime": { + "type": "string", + "format": "date-time", + "description": "Service check date and time" + }, + "evaluationEndDateTime": { + "type": "string", + "format": "date-time", + "description": "Evaluation period end date and time" + }, + "evaluationStartDateTime": { + "type": "string", + "format": "date-time", + "description": "Evaluation period start date and time" + } + } + }, + "BackupJobResponse": { + "type": "object", + "required": [ + "success", + "data" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "$ref": "#/components/schemas/BackupJob" + } + } + }, + "ValidationTriggeredResponse": { + "type": "object", + "description": "Response body returned by POST /validate (202 Accepted).", + "required": [ + "validation_run_id", + "message" + ], + "properties": { + "validation_run_id": { + "type": "string", + "format": "uuid", + "description": "Unique ID for this validation run. Use with GET /validate/{validationRunId} to poll results." + }, + "message": { + "type": "string", + "example": "validation triggered" + } + } + }, + "DeviceTemplateDeleteResponse": { + "type": "object", + "description": "Response returned after deleting a device template.", + "required": [ + "id", + "status", + "deletedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "UUID of the deleted device template.", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 200 + }, + "deletedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp (UTC) when the template was deleted.", + "example": "2026-04-10T16:00:00Z" + } + } + }, + "FlightCheckDiffEntry": { + "type": "object", + "description": "Structured PRE-vs-POST comparison for a single core check.", + "properties": { + "check": { + "type": "string", + "description": "Core check key (e.g. virtualServerState)." + }, + "outcome": { + "type": "string", + "description": "Result of comparing the PRE and POST values for this check.", + "enum": [ + "SAME", + "IMPROVED", + "DEGRADED", + "CHANGED", + "MISSING_DATA" + ] + }, + "before": { + "type": "object", + "additionalProperties": true, + "description": "Relevant PRE-phase status summary." + }, + "after": { + "type": "object", + "additionalProperties": true, + "description": "Relevant POST-phase status summary." + }, + "details": { + "type": "string", + "description": "Human-readable explanation of the difference." + } + } + }, + "SoftwareInstallationJobSummary": { + "type": "object", + "description": "Lightweight software installation job summary for list responses.", + "required": [ + "id", + "name", + "status", + "enabled", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "workflowId": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/UpgradeJobStatus" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether this job is enabled." + }, + "installationType": { + "$ref": "#/components/schemas/InstallationType", + "description": "STANDALONE or HA." + }, + "batchSize": { + "type": "integer", + "description": "Configured batch size (1=serial, >1=batch)." + }, + "deviceCount": { + "type": "integer", + "description": "Number of target devices in this job." + }, + "createdBy": { + "type": "string", + "nullable": true, + "description": "Username of the operator who created the job. Absent when the X-Username header was not present at creation time." + }, + "modifiedBy": { + "type": "string", + "nullable": true, + "description": "Username of the operator who last modified the job. Absent when no modification has been made with an identified actor." + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "DeviceInstallState": { + "type": "object", + "description": "Per-device installation tracking. Populated once the device's batch starts execution.\nOnly present on software installation jobs.\n", + "properties": { + "deviceId": { + "type": "string", + "format": "uuid" + }, + "device_name": { + "type": "string" + }, + "currentVersion": { + "type": "string", + "description": "Software version on the device before the upgrade." + }, + "targetVersion": { + "type": "string", + "description": "Software version being installed." + }, + "plannedVolume": { + "type": "string", + "description": "The boot volume selected for installation (e.g. \"HD1.2\")." + }, + "haRole": { + "type": "string", + "description": "HA role for this device (populated for HA installationType jobs).\nNOTE: an HA pair surfaces as TWO independent per-node entries here \u2014\none per node \u2014 each carrying its own currentStep. Pair-level\ncoordination phases (failover/failback/cross-node gates) are tracked\non a separate pair cursor and are NOT reflected in currentStep.\n", + "enum": [ + "ACTIVE", + "STANDBY" + ] + }, + "currentStep": { + "allOf": [ + { + "$ref": "#/components/schemas/InstallStep" + } + ], + "description": "Current step of this device's installation FSM (same value the\nexecution endpoint reports under instanceProgress.devices[].currentStep).\n" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "COMPLETED", + "FAILED", + "CANCELLED" + ] + }, + "errorMessage": { + "type": "string", + "description": "Error detail if the device installation failed." + }, + "errorCategory": { + "type": "string", + "description": "Category of failure for diagnostics.", + "enum": [ + "CONNECTIVITY", + "CREDENTIAL", + "COMPATIBILITY", + "DISK_SPACE", + "IMAGE_VERIFY", + "INSTALL", + "REBOOT", + "POST_FLIGHT", + "FAILOVER", + "FAILBACK" + ] + }, + "preSnapshotUrl": { + "type": "string", + "description": "Back-link to this device's PRE flight-check snapshot for this job. Null\nuntil captured. Resolves via\nGET /api/v1/fleet/upgrade/flight-checks/snapshots/{snapshotId}.\n" + }, + "postSnapshotUrl": { + "type": "string", + "description": "Back-link to this device's POST flight-check snapshot for this job. Null\nuntil captured. Resolves via\nGET /api/v1/fleet/upgrade/flight-checks/snapshots/{snapshotId}.\n" + }, + "diffUrl": { + "type": "string", + "description": "Back-link to this device's PRE-vs-POST flight-check diff for this job. Null\nuntil both snapshots exist. Resolves via\nGET /api/v1/fleet/upgrade/flight-checks/diffs/{diffId}.\n" + }, + "startedAt": { + "type": "string", + "format": "date-time" + }, + "completedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "DiskAnalysisTaskStatus": { + "type": "string", + "enum": [ + "QUEUED", + "RUNNING", + "COMPLETED", + "FAILED", + "CANCELLED" + ] + }, + "LicenseHealthResponse": { + "type": "object", + "required": [ + "status", + "license", + "storage" + ], + "properties": { + "status": { + "$ref": "#/components/schemas/ServiceStatus" + }, + "license": { + "$ref": "#/components/schemas/LicenseInfo" + }, + "storage": { + "$ref": "#/components/schemas/StorageInfo" + } + } + }, + "SelfIpDefinition": { + "type": "object", + "description": "A self-IP definition for the BIG-IP device.\n\nSelf IPs are allocated from an IP pool specified by `ipPoolReference`.\n", + "required": [ + "name", + "vlanName", + "ipPoolReference" + ], + "properties": { + "name": { + "type": "string", + "description": "Self-IP name. Must be unique within the template.", + "example": "external-self" + }, + "ipPoolReference": { + "type": "string", + "format": "uuid", + "description": "UUID referencing an existing IP pool for self-IP allocation.\n", + "example": "c3d4e5f6-a7b8-4890-8bcd-ef1234567892" + }, + "vlanName": { + "type": "string", + "description": "Name of the VLAN this self-IP is associated with.", + "example": "external" + }, + "portLockdown": { + "type": "string", + "description": "Port lockdown mode.", + "enum": [ + "none", + "default", + "all", + "custom", + "custom-default" + ], + "default": "none", + "example": "default" + }, + "allowServices": { + "type": "array", + "description": "Allowed services when portLockdown is custom/custom-default.", + "nullable": true, + "items": { + "type": "string" + }, + "example": null + } + } + }, + "StorageTestResponse": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + }, + "message": { + "type": "string" + }, + "latency": { + "type": "string" + } + } + } + } + }, + "AddressRange": { + "type": "object", + "properties": { + "firstAddress": { + "type": "string", + "example": "10.0.0.10" + }, + "lastAddress": { + "type": "string", + "example": "10.0.0.100" + } + }, + "required": [ + "firstAddress", + "lastAddress" + ] + }, + "BgpRedistribution": { + "type": "object", + "description": "A routing protocol redistribution entry for a BGP address family.", + "required": [ + "routingProtocol" + ], + "properties": { + "routingProtocol": { + "type": "string", + "description": "The routing protocol to redistribute into BGP (e.g. `connected`, `kernel`).\nThe accepted values depend on the BIG-IP version and configuration.\n", + "example": "connected" + } + } + }, + "ExecutionListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Execution" + } + }, + "total": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "limit": { + "type": "integer" + } + } + }, + "F5OSDevice": { + "type": "object", + "required": [ + "endpoint", + "username", + "password", + "data_center", + "tls_enabled" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the F5OS provider (response only)." + }, + "alias_name": { + "type": "string", + "maxLength": 255, + "description": "Unique, user-supplied label for the device." + }, + "type": { + "type": "string", + "enum": [ + "RSERIES" + ], + "default": "RSERIES", + "description": "F5OS platform type." + }, + "endpoint": { + "type": "string", + "description": "Device endpoint URL with scheme, host and port (e.g. https://10.1.1.5:443)." + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255, + "description": "Data center the device belongs to." + }, + "tls_enabled": { + "type": "boolean", + "description": "When true, the server certificate is verified against `ca`. When false, TLS verification is skipped." + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from the trust store. Required when `tls_enabled` is true." + }, + "cert_fingerprint": { + "type": "string", + "description": "Optional SHA-256 certificate fingerprint pin. When set, the server certificate must match this fingerprint." + } + } + }, + "VlanDefinition": { + "type": "object", + "description": "A VLAN definition.", + "required": [ + "name", + "nic" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "example": "external" + }, + "nic": { + "type": "string", + "description": "Network interface card identifier (e.g., \"1.1\", \"1.2\").", + "pattern": "^[0-9]+\\.[0-9]+$", + "example": "1.1" + }, + "mtu": { + "type": "integer", + "description": "Maximum transmission unit size in bytes.", + "minimum": 576, + "maximum": 9198, + "example": 1500 + }, + "tag": { + "type": "integer", + "description": "VLAN tag identifier.", + "minimum": 1, + "maximum": 4094, + "example": 100 + } + } + }, + "BgpAddressFamily": { + "type": "object", + "description": "An address family configuration for BGP.\nDefines the internet protocol and the list of routing protocols\nto redistribute into BGP for that address family.\nOnly `ipv4` is currently supported for `internetProtocol`.\n", + "required": [ + "internetProtocol", + "redistributionList" + ], + "properties": { + "internetProtocol": { + "type": "string", + "description": "The internet protocol for this address family.\nCurrently only `ipv4` is supported.\n", + "example": "ipv4" + }, + "redistributionList": { + "type": "array", + "description": "List of routing protocols to redistribute into BGP for this address family.\nIf omitted or empty, no redistribution is configured.\n", + "items": { + "$ref": "#/components/schemas/BgpRedistribution" + }, + "example": [ + { + "routingProtocol": "connected" + }, + { + "routingProtocol": "kernel" + } + ] + } + } + }, + "UploadInfoResponse": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "object", + "properties": { + "available": { + "type": "boolean", + "description": "Whether a bundle is available for upgrade", + "example": true + }, + "name": { + "type": "string", + "description": "Bundle filename", + "example": "f5insight-1.1.0-11-bundle.tar.gz" + }, + "version": { + "type": "string", + "description": "Bundle version from uploaded bundle metadata or manifest", + "example": "1.1.0-11" + }, + "size": { + "type": "integer", + "format": "int64", + "description": "Bundle file size in bytes", + "example": 1073741824 + }, + "message": { + "type": "string", + "example": "Bundle ready for upgrade" + } + } + } + } + }, + "AllocationRequest": { + "type": "object", + "properties": { + "allocationId": { + "type": "string", + "description": "Identifier used to make allocation idempotent." + }, + "leaseTags": { + "type": "array", + "description": "Optional labels applied to the resulting lease.", + "items": { + "$ref": "#/components/schemas/Tag" + } + } + }, + "required": [ + "allocationId" + ] + }, + "UpgradeJob": { + "type": "object", + "description": "Generic job response returned by lifecycle action endpoints\n(/activate, /pause, /resume, /cancel). Contains the job id, status, and type\nso the caller can fetch full details from the appropriate typed endpoint.\n", + "required": [ + "id", + "jobType", + "status" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique job identifier." + }, + "workflowId": { + "type": "string", + "format": "uuid", + "description": "Parent workflow entity ID." + }, + "name": { + "type": "string" + }, + "jobType": { + "type": "string", + "description": "Identifies whether this is a software distribution or software installation job.", + "enum": [ + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION" + ] + }, + "status": { + "$ref": "#/components/schemas/UpgradeJobStatus" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "AuditEventsResponse": { + "type": "object", + "required": [ + "events", + "pagination" + ], + "properties": { + "events": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AuditEvent" + }, + "nullable": true, + "description": "Array of audit events for the requested page. Null if storage is empty." + }, + "pagination": { + "$ref": "#/components/schemas/AuditPagination" + } + } + }, + "SoftwareDistributionConfig": { + "type": "object", + "required": [ + "configType" + ], + "properties": { + "configType": { + "type": "string", + "enum": [ + "SOFTWARE_DISTRIBUTION" + ], + "description": "Config type discriminator" + } + } + }, + "InstallationType": { + "type": "string", + "description": "Controls which devices are targeted and how they are treated during upgrade.\nSerial (batchSize=1) or batch (batchSize>1) execution is determined by the batchSize field,\nnot by this enum.\n- STANDALONE: upgrade independent BIG-IP or F5OS devices\n- HA: upgrade HA pairs, maintaining HA continuity during the upgrade [E7 scope]\n", + "enum": [ + "STANDALONE", + "HA" + ] + }, + "LicensePool": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier of the license pool", + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + "name": { + "type": "string", + "description": "Name of the license pool", + "example": "test" + }, + "description": { + "type": "string", + "description": "Description of the license pool", + "example": "" + }, + "type": { + "type": "string", + "enum": [ + "Registration Key Pool" + ], + "description": "Type of license pool", + "example": "Registration Key Pool" + }, + "selfLink": { + "type": "string", + "format": "uri", + "description": "Self-referencing link to the license pool", + "example": "https://localhost/api/licensing/pool/regkey/licenses/7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the pool was created" + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the pool was last updated" + } + } + }, + "UpdateDeviceResponse": { + "type": "object", + "required": [ + "message", + "id" + ], + "properties": { + "message": { + "type": "string", + "description": "Success message", + "example": "Device updated successfully" + }, + "id": { + "type": "string", + "description": "Identifier of the device that was updated" + } + } + }, + "NetworkInfo": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the network" + }, + "network": { + "type": "string", + "description": "Managed Object Reference (network ID)" + } + } + }, + "DeviceTemplateGetResponse": { + "description": "Response for GET by ID. Extends DeviceTemplate with a `status` field.", + "allOf": [ + { + "$ref": "#/components/schemas/DeviceTemplate" + }, + { + "type": "object", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 200 + } + } + } + ] + }, + "SoftwareInstallationExecutionRecord": { + "type": "object", + "description": "Software installation execution record. Field names + types match\nthe generic workflow Execution schema so the cross-feature UI can\nrender installation and distribution / autoscale executions with\nthe same panel.\n\nOn single-execution GET (`/executions/{executionId}`) the response\nadditionally embeds `instanceProgress` \u2014 the per-device runtime\nrollup scoped to this execution. The executions LIST endpoint\nstays lean and never populates that field.\n", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "jobId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "jobName": { + "type": "string", + "readOnly": true, + "description": "Parent software installation job name." + }, + "jobDescription": { + "type": "string", + "readOnly": true, + "description": "Parent software installation job description." + }, + "trigger": { + "type": "string", + "enum": [ + "USER", + "ALERT", + "SYSTEM", + "SCHEDULE" + ], + "readOnly": true + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "PAUSED", + "COMPLETED", + "FAILED", + "CANCELLED" + ], + "readOnly": true + }, + "reason": { + "type": "string", + "description": "Human-readable trigger reason" + }, + "startedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "completedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "durationMs": { + "type": "integer", + "readOnly": true + }, + "activityCount": { + "type": "integer", + "readOnly": true, + "description": "Number of activities (per-device rows) recorded under this execution" + }, + "retryCount": { + "type": "integer", + "readOnly": true + }, + "currentStep": { + "type": "string", + "readOnly": true + }, + "lastError": { + "type": "string", + "readOnly": true + }, + "changeRequest": { + "type": "string", + "nullable": true, + "maxLength": 255, + "description": "Optional change-request identifier supplied at activation time.\nNull when no change request was provided.\n", + "readOnly": true + }, + "correlationId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "createdBy": { + "type": "string", + "nullable": true, + "readOnly": true, + "description": "Username of the operator who created (activated) this execution." + }, + "modifiedBy": { + "type": "string", + "nullable": true, + "readOnly": true, + "description": "Username of the operator who last modified this execution." + }, + "instanceProgress": { + "$ref": "#/components/schemas/InstallInstanceProgress", + "description": "Per-device runtime rollup scoped to this execution. Populated\nonly on the single-execution GET; absent on the executions LIST.\n" + }, + "configSnapshot": { + "$ref": "#/components/schemas/SoftwareInstallationConfig", + "readOnly": true, + "description": "Immutable snapshot of the resolved SoftwareInstallationConfig\n(including per-device volume overrides) captured at activation\ntime. Lets clients inspect the exact config this execution ran\nwith, independent of any post-activation reset of the job config.\nPopulated only on the single-execution GET; absent on the\nexecutions LIST to keep that response lean.\n" + }, + "readinessWarnDeviceCount": { + "type": "integer", + "minimum": 0, + "readOnly": true, + "description": "Number of devices in this execution whose post-upgrade readiness\nroll-up contains at least one WARN finding and no CRITICAL finding.\nDevices are counted by highest severity, so a device with any\nCRITICAL finding is excluded from this WARN count.\n" + }, + "readinessCriticalDeviceCount": { + "type": "integer", + "minimum": 0, + "readOnly": true, + "description": "Number of devices in this execution whose post-upgrade readiness\nroll-up contains at least one CRITICAL finding.\n" + }, + "haCoordination": { + "$ref": "#/components/schemas/HACoordination", + "description": "Cross-node HA orchestration timeline for this execution. Surfaces\nthe pair-level coordinator phases (validate-pair, failover, the\nHITL gates, failback, ...) that belong to NEITHER node alone and\nso are not represented in any single device's per-step timeline.\nPopulated only on the single-execution GET, and only for\nHA-topology executions; absent for STANDALONE executions or when\nno pair cursor exists yet.\n" + } + } + }, + "DatacenterInfo": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the datacenter" + }, + "datacenter": { + "type": "string", + "description": "Managed Object Reference (datacenter ID)" + } + } + }, + "PostflightResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "object", + "required": [ + "checks" + ], + "properties": { + "checks": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PostflightCheck" + } + } + } + } + } + }, + "CloudEnvironment": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "providerReference": { + "$ref": "#/components/schemas/Reference" + }, + "deviceTemplateReference": { + "$ref": "#/components/schemas/Reference" + }, + "isVmwCluster": { + "type": "boolean" + }, + "vmwProperties": { + "$ref": "#/components/schemas/VMwareEnvironmentPropertiesResponse" + }, + "validationStatus": { + "type": "string", + "enum": [ + "PENDING", + "VALIDATED", + "FAILED" + ] + }, + "validationErrors": { + "type": "array", + "items": { + "type": "string" + } + }, + "selfLink": { + "type": "string", + "format": "uri" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "InstanceProgress": { + "type": "object", + "description": "Per-device runtime rollup scoped to a single execution. Same numeric\nshape as `DistributionJobAggregate` minus the job-level `jobId` /\n`status` fields, since the parent execution already carries that\nidentity.\n", + "required": [ + "totalDevices", + "overallPercent", + "devices" + ], + "properties": { + "totalDevices": { + "type": "integer" + }, + "pending": { + "type": "integer" + }, + "transferring": { + "type": "integer" + }, + "verifying": { + "type": "integer" + }, + "completed": { + "type": "integer" + }, + "failed": { + "type": "integer" + }, + "cancelled": { + "type": "integer" + }, + "skipped": { + "type": "integer" + }, + "overallPercent": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Mean of per-device transferProgress within this execution." + }, + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PerDeviceDistributionStatus" + } + } + } + }, + "SortByImages": { + "type": "string", + "enum": [ + "version" + ], + "description": "Field to sort images by" + }, + "JobCreateRequest": { + "type": "object", + "required": [ + "name", + "type", + "config" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "name": { + "type": "string" + }, + "description": { + "type": "string", + "description": "Optional human-readable job description" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "INACTIVE", + "ERROR", + "COMPLETED", + "FAILED", + "CANCELLED", + "DELETING" + ] + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether the job can be activated, paused, or resumed. Defaults to true when omitted." + }, + "config": { + "$ref": "#/components/schemas/JobConfig" + }, + "schedule": { + "$ref": "#/components/schemas/Schedule" + } + } + }, + "ScheduleUpgradeRequest": { + "type": "object", + "required": [ + "kind", + "version", + "scheduled_at" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "example": "patch" + }, + "version": { + "type": "string", + "example": "f5-insight-patch-3.20" + }, + "scheduled_at": { + "type": "string", + "format": "date-time", + "description": "Future UTC timestamp when the upgrade should run", + "example": "2026-05-12T02:00:00Z" + }, + "skip_backup": { + "type": "boolean", + "default": false, + "example": false + }, + "backup_passphrase": { + "type": "string", + "format": "password", + "description": "Required when skip_backup is false. Stored securely and used when the scheduled upgrade creates its pre-upgrade backup.", + "example": "MyStr0ng!Pass" + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ], + "description": "Required when skip_backup is false. Determines whether the scheduled pre-upgrade backup captures all components or config-only.", + "example": "full" + }, + "storage_target": { + "type": "string", + "description": "Required when skip_backup is false. Use \"local\" for local appliance storage or a configured storage target name.", + "example": "local" + }, + "bypass_preflight_checks": { + "type": "boolean", + "default": false, + "description": "Explicit user override for failed preflight checks that have bypass_allowed=true. no_active_job, disk_space, and version_compatibility failures always block scheduled apply." + } + } + }, + "DiskAnalysisTaskAcceptedResponse": { + "type": "object", + "required": [ + "task_id", + "status", + "created_at" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "status": { + "$ref": "#/components/schemas/DiskAnalysisTaskStatus" + }, + "created_at": { + "type": "string", + "format": "date-time" + } + } + }, + "ValidateAIDFRequest": { + "type": "object", + "required": [ + "endpoint", + "tenant_id", + "tenant_token" + ], + "properties": { + "endpoint": { + "type": "string" + }, + "tenant_id": { + "type": "string" + }, + "tenant_token": { + "type": "string" + } + } + }, + "LicenseEntitlementsResponse": { + "type": "object", + "required": [ + "entitlements" + ], + "properties": { + "entitlements": { + "type": "object", + "additionalProperties": true, + "description": "License entitlements data." + }, + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "Response status", + "example": "success" + } + } + }, + "AuditExportResponse": { + "type": "object", + "description": "Response from POST /audit/export. When status is `ready` (200), the file is available for immediate download. When status is `processing` (202), poll the `status_url` endpoint.\n", + "required": [ + "export_id", + "status" + ], + "properties": { + "export_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for this export job", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "status": { + "type": "string", + "enum": [ + "ready", + "processing" + ], + "description": "Current export status" + }, + "download_url": { + "type": "string", + "description": "URL to download the CSV (present for both ready and processing)", + "example": "/api/audit/export/3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "status_url": { + "type": "string", + "description": "URL to poll for status (present when status is processing)", + "example": "/api/audit/export/3fa85f64-5717-4562-b3fc-2c963f66afa6/status" + }, + "sha256": { + "type": "string", + "description": "SHA-256 hex digest of the CSV (present when status is ready)", + "example": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "row_count": { + "type": "integer", + "format": "int64", + "description": "Number of rows in the export", + "example": 42 + } + } + }, + "JobRuntime": { + "type": "object", + "description": "Live runtime state (populated for CONTINUOUS jobs)", + "properties": { + "currentSize": { + "type": "integer" + }, + "lastEvaluatedAt": { + "type": "string", + "format": "date-time" + }, + "lastExecutionId": { + "type": "string", + "format": "uuid" + }, + "lastExecutionStatus": { + "type": "string", + "enum": [ + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED", + "CANCELLED", + "TIMEOUT" + ] + } + } + }, + "Execution": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "jobId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "trigger": { + "type": "string", + "enum": [ + "USER", + "ALERT", + "SYSTEM", + "SCHEDULE" + ], + "readOnly": true + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED", + "CANCELLED", + "TIMEOUT" + ], + "readOnly": true + }, + "reason": { + "type": "string", + "description": "Human-readable trigger reason" + }, + "startedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "completedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "durationMs": { + "type": "integer", + "readOnly": true + }, + "activityCount": { + "type": "integer", + "readOnly": true, + "description": "Number of activities recorded under this execution" + }, + "retryCount": { + "type": "integer", + "readOnly": true + }, + "currentStep": { + "type": "string", + "readOnly": true + }, + "lastError": { + "type": "string", + "readOnly": true + }, + "correlationId": { + "type": "string", + "format": "uuid", + "readOnly": true + } + } + }, + "GlobalReleaseRequest": { + "type": "object", + "description": "Release IPs across all pools by allocation ID and optional lease tags. Allocation ID is required.", + "properties": { + "allocationId": { + "type": "string", + "description": "Identifier of the allocation to release. This field is required and used to search across all pools." + }, + "leaseTags": { + "type": "array", + "description": "Optional labels to further filter leases. When provided, all tags must match (AND logic) for a lease to be released.", + "items": { + "$ref": "#/components/schemas/Tag" + } + } + }, + "required": [ + "allocationId" + ] + }, + "InstallInstanceProgress": { + "type": "object", + "description": "Per-device runtime rollup scoped to a single installation execution.\nSame numeric shape as the distribution InstanceProgress but uses\ninstallation-specific per-device status values.\n", + "required": [ + "totalDevices", + "devices" + ], + "properties": { + "totalDevices": { + "type": "integer" + }, + "pending": { + "type": "integer" + }, + "running": { + "type": "integer" + }, + "completed": { + "type": "integer" + }, + "failed": { + "type": "integer" + }, + "cancelled": { + "type": "integer" + }, + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PerDeviceInstallStatus" + } + } + } + }, + "ScheduledTask": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "task_type": { + "type": "string" + }, + "cron_expression": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "last_run_at": { + "type": "string", + "format": "date-time" + }, + "last_status": { + "type": "string", + "enum": [ + "success", + "failed", + "skipped" + ] + }, + "next_run_at": { + "type": "string", + "format": "date-time" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "warning": { + "type": "string", + "description": "Non-blocking proximity warning. Set when this schedule's next run falls within a fixed window of another schedule's next run; omitted otherwise." + } + } + }, + "CompatUpgradePathListResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CompatUpgradePath" + } + }, + "total": { + "type": "integer" + } + } + }, + "ScalingPolicy": { + "type": "object", + "required": [ + "name", + "direction", + "metricName", + "threshold", + "operator", + "scalingStep" + ], + "properties": { + "name": { + "type": "string", + "description": "Unique policy identifier" + }, + "direction": { + "type": "string", + "enum": [ + "SCALE_OUT", + "SCALE_IN" + ], + "description": "Scaling direction triggered by this policy" + }, + "metricName": { + "type": "string", + "description": "Metric name to evaluate (e.g. cpu_utilization, memory_usage, connections)" + }, + "threshold": { + "type": "number", + "description": "Threshold value for metric comparison" + }, + "operator": { + "type": "string", + "enum": [ + "GREATER_THAN", + "LESS_THAN", + "GREATER_THAN_OR_EQUAL", + "LESS_THAN_OR_EQUAL", + "EQUAL" + ], + "description": "Comparison operator to evaluate against threshold" + }, + "scalingStep": { + "type": "integer", + "minimum": 1, + "description": "Number of instances to scale in/out" + } + }, + "examples": [ + { + "name": "example-scale-out", + "value": { + "name": "scale-out-high-cpu", + "direction": "SCALE_OUT", + "metricName": "cpu_utilization", + "threshold": 80, + "operator": "GREATER_THAN", + "scalingStep": 1 + } + }, + { + "name": "example-scale-in", + "value": { + "name": "scale-in-low-memory", + "direction": "SCALE_IN", + "metricName": "memory_usage", + "threshold": 30, + "operator": "LESS_THAN", + "scalingStep": 2 + } + } + ] + }, + "UpdateCloudEnvironmentRequest": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "isVmwCluster": { + "type": "boolean" + }, + "vmwProperties": { + "$ref": "#/components/schemas/VMwareEnvironmentProperties" + } + } + }, + "CheckResult": { + "type": "object", + "description": "Outcome of a single named validation check.", + "required": [ + "check_name", + "severity", + "status" + ], + "properties": { + "check_name": { + "type": "string", + "description": "Unique identifier of the check. One of:\n ha_sync \u2014 HA sync status check for BIG-IP (HARD)\n image_presence \u2014 software image present on BIG-IP image store (HARD)\n f5os_image_presence \u2014 software image present on F5OS image catalog (HARD)\n f5os_check_version \u2014 F5OS check-version API readiness verification (HARD)\n disk_space \u2014 available disk GB vs 15 GB threshold (SOFT)\n f5os_disk \u2014 F5OS platform disk space check (SOFT)\n cpu_utilization \u2014 5-min avg CPU % (SOFT; Stage 1: always SKIP)\n memory_utilization \u2014 5-min avg memory % (SOFT; Stage 1: always SKIP)\n config_backup \u2014 recent F5OS config backup exists (SOFT)\n cluster \u2014 F5OS cluster nodes/stages healthy (SOFT)\n cores \u2014 no F5OS core/crash-dump files present (SOFT)\n tenant_status - deployed F5OS tenants must not be Pending (HARD); other unhealthy tenant or instance states warn\n service_pods - all F5OS infrastructure service pods are healthy (SOFT)\n fpga_status - F5OS FPGA / DMA / DPSM / VF readiness healthy (SOFT)\n upgrade_path \u2014 upgrade path compatibility check (K13845) (HARD)\n license_compatibility \u2014 license edition version ceiling (HARD)\n license_date \u2014 service check date vs license check date (SOFT)\n f5os_version_support \u2014 F5OS OS version support check (HARD)\n" + }, + "severity": { + "$ref": "#/components/schemas/CheckSeverity" + }, + "status": { + "$ref": "#/components/schemas/CheckStatus" + }, + "message": { + "type": "string", + "description": "Human-readable explanation. Always present when status is WARN, FAIL, or SKIP." + }, + "detail": { + "type": "object", + "additionalProperties": true, + "description": "Structured extra data relevant to the check result.\nExamples:\n disk_space: { available_gb: 8.2, threshold_gb: 15.0 }\n cluster: { healthy_nodes: 1, install_done: 2, install_total: 2 }\n cores: { count: 2, files: [\"core.123\", \"core.456\"] }\n fpga_status: { has_fpga: true, ready_nodes: 1, total_nodes: 1 }\n tenant_status: { blocking_tenants: [\"tenant-a: running-state=\\\"deployed\\\" status=\\\"Pending\\\"\"] }\n upgrade_path: { current_version: \"15.1.2\", target_version: \"17.1.5\", min_source_version: \"16.1.0\" }\n license_date: { license_check_date: \"2024-01-15\", service_check_date: \"2023-12-01\" }\n" + } + } + }, + "CreateBackupRequest": { + "type": "object", + "required": [ + "passphrase" + ], + "properties": { + "name": { + "type": "string", + "description": "Optional backup name. If omitted, auto-generated as backup-YYYYMMDD-HHMMSS." + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ], + "default": "full", + "description": "Type of backup to create. Full backups require a remote storage target and are not supported on local storage; config backups may be stored locally." + }, + "passphrase": { + "type": "string", + "minLength": 12, + "description": "Encryption passphrase. Must be at least 12 characters with uppercase, lowercase, digit, and special character. Max 2 consecutive identical characters." + }, + "storage_target": { + "type": "string", + "description": "Name of the storage target to associate with this backup. Required for full backups (must be a remote target). If omitted, a config backup is stored locally." + } + } + }, + "BigIPAddRequest": { + "description": "BIG-IP add request. `deviceType` must be set to `bigip` so the\nunified add-device endpoint can dispatch to the BIG-IP onboarding\npath; the default in the schema is `bigip` for documentation\npurposes, but callers should still send the field explicitly.\n", + "allOf": [ + { + "type": "object", + "required": [ + "deviceType" + ], + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "bigip" + ], + "default": "bigip" + } + } + }, + { + "$ref": "#/components/schemas/Device" + } + ] + }, + "ExecutionDetail": { + "allOf": [ + { + "$ref": "#/components/schemas/Execution" + }, + { + "type": "object", + "properties": { + "activitySummary": { + "type": "object", + "properties": { + "total": { + "type": "integer" + }, + "running": { + "type": "integer" + }, + "completed": { + "type": "integer" + }, + "failed": { + "type": "integer" + } + } + }, + "latestActivityId": { + "type": "string", + "format": "uuid" + }, + "latestActivityType": { + "type": "string" + } + } + } + ] + }, + "FlightSnapshotListResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FlightSnapshot" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + } + }, + "AIProviderResponse": { + "type": "object", + "properties": { + "provider_name": { + "type": "string" + }, + "base_url": { + "type": "string" + }, + "model": { + "type": "string" + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "Optional CA certificate UUID from trust store for custom SSL/TLS connections" + }, + "skip_tls_verify": { + "type": "boolean", + "description": "Indicates if TLS verification is skipped" + } + } + }, + "SoftwareImage": { + "type": "object", + "required": [ + "id", + "file_name", + "product_family", + "version", + "image_type", + "file_size_bytes", + "storage_path", + "status", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "file_name": { + "type": "string" + }, + "product_family": { + "$ref": "#/components/schemas/ProductFamily" + }, + "image_type": { + "$ref": "#/components/schemas/ImageType" + }, + "status": { + "$ref": "#/components/schemas/ImageStatus" + }, + "version": { + "type": "string" + }, + "build": { + "type": "string" + }, + "base_build": { + "type": "string", + "nullable": true, + "description": "The base BIG-IP build required by a hotfix image, extracted from VERSION.LTM inside the ISO during verification. May be null for non-hotfix images or when the ISO does not include usable hotfix metadata.\n" + }, + "file_size_bytes": { + "type": "integer", + "format": "int64" + }, + "storage_path": { + "type": "string" + }, + "md5_checksum": { + "type": "string" + }, + "md5_verified": { + "type": "boolean" + }, + "sig_pem_verified": { + "type": "boolean" + }, + "md5_expected": { + "type": "string" + }, + "md5_actual": { + "type": "string" + }, + "verification_output": { + "type": "string", + "description": "Raw copy-able verification proof output" + }, + "verified_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when verification completed (set only when status is AVAILABLE or VERIFICATION_FAILED)" + }, + "uploaded_by": { + "type": "string" + }, + "uploaded_at": { + "type": "string", + "format": "date-time" + }, + "build_date": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "The build date of the software image, extracted from metadata.xml inside the ISO during verification. May be null for non-ISO images or ISOs without metadata.xml.\n" + }, + "created_at": { + "type": "string", + "format": "date-time" + } + } + }, + "CompatUpgradePath": { + "type": "object", + "description": "A single BIG-IP upgrade path rule from upgrade.bigip_upgrade_paths.", + "required": [ + "id", + "target_major_version", + "min_source_version", + "source_kbase", + "is_operator_override" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "target_major_version": { + "type": "string", + "description": "Target BIG-IP major version, e.g. \"17\" or \"21\".", + "example": "21" + }, + "min_source_version": { + "type": "string", + "description": "Minimum source version required for this upgrade path (inclusive).", + "example": "17.1.0" + }, + "max_source_version": { + "type": "string", + "nullable": true, + "description": "Maximum source version (inclusive). Null means no upper bound." + }, + "notes": { + "type": "string", + "nullable": true + }, + "source_kbase": { + "type": "string", + "description": "K-article this row originates from.", + "example": "K13845" + }, + "is_operator_override": { + "type": "boolean", + "description": "True for API-managed rows (seeder never overwrites these)." + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "ActivityListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Activity" + } + }, + "total": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "limit": { + "type": "integer" + } + } + }, + "UpgradeJobStatus": { + "type": "string", + "description": "Lifecycle status of an upgrade job. The job is a long-lived\nre-activatable definition; per-run outcomes (success/fail/abort)\nare recorded on the execution row, NOT here. Operator-driven\ncancel converges back to READY at the job level; CANCELLED is\nrecorded on the execution row only.\n", + "enum": [ + "DRAFT", + "READY", + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED" + ] + }, + "DeviceResponse": { + "allOf": [ + { + "$ref": "#/components/schemas/Device" + }, + { + "type": "object", + "properties": { + "deviceName": { + "type": "string", + "description": "Display name for the device. For BIG-IP this is the hostname\nfetched from the BIG-IP system; for F5OS it mirrors the\nuser-supplied `alias_name`. Always populated.\n" + }, + "deviceVersion": { + "type": "string", + "description": "BIG-IP software version (bigip only)." + }, + "devicePlatform": { + "type": "string", + "description": "BIG-IP platform/marketing name (bigip only)." + }, + "deviceType": { + "$ref": "#/components/schemas/DeviceType" + }, + "schema": { + "type": "string", + "description": "Protocol schema (http or https) inferred from endpoint or URL scheme.\nExample: \"https\"\n", + "enum": [ + "http", + "https" + ] + }, + "type": { + "type": "string", + "description": "F5OS platform type (f5os only)." + }, + "host": { + "type": "string", + "description": "IP address or hostname extracted from endpoint. For BIG-IP devices,\nthis is parsed from the endpoint field. For F5OS, this is the provider host.\nExample: \"192.168.1.100\" or \"bigip.example.com\"\n" + }, + "port": { + "type": "integer", + "description": "Port number extracted from endpoint. For BIG-IP devices, defaults to 443\nfor https or 80 for http if not specified. For F5OS, this is the provider port.\nExample: 443\n" + }, + "status": { + "type": "string", + "description": "Device connectivity status. For BIG-IP, derived from Prometheus (`READY` when reachable, `UNREACHABLE` when not). For F5OS, reflects the provider status. Omitted when status data is unavailable.\n" + }, + "hardwareModel": { + "type": "string", + "description": "F5OS hardware model (f5os only)." + }, + "serialNumber": { + "type": "string", + "description": "F5OS serial number (f5os only)." + }, + "osVersion": { + "type": "string", + "description": "F5OS OS version (f5os only)." + }, + "osBuild": { + "type": "string", + "description": "F5OS OS build (f5os only)." + }, + "lastSeenAt": { + "type": "string", + "format": "date-time", + "description": "When the F5OS provider was last reachable (f5os only)." + } + } + } + ] + }, + "DeviceValidationResult": { + "type": "object", + "description": "Validation result for a single device within a job.\nOne row per device; updated in real-time as checks run.\n", + "required": [ + "device_id", + "hostname", + "status", + "current_step", + "check_results" + ], + "properties": { + "device_id": { + "type": "string", + "format": "uuid" + }, + "hostname": { + "type": "string", + "description": "Device hostname as known to fleet inventory." + }, + "status": { + "$ref": "#/components/schemas/ValidationStatus" + }, + "current_step": { + "type": "string", + "description": "Current FSM step for this device. Useful for polling progress mid-run.\nValues: PENDING | CHECKING_HA_SYNC | CHECKING_IMAGE_PRESENCE | CHECKING_F5OS_IMAGE_PRESENCE |\n CHECKING_F5OS_CHECK_VERSION | CHECKING_DISK | CHECKING_F5OS_DISK | CHECKING_F5OS_CONFIG_BACKUP |\n CHECKING_F5OS_CLUSTER | CHECKING_F5OS_CORES | CHECKING_F5OS_SERVICE_PODS |\n CHECKING_F5OS_FPGA | CHECKING_F5OS_TENANT_STATUS | CHECKING_UPGRADE_PATH |\n CHECKING_LICENSE | CHECKING_LICENSE_DATE | CHECKING_F5OS_VERSION_SUPPORT | COMPLETE\n" + }, + "check_results": { + "type": "array", + "description": "Ordered list of check outcomes. Empty until the device starts running.", + "items": { + "$ref": "#/components/schemas/CheckResult" + } + }, + "blocking_check": { + "type": "string", + "description": "Name of the first HARD check that returned FAIL.\nEmpty string if no HARD check failed.\n" + }, + "started_at": { + "type": "string", + "format": "date-time", + "description": "When the first check started for this device." + }, + "completed_at": { + "type": "string", + "format": "date-time", + "description": "When all checks completed (or an error stopped execution)." + } + } + }, + "ScheduledUpgradeListResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ScheduledUpgradeEntry" + } + } + } + }, + "ActivateInstallationJobRequest": { + "type": "object", + "description": "Optional request body for POST /jobs/software-installation/{jobId}/activate.\nAll fields are optional; the endpoint may be called with no body at all.\n", + "properties": { + "changeRequest": { + "type": "string", + "nullable": true, + "maxLength": 255, + "description": "Optional change-request identifier (e.g. \"CHG0012345\") associated with\nthis specific activation/run. Persisted on the execution record so the\nUI can display it in the execution drawer. Each activation of the same\njob may carry a different change request.\n" + } + } + }, + "JobPatchRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "name": { + "type": "string" + }, + "description": { + "type": "string", + "description": "Optional human-readable job description. Set to empty string to clear." + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "INACTIVE", + "ERROR", + "COMPLETED", + "FAILED", + "CANCELLED", + "DELETING" + ] + }, + "enabled": { + "type": "boolean", + "description": "Whether the job can be activated, paused, or resumed." + }, + "config": { + "$ref": "#/components/schemas/JobConfig" + }, + "schedule": { + "$ref": "#/components/schemas/Schedule" + } + } + }, + "ImportTaskAccepted": { + "type": "object", + "required": [ + "task_id" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Identifier to poll via GET /device-management/devices/import/status/{task_id}." + }, + "message": { + "type": "string", + "example": "Import task accepted" + } + } + }, + "UpgradeCatalogResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "object", + "required": [ + "latest_patch", + "latest_full_upgrade", + "patches", + "full_upgrades" + ], + "properties": { + "latest_patch": { + "type": "string", + "description": "Latest available patch version", + "example": "f5insight-1.1.2-62" + }, + "latest_full_upgrade": { + "type": "string", + "description": "Latest available full upgrade version", + "example": "f5insight-1.2.0-1" + }, + "patches": { + "type": "array", + "description": "Latest available patch entry, or empty when none exists", + "items": { + "$ref": "#/components/schemas/UpgradeEntry" + } + }, + "full_upgrades": { + "type": "array", + "description": "Latest available full upgrade entry, or empty when none exists", + "items": { + "$ref": "#/components/schemas/UpgradeEntry" + } + } + } + } + } + }, + "RollbackAcceptedResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "202" + }, + "data": { + "type": "object", + "required": [ + "rollback_id" + ], + "properties": { + "rollback_id": { + "type": "string", + "format": "uuid", + "example": "770e8400-e29b-41d4-a716-446655440007" + } + } + } + } + }, + "ListOfDevices": { + "type": "object", + "additionalProperties": false, + "properties": { + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DeviceResponse" + } + }, + "pagination": { + "type": "object", + "additionalProperties": false, + "description": "Pagination metadata for the devices list.", + "properties": { + "page": { + "type": "integer", + "description": "Current page number.", + "minimum": 1 + }, + "pageSize": { + "type": "integer", + "description": "Number of devices per page.", + "minimum": 1 + }, + "totalDevices": { + "type": "integer", + "description": "Total number of devices matching the filter criteria.", + "minimum": 0 + }, + "totalPages": { + "type": "integer", + "description": "Total number of pages available.", + "minimum": 0 + } + } + } + } + }, + "SoftwareDistributionJob": { + "type": "object", + "description": "Full software distribution job resource including config and execution state.", + "required": [ + "id", + "name", + "status", + "enabled", + "config", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique job identifier." + }, + "workflowId": { + "type": "string", + "format": "uuid", + "description": "Parent workflow entity ID." + }, + "name": { + "type": "string", + "description": "Unique human-readable job name." + }, + "description": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/UpgradeJobStatus" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether this job is enabled. A disabled job (false) cannot be activated,\npaused, or resumed. Defaults to true on creation.\n" + }, + "config": { + "$ref": "#/components/schemas/SoftwareDistributionConfig" + }, + "execution": { + "$ref": "#/components/schemas/JobExecution", + "description": "Present once the job has been activated at least once." + }, + "createdBy": { + "type": "string", + "nullable": true, + "description": "Username of the operator who created the job." + }, + "modifiedBy": { + "type": "string", + "nullable": true, + "description": "Username of the operator who last modified the job." + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "JobListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Job" + } + }, + "total": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "limit": { + "type": "integer" + } + } + }, + "StorageTargetListResponse": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StorageTarget" + } + } + } + }, + "SoftwareDistributionJobSummary": { + "type": "object", + "description": "Lightweight software distribution job summary for list responses.", + "required": [ + "id", + "name", + "status", + "enabled", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "workflowId": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/UpgradeJobStatus" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether this job is enabled." + }, + "batchSize": { + "type": "integer", + "description": "Configured batch size." + }, + "deviceCount": { + "type": "integer", + "description": "Number of target devices in this job." + }, + "createdBy": { + "type": "string", + "nullable": true, + "description": "Username of the operator who created the job. Absent when the X-Username header was not present at creation time." + }, + "modifiedBy": { + "type": "string", + "nullable": true, + "description": "Username of the operator who last modified the job. Absent when no modification has been made with an identified actor." + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "CreateSoftwareInstallationJobRequest": { + "description": "Request body for creating a new software installation job. Name is required.", + "allOf": [ + { + "$ref": "#/components/schemas/SoftwareInstallationJobPayload" + }, + { + "required": [ + "name" + ] + } + ] + }, + "SoftwareInstallationJobListResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SoftwareInstallationJobSummary" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + } + }, + "ImportTaskStatus": { + "type": "object", + "required": [ + "task_id", + "state", + "status", + "progress", + "total", + "successful", + "failed", + "items" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "state": { + "type": "string", + "enum": [ + "INIT", + "IN_PROGRESS", + "COMPLETED", + "FAILED" + ], + "description": "Lifecycle state of the task.\n * INIT \u2014 task created, worker not yet started.\n * IN_PROGRESS \u2014 worker iterating items.\n * COMPLETED \u2014 every item processed (some may have failed; see `status`).\n * FAILED \u2014 task aborted before completing every item.\n" + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "SUCCESS", + "ERROR" + ], + "description": "Outcome summary.\n * RUNNING \u2014 while state is IN_PROGRESS.\n * SUCCESS \u2014 state=COMPLETED with zero failures.\n * ERROR \u2014 state=COMPLETED with at least one failure, or state=FAILED.\n" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100 + }, + "total": { + "type": "integer", + "description": "Number of devices in the original request." + }, + "successful": { + "type": "integer", + "description": "Number of devices that were imported successfully so far." + }, + "failed": { + "type": "integer", + "description": "Number of devices that failed to import so far." + }, + "error_message": { + "type": "string", + "description": "Populated when state=FAILED with a task-level error." + }, + "items": { + "type": "array", + "description": "Per-device result list, in the same order as the request body.", + "items": { + "$ref": "#/components/schemas/ImportTaskItem" + } + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "ValidationError": { + "type": "object", + "properties": { + "code": { + "type": "integer" + }, + "message": { + "type": "string" + }, + "validationType": { + "type": "string", + "enum": [ + "CLUSTER_VALIDATION", + "CONNECTION_TEST", + "DATACENTER_VALIDATION", + "NETWORK_VALIDATION", + "VMIMAGE_VALIDATION" + ] + }, + "details": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + } + } + }, + "LicenseInfo": { + "type": "object", + "required": [ + "activation_timestamp", + "license_sub_status", + "status", + "expiry_date", + "mode_of_operation" + ], + "properties": { + "activation_timestamp": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the license was registered/activated", + "example": "2025-12-03T07:18:11Z" + }, + "license_sub_status": { + "type": "string", + "description": "Activation status", + "example": "Active" + }, + "status": { + "type": "string", + "enum": [ + "Invalid", + "Active", + "Terminated", + "Unlicensed" + ], + "description": "Invalid/Active/Terminated/Unlicensed etc...", + "example": "Active" + }, + "expiry_date": { + "type": "string", + "format": "date-time", + "description": "License subscription expiry date", + "example": "2026-11-29T00:00:32Z" + }, + "telemetry_status": { + "type": "string", + "description": "Telemetry status", + "example": "Enabled" + }, + "telemetry_last_verified": { + "type": "string", + "format": "date-time", + "description": "Last telemetry verification timestamp", + "example": "2025-12-10T05:12:45Z" + }, + "telemetry_error": { + "type": "string", + "description": "Telemetry error message if any", + "example": "if any error while sending telemetry" + }, + "mode_of_operation": { + "type": "string", + "description": "Mode of operation", + "enum": [ + "connected", + "disconnected" + ] + } + } + }, + "ImportTaskItem": { + "type": "object", + "required": [ + "device_type", + "status" + ], + "properties": { + "device_type": { + "type": "string", + "enum": [ + "bigip", + "f5os" + ], + "description": "Discriminator for the input item." + }, + "alias_name": { + "type": "string", + "description": "User-supplied alias (or server default) for the device." + }, + "endpoint": { + "type": "string", + "description": "Endpoint URL of the device as supplied in the request." + }, + "status": { + "type": "string", + "enum": [ + "pending", + "success", + "failed" + ], + "description": "Per-device result. `pending` while the worker has not processed the item yet." + }, + "device_id": { + "type": "string", + "format": "uuid", + "description": "Present on success \u2014 UUID of the persisted device." + }, + "error_message": { + "type": "string", + "description": "Present on failure \u2014 human-readable cause." + } + } + }, + "BulkDeleteImagesRequest": { + "type": "object", + "required": [ + "image_ids" + ], + "properties": { + "image_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + }, + "minItems": 1, + "maxItems": 100 + } + } + }, + "DatastoreInfo": { + "type": "object", + "properties": { + "datastore": { + "type": "string", + "description": "Managed Object Reference (datastore ID)" + }, + "name": { + "type": "string", + "description": "Name of the datastore" + } + } + }, + "ProductFamily": { + "type": "string", + "enum": [ + "BIG-IP", + "F5OS-C", + "F5OS-A" + ] + }, + "ReadinessWarning": { + "type": "object", + "description": "A single graded post-upgrade readiness finding.\n", + "required": [ + "check", + "level", + "message" + ], + "properties": { + "check": { + "type": "string", + "description": "Stable check identifier (e.g. \"cluster\", \"firmwareStatus\")." + }, + "level": { + "type": "string", + "description": "Severity level (INFO, WARN, CRITICAL).", + "enum": [ + "INFO", + "WARN", + "CRITICAL" + ] + }, + "message": { + "type": "string", + "description": "Human-readable, operator-facing finding message." + } + } + }, + "ReadinessDeviceResult": { + "type": "object", + "description": "Per-device readiness check outcome.", + "required": [ + "id", + "run_id", + "device_id", + "hostname", + "current_step", + "status", + "check_results" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "run_id": { + "type": "string", + "format": "uuid" + }, + "device_id": { + "type": "string", + "format": "uuid" + }, + "hostname": { + "type": "string" + }, + "device_type": { + "type": "string", + "description": "Device platform type (BIGIP, RSERIES, VELOS)." + }, + "ha_state": { + "type": "string", + "nullable": true, + "description": "HA failover role (ACTIVE, STANDBY, STANDALONE, UNKNOWN). Null for F5OS devices." + }, + "ha_pair_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "UUID of the HA pair group this device belongs to. Null for standalone/F5OS." + }, + "ha_peer_device_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "UUID of the peer device in the HA pair. Null for standalone/F5OS." + }, + "current_step": { + "type": "string", + "description": "Current FSM step (PENDING, CHECKING_, COMPLETE)." + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "PASSED", + "WARNING", + "FAILED", + "ERROR" + ] + }, + "check_results": { + "type": "array", + "description": "Per-check results \u2014 one entry per requested check type.", + "items": { + "$ref": "#/components/schemas/ReadinessCheckResult" + } + }, + "started_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "completed_at": { + "type": "string", + "format": "date-time", + "nullable": true + } + } + }, + "ConfigAIDFRequest": { + "type": "object", + "required": [ + "endpoint", + "tenant_id", + "tenant_token" + ], + "properties": { + "endpoint": { + "type": "string", + "description": "AIDF endpoint URL" + }, + "tenant_id": { + "type": "string", + "description": "Tenant ID" + }, + "tenant_token": { + "type": "string", + "description": "Tenant authentication token" + }, + "data_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "logs", + "metrics" + ] + }, + "description": "Data types to send to AIDF (logs, metrics, or both). Defaults to [\"logs\", \"metrics\"] if not specified. Cannot be an empty array.", + "example": [ + "logs", + "metrics" + ], + "default": [ + "logs", + "metrics" + ], + "minItems": 1 + } + } + }, + "HealthResponse": { + "type": "object", + "required": [ + "success", + "data" + ], + "properties": { + "success": { + "type": "boolean", + "example": true + }, + "data": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "healthy", + "unhealthy" + ], + "example": "healthy" + }, + "platform_manager": { + "type": "string", + "enum": [ + "available", + "unavailable" + ], + "example": "available" + } + } + } + } + }, + "ReadinessTriggeredResponse": { + "type": "object", + "description": "Response body returned by POST /readiness (202 Accepted).", + "required": [ + "run_id", + "message" + ], + "properties": { + "run_id": { + "type": "string", + "format": "uuid", + "description": "Unique ID for this readiness run. Use with GET /readiness/{runId} to poll results." + }, + "message": { + "type": "string", + "example": "readiness checks triggered" + } + } + }, + "TrustStore": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the certificate" + }, + "name": { + "type": "string", + "maxLength": 255, + "description": "Name of the certificate" + }, + "description": { + "type": "string", + "description": "Description of the certificate" + }, + "certificate_content": { + "type": "string", + "description": "PEM encoded certificate content" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp" + }, + "last_modified": { + "type": "string", + "format": "date-time", + "description": "Last modification timestamp" + } + } + }, + "FleetDevice": { + "type": "object", + "required": [ + "id", + "device_type", + "endpoint" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "device_type": { + "type": "string", + "enum": [ + "BIGIP", + "RSERIES", + "VELOS" + ] + }, + "name": { + "type": "string", + "description": "Alias name from the device store" + }, + "device_name": { + "type": "string" + }, + "endpoint": { + "type": "string", + "description": "Management address (host:port or IP)" + }, + "data_center_id": { + "type": "string", + "format": "uuid", + "description": "Data centre UUID this device belongs to" + }, + "current_version": { + "type": "string", + "example": "17.1.2" + }, + "current_build": { + "type": "string", + "example": "0.0.13" + }, + "edition": { + "type": "string", + "example": "Final" + }, + "platform": { + "type": "string", + "example": "Z100" + }, + "marketing_name": { + "type": "string", + "example": "BIG-IP i5800" + }, + "chassis_serial": { + "type": "string" + }, + "ha_pair_id": { + "type": "string", + "format": "uuid", + "description": "Stable UUID shared by both members of an HA pair; null for standalone devices" + }, + "ha_peer_device_id": { + "type": "string", + "format": "uuid" + }, + "ha_state": { + "type": "string", + "enum": [ + "ACTIVE", + "STANDBY", + "UNKNOWN", + "STANDALONE" + ] + }, + "device_group": { + "type": "string" + }, + "sync_status": { + "type": "string", + "example": "In Sync" + }, + "hosted_on_provider_id": { + "type": "string", + "format": "uuid", + "description": "F5OS provider UUID; null for standalone BIG-IP" + }, + "active_volume": { + "type": "string", + "description": "BIG-IP: name of the currently active boot volume (e.g. HD1.1). Null for F5OS.", + "example": "HD1.1" + }, + "inactive_volumes": { + "description": "BIG-IP only: array of non-active software boot volumes.\nNull for F5OS (RSERIES/VELOS) \u2014 F5OS uses an ISO image model with no boot-volume concept.\n", + "nullable": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/VolumeInfo" + } + }, + "disk_available_gb": { + "type": "number", + "format": "float", + "description": "Total free disk space in GB across all partitions (BIG-IP only)", + "example": 42.5 + }, + "license_edition": { + "type": "string" + }, + "license_check_date": { + "type": "string", + "format": "date" + }, + "service_check_date": { + "type": "string", + "format": "date" + }, + "last_seen_at": { + "type": "string", + "format": "date-time" + }, + "last_refresh_at": { + "type": "string", + "format": "date-time" + }, + "eligibility_status": { + "type": "string", + "enum": [ + "ELIGIBLE", + "INELIGIBLE", + "UNKNOWN" + ] + }, + "recommended_version": { + "type": "string", + "example": "17.1.3" + }, + "is_payg_license": { + "type": "boolean", + "description": "True when the device runs a PAYG cloud marketplace license (F5 KB K82564652).\nPAYG devices do not enforce the Service Check Date on upgrade.\nNull when the device has not yet been refreshed after this field was introduced.\n" + } + } + }, + "UpgradeHistoryResponse": { + "type": "object", + "required": [ + "status", + "dirty_state", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "dirty_state": { + "type": "boolean", + "example": false + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UpgradeHistoryEntry" + } + } + } + }, + "ActiveJobResponse": { + "type": "object", + "required": [ + "status", + "dirty_state", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "dirty_state": { + "type": "boolean", + "example": false + }, + "data": { + "nullable": true, + "type": "object", + "required": [ + "id", + "status", + "progress" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "enum": [ + "pending", + "running", + "done", + "failed" + ] + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100 + } + } + } + } + }, + "JobStatusData": { + "type": "object", + "required": [ + "id", + "version", + "kind", + "status", + "progress", + "rollback_available" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Upgrade history record ID", + "example": "d4e5f6a7-0000-4000-8000-000000000001" + }, + "version": { + "type": "string", + "description": "Target version", + "example": "3.2.1" + }, + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "description": "Upgrade kind", + "example": "patch" + }, + "status": { + "type": "string", + "enum": [ + "pending", + "running", + "done", + "failed" + ], + "description": "Current upgrade status", + "example": "done" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Upgrade progress percentage", + "example": 100 + }, + "rollback_available": { + "type": "boolean", + "description": "True when this patch job can currently be rolled back manually. Manual rollback is available only for the latest successful patch completed within the last 72 hours; failed patch jobs use automatic rollback.", + "example": true + }, + "current_step": { + "type": "string", + "description": "Current upgrade step", + "example": "deployments_ready" + }, + "started_at": { + "type": "string", + "format": "date-time" + }, + "started_by": { + "type": "string", + "example": "admin@f5.com" + }, + "finished_at": { + "type": "string", + "format": "date-time" + }, + "platform_job_id": { + "type": "string", + "format": "uuid" + }, + "download": { + "$ref": "#/components/schemas/DownloadProgress" + }, + "error_message": { + "type": "string" + }, + "log": { + "type": "array", + "items": { + "$ref": "#/components/schemas/JobLogEntry" + } + } + } + }, + "CreateCloudEnvironmentRequest": { + "type": "object", + "required": [ + "name", + "providerReference", + "deviceTemplateReference", + "vmwProperties" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the cloud environment", + "minLength": 1, + "maxLength": 255 + }, + "providerReference": { + "$ref": "#/components/schemas/Reference" + }, + "deviceTemplateReference": { + "$ref": "#/components/schemas/Reference" + }, + "isVmwCluster": { + "type": "boolean", + "description": "Indicates if VMware cluster is being used", + "default": true + }, + "vmwProperties": { + "$ref": "#/components/schemas/VMwareEnvironmentProperties" + } + } + }, + "DiskAnalysisTaskProgress": { + "type": "object", + "properties": { + "total_devices": { + "type": "integer", + "minimum": 0 + }, + "analyzed_devices": { + "type": "integer", + "minimum": 0 + }, + "sufficient_count": { + "type": "integer", + "minimum": 0 + }, + "insufficient_count": { + "type": "integer", + "minimum": 0 + } + } + }, + "PreflightResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "object", + "required": [ + "can_proceed", + "checks" + ], + "properties": { + "can_proceed": { + "type": "boolean", + "description": "True only when all checks pass", + "example": true + }, + "checks": { + "type": "array", + "description": "Individual pre-upgrade health check results", + "items": { + "$ref": "#/components/schemas/PreflightCheck" + } + } + } + } + } + }, + "WorkflowListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Workflow" + } + }, + "total": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "limit": { + "type": "integer" + } + } + }, + "DeviceStatusDetail": { + "type": "object", + "required": [ + "device_name", + "endpoint", + "validation_status", + "created_at", + "updated_at" + ], + "properties": { + "device_name": { + "type": "string", + "description": "Device name/identifier", + "example": "bigip/prod-01" + }, + "endpoint": { + "type": "string", + "description": "Device endpoint URL", + "example": "https://10.1.1.100" + }, + "validation_status": { + "type": "string", + "enum": [ + "PENDING", + "VALIDATING", + "SUCCESS", + "FAILED" + ], + "description": "Validation status for this device", + "example": "SUCCESS" + }, + "error_message": { + "type": "string", + "nullable": true, + "description": "Error message if validation failed", + "example": null + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "When the device entry was created", + "example": "2026-01-29T10:30:00Z" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "When the device status was last updated", + "example": "2026-01-29T10:32:00Z" + } + } + }, + "BulkImportResponse": { + "type": "object", + "required": [ + "total", + "successful", + "failed" + ], + "properties": { + "total": { + "type": "integer", + "description": "Total number of devices in the import request", + "example": 10 + }, + "successful": { + "type": "integer", + "description": "Number of devices successfully imported", + "example": 8 + }, + "failed": { + "type": "integer", + "description": "Number of devices that failed to import", + "example": 2 + }, + "results": { + "type": "array", + "description": "Detailed results for each device", + "items": { + "type": "object", + "properties": { + "device_name": { + "type": "string", + "description": "Device identifier (alias_name or endpoint)", + "example": "bigip-prod-01" + }, + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "Import status for this device", + "example": "success" + }, + "message": { + "type": "string", + "description": "Success message or error details", + "example": "Device imported successfully" + }, + "device_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the imported device (only present on success)", + "example": "123e4567-e89b-12d3-a456-426614174000" + } + } + } + } + } + }, + "ScheduleResponse": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "$ref": "#/components/schemas/ScheduledTask" + } + } + }, + "InstallStep": { + "type": "string", + "description": "Current step of a single device's installation FSM. Written verbatim\nfrom the per-node state machine; identical for standalone and for each\nnode of an HA pair (BIG-IP and F5OS alike).\n\nOPTIONAL / TIMING: this value is OPTIONAL on a per-device row. A device\nwhose status is RUNNING may carry NO currentStep at all \u2014 the column is\nunset until the per-node FSM checkpoints its first state, so callers must\ntreat \"RUNNING with no currentStep\" as \"starting, step not yet recorded\"\n(do NOT assume PENDING). In HA the two nodes of a pair are driven\nSEQUENTIALLY (standby first, then active), so it is expected for the\nstandby to report an advanced step (e.g. REBOOT) while the active node of\nthe SAME pair is still RUNNING with no currentStep yet. On successful\ncompletion the FSM writes COMPLETE.\n\nENTRY-TIME LABELING: currentStep names the FSM state the device has\nENTERED, not the one it has finished. The step is stamped on state entry\n(before the state's work \u2014 including its wait loops \u2014 runs), so a device\nreporting REBOOT is \"in the reboot phase\", which still includes waiting\nfor the device to go down and come back up on the target version. Do not\nread a step as \"this phase is done\".\n\nINSTALL / HOTFIX / REBOOT notes:\n * BIG-IP full-image installs report INSTALL while the target image is\n being installed to the chosen volume.\n * BIG-IP hotfix installs split the install into two operator-visible\n phases: BASE_IMAGE_INSTALL while the matching base image is installed\n (real device progress is available), then WAIT_HOTFIX_INSTALL while\n BIG-IP applies the hotfix (no device-reported percentage, so progress\n is time-based).\n * ATOMIC path (standalone, reboot=true, NO HITL gate): there is NO\n separate REBOOT step. INSTALL issues a fused install+reboot on the\n device and folds BOTH the install-complete wait AND the reboot wait\n into the INSTALL step; on F5OS the FSM may then run\n POST_INSTALL_SETTLE before POST_FLIGHT so transient platform startup\n conditions do not taint the POST snapshot. You will never see REBOOT\n on this path.\n * GATED / HA path (HITL gate requested, or any HA pair node): install\n and reboot are DISCRETE. INSTALL writes software to the inactive\n volume, then the FSM enters REBOOT and (entry-time labeling) reports\n REBOOT before the reboot wait finishes. On F5OS the install RPC itself\n embeds the reboot, so the device may still be writing/applying\n software while currentStep already reads REBOOT \u2014 this is expected,\n not a stuck or mislabeled state.\n", + "enum": [ + "PENDING", + "IMAGE_PRESENT_CHECK", + "VALIDATION", + "PRE_FLIGHT", + "VOLUME_PLAN", + "INSTALL", + "BASE_IMAGE_INSTALL", + "WAIT_HOTFIX_INSTALL", + "HITL_PAUSE_BEFORE_REBOOT", + "REBOOT", + "FIRMWARE_UPGRADE", + "POST_INSTALL_SETTLE", + "POST_FLIGHT", + "COMPLETE", + "FAILED", + "CANCELLED" + ] + }, + "Error": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "code": { + "type": "string" + } + } + }, + "VMTaskResponse": { + "type": "object", + "properties": { + "taskId": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "IN_PROGRESS", + "COMPLETED", + "FAILED" + ] + }, + "envReference": { + "type": "string", + "description": "Environment name used for this task" + }, + "taskType": { + "type": "string", + "enum": [ + "CREATE_VM", + "DELETE_VM" + ] + }, + "message": { + "type": "string" + }, + "vmName": { + "type": "string", + "description": "Name of the created/cloned VM" + }, + "vmUuid": { + "type": "string", + "description": "vCenter Managed Object Reference (MoRef) of the created/cloned VM.\nPopulated as soon as the clone succeeds, so it is available even\nfor tasks that later fail during power-on or IP acquisition.\n" + }, + "vmIP": { + "type": "string", + "description": "IP address of the created/deleted VM" + }, + "selfLink": { + "type": "string", + "format": "uri" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "DeviceTemplateLockResponse": { + "type": "object", + "description": "Response returned after locking or unlocking a device template.", + "required": [ + "id", + "locked", + "lockReason", + "status", + "selfLink", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "UUID of the device template.", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "locked": { + "type": "boolean", + "description": "Current lock state after the operation.", + "example": true + }, + "lockReason": { + "type": "string", + "description": "Current lock reason: NONE (unlocked), READ_ONLY (manually locked).", + "enum": [ + "NONE", + "READ_ONLY" + ], + "example": "READ_ONLY" + }, + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 200 + }, + "selfLink": { + "type": "string", + "description": "URI path to the device template resource.", + "example": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000" + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp (UTC) when the lock state was changed.", + "example": "2026-04-15T08:20:00Z" + } + } + }, + "CleanupImportTaskResponse": { + "type": "object", + "required": [ + "task_id", + "message" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "The import task ID that was cleaned up", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "message": { + "type": "string", + "description": "Success message", + "example": "Successfully cleaned up import task" + } + } + }, + "CreateCloudProviderRequest": { + "type": "object", + "required": [ + "providerType", + "name" + ], + "properties": { + "providerType": { + "type": "string", + "enum": [ + "VMware" + ], + "description": "Type of cloud provider" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "Name of the cloud provider" + }, + "vmwProperties": { + "$ref": "#/components/schemas/VMwareProviderProperties" + } + } + }, + "TaskReference": { + "type": "object", + "description": "Reference link to an async task for polling status", + "properties": { + "taskLink": { + "type": "string", + "format": "uri", + "description": "Link to the task status endpoint for polling", + "example": "https://localhost/api/licensing/pool/tasks/d4e5f6a7-b8c9-0123-defg-456789abcdef" + } + } + }, + "UpgradeStatusResponse": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean", + "example": true + }, + "data": { + "oneOf": [ + { + "$ref": "#/components/schemas/IdleStatus" + }, + { + "$ref": "#/components/schemas/UpgradeOperationStatus" + } + ] + } + } + }, + "PoolLicenseOperationRequest": { + "type": "object", + "description": "Request body for pool-level license operations (assign, reactivate, revoke)", + "required": [ + "deviceAddress", + "deviceUsername", + "devicePassword" + ], + "properties": { + "deviceAddress": { + "type": "string", + "format": "ipv4", + "description": "IP address of the BIG-IP device", + "example": "192.168.1.100" + }, + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + }, + "JobExecution": { + "type": "object", + "description": "Current execution state of a running or completed upgrade job.", + "properties": { + "executionId": { + "type": "string", + "format": "uuid", + "description": "ID of the workflow execution record." + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "COMPLETED", + "FAILED", + "CANCELLED" + ] + }, + "startedAt": { + "type": "string", + "format": "date-time" + }, + "endedAt": { + "type": "string", + "format": "date-time" + }, + "currentBatch": { + "type": "integer", + "description": "The batch number currently being processed (1-based)." + }, + "totalBatches": { + "type": "integer", + "description": "Total number of batches this execution is divided into." + }, + "batches": { + "type": "array", + "description": "Per-batch execution summary.", + "items": { + "$ref": "#/components/schemas/BatchStatus" + } + } + } + }, + "DiskAnalysisTaskResult": { + "type": "object", + "required": [ + "required_size_bytes", + "data", + "summary" + ], + "properties": { + "required_size_bytes": { + "type": "integer", + "format": "int64" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DiskAnalysisBatchResult" + } + }, + "summary": { + "$ref": "#/components/schemas/DiskAnalysisBatchSummary" + } + } + }, + "ErrorResponse": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "CABundleListResponse": { + "type": "object", + "required": [ + "task_id", + "page", + "size", + "total", + "ca_bundles" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the migration task", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "page": { + "type": "integer", + "description": "Current page number (1-based)", + "example": 1 + }, + "size": { + "type": "integer", + "description": "Number of CA bundles per page", + "example": 20 + }, + "total": { + "type": "integer", + "format": "int64", + "description": "Total number of CA bundles in the task", + "example": 5 + }, + "ca_bundles": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StagingCABundle" + }, + "description": "List of staging CA bundles" + } + } + }, + "DiskAnalysisBatchRequest": { + "type": "object", + "required": [ + "required_size_bytes", + "devices" + ], + "properties": { + "required_size_bytes": { + "type": "integer", + "format": "int64", + "minimum": 1, + "description": "Required disk size per device, in bytes" + }, + "devices": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/DiskAnalysisBatchDeviceInput" + } + } + } + }, + "FqdnStatusResponse": { + "type": "object", + "required": [ + "task_id", + "state", + "status", + "progress" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Task identifier", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "state": { + "type": "string", + "enum": [ + "INIT", + "VALIDATE", + "APPLY", + "COMPLETED", + "FAILED" + ], + "description": "Current FSM state of the task", + "example": "APPLY" + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "SUCCESS", + "ERROR" + ], + "description": "Task execution status", + "example": "RUNNING" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Progress percentage (0-100)", + "example": 60 + }, + "error_message": { + "type": "string", + "description": "Error message if task failed", + "example": "FQDN configuration failed: helm upgrade failed" + } + } + }, + "BulkDeleteJobResult": { + "type": "object", + "required": [ + "job_id", + "status" + ], + "properties": { + "job_id": { + "type": "string", + "format": "uuid", + "description": "ID of the job this result applies to" + }, + "status": { + "$ref": "#/components/schemas/BulkDeleteJobResultStatus" + }, + "error": { + "type": "string", + "description": "Human-readable error message (only present when status=FAILED)" + } + } + }, + "DeviceProgressResponse": { + "type": "object", + "required": [ + "task_id", + "task_status", + "task_progress", + "page", + "size", + "total", + "devices" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the migration task", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "task_status": { + "type": "string", + "enum": [ + "RUNNING", + "SUCCESS", + "ERROR" + ], + "description": "Overall task status", + "example": "RUNNING" + }, + "task_progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Overall task completion percentage (0-100)", + "example": 45 + }, + "page": { + "type": "integer", + "description": "Current page number (1-based)", + "example": 1 + }, + "size": { + "type": "integer", + "description": "Number of devices per page", + "example": 20 + }, + "total": { + "type": "integer", + "format": "int64", + "description": "Total number of devices matching filters", + "example": 45 + }, + "last_sync": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of the most recently modified device in this response.\nUse this value as 'since' parameter in next poll for delta updates.\n", + "example": "2026-01-30T12:12:30Z" + }, + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DeviceProgressItem" + }, + "description": "List of device progress items" + } + } + }, + "DeviceTemplate": { + "type": "object", + "description": "Full device template resource representation.\nIncludes identity, lifecycle state, lock state, the template definition,\nvalidation tracking, and audit timestamps.\n", + "required": [ + "id", + "name", + "provider", + "state", + "locked", + "lockReason", + "definition", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Server-generated UUID of the device template.", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "name": { + "type": "string", + "description": "Unique human-readable name.", + "example": "BIG-IP Standard Template" + }, + "provider": { + "type": "string", + "description": "Provider or vendor.", + "example": "VMware" + }, + "description": { + "type": "string", + "description": "Optional description.", + "nullable": true, + "example": "Standard VMware configuration for production workloads" + }, + "state": { + "type": "string", + "description": "Current lifecycle state: DRAFT \u2192 NEW \u2192 DEPLOYING \u2192 DEPLOYED.", + "enum": [ + "DRAFT", + "NEW", + "DEPLOYING", + "DEPLOYED" + ], + "example": "DRAFT" + }, + "locked": { + "type": "boolean", + "description": "When true, the template cannot be modified until unlocked.", + "example": false + }, + "lockReason": { + "type": "string", + "description": "Reason the record is locked: NONE (unlocked), DEPLOYMENT, READ_ONLY.", + "enum": [ + "NONE", + "DEPLOYMENT", + "READ_ONLY" + ], + "example": "NONE" + }, + "definition": { + "$ref": "#/components/schemas/DeviceTemplateDefinition" + }, + "lastValidatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent successful validation. Null if never validated.", + "nullable": true, + "example": null + }, + "validatedAgainstLiveVm": { + "type": "boolean", + "description": "True if the last validation was against a live BIG-IP VM.", + "example": false + }, + "lastDeployedVersion": { + "type": "integer", + "description": "Deploy counter. Reserved for future versioning.", + "nullable": true, + "example": null + }, + "selfLink": { + "type": "string", + "description": "URI path to this device template resource.", + "readOnly": true, + "example": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp (UTC) when the template was created.", + "readOnly": true, + "example": "2026-01-15T09:23:41Z" + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp (UTC) when the template was last modified.", + "readOnly": true, + "example": "2026-01-15T09:23:41Z" + } + } + }, + "JobConfig": { + "type": "object", + "description": "Job configuration (discriminated by workflow type - use AutoScaleConfig, UpgradeConfig, or BackupConfig)", + "discriminator": { + "propertyName": "configType", + "mapping": { + "AUTO_SCALE": "#/components/schemas/AutoScaleConfig", + "SOFTWARE_INSTALLATION": "#/components/schemas/SoftwareInstallationConfig", + "SOFTWARE_DISTRIBUTION": "#/components/schemas/SoftwareDistributionConfig", + "BACKUP": "#/components/schemas/BackupConfig" + } + }, + "properties": { + "configType": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_INSTALLATION", + "SOFTWARE_DISTRIBUTION", + "BACKUP" + ], + "description": "Configuration type that determines which config object to use" + }, + "environmentReference": { + "type": "string", + "description": "[AUTO_SCALE] Reference to managed environment (UUID or alias string)" + }, + "templateReference": { + "type": "string", + "description": "[AUTO_SCALE] Template for new instances (UUID or alias string)" + }, + "licensePoolReference": { + "type": "string", + "description": "[AUTO_SCALE] License pool for allocation (UUID or alias string)" + }, + "providerType": { + "type": "string", + "description": "[AUTO_SCALE] Cloud provider type" + }, + "minSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Minimum pool size" + }, + "maxSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Maximum pool size" + }, + "desiredSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Current/target pool size" + }, + "evaluationPeriod": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Seconds between policy evaluations" + }, + "scaleInMethod": { + "type": "string", + "enum": [ + "NEWEST_FIRST", + "OLDEST_FIRST", + "RANDOM" + ], + "description": "[AUTO_SCALE] Strategy for scaling in" + }, + "scaleOutCooldownSeconds": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Cooldown after scale-out" + }, + "scaleInCooldownSeconds": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Cooldown after scale-in" + }, + "scalingPolicies": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ScalingPolicy" + }, + "description": "[AUTO_SCALE] Scaling policies" + } + } + }, + "IdleStatus": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "idle" + ], + "example": "idle" + }, + "message": { + "type": "string", + "example": "no action in progress" + } + } + }, + "VMwareEnvironmentProperties": { + "type": "object", + "required": [ + "cluster", + "datacenter", + "user", + "password", + "vmImage", + "networkInterfaceMapping" + ], + "properties": { + "cluster": { + "type": "string", + "description": "VMware cluster name" + }, + "datacenter": { + "type": "string", + "description": "VMware datacenter name" + }, + "user": { + "type": "string", + "description": "vCenter username (can include domain)" + }, + "password": { + "type": "string", + "format": "password", + "description": "vCenter password" + }, + "vmImage": { + "type": "string", + "description": "BIG-IP VM image template name" + }, + "networkInterfaceMapping": { + "type": "array", + "description": "Network interface mappings for VM deployment", + "minItems": 1, + "items": { + "type": "object", + "required": [ + "network" + ], + "properties": { + "network": { + "type": "string", + "description": "Network name in vCenter" + } + } + } + }, + "ipPoolAliasMapping": { + "type": "array", + "description": "IP pool alias mappings", + "items": { + "type": "object", + "required": [ + "alias", + "ipPoolReference" + ], + "properties": { + "alias": { + "type": "string", + "description": "Alias name" + }, + "ipPoolReference": { + "type": "string", + "description": "IP pool reference link" + } + } + } + } + } + }, + "Retention": { + "type": "string", + "pattern": "^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$", + "description": "ISO 8601 duration (e.g., P1Y for 1 year, P30D for 30 days).Supported units are Y (years), M (months), D (days), H (hours), M (minutes), S (seconds). Internally converted and rounded up to whole days. Maximum allowed retention is 1 year (P1Y)." + }, + "DiskAnalysisBatchResult": { + "type": "object", + "description": "Per-device disk analysis result. Field presence depends on analysis_status:\n- SUFFICIENT / INSUFFICIENT: available_disk_bytes and has_sufficient_space are always present; error_message is absent.\n- NO_DATA / ERROR: error_message is always present; has_sufficient_space is null; available_disk_bytes is null.\n", + "required": [ + "device_id", + "host", + "analysis_status" + ], + "properties": { + "device_id": { + "type": "string", + "format": "uuid" + }, + "host": { + "type": "string" + }, + "analysis_status": { + "type": "string", + "description": "Result status for this device analysis", + "enum": [ + "SUFFICIENT", + "INSUFFICIENT", + "NO_DATA", + "ERROR" + ] + }, + "available_disk_bytes": { + "type": "integer", + "format": "int64", + "nullable": true, + "description": "Available disk space in bytes. Guaranteed non-null when analysis_status is SUFFICIENT or INSUFFICIENT. Null when analysis_status is NO_DATA or ERROR.\n" + }, + "has_sufficient_space": { + "type": "boolean", + "nullable": true, + "description": "Whether the device meets the required disk space threshold. Guaranteed non-null when analysis_status is SUFFICIENT or INSUFFICIENT. Null when analysis_status is NO_DATA or ERROR.\n" + }, + "error_message": { + "type": "string", + "description": "Human-readable error details. Present when analysis_status is NO_DATA or ERROR. Absent when analysis_status is SUFFICIENT or INSUFFICIENT.\n" + } + } + }, + "ImageListResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SoftwareImage" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + } + }, + "HAPairCoordination": { + "type": "object", + "description": "The orchestration timeline for a single HA pair. The plan is derived\nfrom the SAME resolved controls the coordinator persisted on the pair\ncursor (pause-before-failover / pause-before-second-install /\nautomatic-failback / pause-before-failback), so a gate the operator\ndisabled is simply omitted from the timeline \u2014 mirroring how the\ncoordinator skips it at runtime.\n", + "required": [ + "pairId", + "standbyDeviceId", + "activeDeviceId", + "currentPhase", + "phases" + ], + "properties": { + "pairId": { + "type": "string", + "format": "uuid", + "description": "Identifier of the HA pair this timeline describes." + }, + "standbyDeviceId": { + "type": "string", + "format": "uuid", + "description": "Device that STARTED as standby (upgraded first, ha_order 0).\n" + }, + "standbyDeviceName": { + "type": "string", + "description": "Human-readable name of the standby device, projected when\navailable so the UI need not re-resolve it. Omitted when unknown.\n" + }, + "activeDeviceId": { + "type": "string", + "format": "uuid", + "description": "Device that STARTED as active (upgraded second, ha_order 1).\n" + }, + "activeDeviceName": { + "type": "string", + "description": "Human-readable name of the active device, projected when\navailable so the UI need not re-resolve it. Omitted when unknown.\n" + }, + "currentPhase": { + "$ref": "#/components/schemas/HAPhase", + "description": "The live coordinator phase taken from the pair cursor." + }, + "lastError": { + "type": "string", + "description": "Failure context for the pair, carried when currentPhase is FAILED.\nOmitted otherwise.\n" + }, + "phases": { + "type": "array", + "description": "The ordered, IN-PLAN coordination phases (disabled gates are\nomitted), each classified against the live cursor.\n", + "items": { + "$ref": "#/components/schemas/HAPhaseStep" + } + } + } + }, + "DeviceKind": { + "type": "string", + "description": "Canonical type of the target device", + "enum": [ + "BIGIP", + "RSERIES", + "VELOS" + ] + }, + "BgpConfig": { + "type": "object", + "description": "BGP routing configuration for the BIG-IP device.", + "required": [ + "name", + "localAs", + "routerId", + "routeDomain", + "addressFamilies" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the BGP configuration.", + "example": "my_bgp" + }, + "description": { + "type": "string", + "description": "Optional description of the BGP configuration.", + "nullable": true, + "example": "Example BGP configuration" + }, + "localAs": { + "type": "integer", + "description": "Local AS number.", + "minimum": 1, + "maximum": 4294967295, + "example": 65001 + }, + "routerId": { + "type": "string", + "description": "Router ID reference. Must be the name of a self IP defined in the selfIpList.\nThe actual router ID (IP address) will be resolved from the referenced self IP's address at deployment time.\n", + "example": "external-self" + }, + "routeDomain": { + "type": "string", + "description": "Route domain for the BGP configuration.", + "example": "/Common/0" + }, + "enabled": { + "type": "boolean", + "description": "Whether BGP is enabled.", + "default": true, + "example": true + }, + "defaultLocalPreference": { + "type": "integer", + "description": "Default local preference value.", + "default": 100, + "example": 100 + }, + "holdTime": { + "type": "integer", + "description": "BGP hold time in seconds.", + "default": 90, + "example": 90 + }, + "keepAlive": { + "type": "integer", + "description": "BGP keepalive interval in seconds.", + "default": 30, + "example": 30 + }, + "neighbor": { + "type": "array", + "description": "List of BGP neighbors.", + "items": { + "$ref": "#/components/schemas/BgpNeighbor" + }, + "example": [ + { + "name": "10.0.1.1", + "description": "Upstream BGP neighbor", + "remoteAs": 65002, + "password": "bgpSecretKey123", + "ebgpMultihop": 1, + "fallOver": "bfd", + "bfdTimers": { + "transmitInterval": 300, + "receiveInterval": 300, + "detectionMultiplier": 3 + }, + "enabled": true + } + ] + }, + "addressFamilies": { + "type": "array", + "description": "List of address family configurations for BGP.\nEach entry defines an internet protocol (e.g. `ipv4`) and an optional\nlist of routing protocols to redistribute into BGP.\nIf omitted, a default `ipv4` address family with `kernel` and `connected`\nredistribution is applied automatically.\n", + "items": { + "$ref": "#/components/schemas/BgpAddressFamily" + }, + "example": [ + { + "internetProtocol": "ipv4", + "redistributionList": [ + { + "routingProtocol": "connected" + }, + { + "routingProtocol": "kernel" + } + ] + } + ] + } + } + }, + "DownloadProgress": { + "type": "object", + "required": [ + "bytes", + "total", + "pct", + "speed_bps", + "eta_sec" + ], + "properties": { + "bytes": { + "type": "integer", + "format": "int64", + "example": 26214400 + }, + "total": { + "type": "integer", + "format": "int64", + "example": 41943040 + }, + "pct": { + "type": "integer", + "example": 62 + }, + "speed_bps": { + "type": "integer", + "format": "int64", + "example": 5242880 + }, + "eta_sec": { + "type": "integer", + "example": 3 + } + } + }, + "RollbackStatusResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "object", + "required": [ + "id", + "status", + "progress", + "log" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "example": "770e8400-e29b-41d4-a716-446655440007" + }, + "status": { + "type": "string", + "enum": [ + "pending", + "running", + "done", + "failed" + ], + "example": "done" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "example": 100 + }, + "log": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RollbackLogEntry" + } + } + } + } + } + }, + "FlightCheckStatus": { + "type": "string", + "description": "Outcome of a single core check within a snapshot.", + "enum": [ + "OK", + "DEGRADED", + "ERROR", + "NOT_COLLECTED" + ] + }, + "AuditExportRequest": { + "type": "object", + "description": "Optional filter body for POST /audit/export. All fields correspond to the same query parameters accepted by GET /audit/events.\n", + "properties": { + "username": { + "type": "string" + }, + "event_type": { + "type": "string", + "enum": [ + "user_message", + "assistant_response", + "tool_call", + "tool_result", + "error", + "data_access", + "pdf_export" + ] + }, + "tool": { + "type": "string" + }, + "keyword": { + "type": "string" + }, + "thread_id": { + "type": "string" + }, + "session_id": { + "type": "string" + }, + "date_from": { + "type": "string", + "format": "date-time" + }, + "date_to": { + "type": "string", + "format": "date-time" + } + } + }, + "Device": { + "allOf": [ + { + "$ref": "#/components/schemas/GlobalSettings" + }, + { + "$ref": "#/components/schemas/BasicSettings" + }, + { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the device" + } + } + } + ] + }, + "ReadinessCheckEntry": { + "type": "object", + "description": "A single readiness check to run. The `type` field selects the check\nimplementation.\n", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "description": "The readiness check type. Supported values:\n- `base_image_presence` \u2014 verifies required base OS image is on the device\n- `disk_space` \u2014 verifies sufficient free space for the image distribution\n- `image_compatibility` \u2014 verifies image product family is compatible with the target device type\n", + "enum": [ + "base_image_presence", + "disk_space", + "image_compatibility" + ] + } + } + }, + "BasicSettings": { + "type": "object", + "required": [ + "username", + "password", + "data_center", + "endpoint" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the device" + }, + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string", + "description": "Device endpoint in format ip:port or hostname:port (e.g., 192.168.1.100:443, bigip.example.com:8443)." + } + } + }, + "LicenseActivationResponse": { + "type": "object", + "required": [ + "status", + "message" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "Activation status", + "example": "success" + }, + "message": { + "type": "string", + "description": "Activation result message", + "example": "License activated successfully" + }, + "digitalAssetId": { + "type": "string", + "description": "Digital asset ID assigned by F5 TEEM", + "example": "DA-12345-67890" + }, + "licenseStatus": { + "type": "string", + "description": "Current license status", + "example": "Active" + }, + "activatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the license was activated", + "example": "2025-12-03T07:18:11Z" + }, + "hostLicense": { + "$ref": "#/components/schemas/HostLicenseDetails" + }, + "entitlements": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EntitledFeature" + }, + "description": "List of entitled features for this license" + }, + "subscriptionType": { + "type": "string", + "description": "Type of subscription (e.g., trial, paid, enterprise)", + "example": "trial" + }, + "expiryDate": { + "type": "string", + "format": "date-time", + "description": "License subscription expiry date", + "example": "2026-11-29T00:00:32Z" + } + } + }, + "PerDeviceDistributionStatus": { + "type": "object", + "description": "Runtime status of one device within a software distribution job execution.", + "required": [ + "deviceId", + "deviceKind", + "status", + "transferProgress", + "retryCount", + "checksumVerified" + ], + "properties": { + "deviceId": { + "type": "string", + "format": "uuid" + }, + "deviceName": { + "type": "string", + "description": "Display name resolved from `upgrade.device_upgrade_metadata.device_name`\n(mirrored from `public.devices.device_name` for BIG-IP and\n`public.f5os_providers.name` for F5OS). Empty when the metadata row\nis missing or has no name \u2014 clients should fall back to `deviceId`\nfor display. Best-effort batch lookup; failures don't fail the\nstatus response.\n" + }, + "deviceKind": { + "$ref": "#/components/schemas/DeviceKind" + }, + "status": { + "type": "string", + "description": "PENDING \u2014 waiting for a worker to claim.\nTRANSFERRING \u2014 chunks being pushed to the device.\nVERIFYING \u2014 waiting for on-device verification.\nCOMPLETED \u2014 success.\nFAILED \u2014 retries exhausted.\nCANCELLED \u2014 operator-initiated cancel.\nSKIPPED \u2014 device was locked by another execution at activate time.\n", + "enum": [ + "PENDING", + "TRANSFERRING", + "VERIFYING", + "COMPLETED", + "FAILED", + "CANCELLED", + "SKIPPED" + ] + }, + "transferProgress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Percent of bytes pushed to the device. Debounced; updated at most every few seconds per device." + }, + "retryCount": { + "type": "integer", + "minimum": 0, + "description": "Number of whole-device retries spent. Independent of chunk-level retries inside the BIG-IP client." + }, + "checksumVerified": { + "type": "boolean" + }, + "errorMessage": { + "type": "string", + "nullable": true + }, + "startedAt": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "completedAt": { + "type": "string", + "format": "date-time", + "nullable": true + } + } + }, + "Reference": { + "type": "object", + "required": [ + "link" + ], + "properties": { + "link": { + "type": "string", + "format": "uri" + }, + "fullPath": { + "type": "string" + } + } + }, + "StagingDeviceResponse": { + "type": "object", + "required": [ + "id", + "task_id", + "device_name", + "endpoint", + "validation_status", + "created_at", + "last_modified" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the staging device", + "example": "660e8400-e29b-41d4-a716-446655440001" + }, + "task_id": { + "type": "string", + "format": "uuid", + "description": "Migration task ID this device belongs to", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "device_name": { + "type": "string", + "description": "Name of the device", + "example": "bigip-prod-01.example.com" + }, + "endpoint": { + "type": "string", + "description": "Device endpoint URL", + "example": "https://192.168.1.100:443" + }, + "username": { + "type": "string", + "nullable": true, + "description": "Device username", + "example": "admin" + }, + "data_center": { + "type": "string", + "nullable": true, + "description": "Data center assignment", + "example": "US-EAST-1" + }, + "tls_enabled": { + "type": "boolean", + "nullable": true, + "description": "Whether TLS is enabled", + "example": true + }, + "ca_bundle_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "Associated CA bundle ID", + "example": "660e8400-e29b-41d4-a716-446655440002" + }, + "collection_interval": { + "type": "integer", + "nullable": true, + "description": "Collection interval in seconds", + "example": 60 + }, + "max_concurrent_connections": { + "type": "integer", + "nullable": true, + "description": "Maximum concurrent HTTP connections per device", + "example": 5 + }, + "validation_status": { + "type": "string", + "enum": [ + "PENDING", + "VALIDATING", + "SUCCESS", + "FAILED", + "SKIPPED" + ], + "description": "Current validation status", + "example": "SUCCESS" + }, + "error_message": { + "type": "string", + "nullable": true, + "description": "Error message if validation failed", + "example": "Connection timeout" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp", + "example": "2026-01-30T10:00:00Z" + }, + "last_modified": { + "type": "string", + "format": "date-time", + "description": "Last modification timestamp", + "example": "2026-01-30T12:00:00Z" + } + } + }, + "LicenseOffering": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier of the license offering", + "example": "f1e2d3c4-b5a6-7890-cdef-123456789abc" + }, + "regKey": { + "type": "string", + "description": "Registration key", + "example": "U5939-99933-49705-74523-4841009" + }, + "name": { + "type": "string", + "description": "Name of the license offering", + "example": "" + }, + "description": { + "type": "string", + "description": "Description of the license offering", + "example": "" + }, + "status": { + "type": "string", + "enum": [ + "ACTIVATING_AUTOMATIC", + "ACTIVATING_MANUAL", + "ACTIVATING_MANUAL_NEED_LICENSE_TEXT", + "ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED", + "ACTIVATION_FAILED", + "READY" + ], + "description": "Current activation status of the license offering. ACTIVATING_AUTOMATIC - automatic activation in progress via F5 license server. ACTIVATING_MANUAL - manual activation flow initiated. ACTIVATING_MANUAL_NEED_LICENSE_TEXT - manual activation awaiting license text input from user. ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED - manual activation with license text supplied by user. ACTIVATION_FAILED - activation attempt failed. READY - activation completed successfully and offering is ready for use.\n", + "example": "READY" + }, + "taskId": { + "type": "string", + "format": "uuid", + "description": "ID of the async task processing this offering activation", + "example": "d4e5f6a7-b8c9-0123-defg-456789abcdef" + }, + "licenseText": { + "type": "string", + "description": "Full license text returned by F5 license server" + }, + "licenseState": { + "$ref": "#/components/schemas/LicenseState" + }, + "dossier": { + "type": "string", + "description": "Dossier string generated during activation. Present when status is ACTIVATING_MANUAL_NEED_LICENSE_TEXT. User should submit this to F5 license server to obtain the license text.\n", + "example": "1ac56379204d679f59524f2e64300d03b91b4b9ff08225ce0087d91b6cf061227610" + }, + "publicKey": { + "type": "array", + "items": { + "type": "integer" + }, + "description": "Public key bytes used for license encryption (base64 encoded in JSON)" + }, + "encryptedPrivateKey": { + "type": "array", + "items": { + "type": "integer" + }, + "description": "Encrypted private key bytes (base64 encoded in JSON)" + }, + "message": { + "type": "string", + "description": "Status message providing guidance on next steps", + "example": "You must obtain license text and supply it here" + }, + "selfLink": { + "type": "string", + "format": "uri", + "description": "Self-referencing link", + "example": "https://localhost/api/licensing/pool/regkey/licenses/7dd7b971-6eb8-4b9e-995b-1dcb1287d65f/offerings/U5939-99933-49705-74523-4841009" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the offering was created" + }, + "activatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the offering was activated" + }, + "isAssigned": { + "type": "boolean", + "description": "Indicates whether this offering has been assigned to a device.\ntrue = offering is assigned to a member device\nfalse = offering is available for assignment\n", + "example": false + } + } + }, + "UpdateSoftwareInstallationJobRequest": { + "description": "Replaces the mutable fields of a software installation job.\nOnly allowed when the job is in DRAFT or READY state.\nAll fields are optional \u2014 only the provided fields will be updated.\n", + "allOf": [ + { + "$ref": "#/components/schemas/SoftwareInstallationJobPayload" + } + ] + }, + "Job": { + "type": "object", + "required": [ + "id", + "workflowId", + "type", + "name", + "status", + "config", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "workflowId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "name": { + "type": "string" + }, + "description": { + "type": "string", + "description": "Optional human-readable job description" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "INACTIVE", + "ERROR", + "COMPLETED", + "FAILED", + "CANCELLED", + "DELETING" + ] + }, + "enabled": { + "type": "boolean", + "description": "Whether the job can be activated, paused, or resumed." + }, + "config": { + "$ref": "#/components/schemas/JobConfig", + "description": "Job-level config for runtime behavior" + }, + "effectiveConfig": { + "$ref": "#/components/schemas/JobConfig", + "description": "Resolved config (workflow defaultConfig merged with job config)", + "readOnly": true + }, + "runtime": { + "$ref": "#/components/schemas/JobRuntime" + }, + "schedule": { + "$ref": "#/components/schemas/Schedule", + "description": "Only populated for ON_DEMAND jobs with a schedule configured" + }, + "jobUrl": { + "type": "string", + "readOnly": true, + "description": "Optional REST endpoint for this job. For AutoScale jobs this is the generic workflow job endpoint. Some feature-owned jobs may use a type-specific endpoint.", + "example": "/api/v1/workflows/b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73/jobs/114ca9f9-88a3-49e1-92f2-757d7fedde98" + }, + "version": { + "type": "string", + "readOnly": true + }, + "modifiedBy": { + "type": "string", + "description": "Username of the operator who last modified the job.", + "readOnly": true + }, + "runningExecutionsCount": { + "type": "integer", + "description": "Number of currently RUNNING executions for this job.", + "readOnly": true + }, + "triggerCount": { + "type": "integer", + "description": "Number of configured triggers for this job.", + "readOnly": true + }, + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + } + } + }, + "DataCenter": { + "type": "object", + "additionalProperties": false, + "required": [ + "name" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the data center" + }, + "name": { + "type": "string", + "description": "Name of the Data Center.", + "maxLength": 255 + } + } + }, + "CheckStatus": { + "type": "string", + "description": "Outcome of a single validation check.", + "enum": [ + "PASS", + "WARN", + "FAIL", + "SKIP" + ] + }, + "BulkDeleteImageResult": { + "type": "object", + "required": [ + "image_id", + "status" + ], + "properties": { + "image_id": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "enum": [ + "DELETED", + "FAILED" + ] + }, + "error": { + "$ref": "#/components/schemas/Error" + } + } + }, + "BulkDeleteJobsRequest": { + "type": "object", + "required": [ + "job_ids" + ], + "properties": { + "job_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + }, + "minItems": 1, + "maxItems": 100, + "description": "List of job IDs to delete (1\u2013100 items)" + } + } + }, + "F5OSAddRequest": { + "description": "F5OS add request. All F5OS device fields are merged at the top\nlevel alongside the deviceType discriminator, mirroring the flat\nshape of BigIPAddRequest. No nested `f5os` object.\n", + "allOf": [ + { + "type": "object", + "required": [ + "deviceType" + ], + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "f5os" + ] + } + } + }, + { + "$ref": "#/components/schemas/F5OSDevice" + } + ] + }, + "BulkDeleteJobResultStatus": { + "type": "string", + "enum": [ + "DELETED", + "FAILED" + ], + "description": "DELETED \u2014 job was successfully deleted.\nFAILED \u2014 job could not be deleted (see error for reason).\n" + }, + "ScheduleRecommendationResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "object", + "required": [ + "has_data", + "message" + ], + "properties": { + "has_data": { + "type": "boolean", + "example": true + }, + "best_dow": { + "type": "string", + "example": "Sunday" + }, + "best_hour": { + "type": "integer", + "minimum": 0, + "maximum": 23, + "example": 2 + }, + "best_hour_end": { + "type": "integer", + "minimum": 0, + "maximum": 24, + "example": 4 + }, + "window_label": { + "type": "string", + "example": "Sunday 02:00-04:00 UTC" + }, + "avg_duration_sec": { + "type": "integer", + "example": 487 + }, + "sample_size": { + "type": "integer", + "example": 7 + }, + "message": { + "type": "string", + "example": "Lowest failure rate (0%) across 7 historical patches." + } + } + } + } + }, + "AuditPagination": { + "type": "object", + "description": "Pagination metadata returned alongside audit event lists.", + "required": [ + "page", + "pageSize", + "totalEvents", + "totalPages" + ], + "properties": { + "page": { + "type": "integer", + "description": "Current page number (1-based)", + "example": 1 + }, + "pageSize": { + "type": "integer", + "description": "Number of results per page", + "example": 20 + }, + "totalEvents": { + "type": "integer", + "description": "Total number of events matching the current filters", + "example": 87 + }, + "totalPages": { + "type": "integer", + "description": "Total number of pages", + "example": 5 + } + } + }, + "UpsertCompatUpgradePathRequest": { + "type": "object", + "description": "Request body for POST /compat/upgrade-paths.", + "required": [ + "target_major_version", + "min_source_version" + ], + "properties": { + "target_major_version": { + "type": "string", + "description": "Target BIG-IP major version, e.g. \"17\" or \"21\".", + "minLength": 1, + "example": "21" + }, + "min_source_version": { + "type": "string", + "description": "Minimum source version required (inclusive), e.g. \"17.1.0\".", + "minLength": 1, + "example": "14.0.0" + }, + "max_source_version": { + "type": "string", + "nullable": true, + "description": "Maximum source version (inclusive). Omit or null for no upper bound." + }, + "notes": { + "type": "string", + "nullable": true, + "description": "Optional human-readable note." + } + } + }, + "Activity": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "executionId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "activityType": { + "type": "string", + "description": "Logical action type (e.g. SCALE_OUT, SCALE_IN, UPGRADE)" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "COMPLETED", + "FAILED", + "SKIPPED", + "CANCELLED" + ] + }, + "trigger": { + "type": "string", + "enum": [ + "USER", + "ALERT", + "SYSTEM", + "SCHEDULE" + ] + }, + "reason": { + "type": "string" + }, + "startedAt": { + "type": "string", + "format": "date-time" + }, + "completedAt": { + "type": "string", + "format": "date-time" + }, + "durationMs": { + "type": "integer" + }, + "currentStep": { + "type": "string" + }, + "stepCount": { + "type": "integer" + }, + "correlationId": { + "type": "string", + "format": "uuid" + } + } + }, + "Schedule": { + "type": "object", + "properties": { + "cron": { + "type": "string", + "description": "Unix cron expression (e.g. \"0 2 * * *\" for 2 AM daily, \"0 2 * * 0\" for Sundays at 2 AM)", + "example": "0 2 * * *" + }, + "timezone": { + "type": "string", + "default": "UTC", + "description": "IANA timezone for cron evaluation (e.g. America/New_York, Europe/London)", + "example": "America/New_York" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether the schedule is active" + } + }, + "example": { + "cron": "0 2 * * 0", + "timezone": "America/New_York", + "enabled": true + } + }, + "ProvisionedModule": { + "type": "object", + "description": "A BIG-IP module provisioning entry.", + "required": [ + "module", + "level" + ], + "properties": { + "module": { + "type": "string", + "description": "BIG-IP module name.", + "enum": [ + "AFM", + "AM", + "APM", + "ASM", + "AVR", + "DOS", + "FPS", + "GTM", + "ILX", + "LC", + "LTM", + "PEM", + "SWG", + "URLDB" + ], + "example": "LTM" + }, + "level": { + "type": "string", + "description": "Provisioning level.", + "enum": [ + "DEDICATED", + "MINIMUM", + "NOMINAL", + "NONE" + ], + "example": "NOMINAL" + } + } + }, + "ConnectRequest": { + "type": "object", + "required": [ + "username", + "password", + "providerName" + ], + "properties": { + "username": { + "type": "string", + "description": "vSphere username" + }, + "password": { + "type": "string", + "description": "vSphere password" + }, + "providerName": { + "type": "string", + "description": "Name of the provider (used to resolve vSphere hostname)" + } + } + }, + "ConfigAIProviderRequest": { + "type": "object", + "required": [ + "provider_name" + ], + "properties": { + "provider_name": { + "type": "string", + "description": "AI provider name (e.g., openai, anthropic, local)" + }, + "api_token": { + "type": "string", + "description": "API token for the provider. Required for 'openai' and 'claude' providers, optional for 'local' provider." + }, + "base_url": { + "type": "string", + "description": "Base URL for the provider. Required for 'local' provider, optional for 'openai' and 'claude'." + }, + "model": { + "type": "string", + "description": "Model name to use. Required for 'local' provider, optional for others." + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "Optional CA certificate UUID from trust store for custom SSL/TLS connections" + }, + "skip_tls_verify": { + "type": "boolean", + "description": "Indicates if TLS verification should be skipped for this provider" + } + } + }, + "UpdateSoftwareDistributionJobRequest": { + "description": "Replaces the mutable fields of a software distribution job.\nOnly allowed when the job is in DRAFT or READY state.\nAll fields are optional \u2014 only the provided fields will be updated.\n", + "allOf": [ + { + "$ref": "#/components/schemas/SoftwareDistributionJobPayload" + } + ] + }, + "CheckSeverity": { + "type": "string", + "description": "Whether a check failure is advisory (SOFT) or blocking (HARD).\n- SOFT: warn operator; job can still proceed\n- HARD: a FAIL blocks the job; a WARN reports indeterminate live data without blocking\n", + "enum": [ + "SOFT", + "HARD" + ] + }, + "IPLease": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "poolId": { + "type": "string", + "format": "uuid" + }, + "address": { + "type": "string", + "example": "10.0.0.10" + }, + "gateway": { + "type": "string", + "nullable": true + }, + "allocationId": { + "type": "string", + "nullable": true + }, + "deviceId": { + "type": "string", + "format": "uuid", + "nullable": true + }, + "leaseTags": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Tag" + } + }, + "metadata": { + "type": "object", + "additionalProperties": true + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "deletedAt": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "required": [ + "id", + "poolId", + "address", + "createdAt", + "updatedAt" + ] + }, + "PatchDeviceTemplateDefinition": { + "type": "object", + "description": "Partial template definition for merge-patching (used by PATCH).\nAll fields are optional \u2014 only provided fields are updated.\nOmitted fields retain their current values.\nTo explicitly clear a nullable field, set it to `null`.\n", + "properties": { + "rootPassword": { + "type": "string", + "description": "BIG-IP root password.", + "nullable": true, + "minLength": 1, + "example": "s3cur3P@ss!" + }, + "timeZone": { + "type": "string", + "description": "NTP timezone string.", + "nullable": true, + "example": "America/Los_Angeles" + }, + "defaultRoute": { + "type": "string", + "description": "Default network gateway route.", + "nullable": true, + "example": "10.0.0.1" + }, + "managementSslPort": { + "type": "integer", + "description": "BIG-IP management SSL port.", + "nullable": true, + "example": 443 + }, + "managementIp": { + "$ref": "#/components/schemas/ManagementIp" + }, + "hostnameComponents": { + "type": "array", + "description": "Ordered array of hostname building blocks.", + "items": { + "$ref": "#/components/schemas/HostnameComponent" + } + }, + "lookupServerList": { + "type": "array", + "description": "List of DNS lookup server addresses.", + "items": { + "type": "string" + } + }, + "ntpServerList": { + "type": "array", + "description": "List of NTP server addresses.", + "items": { + "type": "string" + } + }, + "userAccountList": { + "type": "array", + "description": "Array of BIG-IP user accounts.", + "items": { + "$ref": "#/components/schemas/UserAccount" + } + }, + "provisionedModuleList": { + "type": "array", + "description": "Array of BIG-IP modules to provision.", + "items": { + "$ref": "#/components/schemas/ProvisionedModule" + } + }, + "networkRouteList": { + "type": "array", + "description": "Array of network interface routes.", + "items": { + "$ref": "#/components/schemas/NetworkRoute" + } + }, + "vlanList": { + "type": "array", + "description": "Array of VLAN definitions.", + "items": { + "$ref": "#/components/schemas/VlanDefinition" + } + }, + "selfIpList": { + "type": "array", + "description": "Array of self-IP definitions. Replaces the entire selfIpList on PATCH.\n", + "items": { + "$ref": "#/components/schemas/SelfIpDefinition" + } + }, + "bgpConfig": { + "$ref": "#/components/schemas/BgpConfig" + } + } + }, + "DeviceTemplateWriteRequest": { + "type": "object", + "description": "Payload for creating (POST) or fully replacing (PUT) a device template.\n", + "required": [ + "name", + "provider", + "definition" + ], + "properties": { + "name": { + "type": "string", + "description": "Human-readable name for the device template. Must be unique.", + "minLength": 1, + "maxLength": 255, + "example": "BIG-IP Standard Template" + }, + "provider": { + "type": "string", + "description": "Provider or vendor (e.g. VMware, AWS, Azure).", + "minLength": 1, + "maxLength": 255, + "example": "VMware" + }, + "description": { + "type": "string", + "description": "Optional human-readable description.", + "nullable": true, + "maxLength": 1000, + "example": "Standard VMware configuration for production workloads" + }, + "draft": { + "type": "boolean", + "description": "When `true`, the template is created/kept in DRAFT state.\nWhen `false` or omitted, a DRAFT template is promoted to NEW.\n", + "default": false + }, + "definition": { + "$ref": "#/components/schemas/DeviceTemplateDefinition" + } + } + }, + "BulkDeleteImagesResponse": { + "type": "object", + "required": [ + "results" + ], + "properties": { + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkDeleteImageResult" + } + } + } + }, + "BgpNeighbor": { + "type": "object", + "description": "A BGP neighbor configuration.", + "required": [ + "name", + "remoteAs" + ], + "properties": { + "name": { + "type": "string", + "description": "IP address of the BGP neighbor.", + "example": "10.0.1.1" + }, + "description": { + "type": "string", + "description": "Optional description of the neighbor.", + "nullable": true, + "example": "Upstream BGP neighbor" + }, + "remoteAs": { + "type": "integer", + "description": "Remote AS number of the neighbor.", + "minimum": 1, + "maximum": 4294967295, + "example": 65002 + }, + "password": { + "type": "string", + "description": "Optional password for BGP authentication.", + "nullable": true, + "minLength": 1, + "maxLength": 255, + "example": "SecureBGPPassword" + }, + "ebgpMultihop": { + "type": "integer", + "description": "Allow EBGP neighbors not on directly connected networks.\nSpecifies the maximum number of hops allowed to reach the neighbor.\n", + "nullable": true, + "minimum": 1, + "maximum": 255, + "default": 1, + "example": 1 + }, + "fallOver": { + "type": "string", + "description": "Fall-over detection method for BGP neighbor.\n- \"bfd\": Bidirectional Forwarding Detection (BFD)\n- \"bfd-multihop\": BFD for multihop neighbors\n- \"none\": No fall-over detection\n", + "enum": [ + "bfd", + "bfd-multihop", + "none" + ], + "default": "none", + "example": "bfd", + "nullable": true + }, + "bfdTimers": { + "$ref": "#/components/schemas/BFDTimers", + "description": "BFD timer configuration (required if fallOver is \"bfd\" or \"bfd-multihop\").\n", + "nullable": true + }, + "enabled": { + "type": "boolean", + "description": "Whether the neighbor is enabled.", + "default": true, + "example": true + } + } + }, + "ValidationDeviceTarget": { + "type": "object", + "description": "A single device target for the POST /validate request.", + "required": [ + "device_id" + ], + "properties": { + "device_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the device to validate." + }, + "volume_override": { + "type": "string", + "description": "Optional explicit volume name for this device (e.g. \"HD1.2\"). When set, pins this device to that specific volume slot and applies the existing-slot disk-space threshold (2 GB soft) rather than the new-slot threshold (15 GB soft). Mirrors SoftwareInstallationDeviceTarget.volumeOverride so callers can use the same configuration for both validation and job creation. Takes precedence over the top-level volume_strategy on the request for this device.\n" + } + } + }, + "UpdateStorageTargetRequest": { + "type": "object", + "description": "Partial update of a storage target. All fields are optional. Only the\nlisted fields are accepted; any other keys are ignored server-side.\nSensitive/internal fields (id, credentials_ref, status, last_checked_at,\nlatency, created_at, last_modified) cannot be set by clients.\n", + "properties": { + "name": { + "type": "string" + }, + "storage_type": { + "type": "string", + "enum": [ + "nfs", + "smb" + ] + }, + "server": { + "type": "string" + }, + "share_path": { + "type": "string" + }, + "mount_options": { + "type": "string" + }, + "username": { + "type": "string" + }, + "password": { + "type": "string", + "description": "SMB password (stored securely in Vault, never in DB)" + }, + "is_default": { + "type": "boolean", + "description": "When true, marks this target as the default for new backups." + } + } + } + }, + "parameters": { + "SizeParam": { + "name": "size", + "in": "query", + "required": false, + "description": "Number of items per page.", + "schema": { + "type": "integer", + "minimum": 1 + } + }, + "SearchParam": { + "name": "search", + "in": "query", + "description": "Search term to filter devices by name, alias, or endpoint", + "required": false, + "schema": { + "type": "string" + } + }, + "ActivityId": { + "name": "activityId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "SinceParam": { + "name": "since", + "in": "query", + "required": false, + "description": "Return only devices updated after this timestamp (ISO 8601 format).\nUse the lastSync value from previous response for delta updates.\n", + "schema": { + "type": "string", + "format": "date-time" + } + }, + "JobId": { + "name": "jobId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "ProviderId": { + "name": "providerId", + "in": "path", + "description": "UUID of the cloud provider", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "PageSizeParam": { + "name": "page_size", + "in": "query", + "schema": { + "type": "integer", + "default": 20, + "minimum": 1, + "maximum": 500 + } + }, + "PageParam": { + "name": "page", + "in": "query", + "schema": { + "type": "integer", + "minimum": 1, + "default": 1 + } + }, + "DeviceIdParam": { + "name": "deviceId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "DiffIdParam": { + "name": "diffId", + "in": "path", + "required": true, + "description": "Unique ID of a flight-check diff.", + "schema": { + "type": "string", + "format": "uuid" + } + }, + "TaskIdParam": { + "name": "taskId", + "in": "path", + "required": true, + "description": "UUID of the task.", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "660e8400-e29b-41d4-a716-446655440001" + }, + "LimitParam": { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + } + }, + "ExecutionId": { + "name": "executionId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "SortParam": { + "name": "sort", + "in": "query", + "description": "Sort order, e.g. 'name,-created_at' (prefix '-' for descending)", + "required": false, + "schema": { + "type": "string" + } + }, + "SnapshotIdParam": { + "name": "snapshotId", + "in": "path", + "required": true, + "description": "Unique ID of a flight-check snapshot.", + "schema": { + "type": "string", + "format": "uuid" + } + }, + "PoolId": { + "name": "poolId", + "in": "path", + "description": "UUID of the IP pool.", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "WorkflowId": { + "name": "workflowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "DeviceTemplateIdParam": { + "name": "id", + "in": "path", + "required": true, + "description": "UUID of the device template.", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "JobIdParam": { + "name": "jobId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "ImageIdParam": { + "name": "imageId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "CompatIdParam": { + "name": "compatId", + "in": "path", + "required": true, + "description": "Unique ID of a compatibility matrix row.", + "schema": { + "type": "string", + "format": "uuid" + } + } + }, + "securitySchemes": { + "basicAuth": { + "type": "http", + "scheme": "basic", + "description": "Basic authentication" + } + } + } +} \ No newline at end of file diff --git a/F5/Insight/OpenAPIs/f5_insight-v1.2.2.json b/F5/Insight/OpenAPIs/f5_insight-v1.2.2.json new file mode 100644 index 0000000..f361ed5 --- /dev/null +++ b/F5/Insight/OpenAPIs/f5_insight-v1.2.2.json @@ -0,0 +1,33461 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "F5 Insight API", + "description": "Unified API for F5 Insight monitoring and analytics platform including device management, system operations, and AI-powered insights\n\n# Authentication\n\n", + "version": "v1.2.2", + "contact": { + "name": "F5 Insight Team" + } + }, + "servers": [ + { + "url": "/api" + }, + { + "url": "/api/provisioning/v1" + }, + { + "url": "/api/v1/fleet/upgrade" + }, + { + "url": "/" + } + ], + "tags": [ + { + "name": "Authentication" + }, + { + "name": "Authorization", + "description": "Provider group/resource attribute \u2192 Role mapping management (authZ).\nAdmin-only APIs for configuring which LDAP/SAML group values map to which F5 Insight roles.\nAlso includes the internal Zitadel webhook endpoint for runtime group resolution.\n" + }, + { + "name": "AIDF Insights" + }, + { + "name": "AuditConsole" + }, + { + "name": "Backup" + }, + { + "name": "ChatHistory" + }, + { + "name": "Cloud Environments" + }, + { + "name": "Cloud Providers", + "description": "Operations for managing cloud provider configurations" + }, + { + "name": "CompatMatrix" + }, + { + "name": "Configuration" + }, + { + "name": "Device Management" + }, + { + "name": "Device Templates", + "description": "Operations on device template configurations." + }, + { + "name": "ExternalAuth" + }, + { + "name": "FQDN Configuration" + }, + { + "name": "Feature Flags" + }, + { + "name": "FlightChecks" + }, + { + "name": "Health" + }, + { + "name": "IdentityProviders" + }, + { + "name": "Images" + }, + { + "name": "Infrastructure Discovery" + }, + { + "name": "Inventory" + }, + { + "name": "Jobs", + "description": "Configured runtime instances of a Workflow" + }, + { + "name": "License" + }, + { + "name": "License Members", + "description": "Operations for managing license assignments to BIG-IP devices" + }, + { + "name": "License Offering", + "description": "Operations for managing license offerings within pools" + }, + { + "name": "License Pool", + "description": "Operations for managing license pools" + }, + { + "name": "Lifecycle - Continuous", + "description": "Lifecycle control for CONTINUOUS jobs (activate / pause / resume)" + }, + { + "name": "Lifecycle - OnDemand", + "description": "Lifecycle control for ON_DEMAND jobs (run / cancel / schedule)" + }, + { + "name": "Mode Management" + }, + { + "name": "Observability", + "description": "Executions, activities, activity steps, and audit events" + }, + { + "name": "Onboarding" + }, + { + "name": "Readiness" + }, + { + "name": "Schedule" + }, + { + "name": "Settings" + }, + { + "name": "Signals", + "description": "External signals that trigger execution (alerts, desired-size overrides)" + }, + { + "name": "SoftwareDistribution" + }, + { + "name": "SoftwareInstallation" + }, + { + "name": "Storage" + }, + { + "name": "System" + }, + { + "name": "Tasks", + "description": "Operations for tracking async task status" + }, + { + "name": "Telemetry Configuration" + }, + { + "name": "Upgrade" + }, + { + "name": "VM Tasks" + }, + { + "name": "Validation" + }, + { + "name": "Validators" + }, + { + "name": "Workflows", + "description": "Workflow template definitions (type + executionMode + default config)" + }, + { + "name": "others", + "description": "Other endpoints" + } + ], + "paths": { + "/api/auth/login": { + "post": { + "x-mode": "lite", + "summary": "User login", + "operationId": "login", + "tags": [ + "Authentication" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LoginRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Login successful", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResponse" + } + } + } + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/auth/refresh": { + "post": { + "x-mode": "lite", + "summary": "Refresh access token", + "operationId": "refresh", + "tags": [ + "Authentication" + ], + "description": "Refreshes the access token using the refresh token stored in httpOnly cookie.\nNo request body required - refresh token is read from cookie.\n", + "responses": { + "200": { + "description": "Token refreshed successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResponse" + } + } + } + }, + "401": { + "description": "Invalid or expired refresh token", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/auth/logout": { + "post": { + "x-mode": "lite", + "summary": "Logout user (revoke refresh token)", + "operationId": "logout", + "tags": [ + "Authentication" + ], + "description": "Logs out the user by revoking the refresh token stored in httpOnly cookie.\nNo request body required - refresh token is read from cookie.\n", + "responses": { + "200": { + "description": "Logout successful", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MessageResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/auth/logout-all": { + "post": { + "x-mode": "lite", + "summary": "Logout from all devices", + "operationId": "logoutAll", + "tags": [ + "Authentication" + ], + "responses": { + "200": { + "description": "Logged out from all devices successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MessageResponse" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/auth/change-password": { + "post": { + "x-mode": "lite", + "summary": "Change user password", + "operationId": "changePassword", + "tags": [ + "Authentication" + ], + "description": "Change user password using username and password.\nCan be called either with or without Bearer token:\n- With token: User can change their own password\n- Without token: Authentication is done with username and password (for expired password scenarios)\n", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChangePasswordRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Password changed successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MessageResponse" + } + } + } + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Invalid credentials or unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/auth/login/external": { + "post": { + "x-mode": "lite", + "summary": "Initiate OIDC login", + "operationId": "oidcLogin", + "tags": [ + "Authentication" + ], + "description": "Starts the OIDC authorization code flow with PKCE.\nReturns a 302 redirect to the configured identity provider authorization endpoint.\n\nSupports two content types for the optional `idp_type` field:\n\n**application/x-www-form-urlencoded** (recommended for browser forms):\n `idp_type=ldap` or `idp_type=saml`\n\n**application/json**:\n `{\"idp_type\": \"ldap\"}` or `{\"idp_type\": \"saml\"}`\n\nWhen `idp_type` is `ldap` or `saml`, the organization-scoped external login policy is\napplied so LDAP/SAML IDPs are shown on the login page.\nOmitting `idp_type` (or sending an empty body) shows the instance-level login screen.\n", + "requestBody": { + "required": false, + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "type": "object", + "properties": { + "idp_type": { + "type": "string", + "enum": [ + "ldap", + "saml" + ], + "description": "Set to 'ldap' or 'saml' to show organization-scoped identity providers on the login page." + } + } + }, + "example": { + "idp_type": "ldap" + } + }, + "application/json": { + "schema": { + "type": "object", + "properties": { + "idp_type": { + "type": "string", + "enum": [ + "ldap", + "saml" + ], + "description": "Set to 'ldap' or 'saml' to show organization-scoped identity providers on the login page." + } + } + }, + "example": { + "idp_type": "ldap" + } + } + } + }, + "responses": { + "302": { + "description": "Redirect to configured identity provider authorization endpoint", + "headers": { + "Location": { + "schema": { + "type": "string" + } + } + } + }, + "400": { + "description": "Invalid idp_type value or malformed request body", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "501": { + "description": "OIDC not configured", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/auth/callback": { + "get": { + "x-mode": "lite", + "summary": "OIDC authorization callback", + "operationId": "oidcCallback", + "tags": [ + "Authentication" + ], + "description": "The configured identity provider redirects the browser here after successful user authentication.\nExchanges the authorization code for tokens, stores them in a server-side session,\nsets an HttpOnly session cookie, and redirects the browser to the React SPA.\n", + "parameters": [ + { + "name": "code", + "in": "query", + "required": true, + "schema": { + "type": "string" + }, + "description": "Authorization code returned by the identity provider" + }, + { + "name": "state", + "in": "query", + "required": true, + "schema": { + "type": "string" + }, + "description": "State parameter for CSRF protection" + } + ], + "responses": { + "302": { + "description": "Redirect to React SPA after successful token exchange", + "headers": { + "Location": { + "schema": { + "type": "string" + } + }, + "Set-Cookie": { + "schema": { + "type": "string" + }, + "description": "HttpOnly session cookie (f5insight_session)" + } + } + }, + "400": { + "description": "Missing or invalid parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "501": { + "description": "OIDC not configured", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/auth/session": { + "get": { + "x-mode": "lite", + "summary": "Retrieve external login session token", + "operationId": "oidcSession", + "tags": [ + "Authentication" + ], + "description": "Called by the React SPA after landing on /auth/callback.\nReads the HttpOnly session cookie and returns the F5 Insight access token\ndetails needed by the SPA.\n", + "responses": { + "200": { + "description": "Session token retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OIDCSessionResponse" + } + } + } + }, + "401": { + "description": "No valid session cookie or session expired", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "501": { + "description": "OIDC not configured", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/auth/identity-providers": { + "get": { + "x-mode": "lite", + "summary": "List identity providers", + "operationId": "listIdentityProviders", + "tags": [ + "IdentityProviders" + ], + "description": "Returns all configured providers (LDAP, SAML).\n\nAuthenticated callers receive the full provider configuration. Unauthenticated\ncallers receive the public login-page shape, which intentionally omits\nprovider configuration details.\n", + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/ListIdentityProvidersResponse" + }, + { + "$ref": "#/components/schemas/PublicListIdentityProvidersResponse" + } + ] + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/api/auth/identity-providers/ldap": { + "x-feature": "userManagement", + "post": { + "x-mode": "lite", + "summary": "Create LDAP provider", + "operationId": "createLDAPProvider", + "tags": [ + "IdentityProviders" + ], + "description": "Creates a new LDAP identity provider.\n\nCreate only provisions the provider. It does not activate or deactivate any provider.\nUse `POST /auth/identity-providers/{id}/activate` to enable a provider for login.\nThe `enabled` field in the request body is ignored.\n", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateLDAPProviderRequest" + } + } + } + }, + "responses": { + "201": { + "description": "LDAP provider created inactive.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IdentityProviderResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "409": { + "description": "Provider name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + }, + "503": { + "description": "External identity provider management is not configured", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/auth/identity-providers/saml": { + "x-feature": "userManagement", + "post": { + "x-mode": "lite", + "summary": "Create SAML provider", + "operationId": "createSAMLProvider", + "tags": [ + "IdentityProviders" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSAMLProviderRequest" + } + } + } + }, + "responses": { + "201": { + "description": "SAML provider created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IdentityProviderResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "409": { + "description": "Provider name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/api/auth/identity-providers/ldap/{id}": { + "x-feature": "userManagement", + "put": { + "x-mode": "lite", + "summary": "Update LDAP provider (full replace)", + "operationId": "updateLDAPProvider", + "tags": [ + "IdentityProviders" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateLDAPProviderRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IdentityProviderResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/api/auth/identity-providers/saml/{id}": { + "x-feature": "userManagement", + "put": { + "x-mode": "lite", + "summary": "Update SAML provider (full replace)", + "operationId": "updateSAMLProvider", + "tags": [ + "IdentityProviders" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSAMLProviderRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IdentityProviderResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/api/auth/identity-providers/validate": { + "x-feature": "userManagement", + "post": { + "x-mode": "lite", + "summary": "Validate provider config (without saving)", + "operationId": "validateIdentityProvider", + "tags": [ + "IdentityProviders" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidateProviderRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Validation successful", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidateProviderResponse" + } + } + } + }, + "400": { + "description": "Validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidateProviderResponse" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/api/auth/identity-providers/{id}": { + "x-feature": "userManagement", + "get": { + "x-mode": "lite", + "summary": "Get identity provider by ID", + "operationId": "getIdentityProvider", + "tags": [ + "IdentityProviders" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IdentityProviderResponse" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + }, + "delete": { + "x-mode": "lite", + "summary": "Delete identity provider", + "operationId": "deleteIdentityProvider", + "tags": [ + "IdentityProviders" + ], + "description": "Permanently deletes the identity provider.\n\nDeletion is **always allowed**, including active providers and the last remaining provider.\nDeleting an active provider leaves the system with 0 active providers (local login still works).\n", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Provider deleted successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteIdentityProviderResponse" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Provider is still referenced by role mappings", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProviderInUseByRoleMappingsError" + }, + "example": { + "code": "PROVIDER_IN_USE_BY_ROLE_MAPPINGS", + "message": "Identity provider is used by role mappings", + "status": 409, + "category": "RESOURCE", + "help": "Remove role mappings for this provider before deleting it.", + "provider_id": "ldap-id-123", + "mapping_count": 2, + "role_mappings": [ + { + "provider_id": "ldap-id-123", + "role_id": "550e8400-e29b-41d4-a716-446655440000", + "grouped_resource_attribute": [ + "bigip-admins", + "network-admins" + ] + } + ] + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + }, + "503": { + "description": "Unable to validate provider role mapping usage", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "code": "PROVIDER_MAPPING_USAGE_UNAVAILABLE", + "message": "Unable to validate whether this identity provider is used by role mappings", + "status": 503, + "category": "SYSTEM", + "help": "Try again later. The provider was not deleted." + } + } + } + } + } + } + }, + "/api/auth/identity-providers/{id}/activate": { + "x-feature": "userManagement", + "post": { + "x-mode": "lite", + "summary": "Activate identity provider", + "operationId": "activateIdentityProvider", + "tags": [ + "IdentityProviders" + ], + "description": "Activates the provider so it appears on the login page.\n\nIf another LDAP provider is active, activation fails with 409 Conflict.\nDeactivate the currently active LDAP provider before activating a different one.\n\nIdempotent: if the provider is already active, returns its current state without making any changes.\n", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Provider activated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IdentityProviderResponse" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Another LDAP provider is already active", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + }, + "503": { + "description": "External identity provider management is not configured", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/auth/identity-providers/{id}/deactivate": { + "x-feature": "userManagement", + "post": { + "x-mode": "lite", + "summary": "Deactivate identity provider", + "operationId": "deactivateIdentityProvider", + "tags": [ + "IdentityProviders" + ], + "description": "Deactivates the provider for external login.\nIt will no longer appear on the login page.\n\nDeactivation is **always allowed**, including when this is the only active provider.\nDeactivating the last active provider leaves the system with 0 active providers,\nwhich is valid (local login still works; LDAP login becomes unavailable until a provider is re-activated).\n\nIdempotent: if the provider is already inactive, returns its current state without changes.\n", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Provider deactivated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IdentityProviderResponse" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + }, + "503": { + "description": "External identity provider management is not configured", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/auth/fqdn": { + "x-feature": "userManagement", + "get": { + "x-mode": "lite", + "summary": "Get current external FQDN", + "operationId": "getFqdnConfig", + "tags": [ + "ExternalAuth" + ], + "description": "Get the currently configured canonical external URL used by F5 Insight and ZITADEL.", + "responses": { + "200": { + "description": "Current FQDN configuration retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FqdnConfigCurrentResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SystemAPIErrorResponse" + } + } + } + } + } + }, + "post": { + "x-mode": "lite", + "summary": "Configure external FQDN", + "operationId": "configureFqdn", + "tags": [ + "ExternalAuth" + ], + "description": "Configure the canonical external FQDN used by F5 Insight and ZITADEL.\nThe operation runs asynchronously because it performs a Helm upgrade and\nreruns ZITADEL bootstrap to refresh the registered OIDC callback URL.\n", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FqdnConfigRequest" + } + } + } + }, + "responses": { + "202": { + "description": "FQDN configuration task submitted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FqdnConfigResponse" + } + } + } + }, + "400": { + "description": "Invalid FQDN target", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SystemAPIErrorResponse" + } + } + } + }, + "409": { + "description": "Another FQDN configuration task is already running", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SystemAPIErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SystemAPIErrorResponse" + } + } + } + } + } + } + }, + "/api/auth/fqdn/status/{task_id}": { + "x-feature": "userManagement", + "get": { + "x-mode": "lite", + "summary": "Get FQDN configuration status", + "operationId": "getFqdnStatus", + "tags": [ + "ExternalAuth" + ], + "description": "Query the progress of an FQDN configuration task by task_id.", + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "UUID of the FQDN configuration task", + "schema": { + "type": "string", + "format": "uuid", + "example": "123e4567-e89b-12d3-a456-426614174000" + } + } + ], + "responses": { + "200": { + "description": "FQDN configuration status retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FqdnStatusResponse" + } + } + } + }, + "400": { + "description": "Invalid task_id format", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SystemAPIErrorResponse" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SystemAPIErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SystemAPIErrorResponse" + } + } + } + } + } + } + }, + "/api/ai-integrations/llm-provider": { + "x-feature": "aiIntegrations", + "get": { + "tags": [ + "Configuration" + ], + "summary": "Get current AI provider configuration", + "operationId": "getCurrentAIProvider", + "responses": { + "200": { + "description": "Current AI provider configuration", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AIProviderResponse" + } + } + } + }, + "204": { + "description": "No configuration found" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "post": { + "tags": [ + "Configuration" + ], + "summary": "Save AI provider configuration", + "operationId": "saveAIProviderConfig", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConfigAIProviderRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Configuration saved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StatusResponse" + } + } + } + }, + "400": { + "description": "Validation error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Configuration" + ], + "summary": "Delete AI provider configuration", + "operationId": "deleteAIProviderConfig", + "responses": { + "200": { + "description": "Configuration deleted successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StatusResponse" + } + } + } + }, + "404": { + "description": "Configuration not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/ai-integrations/aidf": { + "x-feature": "aiIntegrations", + "get": { + "x-mode": "lite", + "tags": [ + "Configuration" + ], + "summary": "Get current AIDF configuration", + "operationId": "getCurrentAIDFConfig", + "responses": { + "200": { + "description": "Current AIDF configuration", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AIDFConfigResponse" + } + } + } + }, + "204": { + "description": "No configuration found" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "post": { + "x-mode": "lite", + "tags": [ + "Configuration" + ], + "summary": "Save AIDF configuration", + "operationId": "saveAIDFConfig", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConfigAIDFRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Configuration saved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StatusResponse" + } + } + } + }, + "400": { + "description": "Validation error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "delete": { + "x-mode": "lite", + "tags": [ + "Configuration" + ], + "summary": "Delete AIDF configuration", + "operationId": "deleteAIDFConfig", + "responses": { + "200": { + "description": "Configuration deleted successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StatusResponse" + } + } + } + }, + "404": { + "description": "Configuration not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/ai-integrations/aidf/insights": { + "x-feature": "aiIntegrations", + "get": { + "x-mode": "lite", + "tags": [ + "AIDF Insights" + ], + "summary": "Get AIDF security insights", + "description": "Fetches security insights from AIDF including alerts, scoring, and device findings.\nRequires AIDF to be configured. Returns sample data if AIDF endpoint fails.\n", + "operationId": "GetAIDFInsights", + "parameters": [ + { + "name": "start_time", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "end_time", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "AIDF insights retrieved successfully (flattened feed items)", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/InsightFeedItem" + } + } + } + } + }, + "400": { + "description": "Bad request or AIDF not configured", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/ai-integrations/aidf/classifications": { + "x-feature": "aiIntegrations", + "get": { + "x-mode": "lite", + "tags": [ + "AIDF Insights" + ], + "summary": "Get AIDF workload classifications", + "description": "Fetches workload classification insights from AIDF including application discovery,\ntraffic analysis, and compliance indicators.\nRequires AIDF to be configured. Returns sample data if AIDF endpoint fails.\n", + "operationId": "GetAIDFWorkloadClassifications", + "parameters": [ + { + "name": "start_time", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "end_time", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "AIDF classifications retrieved successfully (flattened feed items)", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ClassificationFeedItem" + } + } + } + } + }, + "400": { + "description": "Bad request or AIDF not configured", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/telemetry/types": { + "x-feature": "telemetry", + "get": { + "x-mode": "lite", + "tags": [ + "Telemetry Configuration" + ], + "summary": "List all telemetry types", + "description": "Get all available telemetry types and their enabled status for AIDF forwarding", + "operationId": "getTelemetryTypes", + "responses": { + "200": { + "description": "List of all telemetry types with their configuration", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TelemetryTypesResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "put": { + "x-mode": "lite", + "tags": [ + "Telemetry Configuration" + ], + "summary": "Update enabled telemetry types", + "description": "Bulk update which telemetry types are enabled for AIDF forwarding. Triggers OTEL configuration reload.", + "operationId": "updateTelemetryTypes", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateTelemetryTypesRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Telemetry types updated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StatusResponse" + } + } + } + }, + "400": { + "description": "Validation error - invalid telemetry type names", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/telemetry/types/{type}": { + "x-feature": "telemetry", + "get": { + "x-mode": "lite", + "tags": [ + "Telemetry Configuration" + ], + "summary": "Get specific telemetry type configuration", + "description": "Get the configuration for a specific telemetry type", + "operationId": "getTelemetryType", + "parameters": [ + { + "name": "type", + "in": "path", + "required": true, + "description": "Telemetry type name (API_Discovery or Application_Telemetry)", + "schema": { + "type": "string", + "enum": [ + "API_Discovery", + "Application_Telemetry" + ] + } + } + ], + "responses": { + "200": { + "description": "Telemetry type configuration", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TelemetryTypeConfig" + } + } + } + }, + "400": { + "description": "Invalid telemetry type name", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Telemetry type not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/featureflags/list": { + "x-feature": "systemManagement", + "get": { + "x-mode": "lite", + "tags": [ + "Feature Flags" + ], + "summary": "Get all feature flags", + "operationId": "getFeatureFlags", + "responses": { + "200": { + "description": "List of all feature flags", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeatureFlagsListResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/featureflags/update": { + "x-feature": "systemManagement", + "post": { + "tags": [ + "Feature Flags" + ], + "summary": "Update feature flag", + "operationId": "updateFeatureFlag", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateFeatureFlagRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Feature flag updated successfully", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/onboarding/status": { + "x-feature": "systemManagement", + "get": { + "x-mode": "lite", + "tags": [ + "Onboarding" + ], + "summary": "Get onboarding status", + "description": "Returns the status of components including license, AI integrations, and device onboarding", + "operationId": "getOnboardingStatus", + "responses": { + "200": { + "description": "Onboarding status retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OnboardingStatus" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "patch": { + "x-mode": "lite", + "tags": [ + "Onboarding" + ], + "summary": "Update onboarding status", + "description": "Update onboarding status fields. All fields are optional - only provided fields will be updated.", + "operationId": "updateOnboardingStatus", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OnboardingStatus" + } + } + } + }, + "responses": { + "200": { + "description": "Onboarding status updated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OnboardingStatus" + } + } + } + }, + "400": { + "description": "Invalid request body", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/system/role": { + "x-feature": "systemManagement", + "get": { + "tags": [ + "System" + ], + "summary": "Get system role and node information", + "description": "Returns whether the current device is running in primary or standby mode based on environment variables", + "operationId": "getSystemRole", + "responses": { + "200": { + "description": "System role information retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SystemRoleResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/storage/config": { + "x-feature": "systemManagement", + "get": { + "tags": [ + "Storage" + ], + "summary": "Get storage allocation configuration", + "description": "Retrieve the current storage allocation configuration including percentages, TTL settings, and cleanup thresholds", + "operationId": "getStorageConfig", + "responses": { + "200": { + "description": "Storage configuration retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageAllocationConfigResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "post": { + "tags": [ + "Storage" + ], + "summary": "Update storage allocation configuration", + "description": "Update storage allocation percentages, TTL settings, and cleanup thresholds", + "operationId": "updateStorageConfig", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageAllocationConfigRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Storage configuration updated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageAllocationConfigResponse" + } + } + } + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/validate/inference_provider": { + "x-feature": "systemManagement", + "post": { + "tags": [ + "Validators" + ], + "summary": "Validate AI provider configuration", + "operationId": "validateAIProvider", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidateAIProviderRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Validation successful", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationResponse" + } + } + } + }, + "400": { + "description": "Validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationResponse" + } + } + } + } + } + } + }, + "/api/validate/aidf": { + "x-feature": "systemManagement", + "post": { + "x-mode": "lite", + "tags": [ + "Validators" + ], + "summary": "Validate AIDF configuration", + "operationId": "validateAIDF", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidateAIDFRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Validation successful", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationResponse" + } + } + } + }, + "400": { + "description": "Validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationResponse" + } + } + } + } + } + } + }, + "/api/license/health": { + "x-feature": "licenseManagement", + "get": { + "x-mode": "lite", + "summary": "Check license service health status", + "description": "Returns the health status of the license service including activation status, storage metrics, and license information", + "operationId": "getLicenseHealth", + "tags": [ + "License" + ], + "responses": { + "200": { + "description": "License service is healthy", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseHealthResponse" + } + } + } + }, + "503": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseHealthResponse" + } + } + } + } + } + } + }, + "/api/license/activate": { + "x-feature": "licenseManagement", + "post": { + "x-mode": "lite", + "summary": "Activate license", + "description": "Activates the license for the service and returns activation status, digital asset ID, entitlements, and subscription details", + "operationId": "activateLicense", + "tags": [ + "License" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseActivationRequest" + } + } + } + }, + "responses": { + "200": { + "description": "License activated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseActivationResponse" + } + } + } + }, + "400": { + "description": "Invalid activation request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized activation attempt", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "503": { + "description": "Service unavailable - unable to connect to licensing server", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/data-centers": { + "x-feature": "deviceManagement", + "post": { + "x-mode": "lite", + "operationId": "AddDataCenter", + "description": "Add a new data center to F5 Insights fleet.", + "requestBody": { + "description": "Details of the data center to be added.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataCenter" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Data center added successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddDataCenterResponse" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + }, + "get": { + "x-mode": "lite", + "operationId": "GetDataCenters", + "description": "Retrieve all Data Centers.", + "responses": { + "200": { + "description": "List of all data centers.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListOfDataCenters" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + } + }, + "/api/device-management/data-centers/{id}": { + "x-feature": "deviceManagement", + "delete": { + "x-mode": "lite", + "operationId": "DeleteDataCenter", + "description": "Delete a specific data center by its ID.", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Unique identifier of the data center to delete.", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Data center deleted successfully." + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Data center not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "409": { + "description": "Cannot delete data center with associated devices.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/data-centers/devices": { + "x-feature": "deviceManagement", + "get": { + "x-mode": "lite", + "operationId": "GetDataCentersRegisteredDevices", + "description": "Retrieve all data centers with their registered devices.", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "deviceType", + "in": "query", + "required": false, + "description": "Filter by device kind. One of all, bigip, f5os. Defaults to all.", + "schema": { + "type": "string", + "enum": [ + "all", + "bigip", + "f5os" + ], + "default": "all" + } + } + ], + "responses": { + "200": { + "description": "List of all data centers with their devices.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataCentersWithDevicesResponse" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/trust-store": { + "x-feature": "deviceManagement", + "post": { + "x-mode": "lite", + "operationId": "AddTrustStore", + "description": "certificate for TLS connections.", + "requestBody": { + "description": "Certificate details and content.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddTrustStoreRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Certificate uploaded successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TrustStoreResponse" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + }, + "get": { + "x-mode": "lite", + "operationId": "GetTrustStores", + "description": "Retrieve all certificates from trust store.", + "responses": { + "200": { + "description": "List of certificates.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListOfTrustStores" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + } + }, + "/api/device-management/trust-store/{id}": { + "x-feature": "deviceManagement", + "get": { + "x-mode": "lite", + "operationId": "GetTrustStore", + "description": "Retrieve a specific certificate by ID from trust store.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "Certificate ID" + } + ], + "responses": { + "200": { + "description": "Certificate details.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TrustStore" + } + } + } + }, + "404": { + "description": "Certificate not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + }, + "delete": { + "x-mode": "lite", + "operationId": "DeleteTrustStore", + "description": "Delete a certificate from trust store.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "Certificate ID" + } + ], + "responses": { + "200": { + "description": "Certificate deleted successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MessageResponse" + } + } + } + }, + "404": { + "description": "Certificate not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "409": { + "description": "Certificate is in use by devices.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + } + }, + "/api/device-management/devices": { + "x-feature": "deviceManagement", + "post": { + "x-mode": "lite", + "operationId": "AddDevice", + "description": "Onboard a device (BIG-IP or F5OS) to F5 Insights fleet. The deviceType field selects the kind; defaults to bigip.", + "requestBody": { + "description": "Details of the device to be added (BIG-IP or F5OS).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddDeviceRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Device added successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddDeviceResponse" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + }, + "get": { + "x-mode": "lite", + "operationId": "GetDevices", + "description": "Retrieve all devices (BIG-IP and F5OS) onboarded to F5 Insights with pagination and filtering support. Use deviceType to filter by kind.", + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/SizeParam" + }, + { + "$ref": "#/components/parameters/SinceParam" + }, + { + "$ref": "#/components/parameters/SearchParam" + }, + { + "$ref": "#/components/parameters/SortParam" + }, + { + "name": "deviceType", + "in": "query", + "required": false, + "description": "Filter by device kind. One of all, bigip, f5os. Defaults to all.", + "schema": { + "type": "string", + "enum": [ + "all", + "bigip", + "f5os" + ], + "default": "all" + } + } + ], + "responses": { + "200": { + "description": "List of devices (BIG-IP and F5OS) with pagination metadata.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListOfDevices" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + } + }, + "/api/device-management/devices/{id}": { + "x-feature": "deviceManagement", + "put": { + "x-mode": "lite", + "operationId": "UpdateDevice", + "description": "Updates configuration of a device (BIG-IP or F5OS). The device kind is auto-detected from the id.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Unique identifier of the device to update (BIG-IP or F5OS).", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "Updated details of the device.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Device updated successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateDeviceResponse" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + }, + "patch": { + "x-mode": "lite", + "operationId": "PartialUpdateDevice", + "description": "Partially updates configuration of a device (BIG-IP or F5OS). Only provided fields are updated. The device kind is auto-detected from the id.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Unique identifier of the device to update (BIG-IP or F5OS).", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "Partial device update. Only include fields that should be updated.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DevicePatchRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Device partially updated successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceResponse" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Device not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + }, + "get": { + "x-mode": "lite", + "operationId": "GetDevice", + "description": "Fetch details of a specific device (BIG-IP or F5OS). The device kind is auto-detected from the id.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Unique identifier of the device (BIG-IP or F5OS).", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Device fetched successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceResponse" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + }, + "delete": { + "x-mode": "lite", + "operationId": "DeleteDevice", + "description": "Delete a specific device (BIG-IP or F5OS). The device kind is auto-detected from the id.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Unique identifier of the device (BIG-IP or F5OS).", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Device deleted successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + } + }, + "/api/device-management/devices/{id}/refresh": { + "x-feature": "deviceManagement", + "post": { + "x-mode": "lite", + "operationId": "RefreshDevice", + "description": "Re-discover a device and refresh its inventory details (hardware model, serial number, OS version/build, status, last-seen). Supported for F5OS devices only; returns 400 for BIG-IP. The device kind is auto-detected from the id. This operation is synchronous.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Unique identifier of the device to refresh (F5OS).", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Device refreshed successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceResponse" + } + } + } + }, + "400": { + "description": "Validation error (e.g. refresh not supported for BIG-IP devices).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Device not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + } + }, + "/api/device-management/devices/auto-scale/{autoScaleGroupId}": { + "x-feature": "deviceManagement", + "get": { + "operationId": "GetDevicesByAutoScaleGroup", + "description": "Retrieve all the devices that belong to a specific auto-scale group.", + "parameters": [ + { + "name": "autoScaleGroupId", + "in": "path", + "required": true, + "description": "Unique identifier of the auto-scale group.", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/SizeParam" + }, + { + "$ref": "#/components/parameters/SinceParam" + }, + { + "$ref": "#/components/parameters/SortParam" + } + ], + "responses": { + "200": { + "description": "List of devices belonging to the specified auto-scale group.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListOfDevices" + }, + "example": { + "devices": [ + { + "id": "123e4567-e89b-12d3-a456-426614174000", + "alias_name": "bigip-prod-01", + "description": "Production BIG-IP device", + "username": "admin", + "data_center": "US-EAST-1", + "endpoint": "192.168.1.100:443", + "tls_enabled": true, + "collection_interval": 60, + "max_concurrent_connections": 5, + "deviceName": "bigip1.example.com", + "retention": "30D", + "modules": { + "apm": false, + "cgnat": false, + "dns": false, + "dos": false, + "firewall": false, + "gtm": false, + "policy_api_protection": false, + "policy_asm": false, + "policy_firewall": false, + "policy_ip_intelligence": false, + "policy_nat": false, + "profile_dos": false + } + }, + { + "id": "223e4567-e89b-12d3-a456-426614174001", + "alias_name": "bigip-prod-02", + "description": "Production BIG-IP device 2", + "username": "admin", + "data_center": "US-EAST-1", + "endpoint": "192.168.1.101:443", + "tls_enabled": true, + "collection_interval": 60, + "max_concurrent_connections": 5, + "deviceName": "bigip2.example.com", + "retention": "30D", + "modules": { + "apm": false, + "cgnat": false, + "dns": false, + "dos": false, + "firewall": false, + "gtm": false, + "policy_api_protection": false, + "policy_asm": false, + "policy_firewall": false, + "policy_ip_intelligence": false, + "policy_nat": false, + "profile_dos": false + } + } + ], + "pagination": { + "page": 1, + "pageSize": 20, + "totalDevices": 2, + "totalPages": 1 + } + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Auto-scale group not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + } + }, + "/api/device-management/devices/connection/validate": { + "x-feature": "deviceManagement", + "post": { + "x-mode": "lite", + "operationId": "ValidateDeviceConnection", + "description": "Validate connectivity from F5 Insights to a BIG-IP device using provided credentials.", + "requestBody": { + "description": "Device details required for connection validation.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Connection validation result.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConnectionValidationResponse" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "tags": [ + "others" + ] + } + }, + "/api/device-management/devices/migrate-ast": { + "x-feature": "deviceManagement", + "get": { + "x-mode": "lite", + "operationId": "GetCurrentMigrationTask", + "description": "Get the currently running or most recent migration task.\nReturns the active migration task if one is in progress, otherwise returns the most recent completed/failed task.\n", + "tags": [ + "Device Management" + ], + "responses": { + "200": { + "description": "Migration task information retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MigrationTaskResponse" + } + } + } + }, + "404": { + "description": "No migration tasks found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "post": { + "x-mode": "lite", + "operationId": "StartMigrationTask", + "description": "Start an asynchronous migration task for BIG-IP devices from AST (Application Study Tool) configuration files.\nReturns a task ID that can be used to query migration status.\nOnly one migration task can be running at a time - attempting to start a second task will return an error.\n", + "tags": [ + "Device Management" + ], + "requestBody": { + "description": "AST configuration files containing device information.", + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "required": [ + "defaults_file", + "receivers_file" + ], + "properties": { + "defaults_file": { + "type": "string", + "format": "binary", + "description": "ast_defaults.yaml file containing default settings (YAML format)" + }, + "receivers_file": { + "type": "string", + "format": "binary", + "description": "ast_receivers.yml file containing receiver configurations (YAML format)" + } + } + }, + "encoding": { + "defaults_file": { + "contentType": "application/yaml, application/x-yaml, text/yaml" + }, + "receivers_file": { + "contentType": "application/yaml, application/x-yaml, text/yaml" + } + } + } + } + }, + "responses": { + "202": { + "description": "Migration task created successfully. Use the returned task_id to query status.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MigrationTaskResponse" + } + } + } + }, + "400": { + "description": "Validation error in uploaded files.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "409": { + "description": "A migration task is already in progress.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/migrate-ast/status/{task_id}": { + "x-feature": "deviceManagement", + "get": { + "x-mode": "lite", + "operationId": "GetMigrationStatus", + "description": "Get the status of a device migration task including overall progress and individual device status.\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "The task ID returned from the migration request", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "include_devices", + "in": "query", + "required": false, + "description": "Include individual device status details", + "schema": { + "type": "boolean", + "default": true + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "description": "Maximum number of device details to return", + "schema": { + "type": "integer", + "default": 100, + "minimum": 1, + "maximum": 1000 + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "description": "Offset for pagination of device details", + "schema": { + "type": "integer", + "default": 0, + "minimum": 0 + } + }, + { + "name": "updated_since", + "in": "query", + "required": false, + "description": "Filter devices updated since this timestamp (ISO 8601 format, e.g., 2026-01-30T08:00:00Z)", + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "Migration status retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MigrationStatusResponse" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/migrate-ast/status/{task_id}/devices": { + "x-feature": "deviceManagement", + "get": { + "x-mode": "lite", + "operationId": "GetDeviceProgress", + "description": "Get paginated device-level progress for a migration task with delta update support.\nUse this for live UI updates showing per-device status (Connected/Failed/In Progress).\nSupports polling with 'since' parameter to fetch only recently updated devices.\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "The task ID returned from the migration request", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/SizeParam" + }, + { + "$ref": "#/components/parameters/SinceParam" + }, + { + "$ref": "#/components/parameters/SearchParam" + }, + { + "$ref": "#/components/parameters/SortParam" + } + ], + "responses": { + "200": { + "description": "Device progress retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceProgressResponse" + } + } + } + }, + "400": { + "description": "Invalid request parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/migrate-ast/status/{task_id}/ca-bundles": { + "x-feature": "deviceManagement", + "get": { + "x-mode": "lite", + "operationId": "GetCABundleProgress", + "summary": "Get staging CA certificates for a migration task", + "description": "Retrieve all staging CA certificates associated with a migration task.\nReturns the list of CA bundles that were extracted during the migration process\nand are available for validation and commit operations.\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "The task ID returned from the migration request", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/SizeParam" + } + ], + "responses": { + "200": { + "description": "CA bundle list retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CABundleListResponse" + } + } + } + }, + "400": { + "description": "Invalid request parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/migrate-ast/cleanup/{task_id}": { + "x-feature": "deviceManagement", + "delete": { + "x-mode": "lite", + "operationId": "CleanupMigrationTask", + "description": "Clean up all staging data associated with a migration task.\nThis removes all staging devices and trust store entries that have not been committed.\nSuccessfully committed devices and trust stores remain intact.\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "The task ID to clean up", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "force", + "in": "query", + "required": false, + "description": "Force cleanup even if task is still running.\nWARNING: Use with extreme caution - only when a task is stuck for a very long time.\nForcing cleanup of a running task may lead to inconsistent state.\n", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "Cleanup completed successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CleanupMigrationTaskResponse" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/migrate-ast/retry/{task_id}": { + "x-feature": "deviceManagement", + "post": { + "x-mode": "lite", + "operationId": "RetryFailedMigrationDevices", + "description": "Retry failed devices from an existing migration task.\nThis endpoint reuses the same task ID and only retries devices with validation_status = 'FAILED'.\nFailed devices are reset to 'PENDING' and the task state is reset to 'IN_PROGRESS'.\n\nRequirements:\n- Task must exist and be a MIGRATION task\n- No other migration task can be currently running\n- Task must have at least one failed device\n\nThe retry process:\n1. Validates the task exists and is a migration task\n2. Checks no concurrent migration tasks are running\n3. Resets failed devices to PENDING status\n4. Resets task state to IN_PROGRESS\n5. Reprocesses only the failed devices through the validation workflow\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "The task ID to retry failed devices for", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "202": { + "description": "Retry initiated successfully. Use the same task_id to query status.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RetryFailedMigrationDevicesResponse" + } + } + } + }, + "400": { + "description": "No failed devices to retry", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "409": { + "description": "A migration task is already running", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/migrate-ast/staging-devices/{staging_device_id}": { + "x-feature": "deviceManagement", + "get": { + "x-mode": "lite", + "operationId": "GetStagingDevice", + "summary": "Get a staging device by ID", + "description": "Retrieve details of a specific staging device including its validation status,\nconfiguration, and error messages if any.\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "staging_device_id", + "in": "path", + "required": true, + "description": "UUID of the staging device to retrieve", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Staging device retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StagingDeviceResponse" + } + } + } + }, + "404": { + "description": "Staging device not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "patch": { + "x-mode": "lite", + "operationId": "PatchStagingDevice", + "summary": "Update and commit a staging device", + "description": "Updates a single staging device with provided fields, validates connectivity,\nand commits the device to the main devices table. If a device with the same\nendpoint exists, it will be updated instead of creating a new one.\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "staging_device_id", + "in": "path", + "required": true, + "description": "UUID of the staging device to update", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DevicePatchRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Staging device updated and committed successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PatchStagingDeviceResponse" + } + } + } + }, + "400": { + "description": "Device validation failed or invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Staging device not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/migrate-ast/staging-ca-bundles/{staging_ca_id}": { + "x-feature": "deviceManagement", + "patch": { + "x-mode": "lite", + "operationId": "PatchStagingCABundle", + "summary": "Update and commit a staging CA bundle", + "description": "Updates a single staging CA bundle with provided fields, validates certificate\nformat, and commits the certificate to the trust_store table. If a certificate\nwith the same content already exists, it will be linked instead of creating a duplicate.\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "staging_ca_id", + "in": "path", + "required": true, + "description": "UUID of the staging CA bundle to update", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddTrustStoreRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Staging CA bundle updated and committed successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PatchStagingCABundleResponse" + } + } + } + }, + "400": { + "description": "Invalid certificate data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Staging CA bundle not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/migrate-ast-sync": { + "x-feature": "deviceManagement", + "post": { + "x-mode": "lite", + "operationId": "MigrateASTDevicesSync", + "description": "Synchronous migration of BIG-IP devices from AST configuration files (legacy endpoint).\nFor better experience with large migrations, use the async endpoint instead.\n", + "tags": [ + "Device Management" + ], + "requestBody": { + "description": "AST configuration files containing device information.", + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "required": [ + "defaults_file", + "receivers_file" + ], + "properties": { + "defaults_file": { + "type": "string", + "format": "binary", + "description": "ast_defaults.yaml file containing default settings (YAML format)" + }, + "receivers_file": { + "type": "string", + "format": "binary", + "description": "ast_receivers.yml file containing receiver configurations (YAML format)" + } + } + }, + "encoding": { + "defaults_file": { + "contentType": "application/yaml, application/x-yaml, text/yaml" + }, + "receivers_file": { + "contentType": "application/yaml, application/x-yaml, text/yaml" + } + } + } + } + }, + "responses": { + "200": { + "description": "Migration completed with summary of results.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkImportResponse" + } + } + } + }, + "400": { + "description": "Validation error in uploaded files.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/bulk-import": { + "x-feature": "deviceManagement", + "post": { + "x-mode": "lite", + "operationId": "BulkImportDevices", + "description": "Import multiple devices (BIG-IP and/or F5OS) to F5 Insights in a single operation.", + "tags": [ + "Device Management" + ], + "requestBody": { + "description": "Array of devices to be imported (mixed BIG-IP and F5OS allowed).", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "devices" + ], + "properties": { + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AddDeviceRequest" + }, + "minItems": 1, + "description": "List of devices to import (BIG-IP or F5OS per item)" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Bulk import completed with summary of results.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkImportResponse" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/import": { + "x-feature": "deviceManagement", + "get": { + "x-mode": "lite", + "operationId": "GetCurrentImportTask", + "description": "Get the currently running or most recent import task.\nReturns the active import task if one is in progress, otherwise returns the most recent completed/failed task.\n", + "tags": [ + "Device Management" + ], + "responses": { + "200": { + "description": "Import task state and per-device results.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImportTaskStatus" + } + } + } + }, + "404": { + "description": "No import tasks found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "post": { + "x-mode": "lite", + "operationId": "ImportDevicesAsync", + "description": "Asynchronously import a batch of devices (BIG-IP and/or F5OS) and track the result as a task. Accepts the same `devices[]` body as `bulk-import`; in addition `Content-Type: application/yaml` is supported so a YAML file from disk can be POSTed directly. Returns a task id immediately; poll the status endpoint for per-device outcomes once items start completing.", + "tags": [ + "Device Management" + ], + "requestBody": { + "description": "Array of devices to import (mixed BIG-IP and F5OS allowed).", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "devices" + ], + "properties": { + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AddDeviceRequest" + }, + "minItems": 1, + "maxItems": 1000, + "description": "List of devices to import (BIG-IP or F5OS per item)." + } + } + } + }, + "application/yaml": { + "schema": { + "type": "object", + "required": [ + "devices" + ], + "properties": { + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AddDeviceRequest" + }, + "minItems": 1, + "maxItems": 1000, + "description": "List of devices to import (BIG-IP or F5OS per item)." + } + } + } + } + } + }, + "responses": { + "202": { + "description": "Import task accepted. Poll the status endpoint with the returned task_id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImportTaskAccepted" + } + } + } + }, + "400": { + "description": "Validation error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/import/cleanup/{task_id}": { + "x-feature": "deviceManagement", + "delete": { + "x-mode": "lite", + "operationId": "CleanupImportTask", + "description": "Clean up an async import task and its tracked results.\nRemoves the task record (including the per-device results stored in status_json).\nDevices that were successfully onboarded remain intact in the main tables.\n", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "The import task ID to clean up", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "force", + "in": "query", + "required": false, + "description": "Force cleanup even if the task is still running.\nWARNING: Use with extreme caution - only when a task is stuck for a very long time.\nForcing cleanup of a running task may lead to inconsistent state.\n", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "Cleanup completed successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CleanupImportTaskResponse" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/device-management/devices/import/status/{task_id}": { + "x-feature": "deviceManagement", + "get": { + "x-mode": "lite", + "operationId": "GetImportTaskStatus", + "description": "Returns the current state of an async import task plus the full per-device result list. `items[]` is updated as workers finish each device, so polling shows progress without a separate per-device endpoint.", + "tags": [ + "Device Management" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "Task id returned by POST /device-management/devices/import.", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Task state and per-device results.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImportTaskStatus" + } + } + } + }, + "404": { + "description": "Task not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/license/deactivate": { + "x-feature": "licenseManagement", + "post": { + "x-mode": "lite", + "summary": "Deactivate license", + "description": "Deactivates the license for the service and returns deactivation status", + "operationId": "deactivateLicense", + "tags": [ + "License" + ], + "responses": { + "200": { + "description": "License deactivated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseDeactivationResponse" + } + } + } + }, + "400": { + "description": "Invalid deactivation request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseDeactivationResponse" + } + } + } + }, + "401": { + "description": "Unauthorized deactivation attempt", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseDeactivationResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseDeactivationResponse" + } + } + } + } + } + } + }, + "/api/license/report": { + "x-feature": "licenseManagement", + "get": { + "x-mode": "lite", + "summary": "Download license report", + "description": "Downloads the license report in disconnected mode (base64 encoded)", + "operationId": "downloadReport", + "tags": [ + "License" + ], + "responses": { + "200": { + "description": "License report downloaded successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseReportResponse" + } + } + } + }, + "403": { + "description": "Operation not allowed in connected mode", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "put": { + "summary": "Verify license report", + "description": "Verifies a signed license report acknowledgment from F5 TEEM in disconnected mode", + "operationId": "verifyReport", + "tags": [ + "License" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VerifyReportRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Report verification initiated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MessageResponse" + } + } + } + }, + "400": { + "description": "Invalid request body", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Operation not allowed in connected mode", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/license/entitlements": { + "x-feature": "licenseManagement", + "get": { + "x-mode": "lite", + "summary": "Get license entitlements", + "description": "Retrieves license entitlements from llm sdk", + "operationId": "getLicenseEntitlements", + "tags": [ + "License" + ], + "responses": { + "200": { + "description": "License entitlements retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseEntitlementsResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/auth/me/permissions": { + "get": { + "x-mode": "lite", + "tags": [ + "Authorization" + ], + "summary": "Get current user permissions", + "description": "Returns the authenticated user's F5 Insight role and the permissions\ngranted to that role. Used by the frontend to enable or hide role-based\nUI actions.\n**Requires authentication.**\n", + "operationId": "getMyPermissions", + "responses": { + "200": { + "description": "Current user permissions retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CurrentUserPermissionsResponse" + }, + "example": { + "user_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "role_id": "550e8400-e29b-41d4-a716-446655440001", + "role_name": "Operator", + "permissions": [ + "deviceManagement.get", + "deviceManagement.post", + "dashboards.post", + "telemetry.get" + ], + "grouped_permissions": { + "deviceManagement": [ + "get", + "post" + ], + "dashboards": [ + "post" + ], + "telemetry": [ + "get" + ] + } + } + } + } + }, + "401": { + "description": "Unauthorized \u2013 missing or invalid JWT", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden \u2013 role information missing from JWT context", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "404": { + "description": "Role not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + } + } + } + }, + "/api/auth/roles": { + "get": { + "x-mode": "lite", + "tags": [ + "Authorization" + ], + "summary": "List all roles", + "description": "Returns all available system roles with user counts.\nUsed to populate the role selector when creating or updating a group mapping.\n**Requires authentication.**\n", + "operationId": "listRoles", + "parameters": [ + { + "name": "include_permissions", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "default": false + }, + "description": "Include permission mappings when available." + } + ], + "responses": { + "200": { + "description": "List of roles retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RolesListResponse" + }, + "example": { + "roles": [ + { + "id": "550e8400-e29b-41d4-a716-446655440000", + "name": "Admin", + "description": "Full system access including user management", + "is_builtin": true, + "user_count": 2, + "created_at": "2026-01-01T00:00:00Z" + }, + { + "id": "550e8400-e29b-41d4-a716-446655440001", + "name": "Operator", + "description": "Device configuration and troubleshooting", + "is_builtin": true, + "user_count": 8, + "created_at": "2026-01-01T00:00:00Z" + } + ], + "total_count": 2 + } + } + } + }, + "401": { + "description": "Unauthorized \u2013 missing or invalid JWT", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + } + } + } + }, + "/api/auth/roles/{role_id}": { + "get": { + "x-mode": "lite", + "tags": [ + "Authorization" + ], + "summary": "Get role by ID", + "description": "Returns a single role by its UUID, including its full permission list.\n**Requires authentication.**\n", + "operationId": "getRole", + "parameters": [ + { + "name": "role_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "UUID of the role to retrieve" + } + ], + "responses": { + "200": { + "description": "Role retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RoleListItem" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "name": "Admin", + "description": "Full system access including user management", + "is_builtin": true, + "user_count": 2, + "created_at": "2026-01-01T00:00:00Z", + "permissions": [ + "deviceManagement.get", + "deviceManagement.post" + ] + } + } + } + }, + "401": { + "description": "Unauthorized \u2013 missing or invalid JWT", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "404": { + "description": "Role not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + } + } + } + }, + "/api/auth/group-mappings": { + "get": { + "x-mode": "lite", + "tags": [ + "Authorization" + ], + "summary": "List all provider group \u2192 role mappings", + "description": "Returns configured mappings grouped by identity provider and role.\n**Requires authentication.**\n", + "operationId": "listGroupMappings", + "responses": { + "200": { + "description": "List of group mappings retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AuthZGroupMappingResponse" + } + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + } + } + } + }, + "/api/auth/group-mappings/{role_id}": { + "get": { + "x-mode": "lite", + "tags": [ + "Authorization" + ], + "summary": "Get provider groups mapped to a role", + "description": "Returns all provider-scoped grouped mappings for the given role_id.\n**Requires authentication.**\n", + "operationId": "getGroupMapping", + "parameters": [ + { + "name": "role_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "UUID of the F5 Insight role" + } + ], + "responses": { + "200": { + "description": "Group mappings retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AuthZGroupMappingResponse" + } + } + } + } + }, + "400": { + "description": "Invalid role_id", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + } + } + }, + "put": { + "x-mode": "lite", + "tags": [ + "Authorization" + ], + "summary": "Replace provider groups mapped to a role", + "description": "Creates or fully replaces the grouped_resource_attribute list for the\ngiven provider_id and role_id. Sending an empty grouped_resource_attribute\narray clears mappings for that provider/role.\n**Requires admin role.**\n", + "operationId": "putGroupMapping", + "parameters": [ + { + "name": "role_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "UUID of the F5 Insight role" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpsertGroupMappingRequest" + }, + "example": { + "provider_id": "ldap-id-123\"", + "grouped_resource_attribute": [ + "bigip-admins", + "network-operators" + ] + } + } + } + }, + "responses": { + "200": { + "description": "Group mapping replaced successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthZGroupMappingResponse" + } + } + } + }, + "400": { + "description": "Invalid request body or role_id not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden \u2013 admin role required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + } + } + }, + "patch": { + "x-mode": "lite", + "tags": [ + "Authorization" + ], + "summary": "Add provider groups to a role", + "description": "Adds or moves the provided grouped_resource_attribute values to the\ngiven provider_id and role_id without removing other values already\nmapped to that role.\n**Requires admin role.**\n", + "operationId": "patchGroupMapping", + "parameters": [ + { + "name": "role_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "UUID of the F5 Insight role" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpsertGroupMappingRequest" + }, + "example": { + "provider_id": "ldap-id-123", + "grouped_resource_attribute": [ + "bigip-admins" + ] + } + } + } + }, + "responses": { + "200": { + "description": "Group mapping patched successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthZGroupMappingResponse" + } + } + } + }, + "400": { + "description": "Invalid request body or role_id not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden \u2013 admin role required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + } + } + }, + "delete": { + "x-mode": "lite", + "tags": [ + "Authorization" + ], + "summary": "Delete provider groups mapped to a role", + "description": "Deletes the grouped mapping for the given provider_id and role_id.\nThis removes all grouped_resource_attribute values currently mapped to\nthat provider/role pair.\n**Requires admin role.**\n", + "operationId": "deleteGroupMapping", + "parameters": [ + { + "name": "role_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "UUID of the F5 Insight role" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteGroupMappingRequest" + }, + "example": { + "provider_id": "ldap-id-123" + } + } + } + }, + "responses": { + "204": { + "description": "Group mapping deleted successfully" + }, + "400": { + "description": "Missing provider_id or invalid role_id", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden \u2013 admin role required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "404": { + "description": "Group mapping not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleErrorResponse" + } + } + } + } + } + } + }, + "/api/chat/history/conversations": { + "x-feature": "chatManagement", + "get": { + "tags": [ + "ChatHistory" + ], + "summary": "List conversations", + "description": "List all active (non-expired, non-deleted) conversations for the authenticated user, sorted by most recent message.", + "operationId": "listConversations", + "responses": { + "200": { + "description": "List of conversations", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "conversations": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ChatConversation" + } + } + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/UnauthorizedError" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + }, + "post": { + "tags": [ + "ChatHistory" + ], + "summary": "Create conversation", + "description": "Create a new conversation thread. Returns 429 if the user has reached the 50-thread cap.", + "operationId": "createConversation", + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateConversationRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Conversation created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChatConversation" + } + } + } + }, + "401": { + "$ref": "#/components/responses/UnauthorizedError" + }, + "429": { + "description": "Maximum number of active conversations reached (50)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/api/chat/history/conversations/{id}": { + "x-feature": "chatManagement", + "get": { + "tags": [ + "ChatHistory" + ], + "summary": "Get conversation with messages", + "description": "Get a conversation and its full message history. Returns 410 if the conversation has expired.", + "operationId": "getConversation", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "Conversation ID" + } + ], + "responses": { + "200": { + "description": "Conversation with messages", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConversationWithMessages" + } + } + } + }, + "401": { + "$ref": "#/components/responses/UnauthorizedError" + }, + "404": { + "description": "Conversation not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "410": { + "description": "Conversation has expired", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + }, + "delete": { + "tags": [ + "ChatHistory" + ], + "summary": "Delete conversation", + "description": "Soft-delete a conversation. The conversation will be retained for 30 days for audit purposes before hard-deletion.", + "operationId": "deleteConversation", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "Conversation ID" + } + ], + "responses": { + "204": { + "description": "Conversation deleted" + }, + "401": { + "$ref": "#/components/responses/UnauthorizedError" + }, + "404": { + "description": "Conversation not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/api/chat/history/conversations/{id}/messages": { + "x-feature": "chatManagement", + "post": { + "tags": [ + "ChatHistory" + ], + "summary": "Add message to conversation", + "description": "Add a message to a conversation. Resets the 24-hour TTL rolling window. Returns 410 if the conversation has expired.", + "operationId": "addMessage", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "Conversation ID" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddMessageRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Message added", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChatMessage" + } + } + } + }, + "400": { + "description": "Invalid request (missing role/content or invalid role)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "$ref": "#/components/responses/UnauthorizedError" + }, + "404": { + "description": "Conversation not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "410": { + "description": "Conversation has expired", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/api/chat/export/pdf": { + "x-feature": "chatManagement", + "post": { + "tags": [ + "ChatHistory" + ], + "summary": "Export conversation or single response as PDF", + "description": "Generates and downloads a PDF of either an entire conversation (all turns) or a single assistant response (including its preceding user prompt). PDF is generated server-side using pure-Go rendering (go-pdf/fpdf). Conversations are capped at 200 live messages due to the summarization policy; the export reflects the live message window at time of request. User identity is resolved from the Bearer token \u2014 no user_id in the body. The conversation ownership is validated server-side; a conversation belonging to another user returns 404 (not 403) to avoid ID enumeration.\n", + "operationId": "exportChatPDF", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PDFExportRequest" + }, + "examples": { + "exportConversation": { + "summary": "Export full conversation", + "value": { + "type": "conversation", + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + }, + "exportSingleResponse": { + "summary": "Export single AI response turn", + "value": { + "type": "single", + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "message_id": "7cb94d21-1234-4321-abcd-9f8e7d6c5b4a" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "PDF generated successfully \u2014 binary file download", + "headers": { + "Content-Disposition": { + "required": true, + "schema": { + "type": "string" + }, + "description": "Always `attachment` with a generated filename. Conversation: `F5_Insight_AI_Conversation_.pdf` Single turn: `F5_Insight_AI_Response_.pdf`\n", + "example": "attachment; filename=\"F5_Insight_AI_Conversation_2026-05-26_14-30.pdf\"" + }, + "Content-Length": { + "required": true, + "schema": { + "type": "integer" + }, + "description": "Exact byte size of the PDF" + } + }, + "content": { + "application/pdf": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "400": { + "description": "Invalid request. Possible causes: - Missing or invalid `type` (must be `single` or `conversation`) - Missing `conversation_id` - `type` is `single` but `message_id` is absent\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "status": 400, + "message": "message_id is required for single response export" + } + } + } + }, + "401": { + "$ref": "#/components/responses/UnauthorizedError" + }, + "404": { + "description": "Conversation not found, not owned by the authenticated user, or no messages matched for the given message_id.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "status": 404, + "message": "conversation not found" + } + } + } + }, + "410": { + "description": "Conversation has expired (past 24-hour TTL)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "status": 410, + "message": "conversation has expired" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/api/audit/events": { + "x-feature": "auditConsole", + "get": { + "tags": [ + "AuditConsole" + ], + "summary": "List AI assistant audit events", + "description": "Returns a paginated, filterable list of AI assistant audit events from ClickHouse. Each row represents one agent action (user message, assistant response, tool call, tool result, error, data access, or PDF export). Requires the `audit.read` permission. PII fields (ip_address, user_agent, message, tool_arguments, tool_result) are masked unless the caller also holds the `audit.view_sensitive` permission and passes `view_sensitive=true`.\n", + "operationId": "listAuditEvents", + "parameters": [ + { + "name": "page", + "in": "query", + "required": false, + "description": "Page number (1-based).", + "schema": { + "type": "integer", + "minimum": 1, + "default": 1 + } + }, + { + "name": "size", + "in": "query", + "required": false, + "description": "Results per page (max 100).", + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 20 + } + }, + { + "name": "username", + "in": "query", + "required": false, + "description": "Case-insensitive substring match on the username field.", + "schema": { + "type": "string" + } + }, + { + "name": "event_type", + "in": "query", + "required": false, + "description": "Exact match on event_type.", + "schema": { + "type": "string", + "enum": [ + "user_message", + "assistant_response", + "tool_call", + "tool_result", + "error", + "data_access", + "pdf_export" + ] + } + }, + { + "name": "tool", + "in": "query", + "required": false, + "description": "Case-insensitive substring match on tool_name.", + "schema": { + "type": "string" + } + }, + { + "name": "keyword", + "in": "query", + "required": false, + "description": "Case-insensitive substring match on message OR tool_name.", + "schema": { + "type": "string" + } + }, + { + "name": "thread_id", + "in": "query", + "required": false, + "description": "Exact match on thread_id (conversation ID).", + "schema": { + "type": "string" + } + }, + { + "name": "interaction_id", + "in": "query", + "required": false, + "description": "Exact match on interaction_id.", + "schema": { + "type": "string" + } + }, + { + "name": "session_id", + "in": "query", + "required": false, + "description": "Exact match on session_id.", + "schema": { + "type": "string" + } + }, + { + "name": "date_from", + "in": "query", + "required": false, + "description": "Return events at or after this timestamp (RFC 3339).", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "date_to", + "in": "query", + "required": false, + "description": "Return events at or before this timestamp (RFC 3339).", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "view_sensitive", + "in": "query", + "required": false, + "description": "When `true` (and the caller has `audit.view_sensitive` permission), PII fields are returned unmasked.\n", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "Paginated list of audit events", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuditEventsResponse" + } + } + } + }, + "401": { + "$ref": "#/components/responses/UnauthorizedError" + }, + "403": { + "description": "Insufficient permissions (requires audit.read)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + }, + "503": { + "description": "Audit storage (ClickHouse) unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "status": 503, + "message": "audit storage unavailable" + } + } + } + } + } + } + }, + "/api/audit/export": { + "x-feature": "auditConsole", + "post": { + "tags": [ + "AuditConsole" + ], + "summary": "Request an audit export (CSV)", + "description": "Generates a CSV export of audit events matching the supplied filters. For \u226410 000 matching rows the export is generated synchronously and the response includes a `download_url`. For >10 000 rows the job is queued asynchronously; the response is `202 Accepted` with `status: processing` and a `status_url` to poll. Exports are cached on disk for 30 minutes and deleted after download. A per-user limit of 5 concurrent exports is enforced.\n", + "operationId": "requestAuditExport", + "parameters": [ + { + "name": "view_sensitive", + "in": "query", + "required": false, + "description": "Include unmasked PII in the CSV (requires audit.view_sensitive permission).", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuditExportRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Export ready for download (synchronous path, \u226410 000 rows)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuditExportResponse" + }, + "example": { + "export_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "ready", + "download_url": "/api/audit/export/3fa85f64-5717-4562-b3fc-2c963f66afa6", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "row_count": 42 + } + } + } + }, + "202": { + "description": "Export queued for background processing (>10 000 rows)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuditExportResponse" + }, + "example": { + "export_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "processing", + "status_url": "/api/audit/export/3fa85f64-5717-4562-b3fc-2c963f66afa6/status", + "download_url": "/api/audit/export/3fa85f64-5717-4562-b3fc-2c963f66afa6", + "row_count": 15000 + } + } + } + }, + "401": { + "$ref": "#/components/responses/UnauthorizedError" + }, + "403": { + "description": "Insufficient permissions (requires audit.export)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "413": { + "description": "Export exceeds the maximum row limit (5 000 000 rows)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "status": 413, + "message": "export exceeds maximum row limit" + } + } + } + }, + "429": { + "description": "Per-user concurrent export limit reached (max 5)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "status": 429, + "message": "export limit reached" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + }, + "503": { + "description": "Audit storage unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/audit/export/{id}": { + "x-feature": "auditConsole", + "get": { + "tags": [ + "AuditConsole" + ], + "summary": "Download an audit export CSV", + "description": "Streams the CSV file for the given export ID. The file is deleted from the server after a successful download. If the export is still being processed, returns `202`. If the export has expired (TTL 30 min), returns `410 Gone`.\n", + "operationId": "downloadAuditExport", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Export ID returned by POST /audit/export.", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "CSV file download", + "headers": { + "Content-Disposition": { + "required": true, + "schema": { + "type": "string" + }, + "example": "attachment; filename=\"audit-export-3fa85f64.csv\"" + }, + "X-Content-SHA256": { + "required": true, + "schema": { + "type": "string" + }, + "description": "SHA-256 hex digest of the file for integrity verification" + } + }, + "content": { + "application/octet-stream": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "401": { + "$ref": "#/components/responses/UnauthorizedError" + }, + "404": { + "description": "Export not found or already downloaded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "status": 404, + "message": "export not found or expired" + } + } + } + }, + "410": { + "description": "Export has expired (TTL exceeded)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "status": 410, + "message": "export expired" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/api/provisioning/v1/cloud/environments": { + "get": { + "tags": [ + "Cloud Environments" + ], + "summary": "List all VMware environments", + "description": "List all VMware cloud environments for auto-scaling.", + "operationId": "getCloudEnvironments", + "responses": { + "200": { + "description": "Cloud environment listed successfully", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CloudEnvironment" + } + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "post": { + "tags": [ + "Cloud Environments" + ], + "summary": "Create VMware environment", + "description": "Creates a new VMware cloud environment for auto-scaling.", + "operationId": "createCloudEnvironment", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateCloudEnvironmentRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Cloud environment created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CloudEnvironment" + } + } + } + }, + "400": { + "description": "Bad request - validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationError" + } + } + } + }, + "404": { + "description": "Provider or device template not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "409": { + "description": "Conflict - environment with same name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/environments/{environmentId}": { + "get": { + "tags": [ + "Cloud Environments" + ], + "summary": "Get VMware environment by ID", + "operationId": "getCloudEnvironmentByID", + "parameters": [ + { + "name": "environmentId", + "in": "path", + "required": true, + "description": "UUID of the cloud environment", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Cloud environment returned successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CloudEnvironment" + } + } + } + }, + "404": { + "description": "Cloud environment not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Cloud Environments" + ], + "summary": "Edit VMware environment", + "operationId": "updateCloudEnvironment", + "parameters": [ + { + "name": "environmentId", + "in": "path", + "required": true, + "description": "UUID of the cloud environment", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateCloudEnvironmentRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Cloud environment updated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CloudEnvironment" + } + } + } + }, + "400": { + "description": "Bad request - validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationError" + } + } + } + }, + "404": { + "description": "Cloud environment not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "409": { + "description": "Conflict - environment with same name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Cloud Environments" + ], + "summary": "Delete VMware environment", + "description": "Deletes an existing VMware cloud environment.", + "operationId": "deleteCloudEnvironment", + "parameters": [ + { + "name": "environmentId", + "in": "path", + "required": true, + "description": "UUID of the cloud environment", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "204": { + "description": "Cloud environment deleted successfully" + }, + "400": { + "description": "Bad request - environment is in use", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Cloud environment not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/providers": { + "get": { + "tags": [ + "Cloud Providers" + ], + "summary": "List all cloud providers", + "operationId": "getCloudProviders", + "responses": { + "200": { + "description": "List of cloud providers retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CloudProvider" + } + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + }, + "post": { + "tags": [ + "Cloud Providers" + ], + "summary": "Create a cloud provider", + "operationId": "createCloudProvider", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateCloudProviderRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Cloud provider created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CloudProvider" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "409": { + "description": "Conflict - provider with same name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/api/provisioning/v1/cloud/providers/{providerId}": { + "parameters": [ + { + "$ref": "#/components/parameters/ProviderId" + } + ], + "get": { + "tags": [ + "Cloud Providers" + ], + "summary": "Get cloud provider by ID", + "operationId": "getCloudProvider", + "responses": { + "200": { + "description": "Cloud provider retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CloudProvider" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + }, + "patch": { + "tags": [ + "Cloud Providers" + ], + "summary": "Edit cloud provider", + "operationId": "updateCloudProvider", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateCloudProviderRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Cloud provider updated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CloudProvider" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Conflict - provider with same name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + }, + "delete": { + "tags": [ + "Cloud Providers" + ], + "summary": "Delete cloud provider", + "operationId": "deleteCloudProvider", + "responses": { + "204": { + "description": "Provider deleted successfully" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/api/provisioning/v1/cloud/tasks/create-vm": { + "post": { + "tags": [ + "VM Tasks" + ], + "summary": "Create a VM", + "description": "Kicks off an asynchronous VM creation task in the referenced\ncloud environment. Returns 202 Accepted with task tracking info.\n", + "operationId": "createVMTask", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VMTaskRequest" + } + } + } + }, + "responses": { + "202": { + "description": "VM creation task accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VMTaskResponse" + } + } + } + }, + "400": { + "description": "Bad request - validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Referenced environment not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/tasks/delete-vm": { + "post": { + "tags": [ + "VM Tasks" + ], + "summary": "Delete a VM", + "description": "Kicks off an asynchronous VM deletion task in the referenced\ncloud environment. Returns 202 Accepted with task tracking info.\n", + "operationId": "deleteVMTask", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VMTaskRequest" + } + } + } + }, + "responses": { + "202": { + "description": "VM deletion task accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VMTaskResponse" + } + } + } + }, + "400": { + "description": "Bad request - validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Referenced environment not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/tasks/create-vm/{taskId}": { + "get": { + "tags": [ + "VM Tasks" + ], + "summary": "Get create-vm task status", + "operationId": "getCreateVMTask", + "parameters": [ + { + "name": "taskId", + "in": "path", + "required": true, + "description": "UUID of the VM task", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Task status returned", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VMTaskResponse" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/tasks/delete-vm/{taskId}": { + "get": { + "tags": [ + "VM Tasks" + ], + "summary": "Get delete-vm task status", + "operationId": "getDeleteVMTask", + "parameters": [ + { + "name": "taskId", + "in": "path", + "required": true, + "description": "UUID of the VM task", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Task status returned", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VMTaskResponse" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/connect": { + "post": { + "tags": [ + "Infrastructure Discovery" + ], + "summary": "Establish vSphere connection", + "description": "Establishes a connection to vSphere using provider credentials.\nReturns a connection ID that can be used for subsequent discovery API calls.\n", + "operationId": "connectToVSphere", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConnectRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Connection established successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConnectResponse" + } + } + } + }, + "400": { + "description": "Bad request - missing required parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Provider not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error or connection failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/datacenters": { + "get": { + "tags": [ + "Infrastructure Discovery" + ], + "summary": "List datacenters", + "description": "Lists all available datacenters in the vSphere environment.\n", + "operationId": "listDatacenters", + "parameters": [ + { + "name": "connId", + "in": "query", + "required": true, + "description": "Connection ID from /cloud/connect endpoint", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of datacenters", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DatacenterInfo" + } + } + } + } + }, + "400": { + "description": "Bad request - missing required parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Environment not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/clusters": { + "get": { + "tags": [ + "Infrastructure Discovery" + ], + "summary": "List clusters", + "description": "Lists all clusters in a datacenter.\n", + "operationId": "listClusters", + "parameters": [ + { + "name": "connId", + "in": "query", + "required": true, + "description": "Connection ID from /cloud/connect endpoint", + "schema": { + "type": "string" + } + }, + { + "name": "datacenter", + "in": "query", + "required": true, + "description": "Name of the datacenter", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of clusters", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ClusterInfo" + } + } + } + } + }, + "400": { + "description": "Bad request - missing required parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Environment or datacenter not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/hosts": { + "get": { + "tags": [ + "Infrastructure Discovery" + ], + "summary": "List hosts", + "description": "Lists hosts in a datacenter or cluster. If cluster is provided, lists only hosts\nin that cluster; otherwise lists all hosts in the datacenter.\n", + "operationId": "listHosts", + "parameters": [ + { + "name": "connId", + "in": "query", + "required": true, + "description": "Connection ID from /cloud/connect endpoint", + "schema": { + "type": "string" + } + }, + { + "name": "datacenter", + "in": "query", + "required": true, + "description": "Name of the datacenter", + "schema": { + "type": "string" + } + }, + { + "name": "cluster", + "in": "query", + "required": false, + "description": "Name of the cluster (optional - if omitted, lists all hosts in datacenter)", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of hosts", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HostInfo" + } + } + } + } + }, + "400": { + "description": "Bad request - missing required parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Environment, datacenter, or cluster not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/networks": { + "get": { + "tags": [ + "Infrastructure Discovery" + ], + "summary": "List networks", + "description": "Lists all networks in a datacenter.\n", + "operationId": "listNetworks", + "parameters": [ + { + "name": "connId", + "in": "query", + "required": true, + "description": "Connection ID from /cloud/connect endpoint", + "schema": { + "type": "string" + } + }, + { + "name": "datacenter", + "in": "query", + "required": true, + "description": "Name of the datacenter", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of networks", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NetworkInfo" + } + } + } + } + }, + "400": { + "description": "Bad request - missing required parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Environment or datacenter not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/datastores": { + "get": { + "tags": [ + "Infrastructure Discovery" + ], + "summary": "List datastores", + "description": "Lists all datastores in a datacenter.\n", + "operationId": "listDatastores", + "parameters": [ + { + "name": "connId", + "in": "query", + "required": true, + "description": "Connection ID from /cloud/connect endpoint", + "schema": { + "type": "string" + } + }, + { + "name": "datacenter", + "in": "query", + "required": true, + "description": "Name of the datacenter", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of datastores", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DatastoreInfo" + } + } + } + } + }, + "400": { + "description": "Bad request - missing required parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Environment or datacenter not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/cloud/vm-images": { + "get": { + "tags": [ + "Infrastructure Discovery" + ], + "summary": "List VM images", + "description": "Lists all VM images (templates) available in a datacenter.\n", + "operationId": "listVMImages", + "parameters": [ + { + "name": "connId", + "in": "query", + "required": true, + "description": "Connection ID from /cloud/connect endpoint", + "schema": { + "type": "string" + } + }, + { + "name": "datacenter", + "in": "query", + "required": true, + "description": "Name of the datacenter", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "List of VM images", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/VMInfo" + } + } + } + } + }, + "400": { + "description": "Bad request - missing required parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Environment or datacenter not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/device-templates": { + "get": { + "summary": "List device templates", + "description": "Returns a paginated list of device templates.\n\nSupports OData-style query parameters for filtering, sorting,\npagination, field selection, and total count:\n\n| Parameter | Example |\n|------------|----------------------------------------------|\n| `$filter` | `state eq 'DEPLOYED'` |\n| `$orderby` | `name asc` |\n| `$top` | `10` |\n| `$skip` | `20` |\n| `$select` | `id,name,state` |\n| `$count` | `true` |\n", + "operationId": "ListDeviceTemplates", + "tags": [ + "Device Templates" + ], + "parameters": [ + { + "$ref": "#/components/parameters/ODataFilterParam" + }, + { + "$ref": "#/components/parameters/ODataOrderByParam" + }, + { + "$ref": "#/components/parameters/ODataTopParam" + }, + { + "$ref": "#/components/parameters/ODataSkipParam" + }, + { + "$ref": "#/components/parameters/ODataSelectParam" + }, + { + "$ref": "#/components/parameters/ODataCountParam" + } + ], + "responses": { + "200": { + "description": "Paginated list of device templates", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateListResponse" + }, + "example": { + "status": 200, + "count": 2, + "totalItems": 2, + "items": [ + { + "id": "550e8400-e29b-41d4-a716-446655440000", + "name": "BIG-IP Standard Template", + "provider": "VMware", + "description": "Standard VMware configuration", + "state": "DEPLOYED", + "locked": false, + "lockReason": "NONE", + "createdAt": "2026-01-15T09:23:41Z", + "updatedAt": "2026-03-22T14:45:10Z" + }, + { + "id": "660e8400-e29b-41d4-a716-446655440001", + "name": "BIG-IP HA Template", + "provider": "AWS", + "description": "High availability configuration", + "state": "DRAFT", + "locked": false, + "lockReason": "NONE", + "createdAt": "2026-02-10T11:00:00Z", + "updatedAt": "2026-02-10T11:00:00Z" + } + ], + "selfLink": "/api/device-templates" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": null + } + } + } + } + } + }, + "post": { + "summary": "Create a device template", + "description": "Creates a new device template.\n\nThe optional `draft` flag controls the initial state:\n\n| `draft` | Initial state | Response |\n|---------|---------------|----------|\n| `true` | `DRAFT` | **201 Created** |\n| `false` / omitted | `NEW` | **200 OK** |\n\nTo deploy a template, use the separate `POST /device-templates/{id}/deploy` endpoint.\n", + "operationId": "CreateDeviceTemplate", + "tags": [ + "Device Templates" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateWriteRequest" + }, + "example": { + "name": "BIG-IP Standard Template", + "provider": "VMware", + "description": "Standard VMware configuration for production workloads", + "definition": { + "rootPassword": "s3cur3P@ss!", + "timeZone": "America/Los_Angeles", + "defaultRoute": "10.0.0.1", + "managementSslPort": 443, + "hostnameComponents": [ + { + "type": "STATIC_TEXT", + "value": "bigip-" + }, + { + "type": "SERIAL_NUMBER", + "value": null + } + ], + "lookupServerList": [ + "8.8.8.8", + "8.8.4.4" + ], + "ntpServerList": [ + "0.pool.ntp.org" + ], + "userAccountList": [ + { + "username": "admin", + "password": "adminP@ss!", + "role": "administrator", + "shell": "bash" + } + ], + "provisionedModuleList": [ + { + "module": "LTM", + "level": "NOMINAL" + } + ], + "networkRouteList": [ + { + "name": "default", + "gatewayAddress": "10.0.0.1", + "destination": "0.0.0.0/0" + } + ], + "vlanList": [ + { + "name": "external", + "nic": "1.1", + "mtu": 1500, + "tag": 100 + } + ], + "selfIpList": [ + { + "name": "external-self", + "ipPoolReference": "c3d4e5f6-a7b8-4890-8bcd-ef1234567892", + "vlanName": "external", + "portLockdown": "default", + "allowServices": null + } + ] + } + } + } + } + }, + "responses": { + "200": { + "description": "OK \u2014 device template created in NEW state (`draft=false` or omitted)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateMutationResponse" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "state": "NEW", + "status": 200, + "selfLink": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000", + "createdAt": "2026-01-15T09:23:41Z", + "updatedAt": "2026-01-15T09:23:41Z" + } + } + } + }, + "201": { + "description": "Created \u2014 device template created in DRAFT state (`draft=true`)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateMutationResponse" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "state": "DRAFT", + "status": 201, + "selfLink": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000", + "createdAt": "2026-01-15T09:23:41Z", + "updatedAt": "2026-01-15T09:23:41Z" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 400, + "message": "Bad Request \u2014 request validation failed", + "details": "Field 'name' is required and must be between 1 and 255 characters" + } + } + } + }, + "409": { + "description": "Conflict \u2014 name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "A device template with name 'BIG-IP Standard Template' already exists" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": "failed to create device template" + } + } + } + } + } + } + }, + "/api/provisioning/v1/device-templates/{id}": { + "parameters": [ + { + "$ref": "#/components/parameters/DeviceTemplateIdParam" + } + ], + "get": { + "summary": "Get a device template by ID", + "description": "Returns a single device template identified by its ID.\n\nSupports the OData `$select` parameter to return only specific fields:\n```\nGET /device-templates/{id}?$select=id,name,state\nGET /device-templates/{id}?$select=id,name,locked,lockReason,definition\n```\n", + "operationId": "GetDeviceTemplate", + "tags": [ + "Device Templates" + ], + "parameters": [ + { + "$ref": "#/components/parameters/ODataSelectParam" + } + ], + "responses": { + "200": { + "description": "Device template returned successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateGetResponse" + }, + "example": { + "status": 200, + "id": "550e8400-e29b-41d4-a716-446655440000", + "name": "BIG-IP Standard Template", + "provider": "VMware", + "description": "Standard VMware configuration for production workloads", + "state": "DEPLOYED", + "locked": true, + "lockReason": "READ_ONLY", + "definition": { + "rootPassword": "s3cur3P@ss!", + "timeZone": "America/Los_Angeles", + "defaultRoute": "10.0.0.1", + "managementSslPort": 443, + "hostnameComponents": [ + { + "type": "STATIC_TEXT", + "value": "bigip-" + }, + { + "type": "SERIAL_NUMBER", + "value": null + } + ], + "lookupServerList": [ + "8.8.8.8", + "8.8.4.4" + ], + "ntpServerList": [ + "0.pool.ntp.org" + ], + "userAccountList": [ + { + "username": "admin", + "password": "adminP@ss!", + "role": "administrator", + "shell": "bash" + } + ], + "provisionedModuleList": [ + { + "module": "LTM", + "level": "NOMINAL" + } + ], + "networkRouteList": [ + { + "name": "default", + "gatewayAddress": "10.0.0.1", + "destination": "0.0.0.0/0" + } + ], + "vlanList": [ + { + "name": "external", + "nic": "1.1", + "mtu": 1500, + "tag": 100 + } + ], + "selfIpList": [ + { + "name": "external-self", + "ipPoolReference": "c3d4e5f6-a7b8-4890-8bcd-ef1234567892", + "vlanName": "external", + "portLockdown": "default", + "allowServices": null + } + ] + }, + "lastValidatedAt": "2026-03-10T08:00:00Z", + "validatedAgainstLiveVm": false, + "lastDeployedVersion": null, + "selfLink": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000", + "createdAt": "2026-01-15T09:23:41Z", + "updatedAt": "2026-04-01T14:30:00Z" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": null + } + } + } + } + } + }, + "put": { + "summary": "Update a device template (full replace)", + "description": "Replaces all fields of an existing device template.\n\n**Precondition:** The device template must not be locked (`locked=true` \u2192 409).\nTemplates in `DEPLOYING` state are system-locked and cannot be modified.\n\nThe optional `draft` flag controls state transitions:\n\n| Current state | `draft` | New state | Response |\n|---------------|---------|-----------|----------|\n| `DRAFT` | `true` | `DRAFT` | **200 OK** |\n| `DRAFT` | `false` / omitted | `NEW` | **200 OK** |\n| `NEW` | \u2014 | `NEW` | **200 OK** |\n| `DEPLOYED` | \u2014 | `DEPLOYED` | **200 OK** |\n| `DEPLOYING` | any | \u2014 | **409 Conflict** |\n| Any (locked) | any | \u2014 | **409 Conflict** |\n\nTo deploy a template, use the separate `POST /device-templates/{id}/deploy` endpoint.\n", + "operationId": "UpdateDeviceTemplate", + "tags": [ + "Device Templates" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateWriteRequest" + }, + "example": { + "name": "BIG-IP Standard Template v2", + "provider": "VMware", + "description": "Updated VMware configuration with HA support", + "definition": { + "rootPassword": "n3wS3cur3P@ss!", + "timeZone": "America/Los_Angeles", + "defaultRoute": "10.0.0.1", + "managementSslPort": 443, + "hostnameComponents": [ + { + "type": "STATIC_TEXT", + "value": "bigip-" + }, + { + "type": "SERIAL_NUMBER", + "value": null + } + ], + "lookupServerList": [ + "8.8.8.8", + "8.8.4.4" + ], + "ntpServerList": [ + "0.pool.ntp.org" + ], + "userAccountList": [ + { + "username": "admin", + "password": "adminP@ss!", + "role": "administrator", + "shell": "bash" + } + ], + "provisionedModuleList": [ + { + "module": "LTM", + "level": "NOMINAL" + }, + { + "module": "ASM", + "level": "NOMINAL" + } + ], + "networkRouteList": [ + { + "name": "default", + "gatewayAddress": "10.0.0.1", + "destination": "0.0.0.0/0" + } + ], + "vlanList": [ + { + "name": "external", + "nic": "1.1", + "mtu": 1500, + "tag": 100 + }, + { + "name": "internal", + "nic": "1.2", + "mtu": 1500, + "tag": 200 + } + ], + "selfIpList": [ + { + "name": "external-self", + "ipPoolReference": "c3d4e5f6-a7b8-4890-8bcd-ef1234567892", + "vlanName": "external", + "portLockdown": "default", + "allowServices": null + }, + { + "name": "internal-self", + "ipPoolReference": "d4e5f6a7-b8c9-4890-8bcd-ef1234567893", + "vlanName": "internal", + "portLockdown": "none", + "allowServices": null + } + ] + } + } + } + } + }, + "responses": { + "200": { + "description": "OK \u2014 device template updated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateMutationResponse" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "state": "NEW", + "status": 200, + "selfLink": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000", + "createdAt": "2026-01-15T09:23:41Z", + "updatedAt": "2026-03-22T14:45:10Z" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 400, + "message": "Bad Request \u2014 request validation failed", + "details": "Field 'definition.rootPassword' must be at least 8 characters" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "409": { + "description": "Conflict \u2014 locked, deploying, or name collision", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "template is locked and cannot be modified" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": "failed to update device template" + } + } + } + } + } + }, + "patch": { + "summary": "Partially update a device template", + "description": "Partially updates an existing device template. Only the provided fields\nare modified; omitted fields retain their current values.\n\n**Precondition:** The device template must not be locked.\nTemplates in `DEPLOYING` state cannot be patched.\n\nFor the `definition` object, merge-patch semantics apply:\n- Provided keys are updated.\n- Omitted keys are left unchanged.\n- Keys set to `null` are cleared.\n- Array fields (e.g. `vlanList`, `selfIpList`) are replaced wholesale.\n", + "operationId": "PatchDeviceTemplate", + "tags": [ + "Device Templates" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplatePatchRequest" + }, + "example": { + "description": "Updated description with HA failover notes", + "definition": { + "managementSslPort": 8443 + } + } + } + } + }, + "responses": { + "200": { + "description": "OK \u2014 device template patched successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateMutationResponse" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "state": "NEW", + "status": 200, + "selfLink": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000", + "createdAt": "2026-01-15T09:23:41Z", + "updatedAt": "2026-04-01T16:20:00Z" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 400, + "message": "Bad Request \u2014 request validation failed", + "details": "Invalid value for 'definition.managementSslPort': must be between 1 and 65535" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "409": { + "description": "Conflict \u2014 locked or deploying", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "examples": { + "locked": { + "summary": "Template is locked", + "value": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "template is locked and cannot be modified" + } + }, + "deploying": { + "summary": "Template is deploying", + "value": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "template is currently deploying and cannot be modified" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": "failed to update device template" + } + } + } + } + } + }, + "delete": { + "summary": "Delete a device template", + "description": "Deletes a device template by ID.\n\n**Precondition:** The device template must not be locked.\nTemplates in `DEPLOYING` state cannot be deleted.\n", + "operationId": "DeleteDeviceTemplate", + "tags": [ + "Device Templates" + ], + "responses": { + "200": { + "description": "OK \u2014 device template deleted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateDeleteResponse" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "status": 200, + "deletedAt": "2026-04-10T16:00:00Z" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "409": { + "description": "Conflict \u2014 locked or deploying", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "template is locked and cannot be modified" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": "failed to delete device template" + } + } + } + } + } + } + }, + "/api/provisioning/v1/device-templates/{id}/lock": { + "parameters": [ + { + "$ref": "#/components/parameters/DeviceTemplateIdParam" + } + ], + "post": { + "summary": "Lock a device template", + "description": "Locks a device template to prevent modifications.\nSets `locked=true` and `lockReason=READ_ONLY`.\n\n**Precondition:** Template must not already be locked.\n", + "operationId": "LockDeviceTemplate", + "tags": [ + "Device Templates" + ], + "responses": { + "200": { + "description": "OK \u2014 device template locked", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateLockResponse" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "locked": true, + "lockReason": "READ_ONLY", + "status": 200, + "selfLink": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000", + "updatedAt": "2026-04-15T08:20:00Z" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "409": { + "description": "Conflict \u2014 already locked", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "template is locked and cannot be modified" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": null + } + } + } + } + } + }, + "delete": { + "summary": "Unlock a device template", + "description": "Unlocks a device template to allow modifications.\nSets `locked=false` and `lockReason=NONE`.\n\n**Precondition:** Template must be locked with `lockReason=READ_ONLY`.\nSystem locks (`DEPLOYMENT`) cannot be manually unlocked.\n", + "operationId": "UnlockDeviceTemplate", + "tags": [ + "Device Templates" + ], + "responses": { + "200": { + "description": "OK \u2014 device template unlocked", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateLockResponse" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "locked": false, + "lockReason": "NONE", + "status": 200, + "selfLink": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000", + "updatedAt": "2026-04-15T09:00:00Z" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "409": { + "description": "Conflict \u2014 not locked or system-locked", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "template is currently deploying and cannot be modified" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": null + } + } + } + } + } + } + }, + "/api/provisioning/v1/device-templates/{id}/validate": { + "parameters": [ + { + "$ref": "#/components/parameters/DeviceTemplateIdParam" + } + ], + "post": { + "summary": "Validate a device template", + "description": "Runs multi-tier validation on a device template:\n\n- **Tier 1 \u2014 Data & Sanity:** Required fields, value ranges, cross-field rules.\n- **Tier 2 \u2014 Template / Schema:** Validates the definition against the default template schema.\n- **Tier 3 \u2014 Live VM (future):** Validates against a live BIG-IP VM.\n\nAlways returns HTTP 200. Inspect `valid` and each tier's result for pass/fail.\n", + "operationId": "ValidateDeviceTemplate", + "tags": [ + "Device Templates" + ], + "responses": { + "200": { + "description": "Validation completed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateValidationResponse" + }, + "example": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "status": 200, + "valid": false, + "validatedAt": "2026-04-15T10:30:00Z", + "dataSanity": { + "valid": true, + "errors": [], + "warnings": [] + }, + "templateSchema": { + "valid": false, + "errors": [ + { + "field": "definition.managementSslPort", + "message": "Value must be between 1 and 65535" + } + ], + "warnings": [] + }, + "selfLink": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": null + } + } + } + } + } + } + }, + "/api/provisioning/v1/device-templates/{id}/deploy": { + "parameters": [ + { + "$ref": "#/components/parameters/DeviceTemplateIdParam" + } + ], + "post": { + "summary": "Deploy a device template", + "description": "Triggers deployment of a device template to target infrastructure.\n\n**Preconditions:**\n- Template must be in `NEW` or `DEPLOYED` state\n- Template must not be locked\n- Template must pass validation\n\nReturns 202 Accepted with a task object for tracking deployment progress.\n", + "operationId": "DeployDeviceTemplate", + "tags": [ + "Device Templates" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateDeployRequest" + }, + "example": { + "mgmtIp": "192.168.1.100", + "username": "admin", + "encodedBasicAuth": "YWRtaW46YWRtaW5QYXNzd29yZDEyMw==" + } + } + } + }, + "responses": { + "202": { + "description": "Accepted \u2014 deployment task queued", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateDeployResponse" + }, + "example": { + "status": 202, + "deviceTemplateId": "550e8400-e29b-41d4-a716-446655440000", + "deploymentTaskId": "c3d4e5f6-a7b8-4012-8def-123456789012", + "selfLink": "/api/device-templates/tasks/c3d4e5f6-a7b8-4012-8def-123456789012" + } + } + } + }, + "400": { + "description": "Bad Request \u2014 invalid request payload", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 400, + "message": "Bad Request \u2014 request validation failed", + "details": "Field 'mgmtIp' is required and must be a valid IPv4 address" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "409": { + "description": "Conflict \u2014 locked or already deploying", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "template is currently deploying and cannot be modified" + } + } + } + }, + "422": { + "description": "Unprocessable Entity \u2014 template not in deployable state or validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 422, + "message": "Unprocessable Entity \u2014 template validation failed", + "details": "Template must pass validation before deployment" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": null + } + } + } + } + } + } + }, + "/api/provisioning/v1/device-templates/{id}/clone": { + "parameters": [ + { + "$ref": "#/components/parameters/DeviceTemplateIdParam" + } + ], + "post": { + "summary": "Clone a device template", + "description": "Creates a deep copy of an existing device template with a new name.\nThe clone is always created in `DRAFT` state, unlocked.\n", + "operationId": "CloneDeviceTemplate", + "tags": [ + "Device Templates" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateCloneRequest" + }, + "example": { + "name": "BIG-IP Standard Template (Copy)" + } + } + } + }, + "responses": { + "201": { + "description": "Created \u2014 clone created in DRAFT state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateMutationResponse" + }, + "example": { + "id": "770e8400-e29b-41d4-a716-446655440002", + "state": "DRAFT", + "status": 201, + "selfLink": "/api/device-templates/770e8400-e29b-41d4-a716-446655440002", + "createdAt": "2026-04-20T12:00:00Z", + "updatedAt": "2026-04-20T12:00:00Z" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 400, + "message": "Bad Request \u2014 request validation failed", + "details": "Field 'name' is required for cloning" + } + } + } + }, + "404": { + "description": "Not Found \u2014 source template not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Source device template with ID '550e8400-e29b-41d4-a716-446655440000' not found" + } + } + } + }, + "409": { + "description": "Conflict \u2014 clone name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 409, + "message": "Conflict \u2014 unique constraint violation", + "details": "A device template with name 'BIG-IP Standard Template (Copy)' already exists" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": "failed to create device template" + } + } + } + } + } + } + }, + "/api/provisioning/v1/device-templates/tasks/{taskId}": { + "parameters": [ + { + "$ref": "#/components/parameters/TaskIdParam" + } + ], + "get": { + "summary": "Get a device template task by ID", + "description": "Retrieves a specific task by its ID.\nFor active tasks (PENDING, RUNNING), this endpoint polls the external service\nfor the latest status before returning.\n", + "operationId": "GetDeviceTemplateTask", + "tags": [ + "Device Templates" + ], + "responses": { + "200": { + "description": "OK \u2014 task retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateTask" + }, + "example": { + "id": "660e8400-e29b-41d4-a716-446655440001", + "deviceTemplateId": "550e8400-e29b-41d4-a716-446655440000", + "externalTaskId": "ext-task-12345", + "type": "DEPLOYMENT", + "status": 200, + "taskStatus": "RUNNING", + "state": "onboarding", + "createdAt": "2026-04-20T12:00:00Z", + "updatedAt": "2026-04-20T12:05:00Z", + "selfLink": "/api/device-templates/tasks/660e8400-e29b-41d4-a716-446655440001" + } + } + } + }, + "400": { + "description": "Bad Request \u2014 invalid UUID format", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 400, + "message": "Bad Request \u2014 request validation failed", + "details": "Task ID 'invalid-uuid' is not a valid UUID format" + } + } + } + }, + "404": { + "description": "Not Found \u2014 task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 404, + "message": "Not Found \u2014 resource does not exist", + "details": "Task with ID '660e8400-e29b-41d4-a716-446655440001' not found" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceTemplateError" + }, + "example": { + "status": 500, + "message": "Internal Server Error", + "details": null + } + } + } + } + } + } + }, + "/api/provisioning/v1/ip-pools": { + "get": { + "summary": "List IP pools", + "description": "Retrieve IP pools with optional pagination.", + "operationId": "getIpPools", + "parameters": [ + { + "name": "$top", + "in": "query", + "description": "Maximum number of records to return.", + "required": false, + "schema": { + "type": "integer", + "minimum": 1 + } + }, + { + "name": "$skip", + "in": "query", + "description": "Number of records to skip before returning results.", + "required": false, + "schema": { + "type": "integer", + "minimum": 0 + } + } + ], + "responses": { + "200": { + "description": "A paginated collection of IP pools.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPPoolListResponse" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ] + }, + "post": { + "summary": "Create IP pool", + "description": "Create a new IP pool with CIDR definition and address ranges.", + "operationId": "postIpPools", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPPoolCreateRequest" + } + } + } + }, + "responses": { + "201": { + "description": "IP pool created successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPPool" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ] + } + }, + "/api/provisioning/v1/ip-pools/{poolId}": { + "parameters": [ + { + "$ref": "#/components/parameters/PoolId" + } + ], + "get": { + "summary": "Get IP pool", + "description": "Fetch an IP pool by its identifier.", + "operationId": "getIpPoolsPoolId", + "responses": { + "200": { + "description": "IP pool details.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPPool" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ] + }, + "put": { + "summary": "Update IP pool", + "description": "Replace the configuration of an existing IP pool.", + "operationId": "putIpPoolsPoolId", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPPoolUpdateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Updated IP pool.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPPool" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ] + }, + "delete": { + "summary": "Delete IP pool", + "description": "Permanently remove an IP pool. The operation fails if the pool still has active leases.", + "operationId": "deleteIpPoolsPoolId", + "responses": { + "204": { + "description": "Pool deleted successfully." + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "409": { + "description": "Pool cannot be deleted because of active leases or validation errors.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ] + } + }, + "/api/provisioning/v1/ip-pools/{poolId}/allocate": { + "parameters": [ + { + "$ref": "#/components/parameters/PoolId" + } + ], + "post": { + "summary": "Allocate IP address", + "description": "Allocate an IP address from the specified pool. The request is idempotent on `allocationId`.", + "operationId": "postIpPoolsPoolIdAllocate", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AllocationRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Allocation succeeded and returns the resulting lease.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AllocationResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "409": { + "description": "Allocation failed due to conflicts such as exhausted address space.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ] + } + }, + "/api/provisioning/v1/ip-pools/{poolId}/release": { + "parameters": [ + { + "$ref": "#/components/parameters/PoolId" + } + ], + "post": { + "summary": "Release IP address(es)", + "description": "Release one or more leases that match the provided criteria (allocation ID, address, or tags).", + "operationId": "postIpPoolsPoolIdRelease", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Leases successfully released (if any matched the filters).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ] + } + }, + "/api/provisioning/v1/ip-pools/{poolId}/leases": { + "parameters": [ + { + "$ref": "#/components/parameters/PoolId" + } + ], + "get": { + "summary": "List leases for pool", + "description": "Retrieve all active leases belonging to the specified pool.", + "operationId": "getIpPoolsPoolIdLeases", + "responses": { + "200": { + "description": "Collection of leases for the pool.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPLeaseListResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ] + } + }, + "/api/provisioning/v1/ip-pools/{poolId}/leases/{leaseId}": { + "parameters": [ + { + "$ref": "#/components/parameters/PoolId" + }, + { + "name": "leaseId", + "in": "path", + "description": "UUID of the IP lease.", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "get": { + "summary": "Get lease by ID", + "description": "Retrieve a specific lease by its identifier.", + "operationId": "getIpPoolsPoolIdLeasesLeaseId", + "responses": { + "200": { + "description": "Lease details.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPLease" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ] + } + }, + "/api/provisioning/v1/ip-pools/release": { + "post": { + "summary": "Release IP address(es) globally across all pools", + "description": "Release one or more leases across all IP pools that match the provided allocation ID and optional lease tags.", + "operationId": "postRelease", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GlobalReleaseRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Leases successfully released (if any matched the criteria).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ] + } + }, + "/api/provisioning/v1/ip-pools/leases": { + "post": { + "summary": "Create manual lease", + "description": "Manually create a lease for a specific address in a pool. Validates address belongs to pool ranges and enforces uniqueness.", + "operationId": "postIpPoolsLeases", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPLease" + } + } + } + }, + "responses": { + "200": { + "description": "Lease created successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IPLease" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "409": { + "description": "Lease creation failed due to conflicts (address already allocated or allocationId in use).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "others" + ] + } + }, + "/api/provisioning/v1/licensing/pool/regkey/licenses": { + "get": { + "tags": [ + "License Pool" + ], + "summary": "Fetches all available license pools", + "description": "Fetches all available license pools in the system.", + "operationId": "getLicensePools", + "parameters": [ + { + "name": "$select", + "in": "query", + "required": false, + "description": "Fields to select in the response", + "schema": { + "type": "string" + }, + "example": "id" + } + ], + "responses": { + "200": { + "description": "returns list of all License pools successfully", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/LicensePool" + } + } + } + } + }, + "400": { + "description": "Bad request - invalid input", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "post": { + "tags": [ + "License Pool" + ], + "summary": "Create a new license pool", + "description": "Creates a new license pool that can hold multiple license offerings", + "operationId": "createLicensePool", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the license pool", + "example": "test" + }, + "description": { + "type": "string", + "description": "Description of the license pool", + "example": "" + } + } + }, + "examples": { + "createPool": { + "summary": "Create license pool example", + "value": { + "name": "test", + "description": "" + } + } + } + } + } + }, + "responses": { + "201": { + "description": "License pool created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicensePool" + } + } + } + }, + "400": { + "description": "Bad request - invalid input", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/licensing/pool/regkey/licenses/{poolId}": { + "get": { + "tags": [ + "License Pool" + ], + "summary": "Get license pool by ID", + "description": "Get license pool by given ID in the path parameter", + "operationId": "getLicensePool", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + } + ], + "responses": { + "200": { + "description": "Returns the License pool successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicensePool" + } + } + } + }, + "400": { + "description": "Bad request - invalid input", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool not found" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "delete": { + "tags": [ + "License Pool" + ], + "summary": "Delete a license pool", + "description": "Deletes a license pool. If licenses are added and activated but not assigned to any device, deleting the pool will invalidate all associated registration keys. If any license from the pool is already assigned to a member, returns 400 error.\n", + "operationId": "deleteLicensePool", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + } + ], + "responses": { + "204": { + "description": "License pool deleted successfully" + }, + "400": { + "description": "Bad request - pool has outstanding grants", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "code": 400, + "message": "Found 1 outstanding grant(s). They must be removed before this license can be deleted." + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool not found" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/provisioning/v1/licensing/pool/regkey/licenses/{poolId}/assign": { + "post": { + "tags": [ + "License Pool" + ], + "summary": "Assign an available license from the pool to a device", + "description": "Automatically assigns an available license from the pool to the specified BIG-IP device.\n\nThis is a convenience endpoint that:\n1. Finds all offerings in the pool that are READY and not already assigned to any member\n2. Picks the first available offering\n3. Assigns the license to the specified device\n\nThis is an **asynchronous operation** that returns a TaskReference for polling.\n", + "operationId": "assignPoolLicense", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoolLicenseOperationRequest" + }, + "examples": { + "assignLicense": { + "summary": "Assign license to device", + "value": { + "deviceAddress": "192.168.1.100", + "deviceUsername": "admin", + "devicePassword": "admin" + } + } + } + } + } + }, + "responses": { + "202": { + "description": "License assignment initiated (async operation)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskReference" + } + } + } + }, + "400": { + "description": "Bad request - no available licenses or invalid parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "noAvailableLicenses": { + "summary": "No available licenses in the pool", + "value": { + "code": 400, + "message": "No available licenses in the pool" + } + }, + "invalidDeviceAddress": { + "summary": "Invalid device address", + "value": { + "code": 400, + "message": "Invalid device address" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool not found" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/provisioning/v1/licensing/pool/regkey/licenses/{poolId}/revoke": { + "delete": { + "tags": [ + "License Pool" + ], + "summary": "Revoke license from a device in the pool", + "description": "Revokes the license from a device that has a license assigned from this pool.\n\nThis is a convenience endpoint that:\n1. Finds the member record by device address\n2. Revokes the license from the device (unless force=true)\n3. Removes the member record from the pool\n\nIf `force=true`, the license will be revoked from the pool without contacting the device.\nThis is useful when the device is unreachable or destroyed.\n", + "operationId": "revokePoolLicense", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "force", + "in": "query", + "required": false, + "description": "If true, skip device communication and delete the license assignment from the pool\nwithout contacting the BIG-IP device. Useful when the device is unreachable or destroyed.\n", + "schema": { + "type": "boolean", + "default": false + }, + "example": true + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoolLicenseOperationRequest" + }, + "examples": { + "revokeLicense": { + "summary": "Revoke license from device", + "value": { + "deviceAddress": "192.168.1.100", + "deviceUsername": "admin", + "devicePassword": "admin" + } + } + } + } + } + }, + "responses": { + "204": { + "description": "License successfully revoked from the device" + }, + "400": { + "description": "Bad request - revocation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool not found or device not found in pool", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "deviceNotFound": { + "summary": "Device not found in pool", + "value": { + "code": 404, + "message": "Device 192.168.1.100 not found in pool" + } + } + } + } + } + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/provisioning/v1/licensing/pool/regkey/licenses/{poolId}/offerings": { + "post": { + "tags": [ + "License Offering" + ], + "summary": "Add license offering to the pool", + "description": "Adds a license offering to an existing pool by activating a registration key. Steps - 1. Generate public/private keys and dossier. 2. Check the MODE of activation (AUTOMATIC, MANUAL, CCN) and trigger corresponding flow. 3. Contact F5 License Server at https://authem.f5net.com/license/services/. 4. F5 License server returns license_text if activation is successful.\n", + "operationId": "addLicenseOffering", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "regKey", + "status" + ], + "properties": { + "regKey": { + "type": "string", + "description": "F5 registration key", + "example": "U5939-99933-49705-74523-4841009" + }, + "status": { + "type": "string", + "enum": [ + "ACTIVATING_AUTOMATIC", + "ACTIVATING_MANUAL" + ], + "description": "Activation mode to use when adding the offering. ACTIVATING_AUTOMATIC - contacts F5 license server automatically. ACTIVATING_MANUAL - begins manual activation flow.\n", + "example": "ACTIVATING_AUTOMATIC" + }, + "name": { + "type": "string", + "description": "Optional name for the license offering", + "example": "" + }, + "description": { + "type": "string", + "description": "Optional description for the license offering", + "example": "" + } + } + }, + "examples": { + "automaticActivation": { + "summary": "Automatic activation example", + "value": { + "regKey": "U5939-99933-49705-74523-4841009", + "status": "ACTIVATING_AUTOMATIC", + "name": "", + "description": "" + } + }, + "manualActivation": { + "summary": "Manual activation example", + "value": { + "regKey": "U5939-99933-49705-74523-4841009", + "status": "ACTIVATING_MANUAL", + "name": "", + "description": "" + } + } + } + } + } + }, + "responses": { + "202": { + "description": "License offering activation initiated (async operation)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskReference" + } + } + } + }, + "400": { + "description": "Bad request - invalid registration key or activation failure", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool not found" + }, + "500": { + "description": "Internal server error" + } + } + }, + "get": { + "tags": [ + "License Offering" + ], + "summary": "Get all license offerings in the pool", + "description": "Retrieves all license offerings associated with a specific license pool", + "operationId": "getLicenseOfferings", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "$select", + "in": "query", + "required": false, + "description": "Fields to select in the response", + "schema": { + "type": "string" + }, + "example": "selfLink" + }, + { + "name": "$filter", + "in": "query", + "required": false, + "description": "OData filter expression to filter offerings.\nSupported fields: status, isAssigned, regKey\nExamples:\n- `isAssigned eq false` - Get only available (unassigned) offerings\n- `isAssigned eq true` - Get only assigned offerings\n- `status eq 'READY'` - Get only offerings with READY status\n- `status eq 'READY' and isAssigned eq false` - Get available READY offerings\n", + "schema": { + "type": "string" + }, + "examples": { + "available": { + "summary": "Get available offerings", + "value": "isAssigned eq false" + }, + "assigned": { + "summary": "Get assigned offerings", + "value": "isAssigned eq true" + }, + "readyAndAvailable": { + "summary": "Get ready and available offerings", + "value": "status eq 'READY' and isAssigned eq false" + } + } + } + ], + "responses": { + "200": { + "description": "List of license offerings retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/LicenseOffering" + } + }, + "totalItems": { + "type": "integer", + "description": "Total number of offerings" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool not found" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/provisioning/v1/licensing/pool/regkey/licenses/{poolId}/offerings/{regKey}": { + "get": { + "tags": [ + "License Offering" + ], + "summary": "Get license offering by registration key", + "description": "Retrieves a specific license offering from the pool by its registration key. Returns the full offering details including activation status, license text, and license count information.\n", + "operationId": "getLicenseOffering", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "regKey", + "in": "path", + "required": true, + "description": "Registration key of the license offering", + "schema": { + "type": "string" + }, + "example": "U5939-99933-49705-74523-4841009" + } + ], + "responses": { + "200": { + "description": "License offering retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseOffering" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool or offering not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "code": 404, + "message": "License offering with regKey U5939-99933-49705-74523-4841009 not found in pool 7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + } + } + } + }, + "500": { + "description": "Internal server error" + } + } + }, + "patch": { + "tags": [ + "License Offering" + ], + "summary": "Update or reactivate a license offering", + "description": "Updates an existing license offering in the pool. This endpoint supports three distinct operations\nbased on the `status` field in the request body:\n\n---\n## Operation 1: Automatic Reactivation (Async)\n**Request:** `{\"status\": \"ACTIVATING_AUTOMATIC\"}`\n**Response:** `202 Accepted` with TaskReference\n\nTriggers automatic reactivation via F5 license server. This is an **asynchronous operation**.\n\nSteps:\n1. Validate the offering exists and belongs to the specified pool.\n2. Generate a new dossier for the existing registration key.\n3. Contact F5 License Server at https://authem.f5net.com/license/services/ for reactivation.\n4. F5 License Server returns updated license_text if reactivation is successful.\n5. Update the offering status to READY upon successful reactivation.\n\nPoll the returned task link to check completion status.\n\n---\n## Operation 2: Manual Reactivation - Get New Dossier (Sync)\n**Request:** `{\"status\": \"ACTIVATING_MANUAL\"}`\n**Response:** `200 OK` with LicenseOffering (containing new dossier)\n\nTriggers manual reactivation flow. This is a **synchronous operation** that returns immediately\nwith a new dossier. The offering status will be set to `ACTIVATING_MANUAL_NEED_LICENSE_TEXT`.\n\nSteps:\n1. Validate the offering exists and belongs to the specified pool.\n2. Regenerate dossier (reuses existing keys).\n3. Return the updated offering with the new dossier.\n\nUser should then submit the dossier to F5 license server UI to obtain license text.\n\n---\n## Operation 3: Complete Manual Activation with License Text (Sync)\n**Request:** `{\"status\": \"ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED\", \"licenseText\": \"...\"}`\n**Response:** `200 OK` with LicenseOffering\n\nCompletes manual activation by providing the license text. This is a **synchronous operation**.\nThe offering must be in `ACTIVATING_MANUAL_NEED_LICENSE_TEXT` status.\n\nSteps:\n1. Validate the offering exists and is in ACTIVATING_MANUAL_NEED_LICENSE_TEXT status.\n2. Validate the provided license text format.\n3. Store the license text and parse license state.\n4. Update the offering status to READY.\n", + "operationId": "updateLicenseOffering", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "regKey", + "in": "path", + "required": true, + "description": "Registration key of the license offering to update", + "schema": { + "type": "string" + }, + "example": "U5939-99933-49705-74523-4841009" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateLicenseOfferingRequest" + }, + "examples": { + "reactivateAutomatic": { + "summary": "Operation 1: Automatic Reactivation (Async) \u2192 Returns 202 with TaskReference", + "value": { + "status": "ACTIVATING_AUTOMATIC" + } + }, + "reactivateManual": { + "summary": "Operation 2: Manual Reactivation (Sync) \u2192 Returns 200 with new dossier", + "value": { + "status": "ACTIVATING_MANUAL" + } + }, + "completeManualActivation": { + "summary": "Operation 3: Complete Manual Activation (Sync) \u2192 Returns 200 with activated offering", + "value": { + "status": "ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED", + "licenseText": "Auth vers : 5b\nRegistration key : W5778-33088-84412-26046-5913991\nLicensed date : 20260525\nLicense start : 20260524\nLicense end : 20260625\nService check date : 20260525\nPlatform ID : Z100\nUsage : F5 Internal Product Development\nVendor : F5 Networks, Inc.\n..." + } + } + } + } + } + }, + "responses": { + "200": { + "description": "License offering updated successfully. Returned for **synchronous operations**:\n- `ACTIVATING_MANUAL`: Returns offering with new dossier (status: ACTIVATING_MANUAL_NEED_LICENSE_TEXT)\n- `ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED`: Returns fully activated offering (status: READY)\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LicenseOffering" + }, + "examples": { + "manualReactivationResponse": { + "summary": "Response for ACTIVATING_MANUAL - new dossier generated", + "value": { + "id": "f1e2d3c4-b5a6-7890-cdef-123456789abc", + "regKey": "U5939-99933-49705-74523-4841009", + "name": "", + "status": "ACTIVATING_MANUAL_NEED_LICENSE_TEXT", + "dossier": "1ac56379204d679f59524f2e64300d03b91b4b9ff08225ce0087d91b6cf061227610", + "message": "Dossier generated. Submit this dossier to F5 license server to obtain license text, then call this endpoint with status ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED.", + "selfLink": "https://localhost/api/licensing/pool/regkey/licenses/7dd7b971-6eb8-4b9e-995b-1dcb1287d65f/offerings/U5939-99933-49705-74523-4841009", + "createdAt": "2024-01-15T10:30:00Z" + } + }, + "licenseTextProvidedResponse": { + "summary": "Response for ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED - activation complete", + "value": { + "id": "f1e2d3c4-b5a6-7890-cdef-123456789abc", + "regKey": "U5939-99933-49705-74523-4841009", + "name": "", + "status": "READY", + "licenseText": "Auth vers : 5b\nRegistration key : W5778-33088-84412-26046-5913991\n...", + "licenseState": { + "registrationKey": "W5778-33088-84412-26046-5913991", + "licensedDateTime": "2024-01-15T10:30:00Z", + "licenseEndDateTime": "2025-01-15T10:30:00Z" + }, + "selfLink": "https://localhost/api/licensing/pool/regkey/licenses/7dd7b971-6eb8-4b9e-995b-1dcb1287d65f/offerings/U5939-99933-49705-74523-4841009", + "createdAt": "2024-01-15T10:30:00Z", + "activatedAt": "2024-01-15T10:35:00Z" + } + } + } + } + } + }, + "202": { + "description": "License offering reactivation initiated. Returned for **asynchronous operation**:\n- `ACTIVATING_AUTOMATIC`: Returns task reference for polling\n\nPoll the `taskLink` to check the status of the reactivation operation.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskReference" + }, + "example": { + "taskLink": "https://localhost/api/licensing/pool/tasks/d4e5f6a7-b8c9-0123-defg-456789abcdef" + } + } + } + }, + "400": { + "description": "Bad request - invalid status, missing license text, or operation not allowed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "invalidStatus": { + "summary": "Invalid status for current offering state", + "value": { + "code": 400, + "message": "Cannot complete manual activation: offering is not in ACTIVATING_MANUAL_NEED_LICENSE_TEXT status" + } + }, + "missingLicenseText": { + "summary": "Missing license text for manual completion", + "value": { + "code": 400, + "message": "License text is required when status is ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED" + } + }, + "invalidLicenseText": { + "summary": "Invalid license text format", + "value": { + "code": 400, + "message": "Invalid license text format: missing required fields" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool or offering not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "code": 404, + "message": "License offering with regKey U5939-99933-49705-74523-4841009 not found in pool 7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + } + } + } + }, + "500": { + "description": "Internal server error" + } + } + }, + "delete": { + "tags": [ + "License Offering" + ], + "summary": "Delete license offering from the pool", + "description": "Deletes a specific license offering from the pool. If the license has already been granted to a member, returns 400 error.\n", + "operationId": "deleteLicenseOffering", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "regKey", + "in": "path", + "required": true, + "description": "Registration key of the license offering", + "schema": { + "type": "string" + }, + "example": "U5939-99933-49705-74523-4841009" + } + ], + "responses": { + "204": { + "description": "License offering deleted successfully" + }, + "400": { + "description": "Bad request - license has been granted to a device", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "code": 400, + "message": "The license U5939-99933-49705-74523-4841009 has been granted to a device" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License offering not found" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/provisioning/v1/licensing/pool/regkey/licenses/{poolId}/offerings/{regKey}/members": { + "post": { + "tags": [ + "License Members" + ], + "summary": "Assign license offering to member", + "description": "Assign a license from the pool to a specific BIG-IP device member", + "operationId": "assignLicenseMember", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "regKey", + "in": "path", + "required": true, + "description": "Registration key of the license offering", + "schema": { + "type": "string" + }, + "example": "U5939-99933-49705-74523-4841009" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "deviceAddress", + "deviceUsername", + "devicePassword" + ], + "properties": { + "deviceAddress": { + "type": "string", + "format": "ipv4", + "description": "IP address of the BIG-IP device", + "example": "192.168.1.100" + }, + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + }, + "examples": { + "assignMember": { + "summary": "Assign license to member example", + "value": { + "deviceAddress": "192.168.1.100", + "deviceUsername": "admin", + "devicePassword": "admin" + } + } + } + } + } + }, + "responses": { + "202": { + "description": "License assignment initiated (async operation)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskReference" + } + } + } + }, + "400": { + "description": "Bad request - invalid parameters, no available licenses, or license already granted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "licenseAlreadyGranted": { + "summary": "License already assigned to another device", + "value": { + "code": 400, + "message": "This license has already been granted to a BIG-IP - bigip-ve-001.local" + } + }, + "invalidDeviceAddress": { + "summary": "Invalid device address", + "value": { + "code": 400, + "message": "Invalid device address" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool or offering not found" + }, + "500": { + "description": "Internal server error" + } + } + }, + "get": { + "tags": [ + "License Members" + ], + "summary": "Get all license offering members", + "description": "Retrieves all members (BIG-IP devices) that have been assigned licenses from a specific offering", + "operationId": "getLicenseMembers", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "regKey", + "in": "path", + "required": true, + "description": "Registration key of the license offering", + "schema": { + "type": "string" + }, + "example": "U5939-99933-49705-74523-4841009" + } + ], + "responses": { + "200": { + "description": "List of license members retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/LicenseMember" + } + }, + "totalItems": { + "type": "integer", + "description": "Total number of members" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License pool or offering not found" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/provisioning/v1/licensing/pool/tasks": { + "get": { + "tags": [ + "Tasks" + ], + "summary": "List all tasks", + "description": "Retrieves a paginated list of all async tasks with optional filtering.\nUseful for monitoring and debugging async operations.\n", + "operationId": "listTasks", + "parameters": [ + { + "name": "status", + "in": "query", + "required": false, + "description": "Filter tasks by status", + "schema": { + "type": "string", + "enum": [ + "PENDING", + "IN_PROGRESS", + "COMPLETED", + "FAILED" + ] + }, + "example": "IN_PROGRESS" + }, + { + "name": "type", + "in": "query", + "required": false, + "description": "Filter tasks by type", + "schema": { + "type": "string", + "enum": [ + "ADD_OFFERING", + "REACTIVATE_OFFERING", + "ASSIGN_LICENSE", + "REVOKE_LICENSE" + ] + }, + "example": "ASSIGN_LICENSE" + }, + { + "name": "resourceType", + "in": "query", + "required": false, + "description": "Filter tasks by resource type", + "schema": { + "type": "string", + "enum": [ + "LicenseOffering", + "LicenseMember" + ] + }, + "example": "LicenseMember" + }, + { + "name": "resourceId", + "in": "query", + "required": false, + "description": "Filter tasks by resource ID", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" + }, + { + "name": "page", + "in": "query", + "required": false, + "description": "Page number for pagination (1-based)", + "schema": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "example": 1 + }, + { + "name": "size", + "in": "query", + "required": false, + "description": "Number of items per page", + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 20 + }, + "example": 20 + }, + { + "name": "sort", + "in": "query", + "required": false, + "description": "Sort order for results. Format: field:direction\nSupported fields: createdAt, startedAt, completedAt, status\nDirection: asc or desc\n", + "schema": { + "type": "string", + "default": "createdAt:desc" + }, + "example": "createdAt:desc" + } + ], + "responses": { + "200": { + "description": "List of tasks retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskListResponse" + } + } + } + }, + "400": { + "description": "Bad request - invalid filter parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/licensing/pool/tasks/{taskId}": { + "get": { + "tags": [ + "Tasks" + ], + "summary": "Get task status by ID", + "description": "Retrieves the current status and details of an async task.\nUse this endpoint to poll for task completion after initiating async operations\nlike license activation, assignment, or revocation.\n", + "operationId": "getTaskStatus", + "parameters": [ + { + "name": "taskId", + "in": "path", + "required": true, + "description": "UUID of the task to retrieve", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "d4e5f6a7-b8c9-0123-defg-456789abcdef" + } + ], + "responses": { + "200": { + "description": "Task status retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Task" + }, + "examples": { + "pendingTask": { + "summary": "Task pending", + "value": { + "id": "d4e5f6a7-b8c9-0123-defg-456789abcdef", + "type": "ASSIGN_LICENSE", + "status": "PENDING", + "progress": 0, + "resourceType": "LicenseMember", + "resourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "selfLink": "https://localhost/api/licensing/pool/tasks/d4e5f6a7-b8c9-0123-defg-456789abcdef", + "createdAt": "2024-01-15T10:30:00Z" + } + }, + "inProgressTask": { + "summary": "Task in progress", + "value": { + "id": "d4e5f6a7-b8c9-0123-defg-456789abcdef", + "type": "ADD_OFFERING", + "status": "IN_PROGRESS", + "progress": 50, + "resourceType": "LicenseOffering", + "resourceId": "f1e2d3c4-b5a6-7890-cdef-123456789abc", + "selfLink": "https://localhost/api/licensing/pool/tasks/d4e5f6a7-b8c9-0123-defg-456789abcdef", + "createdAt": "2024-01-15T10:30:00Z", + "startedAt": "2024-01-15T10:30:05Z" + } + }, + "completedTask": { + "summary": "Task completed successfully", + "value": { + "id": "d4e5f6a7-b8c9-0123-defg-456789abcdef", + "type": "ASSIGN_LICENSE", + "status": "COMPLETED", + "progress": 100, + "resourceType": "LicenseMember", + "resourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "resourceLink": "https://localhost/api/licensing/pool/regkey/licenses/7dd7b971-6eb8-4b9e-995b-1dcb1287d65f/offerings/U5939-99933-49705-74523-4841009/members/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "selfLink": "https://localhost/api/licensing/pool/tasks/d4e5f6a7-b8c9-0123-defg-456789abcdef", + "createdAt": "2024-01-15T10:30:00Z", + "startedAt": "2024-01-15T10:30:05Z", + "completedAt": "2024-01-15T10:30:15Z" + } + }, + "failedTask": { + "summary": "Task failed", + "value": { + "id": "d4e5f6a7-b8c9-0123-defg-456789abcdef", + "type": "ADD_OFFERING", + "status": "FAILED", + "progress": 25, + "resourceType": "LicenseOffering", + "resourceId": "f1e2d3c4-b5a6-7890-cdef-123456789abc", + "error": { + "code": 500, + "message": "Failed to contact F5 license server", + "details": "Connection timeout after 30 seconds", + "timestamp": "2024-01-15T10:30:35Z" + }, + "selfLink": "https://localhost/api/licensing/pool/tasks/d4e5f6a7-b8c9-0123-defg-456789abcdef", + "createdAt": "2024-01-15T10:30:00Z", + "startedAt": "2024-01-15T10:30:05Z", + "completedAt": "2024-01-15T10:30:35Z" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "code": 404, + "message": "Task with ID d4e5f6a7-b8c9-0123-defg-456789abcdef not found" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/provisioning/v1/licensing/pool/regkey/licenses/{poolId}/offerings/{regKey}/members/{memberId}": { + "delete": { + "tags": [ + "License Members" + ], + "summary": "Revoke license from member", + "description": "Revokes a license assignment from a specific BIG-IP device member and returns the license to the pool. This is a synchronous operation that contacts the device to deactivate the license. If force=true is specified, the license will be revoked from the pool without contacting the device.\n", + "operationId": "revokeLicenseMember", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "regKey", + "in": "path", + "required": true, + "description": "Registration key of the license offering", + "schema": { + "type": "string" + }, + "example": "U5939-99933-49705-74523-4841009" + }, + { + "name": "memberId", + "in": "path", + "required": true, + "description": "UUID of the license member", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" + }, + { + "name": "force", + "in": "query", + "required": false, + "description": "If true, skip device reachability check and delete the license assignment from the pool without contacting the BIG-IP device. Useful when the device is unreachable or destroyed.\n", + "schema": { + "type": "boolean", + "default": false + }, + "example": true + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "deviceUsername", + "devicePassword" + ], + "properties": { + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + }, + "examples": { + "revokeMember": { + "summary": "Revoke license from member example", + "value": { + "deviceUsername": "admin", + "devicePassword": "admin" + } + } + } + } + } + }, + "responses": { + "204": { + "description": "License successfully revoked from the device" + }, + "400": { + "description": "Bad request - revocation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License member not found" + }, + "500": { + "description": "Internal server error" + } + } + }, + "patch": { + "tags": [ + "License Members" + ], + "summary": "Reactivating license key on member", + "description": "Updates the details of a license member, such as device information. This can be used to correct device information or update the member record after a device change.\n", + "operationId": "reactivateLicenseMember", + "parameters": [ + { + "name": "poolId", + "in": "path", + "required": true, + "description": "UUID of the license pool", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + { + "name": "regKey", + "in": "path", + "required": true, + "description": "Registration key of the license offering", + "schema": { + "type": "string" + }, + "example": "U5939-99933-49705-74523-4841009" + }, + { + "name": "memberId", + "in": "path", + "required": true, + "description": "UUID of the license member to update", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + } + } + } + }, + "responses": { + "202": { + "description": "License member update initiated (async operation)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskReference" + } + } + } + }, + "400": { + "description": "Bad request - invalid input or update failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "License member not found" + }, + "500": { + "description": "Internal server error" + } + } + } + }, + "/api/v1/fleet/upgrade/images": { + "get": { + "operationId": "listImages", + "summary": "List software images", + "tags": [ + "Images" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/PageSizeParam" + }, + { + "name": "product_family", + "in": "query", + "schema": { + "$ref": "#/components/schemas/ProductFamily" + } + }, + { + "name": "sort_by", + "in": "query", + "schema": { + "$ref": "#/components/schemas/SortByImages" + } + }, + { + "name": "sort_order", + "in": "query", + "description": "Sort direction; only applied when sort_by is also provided.", + "schema": { + "$ref": "#/components/schemas/SortOrder" + } + } + ], + "responses": { + "200": { + "description": "List of software images", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImageListResponse" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + }, + "post": { + "operationId": "uploadImage", + "summary": "Upload a software image", + "description": "Accepts a single multipart file upload and offloads the file to shared\nstorage for asynchronous ingestion.\n\nOnly the `file` form field is used by the active upload path. Metadata\nsuch as `product_family`, `image_type`, `version`, and `build` is not\nread from multipart form fields; it is derived later by the upgrade\nfeature from the uploaded filename and, where applicable, from\n`metadata.xml` inside the image during verification.\n\nThe request is intercepted by the backend file-offload middleware, so\nthis operation returns `202 Accepted` after the file is persisted and\nthe image record is reserved for background processing.\n", + "tags": [ + "Images" + ], + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "required": [ + "file" + ], + "properties": { + "file": { + "type": "string", + "format": "binary", + "description": "Software image file (ISO, bin, etc.)" + } + } + } + } + } + }, + "responses": { + "202": { + "description": "Upload accepted for asynchronous processing", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImageUploadAcceptedResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "409": { + "description": "Duplicate filename", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/images/{imageId}": { + "parameters": [ + { + "$ref": "#/components/parameters/ImageIdParam" + } + ], + "get": { + "operationId": "getImage", + "summary": "Get a software image by ID", + "tags": [ + "Images" + ], + "responses": { + "200": { + "description": "Software image details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareImage" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + }, + "delete": { + "operationId": "deleteImage", + "summary": "Delete a software image", + "tags": [ + "Images" + ], + "responses": { + "204": { + "description": "Image deleted" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Image is associated with one or more upgrade jobs and cannot be\ndeleted. The error message lists the offending job types and names.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/images/bulk-delete": { + "post": { + "operationId": "bulkDeleteImages", + "summary": "Delete multiple software images in a single request", + "tags": [ + "Images" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkDeleteImagesRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Per-image deletion results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkDeleteImagesResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + } + }, + "/api/v1/fleet/upgrade/summary": { + "get": { + "operationId": "getFleetSummary", + "summary": "Get fleet summary (device counts by type, version, status)", + "tags": [ + "Inventory" + ], + "responses": { + "200": { + "description": "Fleet summary", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FleetSummary" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/devices": { + "get": { + "operationId": "listFleetDevices", + "summary": "List all fleet devices (BIG-IP + F5OS)", + "tags": [ + "Inventory" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/PageSizeParam" + }, + { + "name": "type", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "BIGIP", + "RSERIES", + "VELOS" + ] + } + }, + { + "name": "search", + "in": "query", + "schema": { + "type": "string" + }, + "description": "Search by hostname, IP, version" + }, + { + "name": "$filter", + "in": "query", + "schema": { + "type": "string" + }, + "description": "OData-style filter expression. Supported fields and operators:\n endpoint eq 'https://10.145.135.45'\n hostname eq 'rseries-lab-01'\n device_type eq 'BIGIP'\nCombine with 'and': endpoint eq '...' and device_type eq 'BIGIP'\n" + }, + { + "name": "$orderby", + "in": "query", + "schema": { + "type": "string" + }, + "description": "OData-style ordering expression.\nSupported fields: hostname, endpoint, current_version, last_refresh_at, device_type\nFormat: ' asc' or ' desc' (default: hostname asc)\n" + } + ], + "responses": { + "200": { + "description": "Paginated fleet device list", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FleetDeviceListResponse" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/devices/{deviceId}": { + "parameters": [ + { + "$ref": "#/components/parameters/DeviceIdParam" + } + ], + "get": { + "operationId": "getFleetDevice", + "summary": "Get fleet device details", + "tags": [ + "Inventory" + ], + "responses": { + "200": { + "description": "Fleet device details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FleetDevice" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/v1/fleet/upgrade/devices/{deviceId}/refresh": { + "parameters": [ + { + "$ref": "#/components/parameters/DeviceIdParam" + } + ], + "post": { + "operationId": "refreshFleetDevice", + "summary": "Trigger on-demand metadata refresh for a device", + "tags": [ + "Inventory" + ], + "responses": { + "200": { + "description": "Device metadata refreshed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FleetDevice" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/v1/fleet/upgrade/devices/disk-analysis": { + "post": { + "operationId": "createDevicesDiskAnalysisTask", + "summary": "Create asynchronous disk space analysis task for multiple devices", + "description": "Starts a background task that checks available disk space on each device\nand compares it against the requested `required_size_bytes` threshold.\n\n**BIG-IP devices** \u2014 calls the iControl REST bash endpoint\n(`POST /mgmt/tm/util/bash`) to run `df -k /shared/images` directly on\nthe device. The reported `available_disk_bytes` reflects free space on\nthe `/shared/images` filesystem, which is where software images are\nstaged before installation.\n\n**F5OS devices (RSERIES / VELOS)** \u2014 queries the F5OS platform REST API\nfor storage metrics.\n\nResults are returned via `GET /devices/disk-analysis/{taskId}`.\n", + "tags": [ + "Inventory" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DiskAnalysisBatchRequest" + } + } + } + }, + "responses": { + "202": { + "description": "Disk space analysis task accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DiskAnalysisTaskAcceptedResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + } + } + } + }, + "/api/v1/fleet/upgrade/devices/disk-analysis/{taskId}": { + "parameters": [ + { + "name": "taskId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "get": { + "operationId": "getDevicesDiskAnalysisTask", + "summary": "Get asynchronous disk space analysis task status and results", + "tags": [ + "Inventory" + ], + "responses": { + "200": { + "description": "Disk analysis task details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DiskAnalysisTaskStatusResponse" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution": { + "get": { + "operationId": "listSoftwareDistributionJobs", + "summary": "List software distribution jobs", + "tags": [ + "SoftwareDistribution" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/PageSizeParam" + }, + { + "name": "status", + "in": "query", + "description": "Filter by job lifecycle status", + "schema": { + "$ref": "#/components/schemas/UpgradeJobStatus" + } + } + ], + "responses": { + "200": { + "description": "Paginated list of software distribution jobs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareDistributionJobListResponse" + }, + "example": { + "data": [ + { + "id": "a1b2c3d4-0000-0000-0000-000000000001", + "workflowId": "wf-0000-0000-0000-000000000001", + "name": "distribute-bigip-17.1.2-to-prod", + "status": "COMPLETED", + "deviceCount": 3, + "createdAt": "2026-05-29T09:00:00Z", + "updatedAt": "2026-05-29T09:30:00Z" + } + ], + "pagination": { + "page": 1, + "page_size": 20, + "total": 1, + "total_pages": 1 + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + }, + "post": { + "operationId": "createSoftwareDistributionJob", + "summary": "Create a software distribution job", + "description": "Creates a new software distribution job. The job starts in DRAFT state and\ncan be edited before activation.\n\nCopies a software image to one or more target devices in parallel batches.\nConfig requires: `imageId`, `deviceTargets`\nConfig optional: `batchSize` (default 10)\n\nOnce created, activate the job with `POST /jobs/{jobId}/activate`.\n", + "tags": [ + "SoftwareDistribution" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSoftwareDistributionJobRequest" + }, + "example": { + "name": "distribute-bigip-17.1.2-to-prod", + "description": "Push BIGIP-17.1.2-0.0.13.iso to 3 production devices before install", + "config": { + "images": [ + { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso" + } + ], + "batchSize": 10, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + }, + { + "deviceId": "cccccccc-cccc-cccc-cccc-cccccccccccc" + } + ] + } + } + } + } + }, + "responses": { + "201": { + "description": "Software distribution job created (in DRAFT state)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareDistributionJob" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "409": { + "description": "Job name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}": { + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ], + "get": { + "operationId": "getSoftwareDistributionJob", + "summary": "Get software distribution job details", + "description": "Returns full job details including configuration, current lifecycle status,\nand execution state.\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "200": { + "description": "Software distribution job details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareDistributionJob" + }, + "example": { + "id": "a1b2c3d4-0000-0000-0000-000000000001", + "workflowId": "wf-0000-0000-0000-000000000001", + "name": "distribute-bigip-17.1.2-to-prod", + "description": "Push image to prod devices", + "status": "COMPLETED", + "config": { + "images": [ + { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso" + } + ], + "batchSize": 10, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + }, + { + "deviceId": "cccccccc-cccc-cccc-cccc-cccccccccccc" + } + ] + }, + "execution": { + "executionId": "exec-0000-0000-0000-000000000001", + "status": "COMPLETED", + "startedAt": "2026-05-29T09:00:00Z", + "endedAt": "2026-05-29T09:28:00Z", + "currentBatch": 1, + "totalBatches": 1, + "batches": [ + { + "batchNumber": 1, + "status": "COMPLETED", + "currentStep": "COMPLETE", + "deviceIds": [ + "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", + "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", + "cccccccc-cccc-cccc-cccc-cccccccccccc" + ] + } + ] + }, + "createdAt": "2026-05-29T08:55:00Z", + "updatedAt": "2026-05-29T09:28:00Z" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + }, + "patch": { + "operationId": "updateSoftwareDistributionJob", + "summary": "Update software distribution job configuration", + "description": "Replaces the job configuration.\nOnly allowed when the job is in DRAFT or READY state.\n", + "tags": [ + "SoftwareDistribution" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSoftwareDistributionJobRequest" + }, + "example": { + "name": "distribute-bigip-17.1.2-to-prod-v2", + "description": "Updated device list", + "config": { + "images": [ + { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso" + } + ], + "batchSize": 5, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + } + ] + } + } + } + } + }, + "responses": { + "200": { + "description": "Job updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareDistributionJob" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job cannot be updated in its current state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "delete": { + "operationId": "deleteSoftwareDistributionJob", + "summary": "Delete a software distribution job", + "description": "Permanently deletes a software distribution job.\nOnly allowed when the job is not in RUNNING state.\nTerminates any in-progress execution before deletion.\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "204": { + "description": "Job deleted" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job cannot be deleted in its current state (e.g. RUNNING)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-installation": { + "get": { + "operationId": "listSoftwareInstallationJobs", + "summary": "List software installation jobs", + "tags": [ + "SoftwareInstallation" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/PageSizeParam" + }, + { + "name": "status", + "in": "query", + "description": "Filter by job lifecycle status", + "schema": { + "$ref": "#/components/schemas/UpgradeJobStatus" + } + }, + { + "name": "installationType", + "in": "query", + "description": "Filter by installation type", + "schema": { + "$ref": "#/components/schemas/InstallationType" + } + } + ], + "responses": { + "200": { + "description": "Paginated list of software installation jobs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareInstallationJobListResponse" + }, + "example": { + "data": [ + { + "id": "b2c3d4e5-0000-0000-0000-000000000002", + "workflowId": "wf-0000-0000-0000-000000000001", + "name": "install-bigip-17.1.2-standalone-batch", + "status": "RUNNING", + "installationType": "STANDALONE", + "batchSize": 10, + "deviceCount": 5, + "createdAt": "2026-05-29T10:00:00Z", + "updatedAt": "2026-05-29T10:45:00Z" + } + ], + "pagination": { + "page": 1, + "page_size": 20, + "total": 1, + "total_pages": 1 + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + }, + "post": { + "operationId": "createSoftwareInstallationJob", + "summary": "Create a software installation job", + "description": "Creates a new software installation job. The job starts in DRAFT state and\ncan be edited before activation.\n\n**installationType controls device targeting mode:**\n- `STANDALONE` \u2014 upgrades independent BIG-IP or F5OS devices\n- `HA` \u2014 upgrades HA pairs, maintaining service continuity\n\n**batchSize controls serial vs batch execution:**\n- `batchSize=1` \u2014 serial: upgrades one device (or HA pair) at a time\n- `batchSize>1` \u2014 batch: upgrades multiple devices (or HA pairs) in parallel\n\nConfig requires: `imageId`, `installationType`, `deviceTargets`\nConfig optional: `batchSize` (default 10), `execution` controls (default true)\n\nVolume selection is **job-level** via `volumeStrategy`; a per-device `volumeOverride`\non a device target takes precedence for that device only.\n\n**At most 5 installation jobs may be in RUNNING state simultaneously.**\n", + "tags": [ + "SoftwareInstallation" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSoftwareInstallationJobRequest" + }, + "examples": { + "standaloneSerial": { + "summary": "Upgrade 3 independent devices serially, device C uses a specific volume (STANDALONE, batchSize=1)", + "value": { + "name": "install-bigip-17.1.2-standalone-serial", + "description": "Upgrade 3 devices one at a time", + "config": { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso", + "installationType": "STANDALONE", + "batchSize": 1, + "volumeStrategy": "NEXT_SEQUENTIAL_NEW", + "execution": { + "hitlPauseBetweenBatches": true, + "hitlPauseBeforeReboot": true, + "reboot": true + }, + "flightChecks": { + "enabled": true + }, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + }, + { + "deviceId": "cccccccc-cccc-cccc-cccc-cccccccccccc", + "volumeOverride": "HD1.3" + } + ] + } + } + }, + "standaloneBatch": { + "summary": "Upgrade 5 independent devices in batches (STANDALONE, batchSize=10), device D uses a specific volume", + "value": { + "name": "install-bigip-17.1.2-standalone-batch", + "description": "Upgrade 5 production BIG-IPs in parallel batches", + "config": { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso", + "installationType": "STANDALONE", + "batchSize": 10, + "volumeStrategy": "NEXT_SEQUENTIAL_NEW", + "execution": { + "hitlPauseBetweenBatches": true, + "reboot": true + }, + "installConfig": true, + "flightChecks": { + "enabled": true, + "coreChecks": { + "trunkStatus": true, + "interfaceStatus": true, + "virtualServerState": true, + "poolHealth": true, + "poolMemberHealth": true + } + }, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + }, + { + "deviceId": "cccccccc-cccc-cccc-cccc-cccccccccccc" + }, + { + "deviceId": "dddddddd-dddd-dddd-dddd-dddddddddddd", + "volumeOverride": "HD1.2" + }, + { + "deviceId": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee" + } + ] + } + } + }, + "haSerial": { + "summary": "Upgrade HA pairs one at a time (HA, batchSize=1) [E7 scope \u2014 not yet implemented]", + "value": { + "name": "install-bigip-17.1.2-ha-serial", + "description": "Upgrade HA pairs one pair at a time", + "config": { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso", + "installationType": "HA", + "batchSize": 1, + "volumeStrategy": "NEXT_SEQUENTIAL_NEW", + "execution": { + "hitlPauseBetweenBatches": true, + "hitlPauseAfterStandbyInstallBeforeReboot": true, + "reboot": false + }, + "installConfig": false, + "flightChecks": { + "enabled": false + }, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + } + ] + } + } + }, + "haBatch": { + "summary": "Upgrade HA pairs in parallel batches (HA, batchSize>1) [E7 scope \u2014 not yet implemented]", + "value": { + "name": "install-bigip-17.1.2-ha-batch", + "description": "Upgrade HA pairs in batches of 2", + "config": { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso", + "installationType": "HA", + "batchSize": 10, + "volumeStrategy": "NEXT_SEQUENTIAL_NEW", + "execution": { + "hitlPauseBetweenBatches": true, + "hitlPauseBeforeReboot": true, + "reboot": true + }, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + }, + { + "deviceId": "cccccccc-cccc-cccc-cccc-cccccccccccc" + }, + { + "deviceId": "dddddddd-dddd-dddd-dddd-dddddddddddd" + } + ] + } + } + } + } + } + } + }, + "responses": { + "201": { + "description": "Software installation job created (in DRAFT state)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareInstallationJob" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "409": { + "description": "Job name already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-installation/{jobId}": { + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ], + "get": { + "operationId": "getSoftwareInstallationJob", + "summary": "Get software installation job details", + "description": "Returns full job details including configuration, current lifecycle status,\nand per-device install state for any devices that have started execution.\n", + "tags": [ + "SoftwareInstallation" + ], + "responses": { + "200": { + "description": "Software installation job details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareInstallationJob" + }, + "example": { + "id": "b2c3d4e5-0000-0000-0000-000000000002", + "workflowId": "wf-0000-0000-0000-000000000001", + "name": "install-bigip-17.1.2-standalone-batch", + "description": "Upgrade 5 production BIG-IPs in parallel batches of 2", + "status": "RUNNING", + "config": { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso", + "installationType": "STANDALONE", + "batchSize": 10, + "volumeStrategy": "NEXT_SEQUENTIAL_NEW", + "execution": { + "hitlPauseBetweenBatches": true, + "hitlPauseBeforeReboot": true, + "reboot": true + }, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + }, + { + "deviceId": "cccccccc-cccc-cccc-cccc-cccccccccccc", + "volumeOverride": "HD1.3" + } + ] + }, + "execution": { + "executionId": "exec-0000-0000-0000-000000000002", + "status": "RUNNING", + "startedAt": "2026-05-29T10:00:00Z", + "currentBatch": 2, + "totalBatches": 3, + "batches": [ + { + "batchNumber": 1, + "status": "COMPLETED", + "currentStep": "COMPLETE", + "deviceIds": [ + "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", + "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + ] + } + ] + }, + "deviceInstallStates": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", + "hostname": "bigip-prod-01", + "currentVersion": "17.1.1", + "targetVersion": "17.1.2", + "plannedVolume": "HD1.2", + "status": "COMPLETED", + "currentStep": "COMPLETE", + "startedAt": "2026-05-29T10:00:00Z", + "completedAt": "2026-05-29T10:44:30Z" + } + ], + "createdAt": "2026-05-29T09:55:00Z", + "updatedAt": "2026-05-29T10:45:00Z" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + }, + "patch": { + "operationId": "updateSoftwareInstallationJob", + "summary": "Update software installation job configuration", + "description": "Replaces the job configuration.\nOnly allowed when the job is in DRAFT or READY state.\n", + "tags": [ + "SoftwareInstallation" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSoftwareInstallationJobRequest" + }, + "examples": { + "updateStandaloneBatch": { + "summary": "Update batch size and device list (STANDALONE, batchSize=10 for parallel batch), device B uses a specific volume", + "value": { + "name": "install-bigip-17.1.2-batch-v2", + "description": "Updated batch size", + "config": { + "imageId": "11111111-1111-1111-1111-111111111111", + "imageFileName": "BIGIP-17.1.2-0.0.13.iso", + "installationType": "STANDALONE", + "batchSize": 10, + "volumeStrategy": "NEXT_SEQUENTIAL_NEW", + "execution": { + "hitlPauseBetweenBatches": false, + "hitlPauseBeforeReboot": false, + "reboot": true + }, + "flightChecks": { + "enabled": true, + "coreChecks": { + "trunkStatus": true, + "interfaceStatus": true, + "virtualServerState": true, + "poolHealth": true, + "poolMemberHealth": false + } + }, + "deviceTargets": [ + { + "deviceId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "deviceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", + "volumeOverride": "HD1.2" + } + ] + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Job updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareInstallationJob" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job cannot be updated in its current state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "delete": { + "operationId": "deleteSoftwareInstallationJob", + "summary": "Delete a software installation job", + "description": "Permanently deletes a software installation job.\nOnly allowed when the job is not in RUNNING state.\nTerminates any in-progress execution before deletion.\n", + "tags": [ + "SoftwareInstallation" + ], + "responses": { + "204": { + "description": "Job deleted" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job cannot be deleted in its current state (e.g. RUNNING)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}/activate": { + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ], + "post": { + "operationId": "activateSoftwareDistributionJob", + "summary": "Start a software distribution job", + "description": "Transitions a software distribution job from DRAFT/READY \u2192 RUNNING and begins\ndistributing the image to target devices in batches.\n\n**Pre-execution checks:**\n- Image must exist and be accessible in the image registry\n- All target devices must be reachable\n", + "tags": [ + "SoftwareDistribution" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivateDistributionJobRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Job activated and distribution started", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeJob" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job cannot be activated (wrong state or image not accessible)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}/pause": { + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ], + "post": { + "operationId": "pauseSoftwareDistributionJob", + "summary": "Pause a running software distribution job", + "description": "Pauses the distribution job at the queue level. The worker pool\nstops claiming new PENDING devices; devices already TRANSFERRING\nor VERIFYING run to completion (chunked uploads cannot be safely\ninterrupted mid-stream). Job transitions to PAUSING immediately;\nonce all in-flight devices finish, the service flips to PAUSED.\nOperator then calls /resume or /cancel.\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "202": { + "description": "Pause accepted \u2014 job is PAUSING (draining in-flight)" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job is not in a pausable state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}/resume": { + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ], + "post": { + "operationId": "resumeSoftwareDistributionJob", + "summary": "Resume a paused software distribution job", + "description": "Resumes a PAUSED distribution job. Job transitions back to\nRUNNING; a fresh worker pool is spawned to pick up the PENDING\ndevices that were held back during the pause. Devices already\nCOMPLETED stay COMPLETED \u2014 no rework. Returns 409 if the job\nis still PAUSING (drain in progress); wait for PAUSED first.\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "202": { + "description": "Resume accepted \u2014 job is back to RUNNING" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job is not in a resumable state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}/cancel": { + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ], + "post": { + "operationId": "cancelSoftwareDistributionJob", + "summary": "Cancel a running or paused software distribution job", + "description": "Durably signals job cancellation by transitioning to CANCELLING.\n- The claim gate immediately stops the worker pool from picking\n new devices.\n- In-flight workers run to completion of their current device\n (no mid-stream kill \u2014 chunked uploads can't be safely\n interrupted).\n- When the pool drains, remaining non-terminal per-device rows\n are marked CANCELLED and the job returns to READY (re-activatable);\n the CANCELLED outcome is recorded on the EXECUTION row, not\n the job, because the job is a long-lived re-activatable\n definition.\n- Safe across pods and pod restarts: CANCELLING is durable in\n the DB so a different pod / a restarted pod converges to\n READY at the job level without operator intervention.\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "202": { + "description": "Cancel accepted \u2014 job is CANCELLING; converges to READY at the job level (CANCELLED on the execution row)" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job is not in a cancellable state (e.g. already COMPLETED or in a non-cancellable lifecycle state)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}/status": { + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ], + "get": { + "operationId": "getSoftwareDistributionJobStatus", + "summary": "Get per-device runtime status for a software distribution job", + "description": "Returns the per-device runtime status of a software distribution job\nplus a rolled-up summary (counts per status + overall transfer percent).\nDistinct from `GET /jobs/software-distribution/{jobId}`, which returns\nthe saved job record only.\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "200": { + "description": "Per-device + roll-up status", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DistributionJobAggregate" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}/executions": { + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ], + "get": { + "operationId": "listSoftwareDistributionJobExecutions", + "summary": "List executions of a software distribution job", + "description": "Returns all executions of a job ordered by `startedAt` descending\n(newest first). Same item shape as the generic workflow executions\nlist (`GET /workflows/{wfId}/jobs/{jobId}/executions`) so the\ncross-feature UI can render distribution + autoscale + installation\nexecution lists with the same component.\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "200": { + "description": "List of executions", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "items" + ], + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SoftwareDistributionExecution" + } + }, + "totalItems": { + "type": "integer" + } + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}/executions/{executionId}": { + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + }, + { + "name": "executionId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "get": { + "operationId": "getSoftwareDistributionJobExecution", + "summary": "Get a single execution of a software distribution job", + "description": "Returns the execution record in the same shape as the generic\nworkflows API (`GET /workflows/{wfId}/jobs/{jobId}/executions/{execId}`)\nso the cross-feature UI can render distribution executions with the\nsame panel it uses for autoscale / installation. Per-device runtime\nprogress is embedded inline via the `instanceProgress` field \u2014 only\non this single-execution GET, not on the executions LIST.\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "200": { + "description": "Execution detail", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareDistributionExecution" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-distribution/{jobId}/targets/{deviceId}": { + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + }, + { + "$ref": "#/components/parameters/DeviceIdParam" + } + ], + "delete": { + "operationId": "cancelSoftwareDistributionTarget", + "summary": "Cancel distribution for one device in a running job", + "description": "Cancels in-flight distribution for a single device within a running job.\nOrthogonal to the job-level cancel \u2014 the rest of the job continues.\n\n- Device's distribution_state row transitions to CANCELLED\n- The device lock for this job is released\n- If the device is currently TRANSFERRING, the next chunk boundary\n observes the cancel and the goroutine returns\n", + "tags": [ + "SoftwareDistribution" + ], + "responses": { + "202": { + "description": "Per-target cancel accepted" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Device is already in a terminal state for this job (COMPLETED / FAILED / CANCELLED / SKIPPED)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-installation/{jobId}/activate": { + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ], + "post": { + "operationId": "activateSoftwareInstallationJob", + "summary": "Start a software installation job", + "description": "Transitions a software installation job from DRAFT/READY \u2192 RUNNING and begins\nthe installation pipeline.\n\n**Pre-execution checks:**\n- Image must be in VERIFIED state\n- All target devices must be reachable\n- No target device may be locked by another running job\n- Total running software installation jobs must be fewer than 5\n\nExecution creates batches based on `batchSize` and processes devices one\nbatch at a time. If `hitlPauseBetweenBatches` is true, execution pauses\nbetween batches for operator confirmation.\n", + "tags": [ + "SoftwareInstallation" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivateInstallationJobRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Job activated and installation started", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeJob" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job cannot be activated (wrong state, image not verified, device locked, or max concurrent jobs reached)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-installation/{jobId}/pause": { + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ], + "post": { + "operationId": "pauseSoftwareInstallationJob", + "summary": "Pause a running software installation job (HITL)", + "description": "Pauses the installation job at the next available HITL checkpoint (between batches).\nThe current batch in progress will complete before the pause takes effect.\nJob transitions to PAUSED state and waits for operator to call /resume or /cancel.\nOnly applicable to software installation jobs with hitlPauseBetweenBatches=true.\n", + "tags": [ + "SoftwareInstallation" + ], + "responses": { + "200": { + "description": "Pause requested \u2014 job will pause at the next batch boundary", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeJob" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job is not in a pausable state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-installation/{jobId}/resume": { + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ], + "post": { + "operationId": "resumeSoftwareInstallationJob", + "summary": "Resume a paused software installation job", + "description": "Resumes a PAUSED software installation job. Execution continues with the next\npending batch. Job transitions back to RUNNING state.\n", + "tags": [ + "SoftwareInstallation" + ], + "responses": { + "200": { + "description": "Job resumed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeJob" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job is not in a resumable state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-installation/{jobId}/executions": { + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ], + "get": { + "operationId": "listSoftwareInstallationJobExecutions", + "summary": "List executions of a software installation job", + "description": "Returns all executions of a job ordered by `startedAt` descending\n(newest first). Same item shape as the generic workflow executions\nlist (`GET /workflows/{wfId}/jobs/{jobId}/executions`) so the\ncross-feature UI can render distribution + autoscale + installation\nexecution lists with the same component.\n", + "tags": [ + "SoftwareInstallation" + ], + "responses": { + "200": { + "description": "List of executions", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "items" + ], + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SoftwareInstallationExecutionRecord" + } + }, + "totalItems": { + "type": "integer" + } + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-installation/{jobId}/executions/{executionId}": { + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + }, + { + "name": "executionId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "get": { + "operationId": "getSoftwareInstallationJobExecution", + "summary": "Get a single execution of a software installation job", + "description": "Returns the execution record in the same shape as the generic\nworkflows API (`GET /workflows/{wfId}/jobs/{jobId}/executions/{execId}`)\nso the cross-feature UI can render installation executions with the\nsame panel it uses for distribution / autoscale. Per-device runtime\nprogress is embedded inline via the `instanceProgress` field \u2014 only\non this single-execution GET, not on the executions LIST.\n", + "tags": [ + "SoftwareInstallation" + ], + "responses": { + "200": { + "description": "Execution detail", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SoftwareInstallationExecutionRecord" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/v1/fleet/upgrade/jobs/software-installation/{jobId}/cancel": { + "parameters": [ + { + "$ref": "#/components/parameters/JobIdParam" + } + ], + "post": { + "operationId": "cancelSoftwareInstallationJob", + "summary": "Cancel a running or paused software installation job", + "description": "Cancels the installation job gracefully.\n- Any in-progress batch is allowed to complete its current step (no mid-step kill)\n- All pending devices transition to CANCELLED state\n- Device locks are released\n- Job returns to READY (re-activatable); the CANCELLED outcome\n is recorded on the EXECUTION row, not the job, because the\n job is a long-lived re-activatable definition\n", + "tags": [ + "SoftwareInstallation" + ], + "responses": { + "200": { + "description": "Job cancelled", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeJob" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "description": "Job is not in a cancellable state (e.g. already COMPLETED or in a non-cancellable lifecycle state)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/fleet/upgrade/validate": { + "post": { + "operationId": "triggerValidation", + "summary": "Trigger async pre-job validation for a list of devices against an image", + "description": "Starts the pluggable validation engine for the supplied devices against the\ngiven target image. No job needs to exist \u2014 this endpoint is called **before**\njob creation to confirm all selected devices are eligible for the upgrade.\n\nReturns `202 Accepted` immediately with a `validation_run_id`.\nPoll `GET /validate/{validationRunId}` until `status` is no longer `PENDING` or `RUNNING`.\n\nBefore the validation checks run, the engine performs a **live metadata refresh**\nfor each device so that all checks operate on up-to-date data (current version,\nservice check date, license check date, available disk, etc.). The refresh result\nis best-effort \u2014 a refresh failure logs a warning but does not abort validation.\n\n---\n\n### Soft checks \u2014 warn operator; job may still proceed (`can_proceed: true`)\n\n| Check | Source | Threshold |\n|-------|--------|-----------|\n| `disk_space` | Cached `disk_available_gb` from last device refresh | < 15 GB for new volume slot; < 2 GB for existing slot |\n| `cpu_utilization` | Stage 1: always **SKIP** \u2014 Stage 2: 5-min avg via iControl REST | > 80% |\n| `memory_utilization` | Stage 1: always **SKIP** \u2014 Stage 2: 5-min avg via iControl REST | > 90% |\n| `license_date` | `service_check_date` (from `bigip.license`) vs `license_check_date` (from `/etc/version_date` on device, falls back to K7727 static table) | Service check date must be \u2265 license check date of the target version |\n\n### Hard checks \u2014 block upgrade; job cannot proceed (`can_proceed: false`)\n\n| Check | Source | Rule |\n|-------|--------|------|\n| `upgrade_path` | `upgrade.bigip_upgrade_paths` table (seeded from F5 KB K13845) | Current version must satisfy the minimum-source-version rule for the target major version (BIG-IP only) |\n| `license_compatibility` | `bigip.license` active-modules (fetched live or cached) | License edition must not have an \"Exclusive Version\" ceiling below the target version (BIG-IP only) |\n| `f5os_version_support` | `upgrade.f5os_supported_versions` table (seeded from F5 KB K86001294) | Target F5OS version must be explicitly listed as supported for the device's hardware platform (F5OS only) |\n\n---\n\n### License Date check detail (`license_date`)\n\nBIG-IP will refuse to load its configuration after booting into a newly-upgraded\nvolume if the **service check date** in `bigip.license` predates the\n**license check date** (LCD) baked into that version's build\n(published in F5 KB K7727, stored in `/etc/version_date` on the device).\n\nThe engine reads the LCD in the following order:\n1. Live read of `/etc/version_date` via the iControl REST bash endpoint\n (`POST /mgmt/tm/util/bash`), populated into `device_upgrade_metadata.license_check_date`\n during the pre-validation refresh.\n2. Fallback to the static K7727 lookup table keyed by `major.minor` of the\n **target** image version, when the live read is unavailable.\n\nA `WARN` result means the device's service contract should be re-activated before\nupgrading (see F5 KB K7727: *License activation may be required before a software\nupgrade for BIG-IP*). The check is **SOFT** \u2014 the operator can proceed, but F5\nstrongly recommends reactivating the license first.\n\n---\n\nRe-triggering with the same inputs creates a fresh validation run (a new\n`validation_run_id` is returned each time).\n", + "tags": [ + "Validation" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationTriggerRequest" + } + } + } + }, + "responses": { + "202": { + "description": "Validation triggered \u2014 poll GET /validate/{validationRunId} for results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationTriggeredResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + } + }, + "/api/v1/fleet/upgrade/validate/{validationRunId}": { + "parameters": [ + { + "name": "validationRunId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "The validation run ID returned by POST /validate" + } + ], + "get": { + "operationId": "getValidationResults", + "summary": "Get results for a validation run", + "description": "Returns persisted per-device validation results for a run.\nPoll until `status` is no longer `PENDING` or `RUNNING`.\n`can_proceed: true` means no HARD check failures exist across any device.\n", + "tags": [ + "Validation" + ], + "responses": { + "200": { + "description": "Validation results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationSummary" + }, + "example": { + "validation_run_id": "a1b2c3d4-0000-0000-0000-000000000001", + "image_id": "img-uuid-0000-0000-0000-000000000001", + "status": "WARNING", + "device_count": 3, + "pass_count": 2, + "warn_count": 1, + "fail_count": 0, + "error_count": 0, + "can_proceed": true, + "triggered_at": "2026-08-06T10:00:00Z", + "completed_at": "2026-08-06T10:00:05Z", + "devices": [ + { + "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", + "hostname": "bigip-prod-01", + "status": "PASSED", + "current_step": "COMPLETE", + "blocking_check": "", + "check_results": [ + { + "check_name": "disk_space", + "severity": "SOFT", + "status": "PASS" + }, + { + "check_name": "cpu_utilization", + "severity": "SOFT", + "status": "SKIP", + "message": "CPU check not yet implemented (Stage 2)" + }, + { + "check_name": "memory_utilization", + "severity": "SOFT", + "status": "SKIP", + "message": "Memory check not yet implemented (Stage 2)" + }, + { + "check_name": "upgrade_path", + "severity": "HARD", + "status": "PASS" + }, + { + "check_name": "license_compatibility", + "severity": "HARD", + "status": "PASS" + }, + { + "check_name": "license_date", + "severity": "SOFT", + "status": "PASS" + } + ] + }, + { + "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", + "hostname": "bigip-prod-02", + "status": "WARNING", + "current_step": "COMPLETE", + "blocking_check": "", + "check_results": [ + { + "check_name": "disk_space", + "severity": "SOFT", + "status": "WARN", + "message": "disk space 8.2 GB is below recommended 15 GB threshold", + "detail": { + "available_gb": 8.2, + "threshold_gb": 15 + } + }, + { + "check_name": "upgrade_path", + "severity": "HARD", + "status": "PASS" + }, + { + "check_name": "license_compatibility", + "severity": "HARD", + "status": "PASS" + }, + { + "check_name": "license_date", + "severity": "SOFT", + "status": "PASS" + } + ] + }, + { + "device_id": "cccccccc-cccc-cccc-cccc-cccccccccccc", + "hostname": "bigip-prod-03", + "status": "FAILED", + "current_step": "COMPLETE", + "blocking_check": "upgrade_path", + "check_results": [ + { + "check_name": "disk_space", + "severity": "SOFT", + "status": "PASS" + }, + { + "check_name": "upgrade_path", + "severity": "HARD", + "status": "FAIL", + "message": "Current version 15.1.2 is not compatible with target image BIGIP-17.1.5. Minimum source version required: 16.1.0", + "detail": { + "current_version": "15.1.2", + "target_version": "17.1.5", + "min_source_version": "16.1.0" + } + } + ] + } + ] + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/v1/fleet/upgrade/readiness": { + "get": { + "operationId": "listReadinessRuns", + "summary": "List readiness check runs", + "description": "Returns a paginated list of readiness check runs with rollup summaries.\nEach item contains the run status, device counts, and timestamps \u2014 but\nnot the full per-device results. Use `GET /readiness/{runId}` for the\ndetailed per-device breakdown.\n", + "tags": [ + "Readiness" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/PageSizeParam" + }, + { + "name": "status", + "in": "query", + "description": "Filter runs by rolled-up status.", + "schema": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "PASSED", + "WARNING", + "FAILED", + "ERROR" + ] + } + } + ], + "responses": { + "200": { + "description": "Paginated list of readiness runs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadinessRunListResponse" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + }, + "post": { + "operationId": "triggerReadinessChecks", + "summary": "Trigger async pre-distribution readiness checks for target devices", + "description": "Runs the requested readiness checks against the specified target devices.\nThis is a pre-distribution gate \u2014 call before distributing images to verify\nthat target devices are ready to receive the distribution.\n\nThe request envelope holds shared context (device targets and image IDs)\nand a list of check types to run. Image metadata is resolved once and\nshared across all checks.\n\nReturns `202 Accepted` with a `run_id`. Poll `GET /readiness/{runId}`\nuntil `status` is no longer `PENDING` or `RUNNING`.\n\n---\n\n### Supported check types\n\n| Type | What it checks | Severity |\n|------|----------------|----------|\n| `base_image_presence` | For each hotfix image, verifies the required base OS image is present on the device's image catalog (or co-distributed). | SOFT/WARN |\n| `disk_space` | Sums image file sizes and verifies the device has enough free space in its image filesystem. Also updates `disk_available_gb` in device metadata. | SOFT/WARN |\n| `image_compatibility` | Verifies each image's product family is compatible with the target device type (e.g. BIG-IP images cannot target F5OS devices and vice versa). | HARD/FAIL |\n\n---\n\n### Adding a new check type (internal)\n\n1. Implement the `Check` interface.\n2. Register a `ReadinessDescriptor` in `DefaultReadinessRegistry`.\n3. Add the type to the enum in this schema.\n\nNo API envelope changes are required.\n", + "tags": [ + "Readiness" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadinessTriggerRequest" + } + } + } + }, + "responses": { + "202": { + "description": "Readiness checks triggered \u2014 poll GET /readiness/{runId} for results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadinessTriggeredResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + } + }, + "/api/v1/fleet/upgrade/readiness/{runId}": { + "parameters": [ + { + "name": "runId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "The readiness run ID returned by POST /readiness" + } + ], + "get": { + "operationId": "getReadinessResults", + "summary": "Get results for a readiness check run", + "description": "Returns persisted per-device readiness results for a run.\nPoll until `status` is no longer `PENDING` or `RUNNING`.\n`can_proceed: true` means no hard-blocking failures exist.\n", + "tags": [ + "Readiness" + ], + "responses": { + "200": { + "description": "Readiness check results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadinessSummary" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/v1/fleet/upgrade/compat/upgrade-paths": { + "get": { + "operationId": "listCompatUpgradePaths", + "summary": "List BIG-IP upgrade path rules (K13845)", + "description": "Returns all rows in upgrade.bigip_upgrade_paths.\nIncludes both YAML-seeded rows (is_operator_override=false) and\noperator-managed rows (is_operator_override=true).\n", + "tags": [ + "CompatMatrix" + ], + "responses": { + "200": { + "description": "List of upgrade path rules", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CompatUpgradePathListResponse" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + }, + "post": { + "operationId": "upsertCompatUpgradePath", + "summary": "Add or update a BIG-IP upgrade path rule (K13845 operator override)", + "description": "Inserts or updates a row in upgrade.bigip_upgrade_paths using the\nnatural key `(target_major_version, min_source_version)`.\nThe row is always marked `is_operator_override=true` \u2014 the CompatSeeder\nwill never overwrite it on service restart.\n\n**Why upsert (not separate POST/PATCH)?**\nThe natural business key is `(target_major_version, min_source_version)`,\nnot the UUID. Operators think in terms of rules, not opaque IDs. The\nupsert pattern lets operators:\n- Add a new rule without checking whether it already exists\n- Update an existing rule (including YAML-seeded rows) without needing to look up its UUID first\n- Use the same idempotent script to enforce desired state across environments\n\n**Response codes:**\n- `201 Created` \u2014 a new row was inserted (the natural key did not previously exist)\n- `200 OK` \u2014 an existing row was updated (the natural key already existed)\n", + "tags": [ + "CompatMatrix" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpsertCompatUpgradePathRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Existing row updated (natural key already existed)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CompatUpgradePath" + } + } + } + }, + "201": { + "description": "New row created (natural key did not previously exist)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CompatUpgradePath" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + } + }, + "/api/v1/fleet/upgrade/compat/upgrade-paths/{compatId}": { + "parameters": [ + { + "$ref": "#/components/parameters/CompatIdParam" + } + ], + "get": { + "operationId": "getCompatUpgradePath", + "summary": "Get a BIG-IP upgrade path rule by ID", + "description": "Returns a single row from upgrade.bigip_upgrade_paths addressed by its UUID.\nIncludes both YAML-seeded rows (is_operator_override=false) and\noperator-managed rows (is_operator_override=true).\n", + "tags": [ + "CompatMatrix" + ], + "responses": { + "200": { + "description": "Upgrade path rule", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CompatUpgradePath" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + }, + "delete": { + "operationId": "deleteCompatUpgradePath", + "summary": "Delete a BIG-IP upgrade path rule by ID", + "tags": [ + "CompatMatrix" + ], + "responses": { + "204": { + "description": "Row deleted" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/v1/fleet/upgrade/flight-checks/snapshots": { + "get": { + "operationId": "listFlightSnapshots", + "summary": "List flight-check snapshots", + "description": "Returns a paginated list of flight-check snapshots. Because a fleet\naccumulates many snapshots over time, callers should scope the query with\nthe `jobId`, `deviceId` and/or `phase` filters (e.g. all snapshots for a\ngiven installation job, or both phases for one device in one job).\n", + "tags": [ + "FlightChecks" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/PageSizeParam" + }, + { + "name": "jobId", + "in": "query", + "description": "Filter to snapshots captured under this installation job.", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "deviceId", + "in": "query", + "description": "Filter to snapshots captured from this device.", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "phase", + "in": "query", + "description": "Filter to a single phase (PRE or POST).", + "schema": { + "type": "string", + "enum": [ + "PRE", + "POST" + ] + } + } + ], + "responses": { + "200": { + "description": "Paginated list of flight-check snapshots", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FlightSnapshotListResponse" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + } + }, + "/api/v1/fleet/upgrade/flight-checks/snapshots/{snapshotId}": { + "parameters": [ + { + "$ref": "#/components/parameters/SnapshotIdParam" + } + ], + "get": { + "operationId": "getFlightSnapshot", + "summary": "Get a single flight-check snapshot by ID", + "description": "Returns one PRE or POST flight-check snapshot, addressed by its own ID.\nThe response includes the captured core-check results plus the snapshot's\ndeviceId, jobId, phase (PRE/POST) and capturedAt timestamp.\n", + "tags": [ + "FlightChecks" + ], + "responses": { + "200": { + "description": "Flight-check snapshot", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FlightSnapshot" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/v1/fleet/upgrade/flight-checks/diffs": { + "get": { + "operationId": "listFlightDiffs", + "summary": "List PRE-vs-POST flight-check diffs", + "description": "Returns a paginated list of PRE-vs-POST flight-check diffs. Because a fleet\naccumulates many diffs over time, callers should scope the query with the\n`jobId` and/or `deviceId` filters (e.g. all diffs for a given installation\njob, or the diff history for one device).\n", + "tags": [ + "FlightChecks" + ], + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/PageSizeParam" + }, + { + "name": "jobId", + "in": "query", + "description": "Filter to diffs computed under this installation job.", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "deviceId", + "in": "query", + "description": "Filter to diffs computed for this device.", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Paginated list of flight-check diffs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FlightCheckDiffListResponse" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + } + }, + "/api/v1/fleet/upgrade/flight-checks/diffs/{diffId}": { + "parameters": [ + { + "$ref": "#/components/parameters/DiffIdParam" + } + ], + "get": { + "operationId": "getFlightDiff", + "summary": "Get a single PRE-vs-POST flight-check diff by ID", + "description": "Returns one PRE-vs-POST flight-check diff, addressed by its own ID. The\nresponse includes the per-check diff entries plus the diff's deviceId,\njobId, computedAt timestamp, and back-links to the PRE and POST snapshots\nit was computed from (preSnapshotUrl / postSnapshotUrl \u2014 each resolvable via\nGET /api/v1/fleet/upgrade/flight-checks/snapshots/{snapshotId}).\n", + "tags": [ + "FlightChecks" + ], + "responses": { + "200": { + "description": "Flight-check diff", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FlightCheckDiff" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/provisioning/v1/workflows": { + "get": { + "tags": [ + "Workflows" + ], + "summary": "List workflow templates", + "description": "Returns workflow templates that define reusable workflow behavior.\nSupports filtering by workflow type, execution mode, and template lifecycle status.\nUse this endpoint for catalog/discovery before creating Jobs.\n", + "operationId": "listWorkflows", + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/LimitParam" + }, + { + "name": "type", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + } + }, + { + "name": "executionMode", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "CONTINUOUS", + "ON_DEMAND" + ] + } + }, + { + "name": "status", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "DRAFT", + "ACTIVE", + "DEPRECATED" + ] + } + } + ], + "responses": { + "200": { + "description": "List of workflow templates", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkflowListResponse" + }, + "example": { + "items": [ + { + "id": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "name": "autoscale-default", + "description": "Autoscale default template", + "type": "AUTO_SCALE", + "executionMode": "CONTINUOUS", + "createdAt": "2026-05-18T10:00:00.000Z" + } + ], + "total": 1, + "page": 1, + "limit": 50 + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + } + } + } + }, + "/api/provisioning/v1/jobs": { + "get": { + "tags": [ + "Observability" + ], + "summary": "List jobs across all workflows", + "description": "Global jobs listing endpoint across workflow templates.\nUseful for platform views, tenant operations dashboards, and central search.\n", + "operationId": "listAllJobs", + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/LimitParam" + }, + { + "name": "workflowId", + "in": "query", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "type", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + } + }, + { + "name": "executionMode", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "CONTINUOUS", + "ON_DEMAND" + ] + } + }, + { + "name": "status", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSED", + "INACTIVE", + "ERROR", + "DELETING" + ] + } + } + ], + "responses": { + "200": { + "description": "List of jobs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobListPaginatedResponse" + }, + "example": { + "items": [ + { + "id": "220f0b6b-87e7-4e5f-bcc2-9f2d26786ac6", + "workflowId": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "name": "tenant-a-autoscale", + "status": "ACTIVE", + "createdAt": "2026-05-18T12:00:00.000Z", + "updatedAt": "2026-05-18T14:45:00.000Z" + } + ], + "pagination": { + "page": 1, + "page_size": 50, + "total": 1, + "total_pages": 1 + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + } + } + } + }, + "/api/provisioning/v1/jobs/bulk-delete": { + "post": { + "tags": [ + "Jobs" + ], + "summary": "Bulk delete jobs", + "description": "Delete multiple jobs in a single request. Each job is processed\nindependently \u2014 partial success is possible. Jobs that are in an\nactive lifecycle state (RUNNING, ACTIVE, PAUSING, PAUSED, CANCELLING)\ncannot be deleted and will be reported as FAILED in the response.\nThe deletion propagates to feature-specific tables (software installation,\nsoftware distribution) via the pg_notify mechanism.\n", + "operationId": "bulkDeleteJobs", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkDeleteJobsRequest" + }, + "example": { + "job_ids": [ + "550e8400-e29b-41d4-a716-446655440001", + "550e8400-e29b-41d4-a716-446655440002" + ] + } + } + } + }, + "responses": { + "200": { + "description": "Bulk delete results (partial success possible)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkDeleteJobsResponse" + }, + "example": { + "results": [ + { + "job_id": "550e8400-e29b-41d4-a716-446655440001", + "status": "DELETED" + }, + { + "job_id": "550e8400-e29b-41d4-a716-446655440002", + "status": "FAILED", + "error": "job cannot be deleted while it has live work \u2014 abort the job first" + } + ] + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + } + } + } + }, + "/api/provisioning/v1/executions": { + "get": { + "tags": [ + "Observability" + ], + "summary": "List executions across all workflows and jobs", + "description": "Global execution timeline across the entire platform.\nSupports filtering by workflow, job, execution mode, trigger, and time window.\n", + "operationId": "listAllExecutions", + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/LimitParam" + }, + { + "name": "workflowId", + "in": "query", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "jobId", + "in": "query", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "type", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + } + }, + { + "name": "executionMode", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "CONTINUOUS", + "ON_DEMAND" + ] + } + }, + { + "name": "status", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED", + "CANCELLED", + "TIMEOUT" + ] + } + }, + { + "name": "trigger", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "USER", + "ALERT", + "SYSTEM", + "SCHEDULE" + ] + } + }, + { + "name": "since", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "until", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "List of executions", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecutionListResponse" + }, + "example": { + "items": [ + { + "id": "2f2f8b64-91d2-4d4f-9aa8-03b8a9238ea1", + "jobId": "220f0b6b-87e7-4e5f-bcc2-9f2d26786ac6", + "trigger": "SYSTEM", + "status": "RUNNING", + "reason": "Continuous controller active", + "startedAt": "2026-05-18T08:10:00.000Z", + "activityCount": 37 + }, + { + "id": "7d8f5576-6414-410f-8f5a-0c34f95df3b0", + "jobId": "114ca9f9-88a3-49e1-92f2-757d7fedde98", + "trigger": "USER", + "status": "COMPLETED", + "reason": "Manual emergency run", + "startedAt": "2026-05-18T12:10:00.000Z", + "completedAt": "2026-05-18T12:17:00.000Z", + "activityCount": 1 + } + ], + "total": 2, + "page": 1, + "limit": 50 + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}": { + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + } + ], + "get": { + "tags": [ + "Workflows" + ], + "summary": "Get a workflow template", + "description": "Returns a single workflow template by ID including type, execution mode,\nversioning metadata, and default configuration.\n", + "operationId": "getWorkflow", + "responses": { + "200": { + "description": "Workflow template", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Workflow" + }, + "example": { + "id": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "name": "autoscale-template-prod", + "description": "Production autoscale template for monitoring and scaling", + "type": "AUTO_SCALE", + "executionMode": "CONTINUOUS", + "createdAt": "2026-05-18T10:10:00.000Z" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs": { + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + } + ], + "get": { + "tags": [ + "Jobs" + ], + "summary": "List jobs for a workflow", + "description": "Lists runtime Jobs created from a workflow template.\nJobs represent environment- or tenant-specific instantiations of the template.\nSupports status filtering and pagination.\n", + "operationId": "listJobs", + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/LimitParam" + }, + { + "name": "status", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSED", + "INACTIVE", + "ERROR", + "DELETING" + ] + } + } + ], + "responses": { + "200": { + "description": "List of jobs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobListResponse" + }, + "example": { + "items": [ + { + "id": "114ca9f9-88a3-49e1-92f2-757d7fedde98", + "workflowId": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "name": "tenant-a-autoscale", + "status": "ACTIVE", + "createdAt": "2026-05-18T11:00:00.000Z", + "updatedAt": "2026-05-18T11:00:00.000Z" + } + ], + "total": 1, + "page": 1, + "limit": 50 + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + }, + "post": { + "tags": [ + "Jobs" + ], + "summary": "Create a job (runtime instance of a workflow)", + "description": "Creates a new runtime Job under a workflow template.\nJob-level `config` overrides are merged with template `defaultConfig`\nto produce `effectiveConfig` used during execution.\n", + "operationId": "createJob", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobCreateRequest" + }, + "examples": { + "autoscale": { + "summary": "Create AutoScale job", + "value": { + "type": "AUTO_SCALE", + "name": "tenant-a-autoscale", + "status": "READY", + "config": { + "configType": "AUTO_SCALE", + "environmentReference": "550e8400-e29b-41d4-a716-446655440000", + "templateReference": "550e8400-e29b-41d4-a716-446655440001", + "licensePoolReference": "550e8400-e29b-41d4-a716-446655440003", + "minSize": 2, + "maxSize": 8, + "desiredSize": 3, + "evaluationPeriod": 300, + "scaleInMethod": "NEWEST_FIRST", + "scaleOutCooldownSeconds": 600, + "scaleInCooldownSeconds": 900 + } + } + }, + "autoscaleBurst": { + "summary": "Create burst-capable AutoScale job", + "value": { + "type": "AUTO_SCALE", + "name": "tenant-b-autoscale-burst", + "config": { + "configType": "AUTO_SCALE", + "environmentReference": "550e8400-e29b-41d4-a716-446655440020", + "templateReference": "550e8400-e29b-41d4-a716-446655440021", + "licensePoolReference": "550e8400-e29b-41d4-a716-446655440023", + "minSize": 3, + "maxSize": 15, + "desiredSize": 5, + "evaluationPeriod": 120, + "scaleInMethod": "NEWEST_FIRST", + "scaleOutCooldownSeconds": 300, + "scaleInCooldownSeconds": 600 + } + } + } + } + } + } + }, + "responses": { + "201": { + "description": "Job created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + }, + "example": { + "id": "114ca9f9-88a3-49e1-92f2-757d7fedde98", + "workflowId": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "name": "tenant-a-autoscale", + "type": "AUTO_SCALE", + "status": "READY", + "version": "v1", + "createdAt": "2026-05-18T11:00:00.000Z", + "updatedAt": "2026-05-18T11:00:00.000Z" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}": { + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ], + "get": { + "tags": [ + "Jobs" + ], + "summary": "Get a job", + "description": "Returns one Job including resolved configuration (`effectiveConfig`),\nlifecycle status, and runtime/schedule state when applicable.\n", + "operationId": "getJob", + "responses": { + "200": { + "description": "Job", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + }, + "example": { + "id": "114ca9f9-88a3-49e1-92f2-757d7fedde98", + "workflowId": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "name": "tenant-a-autoscale", + "type": "AUTO_SCALE", + "status": "ACTIVE", + "config": { + "configType": "AUTO_SCALE", + "minSize": 2, + "maxSize": 8, + "desiredSize": 4, + "scaleOutCooldownSeconds": 600, + "scaleInCooldownSeconds": 900 + }, + "runtime": { + "currentSize": 4, + "lastEvaluatedAt": "2026-05-18T11:09:30.000Z" + }, + "createdAt": "2026-05-18T11:00:00.000Z", + "updatedAt": "2026-05-18T11:10:00.000Z" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + }, + "patch": { + "tags": [ + "Jobs" + ], + "summary": "Partially update a job config", + "description": "Not allowed while a CONTINUOUS job is ACTIVE or an ON_DEMAND execution is RUNNING.", + "operationId": "patchJob", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobPatchRequest" + }, + "examples": { + "updateName": { + "summary": "Update job name", + "value": { + "name": "tenant-a-autoscale-prod" + } + }, + "updateStatus": { + "summary": "Pause job updates during maintenance", + "value": { + "status": "PAUSED" + } + }, + "updateDesiredSize": { + "summary": "Update desired size for AutoScale job", + "value": { + "config": { + "configType": "AUTO_SCALE", + "desiredSize": 5 + } + } + }, + "updateAutoScaleConfig": { + "summary": "Update AutoScale configuration", + "value": { + "config": { + "configType": "AUTO_SCALE", + "licensePoolReference": "550e8400-e29b-41d4-a716-446655440003", + "minSize": 2, + "maxSize": 12, + "desiredSize": 4, + "scaleOutCooldownSeconds": 300 + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Updated job", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + }, + "example": { + "id": "114ca9f9-88a3-49e1-92f2-757d7fedde98", + "workflowId": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "name": "tenant-a-autoscale-prod", + "type": "AUTO_SCALE", + "status": "ACTIVE", + "updatedAt": "2026-05-18T11:20:00.000Z" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "$ref": "#/components/responses/Conflict" + } + } + }, + "delete": { + "tags": [ + "Jobs" + ], + "summary": "Delete a job", + "description": "Terminates any running executions before deletion.", + "operationId": "deleteJob", + "responses": { + "204": { + "description": "Deleted" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "$ref": "#/components/responses/Conflict" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/devices": { + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ], + "get": { + "tags": [ + "Jobs" + ], + "summary": "List autoscale devices for a job", + "description": "Returns all autoscale device rows associated with the job.\n", + "operationId": "listDevices", + "responses": { + "200": { + "description": "Devices for the job", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InstanceListResponse" + }, + "example": { + "items": [ + { + "id": "65b1c38e-44b9-48e3-9fd3-38ffab1b6da1", + "workflowId": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "jobId": "114ca9f9-88a3-49e1-92f2-757d7fedde98", + "hostname": "bigip-tenant-a-01", + "ip": "10.145.134.204", + "status": "READY", + "managementAddr": "10.145.134.204", + "providerGuestRef": "vm-stub-65b1c38e-44b9-48e3-9fd3-38ffab1b6da1", + "createdAt": "2026-05-18T11:20:00.000Z", + "updatedAt": "2026-05-18T11:20:00.000Z", + "deletedAt": null + } + ], + "totalItems": 1 + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/activate": { + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ], + "post": { + "tags": [ + "Lifecycle - Continuous" + ], + "summary": "Activate a CONTINUOUS job", + "description": "Transitions job from READY/PAUSED \u2192 ACTIVE.\nOnly valid for jobs whose parent Workflow has executionMode=CONTINUOUS.\nStarts (or reuses) the long-lived continuous execution container for activity generation.\n", + "operationId": "activateJob", + "responses": { + "200": { + "description": "Job activated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + }, + "example": { + "id": "2f2f8b64-91d2-4d4f-9aa8-03b8a9238ea1", + "jobId": "220f0b6b-87e7-4e5f-bcc2-9f2d26786ac6", + "workflowId": "b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73", + "status": "RUNNING", + "startedAt": "2026-05-18T12:00:00.000Z" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "$ref": "#/components/responses/Conflict" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/pause": { + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ], + "post": { + "tags": [ + "Lifecycle - Continuous" + ], + "summary": "Pause a CONTINUOUS job", + "description": "Halts automatic evaluation for CONTINUOUS execution.\nNo new activities are triggered while paused.\nIn-flight activity processing may complete before full pause takes effect.\n", + "operationId": "pauseJob", + "responses": { + "200": { + "description": "Job paused", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + }, + "example": { + "message": "job paused" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "$ref": "#/components/responses/Conflict" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/resume": { + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ], + "post": { + "tags": [ + "Lifecycle - Continuous" + ], + "summary": "Resume a paused CONTINUOUS job", + "description": "Resumes automatic evaluation for a previously paused CONTINUOUS job.\nNew activities can be generated again based on policy/signal conditions.\n", + "operationId": "resumeJob", + "responses": { + "200": { + "description": "Job resumed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + }, + "example": { + "message": "job resumed" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "$ref": "#/components/responses/Conflict" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/signal": { + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ], + "post": { + "tags": [ + "Signals" + ], + "summary": "Send a generic signal to a job", + "description": "Generic signal endpoint for job-level signaling.\n\nExamples:\n- CONTINUOUS jobs: metric/policy signals that may trigger an activity.\n- ON_DEMAND jobs: external events that may trigger or annotate execution behavior.\nSignal interpretation is workflow-type specific and implemented by the corresponding handler.\n", + "operationId": "submitJobSignal", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobSignalRequest" + }, + "examples": { + "metricAlert": { + "summary": "Metric alert signal for scaling", + "value": { + "signalId": "sig-20260518-001", + "signalType": "METRIC_ALERT", + "source": "monitoring-pipeline", + "reason": "CPU threshold exceeded", + "labels": { + "cluster": "prod-a", + "environment": "production" + }, + "payload": { + "metricName": "cpu_utilization", + "metricValue": 91, + "threshold": 80, + "timestamp": "2026-05-18T14:30:00.000Z" + } + } + }, + "policyEvent": { + "summary": "Policy event signal", + "value": { + "signalId": "sig-20260518-002", + "signalType": "POLICY_EVENT", + "source": "event-engine", + "reason": "Scheduled maintenance window", + "labels": { + "maintenance-window": "enabled" + }, + "payload": { + "action": "pause_scaling", + "duration_minutes": 120 + } + } + }, + "externalEvent": { + "summary": "External event signal", + "value": { + "signalId": "sig-20260518-003", + "signalType": "EXTERNAL_EVENT", + "source": "slack-integration", + "reason": "Manual scale request via Slack command", + "labels": { + "user-id": "slack-uid-12345", + "channel": "infrastructure" + }, + "payload": { + "action": "scale_out", + "count": 2, + "user": "ops-engineer" + } + } + } + } + } + } + }, + "responses": { + "202": { + "description": "Signal accepted and processing enqueued", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobSignalResponse" + }, + "example": { + "accepted": true, + "correlationId": "9f7224ff-f108-4284-a80e-5f31135606fe", + "message": "desired size updated from 3 to 4 based on metric cpu_utilization=91.00", + "executionId": "2f2f8b64-91d2-4d4f-9aa8-03b8a9238ea1" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "409": { + "$ref": "#/components/responses/Conflict" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/executions": { + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ], + "get": { + "tags": [ + "Observability" + ], + "summary": "List executions for a job", + "description": "Execution cardinality depends on the parent workflow executionMode:\n\n- CONTINUOUS: at most one long-lived execution exists for a job.\n- ON_DEMAND: one execution per trigger (user/schedule/system), returned as history.\nUse filters (`status`, `trigger`, `since`, `until`) for timeline and troubleshooting use-cases.\n", + "operationId": "listExecutions", + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/LimitParam" + }, + { + "name": "status", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED", + "CANCELLED", + "TIMEOUT" + ] + } + }, + { + "name": "trigger", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "USER", + "ALERT", + "SYSTEM", + "SCHEDULE" + ] + } + }, + { + "name": "since", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "until", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "List of executions", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecutionListResponse" + }, + "examples": { + "continuousMode": { + "summary": "CONTINUOUS job (single execution)", + "value": { + "items": [ + { + "id": "2f2f8b64-91d2-4d4f-9aa8-03b8a9238ea1", + "jobId": "b4b9a9a0-4ecb-4f9a-b9ab-8a25fdca0db8", + "trigger": "SYSTEM", + "status": "RUNNING", + "reason": "Continuous controller active", + "startedAt": "2026-05-18T08:10:00.000Z", + "activityCount": 37 + } + ], + "total": 1, + "page": 1, + "limit": 50 + } + }, + "onDemandMode": { + "summary": "ON_DEMAND simulation job (multiple runs)", + "value": { + "items": [ + { + "id": "7d8f5576-6414-410f-8f5a-0c34f95df3b0", + "jobId": "b4b9a9a0-4ecb-4f9a-b9ab-8a25fdca0db8", + "trigger": "USER", + "status": "COMPLETED", + "reason": "Manual autoscale simulation run", + "startedAt": "2026-05-18T10:00:00.000Z", + "completedAt": "2026-05-18T10:07:31.000Z", + "activityCount": 1 + }, + { + "id": "0e6ea02f-d03c-4cf4-8434-feb23a9f9eb6", + "jobId": "b4b9a9a0-4ecb-4f9a-b9ab-8a25fdca0db8", + "trigger": "SCHEDULE", + "status": "FAILED", + "reason": "Nightly run", + "startedAt": "2026-05-17T02:00:00.000Z", + "completedAt": "2026-05-17T02:02:10.000Z", + "activityCount": 1 + } + ], + "total": 2, + "page": 1, + "limit": 50 + } + } + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/executions/{executionId}": { + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + }, + { + "$ref": "#/components/parameters/ExecutionId" + } + ], + "get": { + "tags": [ + "Observability" + ], + "summary": "Get execution detail including activity summary", + "description": "Returns execution metadata and activity-level summary.\n\n- For CONTINUOUS jobs, this is the single long-lived execution that accumulates many activities.\n- For ON_DEMAND jobs, this is one triggered run.\n\nUse `/executions/{executionId}/activities` to page through activities.\nThis endpoint is summary-focused and avoids returning unbounded activity step payloads.\n", + "operationId": "getExecution", + "responses": { + "200": { + "description": "Execution detail with activity summary", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecutionDetail" + }, + "example": { + "id": "2f2f8b64-91d2-4d4f-9aa8-03b8a9238ea1", + "jobId": "220f0b6b-87e7-4e5f-bcc2-9f2d26786ac6", + "trigger": "SYSTEM", + "status": "RUNNING", + "reason": "Continuous controller active", + "startedAt": "2026-05-18T08:10:00.000Z", + "activityCount": 37, + "activitySummary": { + "total": 37, + "running": 1, + "completed": 35, + "failed": 1 + }, + "latestActivityId": "0c4208f9-f7bf-4891-a2a3-df08eb7720d8", + "latestActivityType": "SCALE_OUT" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/executions/{executionId}/activities": { + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + }, + { + "$ref": "#/components/parameters/ExecutionId" + } + ], + "get": { + "tags": [ + "Observability" + ], + "summary": "List activities for an execution", + "description": "Activities are action units inside an execution.\nExamples: `SCALE_OUT`, `SCALE_IN`, `UPGRADE`, `PRECHECK`, `POSTCHECK`.\n\n- CONTINUOUS: this list grows over the life of the single execution.\n- ON_DEMAND: this list typically contains one or a small fixed set of activities.\nUse this endpoint to inspect action-level outcomes before drilling into step-level detail.\n", + "operationId": "listExecutionActivities", + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/LimitParam" + }, + { + "name": "activityType", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "COMPLETED", + "FAILED", + "SKIPPED", + "CANCELLED" + ] + } + }, + { + "name": "since", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "List of activities", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivityListResponse" + }, + "example": { + "items": [ + { + "id": "0c4208f9-f7bf-4891-a2a3-df08eb7720d8", + "executionId": "2f2f8b64-91d2-4d4f-9aa8-03b8a9238ea1", + "activityType": "SCALE_OUT", + "status": "COMPLETED", + "trigger": "ALERT", + "reason": "cpu_utilization > 90", + "startedAt": "2026-05-18T12:20:00.000Z", + "completedAt": "2026-05-18T12:21:15.000Z", + "durationMs": 75000, + "stepCount": 4 + }, + { + "id": "2729938f-ae9c-4d6b-8d93-2852fc7f4c8c", + "executionId": "2f2f8b64-91d2-4d4f-9aa8-03b8a9238ea1", + "activityType": "SCALE_IN", + "status": "RUNNING", + "trigger": "SYSTEM", + "reason": "low utilization evaluation", + "startedAt": "2026-05-18T12:30:00.000Z", + "stepCount": 3 + } + ], + "total": 2, + "page": 1, + "limit": 50 + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/executions/{executionId}/activities/{activityId}": { + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + }, + { + "$ref": "#/components/parameters/ExecutionId" + }, + { + "$ref": "#/components/parameters/ActivityId" + } + ], + "get": { + "tags": [ + "Observability" + ], + "summary": "Get activity detail including steps", + "description": "Returns one activity with full step breakdown, retries, timing, and error details.\nUse this as the primary endpoint for root-cause analysis of a failed activity.\n", + "operationId": "getExecutionActivity", + "responses": { + "200": { + "description": "Activity with steps", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivityDetail" + }, + "example": { + "id": "0c4208f9-f7bf-4891-a2a3-df08eb7720d8", + "executionId": "2f2f8b64-91d2-4d4f-9aa8-03b8a9238ea1", + "activityType": "SCALE_OUT", + "status": "COMPLETED", + "trigger": "ALERT", + "reason": "cpu_utilization > 90", + "startedAt": "2026-05-18T12:20:00.000Z", + "completedAt": "2026-05-18T12:21:15.000Z", + "durationMs": 75000, + "currentStep": "FINISHED", + "stepCount": 4, + "steps": [ + { + "id": "67b5f8ad-a992-46da-af82-38f5d9a0a4ee", + "activityId": "0c4208f9-f7bf-4891-a2a3-df08eb7720d8", + "stepName": "validate-pools", + "sequence": 1, + "status": "COMPLETED", + "startedAt": "2026-05-18T12:20:00.000Z", + "completedAt": "2026-05-18T12:20:10.000Z", + "durationMs": 10000 + }, + { + "id": "94aab872-52a5-4b8a-8a95-ffcb2ac5d41a", + "activityId": "0c4208f9-f7bf-4891-a2a3-df08eb7720d8", + "stepName": "provision-instance", + "sequence": 2, + "status": "COMPLETED", + "startedAt": "2026-05-18T12:20:10.000Z", + "completedAt": "2026-05-18T12:20:55.000Z", + "durationMs": 45000 + }, + { + "id": "20f06e25-48ca-41a9-b6bd-ef517f4ca886", + "activityId": "0c4208f9-f7bf-4891-a2a3-df08eb7720d8", + "stepName": "register-instance", + "sequence": 3, + "status": "COMPLETED", + "startedAt": "2026-05-18T12:20:55.000Z", + "completedAt": "2026-05-18T12:21:05.000Z", + "durationMs": 10000 + }, + { + "id": "2969654c-f790-4a60-8e0f-cfb75a97f6c8", + "activityId": "0c4208f9-f7bf-4891-a2a3-df08eb7720d8", + "stepName": "post-check", + "sequence": 4, + "status": "COMPLETED", + "startedAt": "2026-05-18T12:21:05.000Z", + "completedAt": "2026-05-18T12:21:15.000Z", + "durationMs": 10000 + } + ] + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/provisioning/v1/workflows/{workflowId}/jobs/{jobId}/events": { + "parameters": [ + { + "$ref": "#/components/parameters/WorkflowId" + }, + { + "$ref": "#/components/parameters/JobId" + } + ], + "get": { + "tags": [ + "Observability" + ], + "summary": "List audit events for a job", + "description": "Returns audit/event stream entries related to the Job lifecycle and execution processing.\nEvents are useful for timeline reconstruction and correlation across components.\n", + "operationId": "listEvents", + "parameters": [ + { + "$ref": "#/components/parameters/PageParam" + }, + { + "$ref": "#/components/parameters/LimitParam" + }, + { + "name": "source", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "eventType", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "correlationId", + "in": "query", + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "since", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "List of events", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EventListResponse" + }, + "example": { + "items": [ + { + "id": "dfee47f7-5e66-4ff2-91ea-e7f7052d6d76", + "jobId": "220f0b6b-87e7-4e5f-bcc2-9f2d26786ac6", + "source": "autoscale-engine", + "eventType": "SCALE_OUT_TRIGGERED", + "message": "CPU threshold exceeded", + "payload": { + "metricName": "cpu_utilization", + "metricValue": 91 + }, + "eventTime": "2026-05-18T12:19:59.000Z", + "correlationId": "9f7224ff-f108-4284-a80e-5f31135606fe" + } + ], + "total": 1, + "page": 1, + "limit": 50 + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/system/health": { + "get": { + "summary": "Health check endpoint", + "description": "Returns the health status of the system manager service", + "operationId": "getHealth", + "tags": [ + "Health" + ], + "responses": { + "200": { + "description": "Service is healthy", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HealthResponse" + } + } + } + } + } + } + }, + "/api/system/version": { + "get": { + "summary": "Get system version", + "description": "Returns the current F5 Insight version information", + "operationId": "getVersion", + "tags": [ + "Health" + ], + "responses": { + "200": { + "description": "Version information retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VersionResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/upload": { + "x-feature": "systemManagement", + "get": { + "summary": "Get uploaded bundle info", + "description": "Returns information about the currently uploaded bundle, if any", + "operationId": "getUploadedBundle", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Bundle info retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadInfoResponse" + } + } + } + } + } + }, + "delete": { + "summary": "Delete uploaded upgrade bundle", + "description": "Deletes uploaded offline upgrade bundles from local bundle storage.\nWhen version and/or kind are provided, only matching bundles are removed.\nWhen no filters are provided, all uploaded offline bundles are removed.\n", + "operationId": "deleteUploadedBundle", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "version", + "in": "query", + "required": false, + "description": "Uploaded bundle version to delete", + "schema": { + "type": "string", + "example": "1.2.1-3" + } + }, + { + "name": "kind", + "in": "query", + "required": false, + "description": "Uploaded bundle kind to delete", + "schema": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "example": "patch" + } + } + ], + "responses": { + "200": { + "description": "Uploaded bundle deleted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SuccessResponse" + } + } + } + }, + "400": { + "description": "No matching uploaded bundle found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Upgrade operation already in progress", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to delete uploaded bundle", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + }, + "post": { + "summary": "Upload upgrade bundle", + "description": "Upload an offline patch or full_upgrade bundle for offline / air-gapped deployments.\nAccepts a multipart/form-data upload with field name `bundle`.\nThe archive must be a .tar.gz file up to 8 GB.\nThe upgrade version and kind are auto-detected from manifest.yml/manifest.json, with legacy top-level directory detection as a fallback.\nAfter upload, the bundle appears in GET /api/system/upgrade/catalog and can be applied with POST /api/system/upgrade/apply.\n", + "operationId": "uploadUpgradeBundle", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "required": [ + "bundle" + ], + "properties": { + "bundle": { + "type": "string", + "format": "binary", + "description": "Upgrade bundle .tar.gz file (max 8 GB)" + } + } + } + } + } + }, + "responses": { + "201": { + "description": "Bundle uploaded and validated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadResponse" + } + } + } + }, + "400": { + "description": "Invalid request or bundle", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Another operation is in progress", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "413": { + "description": "File exceeds 8 GB limit", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "422": { + "description": "Invalid archive format or missing required structure", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/start": { + "x-feature": "systemManagement", + "post": { + "summary": "Start upgrade", + "description": "Not supported since F5 Insight 1.2.0.\nUse POST /api/system/upgrade/apply instead.\n", + "operationId": "startUpgrade", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "responses": { + "410": { + "description": "Endpoint is not supported", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/status": { + "x-feature": "systemManagement", + "get": { + "summary": "Get upgrade status", + "description": "Returns the current status of the upgrade operation", + "operationId": "getUpgradeStatus", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Status retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeStatusResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/catalog": { + "get": { + "summary": "Get upgrade catalog", + "description": "Returns only the latest available patch and latest available full\nupgrade for the selected source. Use mode=online to return only F5\nDownloads entries, or mode=offline to return only offline local/uploaded\nbundle entries. The mode query parameter is required.\n", + "operationId": "getUpgradeCatalog", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "mode", + "in": "query", + "required": true, + "description": "Catalog source filter.", + "schema": { + "type": "string", + "enum": [ + "online", + "offline" + ] + } + } + ], + "responses": { + "200": { + "description": "Catalog retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeCatalogResponse" + } + } + } + }, + "400": { + "description": "Missing or invalid mode query parameter", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/current": { + "get": { + "summary": "Get current running version", + "description": "Returns the APP_VERSION environment variable from the running system-manager pod.", + "operationId": "getUpgradeCurrent", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Current version returned", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CurrentVersionResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/preflight": { + "get": { + "summary": "Run preflight checks for upgrade", + "description": "Runs preflight checks before a patch or full_upgrade can be applied.\nChecks include no_active_job, disk_space, pod_health, dr_pair,\nversion_compatibility, and bundle_signature for online upgrades.\n", + "operationId": "getUpgradePreflight", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "kind", + "in": "query", + "required": true, + "description": "Upgrade kind to validate preflight for", + "schema": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "example": "patch" + } + }, + { + "name": "version", + "in": "query", + "required": true, + "description": "Target version to validate (e.g., f5-insight-patch-1.2.3)", + "schema": { + "type": "string", + "example": "f5-insight-patch-1.2.3" + } + } + ], + "responses": { + "200": { + "description": "Preflight checks completed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PreflightResponse" + } + } + } + }, + "400": { + "description": "Invalid version parameter", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Version not found in catalog", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/apply": { + "post": { + "summary": "Apply upgrade", + "description": "Starts an upgrade job for an uploaded/local bundle or an online F5\nDownloads catalog entry.\nRuns backend preflight validation before creating the upgrade job so\ndirect API callers cannot bypass failed checks.\nThe request is persisted in upgrade_history and handed to\nplatform-manager over the Unix domain socket. For online entries,\nsystem-manager downloads the selected bundle to disk, verifies SHA256\nand any provided signature, then applies the same local bundle path.\n", + "operationId": "postUpgradeApply", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApplyUpgradeRequest" + } + } + } + }, + "responses": { + "202": { + "description": "Upgrade initiated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApplyAcceptedResponse" + } + } + } + }, + "400": { + "description": "Invalid request or validation failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Upgrade already in progress or preflight checks failed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Platform manager unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/jobs/{job_id}": { + "get": { + "summary": "Get upgrade job status", + "description": "Unified polling endpoint for upgrade status, rollback state, rollback\njob status, and postflight checks.\n", + "operationId": "getUpgradeJob", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "description": "Upgrade history record ID", + "schema": { + "type": "string", + "format": "uuid", + "example": "550e8400-e29b-41d4-a716-446655440000" + } + } + ], + "responses": { + "200": { + "description": "Job status retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobStatusResponse" + } + } + } + }, + "404": { + "description": "Job not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/jobs/{job_id}/cancel": { + "post": { + "summary": "Cancel patch upgrade job", + "description": "Cancels a pending/running patch job. Full upgrade jobs cannot be cancelled. If patch deployment has already started, automatic rollback is triggered; jobs cancelled before deployment are marked clean.", + "operationId": "postUpgradeJobCancel", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "description": "Upgrade history record ID", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "202": { + "description": "Cancel accepted" + }, + "400": { + "description": "Cancel is only supported for patch upgrade jobs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Job not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "No active job to cancel", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/jobs/{job_id}/postflight": { + "get": { + "summary": "Run post-flight health checks", + "description": "Runs post-deployment health checks for a completed upgrade job.", + "operationId": "getUpgradeJobPostflight", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "description": "Upgrade history record ID", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Post-flight results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PostflightResponse" + } + } + } + }, + "404": { + "description": "Job not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/jobs/{job_id}/rollback": { + "post": { + "summary": "Roll back upgrade job", + "description": "Manually starts rollback for the latest successful patch job within 72 hours of completion. Failed patch jobs trigger automatic rollback when deployment has started.", + "operationId": "postUpgradeJobRollback", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "description": "Upgrade history record ID", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "202": { + "description": "Rollback started", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RollbackAcceptedResponse" + } + } + } + }, + "400": { + "description": "Rollback is not available for this job", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Job not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Another operation is already in progress", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/jobs/{job_id}/rollback-state": { + "get": { + "summary": "Check rollback state availability", + "description": "Returns whether manual rollback is currently available for this job. Manual rollback is available for the latest successful patch job within 72 hours of completion; failed patch jobs use automatic rollback.", + "operationId": "getUpgradeJobRollbackState", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "description": "Upgrade history record ID", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Rollback state checked", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RollbackStateResponse" + } + } + } + }, + "404": { + "description": "Job not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/rollback/{rollback_id}": { + "get": { + "summary": "Poll rollback job status", + "description": "Returns rollback status, progress, and structured log lines.", + "operationId": "getUpgradeRollback", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "rollback_id", + "in": "path", + "required": true, + "description": "Rollback history record ID", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Rollback status", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RollbackStatusResponse" + } + } + } + }, + "404": { + "description": "Rollback job not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/jobs/{job_id}/confirm-clean": { + "post": { + "summary": "Confirm upgrade state is clean", + "description": "Admin-only override that clears unresolved dirty-state for a failed upgrade after admin review and records rollback_history status admin_confirmed. Only available when the job is failed and dirty_state is true.", + "operationId": "postUpgradeJobConfirmClean", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "description": "Upgrade history record ID", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Dirty state cleared" + }, + "403": { + "description": "Admin role required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Job not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Job is already clean or is not an unresolved failed upgrade", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/active-job": { + "get": { + "summary": "Get active upgrade job", + "description": "Returns the single pending/running job. When no active job exists, returns 200 with data set to null. Failed dirty-state jobs are available through history; patch deployment failures trigger automatic rollback.", + "operationId": "getUpgradeActiveJob", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Active job result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActiveJobResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/history": { + "get": { + "summary": "Get upgrade history", + "description": "Returns the last 50 upgrade jobs, newest first, with top-level dirty_state.", + "operationId": "getUpgradeHistory", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Patch history", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeHistoryResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/history/stats": { + "get": { + "summary": "Get all-time upgrade stats", + "description": "Returns aggregate statistics across all historical upgrade jobs.", + "operationId": "getUpgradeHistoryStats", + "x-mode": "lite", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Aggregate stats", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpgradeHistoryStatsResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/scheduled": { + "get": { + "summary": "List pending scheduled upgrade jobs", + "description": "Returns all scheduled upgrade jobs with status pending.", + "operationId": "getUpgradeScheduled", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Scheduled jobs list", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduledUpgradeListResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/schedule": { + "post": { + "summary": "Schedule an upgrade", + "description": "Schedules a patch or full_upgrade to run at a future UTC timestamp.", + "operationId": "postUpgradeSchedule", + "tags": [ + "Upgrade" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleUpgradeRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Schedule created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduledUpgradeCreatedResponse" + } + } + } + }, + "400": { + "description": "scheduled_at must be a future timestamp", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/scheduled/{sched_id}": { + "delete": { + "summary": "Cancel a pending scheduled upgrade job", + "description": "Cancels a pending scheduled job. Has no effect on jobs already triggered.", + "operationId": "deleteUpgradeScheduled", + "tags": [ + "Upgrade" + ], + "parameters": [ + { + "name": "sched_id", + "in": "path", + "required": true, + "description": "Scheduled upgrade job ID", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Scheduled job cancelled" + }, + "404": { + "description": "Scheduled job not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/scheduled/history": { + "get": { + "summary": "List completed scheduled upgrade jobs", + "description": "Returns scheduled jobs in terminal states done, failed, and cancelled. Pending jobs are excluded.", + "operationId": "getUpgradeScheduledHistory", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Scheduled job history", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduledUpgradeListResponse" + } + } + } + } + } + } + }, + "/api/system/upgrade/schedule/recommendation": { + "get": { + "summary": "Get recommended scheduling window", + "description": "Analyses upgrade history to find the best 2-hour UTC scheduling window.", + "operationId": "getUpgradeScheduleRecommendation", + "tags": [ + "Upgrade" + ], + "responses": { + "200": { + "description": "Recommendation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleRecommendationResponse" + } + } + } + } + } + } + }, + "/api/system/backups": { + "x-feature": "systemManagement", + "get": { + "summary": "List backups", + "description": "Returns a list of all backup and restore jobs", + "operationId": "listBackups", + "tags": [ + "Backup" + ], + "responses": { + "200": { + "description": "List of jobs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackupListResponse" + } + } + } + }, + "500": { + "description": "Failed to list backups", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + }, + "post": { + "summary": "Create a backup", + "description": "Triggers a backup operation. Returns a job ID to track progress.", + "operationId": "createBackup", + "tags": [ + "Backup" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateBackupRequest" + } + } + } + }, + "responses": { + "202": { + "description": "Backup started", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackupJobResponse" + } + } + } + }, + "400": { + "description": "Invalid request. Includes SYSTEM-0003 when a full backup is requested without a remote storage target (full backups are not supported on local storage), an invalid backup name/passphrase, or an unknown storage target.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Another backup/restore is in progress", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to create the backup job", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Platform manager is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/backups/analysis": { + "get": { + "summary": "Backup size anomaly analysis", + "description": "Compares the most recent completed backup size against the rolling\naverage of the previous 3 completed backups. Returns is_anomalous=true\nwhen the latest backup is more than 30% smaller than the rolling average\n(pct_of_avg < 70).\n", + "operationId": "getBackupsAnalysis", + "tags": [ + "Backup" + ], + "responses": { + "200": { + "description": "Analysis result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackupSizeAnalysisResponse" + } + } + } + }, + "500": { + "description": "Failed to calculate backup analysis", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/backups/{id}": { + "x-feature": "systemManagement", + "get": { + "summary": "Get backup details", + "description": "Returns details of a specific backup job including live progress", + "operationId": "getBackup", + "tags": [ + "Backup" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Backup details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackupJobResponse" + } + } + } + }, + "404": { + "description": "Backup not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + }, + "delete": { + "summary": "Delete a backup", + "description": "Deletes a backup file and its job record", + "operationId": "deleteBackup", + "tags": [ + "Backup" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Backup deleted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SuccessResponse" + } + } + } + }, + "404": { + "description": "Backup not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to delete the backup", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/backups/{id}/download": { + "x-feature": "systemManagement", + "get": { + "summary": "Download backup file", + "description": "Downloads the backup archive file", + "operationId": "downloadBackup", + "tags": [ + "Backup" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Backup file stream", + "content": { + "application/octet-stream": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "404": { + "description": "Backup not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/backups/{id}/restore": { + "x-feature": "systemManagement", + "post": { + "summary": "Restore from backup", + "description": "Triggers a restore from the specified backup", + "operationId": "createRestore", + "tags": [ + "Backup" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "passphrase" + ], + "properties": { + "passphrase": { + "type": "string", + "description": "Encryption passphrase used when backup was created" + }, + "components": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "data", + "config", + "network", + "dns", + "hostname", + "ntp", + "proxy", + "ssh" + ] + }, + "description": "Components to restore. Valid values data, config, network, dns, hostname, ntp, proxy, ssh. 'data' covers databases, 'config' covers configuration; system settings (dns, ntp, proxy, ssh, network, hostname) must be selected individually." + }, + "force": { + "type": "boolean", + "description": "Skip pre-restore state preservation (no rollback possible)" + } + } + } + } + } + }, + "responses": { + "202": { + "description": "Restore started", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackupJobResponse" + } + } + } + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Backup, backup file, or referenced storage target not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Another operation is in progress", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to start the restore job", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Platform manager is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/backups/upload": { + "x-feature": "systemManagement", + "post": { + "summary": "Upload backup file", + "description": "Upload a backup .tar file from another system without restoring", + "operationId": "uploadBackup", + "tags": [ + "Backup" + ], + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "required": [ + "backup" + ], + "properties": { + "backup": { + "type": "string", + "format": "binary", + "description": "Backup .tar file" + } + } + } + } + } + }, + "responses": { + "201": { + "description": "Backup uploaded", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackupJobResponse" + } + } + } + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to save the uploaded backup", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/backups/import": { + "x-feature": "systemManagement", + "post": { + "summary": "Import backup from path", + "description": "Import a backup file from a local path or remote storage target.\nReads the manifest via platform-manager to validate and extract metadata.\nCreates a DB record referencing the file location without copying.\n", + "operationId": "importBackup", + "tags": [ + "Backup" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImportBackupRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Backup imported", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackupJobResponse" + } + } + } + }, + "400": { + "description": "Invalid request or file not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Backup already imported", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to import the backup", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Storage target or platform manager unreachable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/storage-targets": { + "x-feature": "systemManagement", + "get": { + "summary": "List storage targets", + "description": "Returns all configured storage targets", + "operationId": "listStorageTargets", + "tags": [ + "Storage" + ], + "responses": { + "200": { + "description": "List of storage targets", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageTargetListResponse" + } + } + } + }, + "500": { + "description": "Failed to list storage targets", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + }, + "post": { + "summary": "Create storage target", + "description": "Create a new NFS or SMB storage target", + "operationId": "createStorageTarget", + "tags": [ + "Storage" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStorageTargetRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Storage target created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageTargetResponse" + } + } + } + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to create the storage target", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Vault is unavailable and the credential could not be stored", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/storage-targets/{id}": { + "x-feature": "systemManagement", + "get": { + "summary": "Get storage target", + "operationId": "getStorageTarget", + "tags": [ + "Storage" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Storage target details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageTargetResponse" + } + } + } + }, + "404": { + "description": "Not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + }, + "put": { + "summary": "Update storage target", + "operationId": "updateStorageTarget", + "tags": [ + "Storage" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStorageTargetRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Storage target updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageTargetResponse" + } + } + } + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Storage target not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to update the storage target", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Vault is unavailable and the credential could not be updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + }, + "delete": { + "summary": "Delete storage target", + "operationId": "deleteStorageTarget", + "tags": [ + "Storage" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Storage target deleted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SuccessResponse" + } + } + } + }, + "400": { + "description": "Cannot delete default local target", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Storage target not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to delete the storage target", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/storage-targets/{id}/test": { + "x-feature": "systemManagement", + "post": { + "summary": "Test storage connectivity", + "description": "Mount, write test file, unmount. Returns success with latency.", + "operationId": "testStorageTarget", + "tags": [ + "Storage" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Test result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageTestResponse" + } + } + } + }, + "404": { + "description": "Storage target not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Platform manager is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/storage-targets/test": { + "x-feature": "systemManagement", + "post": { + "summary": "Test storage connectivity without creating", + "description": "Tests connectivity to a storage target using the provided config. Does not save anything.", + "operationId": "testStorageConnectivity", + "tags": [ + "Storage" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestStorageTargetRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Test result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageTestResponse" + } + } + } + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Platform manager is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/backup-settings": { + "x-feature": "systemManagement", + "get": { + "summary": "Get backup settings", + "description": "Returns current backup settings (retention count, default storage target)", + "operationId": "getBackupSettings", + "tags": [ + "Settings" + ], + "responses": { + "200": { + "description": "Current settings", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackupSettingsResponse" + } + } + } + }, + "500": { + "description": "Failed to load backup settings", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + }, + "put": { + "summary": "Update backup settings", + "description": "Update backup settings", + "operationId": "updateBackupSettings", + "tags": [ + "Settings" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateBackupSettingsRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Settings updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackupSettingsResponse" + } + } + } + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to update backup settings", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/backup-schedules": { + "x-feature": "systemManagement", + "get": { + "summary": "List backup schedules", + "description": "Returns all configured backup schedules. Multiple schedules are allowed (one per backup type).", + "operationId": "getBackupSchedule", + "tags": [ + "Schedule" + ], + "responses": { + "200": { + "description": "Configured schedules", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleListResponse" + } + } + } + }, + "500": { + "description": "Failed to list backup schedules", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Scheduler is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + }, + "post": { + "summary": "Create backup schedule", + "description": "Create a named backup schedule. Multiple schedules allowed. Duplicate names rejected.", + "operationId": "createBackupSchedule", + "tags": [ + "Schedule" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateScheduleRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Schedule created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleResponse" + } + } + } + }, + "400": { + "description": "Invalid request, e.g. a full backup schedule without a remote storage target", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Schedule already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to create the backup schedule", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Scheduler or Vault is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/backup-schedules/{id}": { + "x-feature": "systemManagement", + "get": { + "summary": "Get backup schedule by ID", + "operationId": "getBackupScheduleById", + "tags": [ + "Schedule" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Schedule details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleResponse" + } + } + } + }, + "404": { + "description": "Schedule not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Scheduler is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + }, + "put": { + "summary": "Update backup schedule", + "operationId": "updateBackupSchedule", + "tags": [ + "Schedule" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Schedule updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleResponse" + } + } + } + }, + "400": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Schedule not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Conflicting schedule for this backup type", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Failed to update the backup schedule", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Scheduler is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + }, + "delete": { + "summary": "Delete backup schedule", + "operationId": "deleteBackupSchedule", + "tags": [ + "Schedule" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Schedule deleted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SuccessResponse" + } + } + } + }, + "404": { + "description": "Schedule not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "503": { + "description": "Scheduler is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/mode": { + "x-feature": "systemManagement", + "post": { + "summary": "Initiate system mode switch", + "x-mode": "lite", + "description": "Switch F5 Insight between lite and full modes.\n\n**Mode Descriptions:**\n- **lite**: Minimal mode with otel-collector, clickhouse, backend, frontend, postgres, vault, zitadel, platform-manager\n- **full**: Full observability mode with additional services: victoriametrics, vmagent, vmalert, system-manager\n\n**Constraints:**\n- Cannot switch from full \u2192 lite (downgrade blocked)\n- Cannot switch to same mode\n- License validation required for lite \u2192 full upgrade\n- Returns 202 with task_id for async tracking\n", + "operationId": "initiateModeSwitch", + "tags": [ + "Mode Management" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModeSwitchRequest" + } + } + } + }, + "responses": { + "202": { + "description": "Mode switch initiated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModeSwitchResponse" + } + } + } + }, + "400": { + "description": "Invalid request (same mode, full\u2192lite not allowed, invalid mode)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "403": { + "description": "License validation failed (lite\u2192full requires valid license)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/fqdn": { + "post": { + "summary": "Configure external FQDN", + "description": "Configure the canonical external FQDN used by F5 Insight and Zitadel.\nThe operation runs asynchronously because it performs a Helm upgrade and\nreruns Zitadel bootstrap to refresh the registered OIDC callback URL.\n", + "operationId": "configureFqdn", + "tags": [ + "FQDN Configuration" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FqdnConfigRequest" + } + } + } + }, + "responses": { + "202": { + "description": "FQDN configuration task submitted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FqdnConfigResponse" + } + } + } + }, + "400": { + "description": "Invalid FQDN target", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "409": { + "description": "Another FQDN configuration task is already running", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/fqdn/status/{task_id}": { + "get": { + "summary": "Get FQDN configuration status", + "description": "Query the progress of an FQDN configuration task by task_id.", + "operationId": "getFqdnStatus", + "tags": [ + "FQDN Configuration" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "UUID of the FQDN configuration task", + "schema": { + "type": "string", + "format": "uuid", + "example": "123e4567-e89b-12d3-a456-426614174000" + } + } + ], + "responses": { + "200": { + "description": "FQDN configuration status retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FqdnStatusResponse" + } + } + } + }, + "400": { + "description": "Invalid task_id format", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/mode/status/{task_id}": { + "x-feature": "systemManagement", + "get": { + "summary": "Get mode switch status", + "x-mode": "lite", + "description": "Query the progress of a mode switch task by task_id.\n\n**FSM States:**\n- INIT: Task initialized\n- IN_PROGRESS: Running (VALIDATE \u2192 SAVE_STATE \u2192 SCALE \u2192 WAIT_READY \u2192 HEALTH_CHECK)\n- COMPLETED: Successfully finished\n- FAILED: Error occurred\n", + "operationId": "getModeStatus", + "tags": [ + "Mode Management" + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "description": "UUID of the mode switch task", + "schema": { + "type": "string", + "format": "uuid", + "example": "123e4567-e89b-12d3-a456-426614174000" + } + } + ], + "responses": { + "200": { + "description": "Mode switch status retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModeStatusResponse" + } + } + } + }, + "400": { + "description": "Invalid task_id format", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "404": { + "description": "Task not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/mode/capabilities": { + "get": { + "summary": "Get available system modes and capabilities", + "x-mode": "lite", + "description": "Returns information about the current system mode (lite/full).\n", + "operationId": "getModeCapabilities", + "tags": [ + "Mode Management" + ], + "responses": { + "200": { + "description": "Mode capabilities retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModeCapabilitiesResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + }, + "/api/system/mode/active-task": { + "get": { + "summary": "Get active mode switch task", + "x-mode": "lite", + "description": "Returns the currently running (non-terminal) mode switch task.\nReturns 404 when no mode switch is in progress.\n", + "operationId": "getActiveModeTask", + "tags": [ + "Mode Management" + ], + "responses": { + "200": { + "description": "Active mode switch task found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActiveModeSwitchTaskResponse" + } + } + } + }, + "404": { + "description": "No mode switch task in progress", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIErrorResponse" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "AuditEvent": { + "type": "object", + "description": "A single AI assistant audit event row from ClickHouse.", + "properties": { + "event_id": { + "type": "string", + "format": "uuid", + "description": "Unique event identifier", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "session_id": { + "type": "string", + "description": "Browser/session identifier", + "example": "sess-abc123" + }, + "thread_id": { + "type": "string", + "description": "Conversation/thread identifier (maps to chat history conversation_id)", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "interaction_id": { + "type": "string", + "description": "Single request-response cycle identifier within a thread", + "example": "interact-xyz" + }, + "user_id": { + "type": "string", + "description": "Authenticated user ID", + "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" + }, + "username": { + "type": "string", + "description": "Authenticated username", + "example": "admin" + }, + "event_type": { + "type": "string", + "enum": [ + "user_message", + "assistant_response", + "tool_call", + "tool_result", + "error", + "data_access", + "pdf_export" + ], + "description": "Type of agent action that generated this event" + }, + "message": { + "type": "string", + "description": "User message text, assistant response text, or error message. Masked as `[MASKED]` unless caller has `audit.view_sensitive`.\n" + }, + "tool_name": { + "type": "string", + "description": "Name of the tool invoked (populated for tool_call/tool_result events)", + "example": "list_pools" + }, + "tool_arguments": { + "type": "string", + "description": "JSON-encoded tool arguments. PII masked unless view_sensitive.", + "example": "{\"device_name\":\"bigip-01\"}" + }, + "tool_result": { + "type": "string", + "description": "JSON-encoded tool result. PII masked unless view_sensitive." + }, + "error_message": { + "type": "string", + "description": "Error details for error-type events." + }, + "provider": { + "type": "string", + "description": "LLM provider name", + "example": "openai" + }, + "model": { + "type": "string", + "description": "LLM model name", + "example": "gpt-4o" + }, + "ip_address": { + "type": "string", + "description": "Client IP address. Masked unless view_sensitive.", + "example": "192.168.1.***" + }, + "user_agent": { + "type": "string", + "description": "Client user agent. Always `[MASKED]` unless view_sensitive." + }, + "timestamp": { + "type": "string", + "format": "date-time", + "description": "Event timestamp (UTC)", + "example": "2026-06-01T10:30:00Z" + }, + "duration_ms": { + "type": "integer", + "description": "Duration of the operation in milliseconds (populated for tool_result events)", + "example": 342 + }, + "outcome": { + "type": "string", + "enum": [ + "success", + "failure", + "pending" + ], + "description": "Outcome of the agent action" + }, + "extra": { + "type": "string", + "description": "Additional JSON metadata" + } + } + }, + "AuditPagination": { + "type": "object", + "description": "Pagination metadata returned alongside audit event lists.", + "required": [ + "page", + "pageSize", + "totalEvents", + "totalPages" + ], + "properties": { + "page": { + "type": "integer", + "description": "Current page number (1-based)", + "example": 1 + }, + "pageSize": { + "type": "integer", + "description": "Number of results per page", + "example": 20 + }, + "totalEvents": { + "type": "integer", + "description": "Total number of events matching the current filters", + "example": 87 + }, + "totalPages": { + "type": "integer", + "description": "Total number of pages", + "example": 5 + } + } + }, + "AuditEventsResponse": { + "type": "object", + "required": [ + "events", + "pagination" + ], + "properties": { + "events": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AuditEvent" + }, + "nullable": true, + "description": "Array of audit events for the requested page. Null if storage is empty." + }, + "pagination": { + "$ref": "#/components/schemas/AuditPagination" + } + } + }, + "AuditExportRequest": { + "type": "object", + "description": "Optional filter body for POST /audit/export. All fields correspond to the same query parameters accepted by GET /audit/events.\n", + "properties": { + "username": { + "type": "string" + }, + "event_type": { + "type": "string", + "enum": [ + "user_message", + "assistant_response", + "tool_call", + "tool_result", + "error", + "data_access", + "pdf_export" + ] + }, + "tool": { + "type": "string" + }, + "keyword": { + "type": "string" + }, + "thread_id": { + "type": "string" + }, + "session_id": { + "type": "string" + }, + "date_from": { + "type": "string", + "format": "date-time" + }, + "date_to": { + "type": "string", + "format": "date-time" + } + } + }, + "AuditExportResponse": { + "type": "object", + "description": "Response from POST /audit/export. When status is `ready` (200), the file is available for immediate download. When status is `processing` (202), poll the `status_url` endpoint.\n", + "required": [ + "export_id", + "status" + ], + "properties": { + "export_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for this export job", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "status": { + "type": "string", + "enum": [ + "ready", + "processing" + ], + "description": "Current export status" + }, + "download_url": { + "type": "string", + "description": "URL to download the CSV (present for both ready and processing)", + "example": "/api/audit/export/3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "status_url": { + "type": "string", + "description": "URL to poll for status (present when status is processing)", + "example": "/api/audit/export/3fa85f64-5717-4562-b3fc-2c963f66afa6/status" + }, + "sha256": { + "type": "string", + "description": "SHA-256 hex digest of the CSV (present when status is ready)", + "example": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "row_count": { + "type": "integer", + "format": "int64", + "description": "Number of rows in the export", + "example": 42 + } + } + }, + "RoleListItem": { + "type": "object", + "description": "A role summary returned by GET /auth/roles.", + "properties": { + "id": { + "type": "string", + "description": "Unique role identifier", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "name": { + "type": "string", + "description": "Display name for the role", + "example": "Admin" + }, + "description": { + "type": "string", + "description": "Role description", + "example": "Full system access including user management" + }, + "is_builtin": { + "type": "boolean", + "description": "Whether the role is built into the system", + "example": true + }, + "user_count": { + "type": "integer", + "format": "int64", + "description": "Number of users assigned to the role", + "example": 2 + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp (ISO 8601)", + "example": "2026-01-01T00:00:00Z" + }, + "permissions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Permissions granted to this role. Included when include_permissions=true.", + "example": [ + "deviceManagement.get", + "dashboards.get", + "dashboards.post" + ] + } + }, + "required": [ + "id", + "name", + "description", + "is_builtin", + "user_count", + "created_at" + ] + }, + "RolesListResponse": { + "type": "object", + "description": "Response body for GET /auth/roles.", + "properties": { + "roles": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RoleListItem" + } + }, + "total_count": { + "type": "integer", + "description": "Total number of roles returned", + "example": 3 + } + }, + "required": [ + "roles", + "total_count" + ] + }, + "Role": { + "type": "object", + "description": "A system role that can be assigned to users via LDAP group mappings.", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique role identifier (UUID)", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "role_name": { + "type": "string", + "description": "Human-readable role name", + "example": "admin" + } + }, + "required": [ + "id", + "role_name" + ] + }, + "AuthZRole": { + "type": "object", + "description": "Role object returned by the authorization feature endpoints.", + "properties": { + "id": { + "type": "string", + "description": "Unique role identifier", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "role_name": { + "type": "string", + "description": "Human-readable role name", + "example": "admin" + } + }, + "required": [ + "id", + "role_name" + ] + }, + "CurrentUserPermissionsResponse": { + "type": "object", + "description": "Permissions granted to the currently authenticated user.", + "properties": { + "user_id": { + "type": "string", + "description": "Authenticated user ID from the F5 JWT", + "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" + }, + "role_id": { + "type": "string", + "description": "F5 Insight role ID from the F5 JWT", + "example": "550e8400-e29b-41d4-a716-446655440001" + }, + "role_name": { + "type": "string", + "description": "Human-readable F5 Insight role name", + "example": "Operator" + }, + "permissions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Flat, sorted list of permissions granted to the role", + "example": [ + "deviceManagement.get", + "dashboards.get", + "dashboards.post", + "telemetry.get" + ] + }, + "grouped_permissions": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": "Permissions grouped by feature/resource name", + "example": { + "deviceManagement": [ + "get" + ], + "dashboards": [ + "get", + "post" + ], + "telemetry": [ + "get" + ] + } + } + }, + "required": [ + "user_id", + "role_id", + "role_name", + "permissions", + "grouped_permissions" + ] + }, + "GroupRoleMapping": { + "type": "object", + "description": "Groups identity-provider resource attribute values by provider and F5\nInsight role. The database stores one row per value, but the API exposes\nthe role's configured values as an array for the frontend.\n", + "properties": { + "provider_id": { + "type": "string", + "description": "Identity provider ID", + "example": "ldap-id-123" + }, + "grouped_resource_attribute": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Group/resource attribute values mapped to this role", + "example": [ + "bigip-admins", + "network-operators" + ] + }, + "role_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the assigned F5 Insight role", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "role": { + "$ref": "#/components/schemas/Role", + "description": "Populated role object" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp (ISO 8601)" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Last update timestamp (ISO 8601)" + }, + "created_by": { + "type": "string", + "description": "User ID of the admin who created this mapping", + "nullable": true + }, + "updated_by": { + "type": "string", + "description": "User ID of the admin who last updated this mapping", + "nullable": true + } + }, + "required": [ + "provider_id", + "grouped_resource_attribute", + "role_id" + ] + }, + "AuthZGroupMappingResponse": { + "type": "object", + "description": "Group mapping response returned by the authorization feature endpoints.\nIt matches authZ/models.GroupMappingResponse.\n", + "properties": { + "provider_id": { + "type": "string", + "description": "Identity provider ID", + "example": "ldap-id-123" + }, + "role_id": { + "type": "string", + "description": "F5 Insight role ID", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "role": { + "$ref": "#/components/schemas/AuthZRole", + "description": "Populated role object" + }, + "grouped_resource_attribute": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Group/resource attribute values mapped to this role", + "example": [ + "bigip-admins", + "network-operators" + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp (ISO 8601)" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Last update timestamp (ISO 8601)" + }, + "created_by": { + "type": "string", + "description": "User ID of the admin who created this mapping" + }, + "updated_by": { + "type": "string", + "description": "User ID of the admin who last updated this mapping" + } + }, + "required": [ + "provider_id", + "role_id", + "role", + "grouped_resource_attribute" + ] + }, + "ProviderInUseByRoleMappingsError": { + "type": "object", + "description": "Returned when deleting an identity provider that is still referenced by role mappings.", + "properties": { + "code": { + "type": "string", + "example": "PROVIDER_IN_USE_BY_ROLE_MAPPINGS" + }, + "message": { + "type": "string", + "example": "Identity provider is used by role mappings" + }, + "status": { + "type": "integer", + "example": 409 + }, + "category": { + "type": "string", + "example": "RESOURCE" + }, + "help": { + "type": "string", + "example": "Remove role mappings for this provider before deleting it." + }, + "provider_id": { + "type": "string", + "description": "Identity provider ID that is still referenced", + "example": "ldap-id-123" + }, + "mapping_count": { + "type": "integer", + "description": "Number of stored group-role mapping rows that reference this provider", + "example": 2 + }, + "role_mappings": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GroupRoleMapping" + } + } + }, + "required": [ + "code", + "message", + "status", + "category", + "help", + "provider_id", + "mapping_count" + ] + }, + "UpsertGroupMappingRequest": { + "type": "object", + "description": "Request body for PUT/PATCH /auth/group-mappings/{role_id}.", + "properties": { + "provider_id": { + "type": "string", + "description": "Identity provider ID", + "minLength": 1, + "example": "ldap-id-123" + }, + "grouped_resource_attribute": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "description": "Group/resource attribute values to map to the role in the path", + "example": [ + "bigip-admins", + "network-operators" + ] + } + }, + "required": [ + "provider_id", + "grouped_resource_attribute" + ] + }, + "DeleteGroupMappingRequest": { + "type": "object", + "description": "Request body for DELETE /auth/group-mappings/{role_id}.", + "properties": { + "provider_id": { + "type": "string", + "description": "Identity provider ID", + "minLength": 1, + "example": "ldap-id-123" + } + }, + "required": [ + "provider_id" + ] + }, + "LDAPGroupLookupRequest": { + "type": "object", + "description": "Internal webhook request from the Zitadel action script.\nContains the authenticating user's Zitadel ID, provider ID, and resolved\ngroup/resource attribute values.\n", + "properties": { + "user_id": { + "type": "string", + "description": "Zitadel user ID of the authenticating user", + "example": "user-id-abc123" + }, + "provider_id": { + "type": "string", + "description": "Identity provider ID that authenticated the user", + "example": "ldap-id-123" + }, + "groups": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Group/resource attribute values for the user", + "example": [ + "bigip-admins", + "network-operators" + ] + } + }, + "required": [ + "user_id", + "groups" + ] + }, + "LDAPGroupLookupResponse": { + "type": "object", + "description": "Response returned to the Zitadel action script.\nThe role names can be injected as a custom claim (e.g. `x-f5-roles`) in the JWT\nby the Zitadel action.\n", + "properties": { + "roles": { + "type": "array", + "items": { + "type": "string" + }, + "description": "F5 Insight role names mapped from the user's LDAP groups", + "example": [ + "admin", + "operator" + ] + } + }, + "required": [ + "roles" + ] + }, + "Error": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "code": { + "type": "string" + } + } + }, + "LDAPAttributeMapping": { + "type": "object", + "required": [ + "id", + "username", + "email", + "first_name", + "last_name", + "display_name" + ], + "properties": { + "id": { + "type": "string", + "example": "uid" + }, + "username": { + "type": "string", + "example": "uid" + }, + "email": { + "type": "string", + "example": "mail" + }, + "first_name": { + "type": "string", + "example": "givenName" + }, + "last_name": { + "type": "string", + "example": "sn" + }, + "display_name": { + "type": "string", + "example": "displayName" + } + } + }, + "LDAPConfig": { + "type": "object", + "required": [ + "servers", + "base_dn", + "bind_dn", + "bind_password", + "user_base", + "user_object_classes", + "user_unique_attribute", + "attributes" + ], + "properties": { + "servers": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "ldaps://ldap.company.com:636" + ] + }, + "start_tls": { + "type": "boolean", + "default": false + }, + "base_dn": { + "type": "string", + "example": "dc=company,dc=com" + }, + "bind_dn": { + "type": "string", + "example": "cn=readonly,dc=company,dc=com" + }, + "bind_password": { + "type": "string", + "example": "secret123", + "description": "Required on CREATE and validate. Optional on UPDATE (omit to keep the existing password)." + }, + "user_base": { + "type": "string", + "example": "ou=people" + }, + "user_object_classes": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "inetOrgPerson" + ], + "description": "One or more LDAP object classes used to filter users (e.g. ['inetOrgPerson'])." + }, + "user_unique_attribute": { + "type": "string", + "example": "uid" + }, + "user_filters": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "uid", + "objectClass=inetOrgPerson" + ], + "description": "List of LDAP filter entries used during user lookup. Include the login attribute (e.g. 'uid') and any additional filters (e.g. 'objectClass=inetOrgPerson')." + }, + "attributes": { + "$ref": "#/components/schemas/LDAPAttributeMapping" + }, + "timeout": { + "type": "integer", + "default": 0, + "example": 0, + "description": "Timeout in seconds. 0 or omitted lets the identity provider service apply its default." + }, + "ca_certificate_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "Optional trust-store CA certificate used to verify LDAP StartTLS or LDAPS server certificates." + } + } + }, + "CreateLDAPProviderRequest": { + "type": "object", + "required": [ + "name", + "ldap_config" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 200, + "example": "Corporate LDAP", + "description": "1-200 characters. Must be unique." + }, + "enabled": { + "type": "boolean", + "description": "**Ignored by the server.** New LDAP providers are created inactive.\nUse the activate endpoint to enable a provider for login.\n" + }, + "ldap_config": { + "$ref": "#/components/schemas/LDAPConfig" + } + } + }, + "UpdateLDAPProviderRequest": { + "type": "object", + "required": [ + "name", + "ldap_config" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 200, + "example": "Corporate LDAP", + "description": "1-200 characters. Must be unique." + }, + "enabled": { + "type": "boolean" + }, + "ldap_config": { + "$ref": "#/components/schemas/LDAPConfig" + } + } + }, + "SAMLConfig": { + "type": "object", + "required": [ + "metadata_source" + ], + "properties": { + "metadata_source": { + "type": "string", + "enum": [ + "url", + "xml" + ], + "description": "Whether metadata is provided by URL or raw XML" + }, + "metadata_url": { + "type": "string", + "description": "URL of the SAML IdP metadata XML document" + }, + "metadata_xml": { + "type": "string", + "description": "Base64-encoded SAML IdP metadata XML" + }, + "binding": { + "type": "string", + "enum": [ + "post", + "redirect", + "artifact" + ], + "default": "post" + }, + "with_signed_request": { + "type": "boolean", + "default": true, + "description": "Whether to sign AuthnRequests sent to the IdP" + } + } + }, + "CreateSAMLProviderRequest": { + "type": "object", + "required": [ + "name", + "saml_config" + ], + "properties": { + "name": { + "type": "string" + }, + "enabled": { + "type": "boolean", + "default": true + }, + "saml_config": { + "$ref": "#/components/schemas/SAMLConfig" + } + } + }, + "UpdateSAMLProviderRequest": { + "type": "object", + "required": [ + "name", + "saml_config" + ], + "properties": { + "name": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "saml_config": { + "$ref": "#/components/schemas/SAMLConfig" + } + } + }, + "SAMLResponseConfig": { + "type": "object", + "description": "SAML configuration returned in GET responses.", + "properties": { + "metadata_xml": { + "type": "string", + "description": "Base64-encoded SAML Identity Provider (IdP) metadata XML" + }, + "binding": { + "type": "string", + "enum": [ + "post", + "redirect", + "artifact" + ] + }, + "with_signed_request": { + "type": "boolean", + "description": "Whether AuthnRequests sent to the IdP are signed" + }, + "zitadel_metadata_url": { + "type": "string", + "format": "uri", + "description": "Metadata URL - use this as the Entity ID in your IdP configuration", + "readOnly": true + }, + "zitadel_acs_url": { + "type": "string", + "format": "uri", + "description": "Assertion Consumer Service (ACS) URL - use this as the Single Sign-On URL in your IdP configuration", + "readOnly": true + }, + "zitadel_slo_url": { + "type": "string", + "format": "uri", + "description": "Single Logout (SLO) URL - use this as the Single Logout URL in your IdP configuration", + "readOnly": true + } + } + }, + "IdentityProviderResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "provider_type": { + "type": "string", + "enum": [ + "ldap", + "saml" + ] + }, + "enabled": { + "type": "boolean" + }, + "ldap_config": { + "$ref": "#/components/schemas/LDAPConfig", + "nullable": true + }, + "saml_config": { + "$ref": "#/components/schemas/SAMLResponseConfig", + "nullable": true + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "last_sync": { + "type": "string", + "format": "date-time", + "nullable": true + } + } + }, + "ListIdentityProvidersResponse": { + "type": "object", + "properties": { + "providers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IdentityProviderResponse" + } + }, + "local_login_enabled": { + "type": "boolean" + }, + "total_count": { + "type": "integer" + } + } + }, + "PublicProviderInfo": { + "type": "object", + "description": "Minimal provider summary returned to unauthenticated callers.", + "properties": { + "id": { + "type": "string", + "description": "Zitadel identity provider ID" + }, + "name": { + "type": "string", + "description": "Provider display name" + }, + "provider_type": { + "type": "string", + "enum": [ + "ldap", + "saml" + ] + }, + "enabled": { + "type": "boolean" + } + }, + "required": [ + "id", + "name", + "provider_type", + "enabled" + ] + }, + "PublicListIdentityProvidersResponse": { + "type": "object", + "description": "Public login-page provider list returned without authentication.", + "properties": { + "providers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PublicProviderInfo" + } + }, + "local_login_enabled": { + "type": "boolean" + }, + "total_count": { + "type": "integer" + } + }, + "required": [ + "providers", + "local_login_enabled", + "total_count" + ] + }, + "DeleteIdentityProviderResponse": { + "type": "object", + "description": "Response body returned after deleting an identity provider.", + "properties": { + "status": { + "type": "string", + "example": "success" + }, + "message": { + "type": "string", + "example": "Identity provider 'corp-ldap' deleted successfully" + }, + "id": { + "type": "string", + "description": "Deleted identity provider ID" + } + }, + "required": [ + "status", + "message", + "id" + ] + }, + "ValidateProviderDetails": { + "type": "object", + "properties": { + "connection_successful": { + "type": "boolean" + }, + "bind_successful": { + "type": "boolean" + }, + "user_search_successful": { + "type": "boolean" + }, + "users_found": { + "type": "integer", + "description": "Number of LDAP user entries returned by the validation search." + }, + "group_search_successful": { + "type": "boolean", + "description": "Whether LDAP group discovery succeeded during validation." + }, + "group_search_base": { + "type": "string", + "description": "LDAP base DN used to discover groups during validation." + }, + "groups_found": { + "type": "integer", + "description": "Number of LDAP groups returned by group discovery." + }, + "groups": { + "type": "array", + "description": "LDAP group CN values returned by group discovery.", + "items": { + "type": "string" + } + } + } + }, + "ValidateProviderRequest": { + "type": "object", + "required": [ + "provider_type" + ], + "properties": { + "provider_type": { + "type": "string", + "enum": [ + "ldap", + "saml" + ] + }, + "provider_id": { + "type": "string", + "description": "Optional. Set when validating an existing provider (edit / \"Check Connection\" flow). When provider_id is set and bind_password is omitted, the API returns a clear error because stored passwords are never returned; the user must re-enter bind_password.\n" + }, + "ldap_config": { + "$ref": "#/components/schemas/LDAPConfig", + "nullable": true + } + } + }, + "ValidateProviderResponse": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "validation_success", + "validation_error" + ] + }, + "error": { + "type": "string", + "nullable": true + }, + "details": { + "$ref": "#/components/schemas/ValidateProviderDetails" + } + } + }, + "OpenAPIResponse": { + "type": "object", + "properties": { + "openapi": { + "type": "string" + }, + "info": { + "type": "object", + "additionalProperties": true + }, + "paths": { + "type": "object", + "additionalProperties": true + }, + "components": { + "type": "object", + "additionalProperties": true + } + } + }, + "ErrorResponse": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "SimpleErrorResponse": { + "type": "object", + "description": "Simple error response returned by handlers that write an error string.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + }, + "SystemHealthResponse": { + "type": "object", + "required": [ + "cpu", + "memory", + "disk" + ], + "properties": { + "cpu": { + "type": "number", + "format": "float", + "description": "CPU usage percentage (0-100)", + "example": 45.5 + }, + "memory": { + "type": "number", + "format": "float", + "description": "Memory usage percentage (0-100)", + "example": 67.2 + }, + "disk": { + "type": "number", + "format": "float", + "description": "Disk usage percentage (0-100)", + "example": 82.1 + }, + "disk_total_gb": { + "type": "number", + "format": "float", + "description": "Total disk size in GB", + "example": 600 + }, + "services": { + "type": "array", + "description": "Health status of backend services (future)", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "healthy", + "degraded", + "unhealthy" + ] + } + } + } + } + } + }, + "SystemRoleResponse": { + "type": "object", + "required": [ + "node_id", + "node_name", + "status", + "role" + ], + "properties": { + "node_id": { + "type": "string", + "description": "Unique identifier for the node", + "example": "standby-node-uuid" + }, + "node_name": { + "type": "string", + "description": "Name of the node", + "example": "node-2" + }, + "status": { + "type": "string", + "description": "Current status of the node", + "enum": [ + "active", + "inactive", + "unknown" + ], + "example": "active" + }, + "role": { + "type": "string", + "description": "Role of the node in the cluster", + "enum": [ + "primary", + "standby", + "unknown" + ], + "example": "primary" + } + } + }, + "StatusResponse": { + "type": "object", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "validation_success", + "validation_error", + "save_successful", + "save_error", + "internal_error", + "healthy", + "unhealthy" + ] + } + } + }, + "BigIPQueryRequest": { + "type": "object", + "required": [ + "device", + "endpoint" + ], + "properties": { + "device": { + "type": "string", + "description": "Device name" + }, + "endpoint": { + "type": "string", + "description": "API endpoint path" + } + } + }, + "BigIPQueryResponse": { + "type": "object", + "additionalProperties": true, + "description": "Dynamic response from BigIP device" + }, + "ClickHouseQueryRequest": { + "type": "object", + "required": [ + "query" + ], + "properties": { + "query": { + "type": "string", + "description": "ClickHouse SQL query" + } + } + }, + "ClickHouseQueryResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true + } + }, + "error": { + "type": "string" + }, + "status": { + "type": "string" + }, + "columns": { + "type": "array", + "items": { + "type": "string" + } + }, + "row_count": { + "type": "integer" + }, + "column_types": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "ConfigAIProviderRequest": { + "type": "object", + "required": [ + "provider_name" + ], + "properties": { + "provider_name": { + "type": "string", + "description": "AI provider name (e.g., openai, anthropic, local)" + }, + "api_token": { + "type": "string", + "description": "API token for the provider. Required for 'openai' and 'claude' providers, optional for 'local' provider." + }, + "base_url": { + "type": "string", + "description": "Base URL for the provider. Required for 'local' provider, optional for 'openai' and 'claude'." + }, + "model": { + "type": "string", + "description": "Model name to use. Required for 'local' provider, optional for others." + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "Optional CA certificate UUID from trust store for custom SSL/TLS connections" + }, + "skip_tls_verify": { + "type": "boolean", + "description": "Indicates if TLS verification should be skipped for this provider" + } + } + }, + "AIProviderResponse": { + "type": "object", + "properties": { + "provider_name": { + "type": "string" + }, + "base_url": { + "type": "string" + }, + "model": { + "type": "string" + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "Optional CA certificate UUID from trust store for custom SSL/TLS connections" + }, + "skip_tls_verify": { + "type": "boolean", + "description": "Indicates if TLS verification is skipped" + } + } + }, + "ConfigAIDFRequest": { + "type": "object", + "required": [ + "endpoint", + "tenant_id", + "tenant_token" + ], + "properties": { + "endpoint": { + "type": "string", + "description": "AIDF endpoint URL" + }, + "tenant_id": { + "type": "string", + "description": "Tenant ID" + }, + "tenant_token": { + "type": "string", + "description": "Tenant authentication token" + }, + "data_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "logs", + "metrics" + ] + }, + "description": "Data types to send to AIDF (logs, metrics, or both). Defaults to [\"logs\", \"metrics\"] if not specified. Cannot be an empty array.", + "example": [ + "logs", + "metrics" + ], + "default": [ + "logs", + "metrics" + ], + "minItems": 1 + } + } + }, + "AIDFConfigResponse": { + "type": "object", + "properties": { + "endpoint": { + "type": "string" + }, + "tenant_id": { + "type": "string" + }, + "data_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "logs", + "metrics" + ] + }, + "description": "Data types being sent to AIDF" + } + } + }, + "InsightFeedItem": { + "type": "object", + "description": "Flattened security insight for frontend display", + "required": [ + "id", + "title", + "message", + "severity", + "category", + "deviceName", + "host", + "virtualServer", + "firstDetected" + ], + "properties": { + "id": { + "type": "string", + "example": "sec-001" + }, + "title": { + "type": "string", + "example": "Content Security Policy Missing" + }, + "message": { + "type": "string", + "example": "The Content-Security-Policy header is not configured for host legacy-app.corp.example.com" + }, + "severity": { + "type": "string", + "enum": [ + "critical", + "high", + "medium", + "low", + "info" + ], + "example": "medium" + }, + "category": { + "type": "string", + "example": "Header" + }, + "deviceName": { + "type": "string", + "example": "bigip-nyc-01.example.com" + }, + "host": { + "type": "string", + "example": "legacy-app.corp.example.com" + }, + "virtualServer": { + "type": "string", + "example": "/Common/vs_web_80" + }, + "firstDetected": { + "type": "string", + "format": "date-time", + "example": "2026-02-02T08:09:00Z" + } + } + }, + "ClassificationFeedItem": { + "type": "object", + "description": "Flattened workload classification insight for frontend display", + "required": [ + "id", + "title", + "description", + "severity", + "status", + "category", + "deviceName", + "host", + "virtualServer", + "firstDetected", + "confidence", + "appCategory", + "appSubcategory", + "matchedRule" + ], + "properties": { + "id": { + "type": "string", + "example": "app-001" + }, + "title": { + "type": "string", + "example": "E-Commerce Application - Payment Gateway" + }, + "description": { + "type": "string", + "example": "High-value e-commerce application with PCI-DSS compliance requirements" + }, + "severity": { + "type": "string", + "enum": [ + "critical", + "high", + "medium", + "low", + "info" + ], + "example": "high" + }, + "status": { + "type": "string", + "enum": [ + "open", + "acknowledged", + "resolved" + ], + "example": "open" + }, + "category": { + "type": "string", + "example": "Application Discovery" + }, + "deviceName": { + "type": "string", + "example": "bigip-nyc-01.example.com" + }, + "host": { + "type": "string", + "example": "checkout.retailstore.example.com" + }, + "virtualServer": { + "type": "string", + "example": "/Common/vs_ecommerce_443" + }, + "firstDetected": { + "type": "string", + "format": "date-time", + "example": "2026-01-15T09:15:00Z" + }, + "confidence": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 1, + "example": 0.97, + "description": "Classification confidence score (0-1)" + }, + "appCategory": { + "type": "string", + "example": "E-Commerce", + "description": "Classified application category" + }, + "appSubcategory": { + "type": "string", + "example": "Payment Processing", + "description": "Classified application subcategory" + }, + "matchedRule": { + "type": "string", + "example": "Payment Gateway with PCI Compliance Indicators", + "description": "The classification rule that matched" + } + } + }, + "FeatureFlag": { + "type": "object", + "description": "A feature flag with name and value", + "properties": { + "featureName": { + "type": "string", + "description": "Name of the feature", + "example": "perf_SSL_Mbps" + }, + "featureValue": { + "type": "string", + "description": "Value of the feature (can be numeric or \"enabled\"/\"disabled\")", + "example": "2000" + } + } + }, + "FeatureFlagsListResponse": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/FeatureFlag" + } + }, + "UpdateFeatureFlagRequest": { + "type": "object", + "required": [ + "name", + "enabled" + ], + "properties": { + "name": { + "type": "string" + }, + "enabled": { + "type": "boolean" + } + } + }, + "ServiceHealthResponse": { + "type": "object", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "healthy", + "unhealthy" + ] + }, + "error": { + "type": "string" + } + } + }, + "TokenRequest": { + "type": "object", + "required": [ + "selectedDevices" + ], + "properties": { + "selectedDevices": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "description": "List of selected device names" + } + } + }, + "PaginationParams": { + "type": "object", + "description": "Common pagination parameters for paginated requests", + "properties": { + "page": { + "type": "integer", + "description": "Page number (1-based)", + "minimum": 1 + }, + "page_size": { + "type": "integer", + "description": "Number of results per page", + "minimum": 1, + "maximum": 1000 + }, + "offset": { + "type": "integer", + "description": "Offset for pagination (alternative to page)", + "minimum": 0 + }, + "limit": { + "type": "integer", + "description": "Maximum number of results to return", + "minimum": 1, + "maximum": 10000 + } + } + }, + "SortingParams": { + "type": "object", + "description": "Common sorting parameters", + "properties": { + "sort_by": { + "type": "string", + "description": "Field name to sort results by" + }, + "sort_order": { + "type": "string", + "enum": [ + "asc", + "desc" + ], + "description": "Sort order (ascending or descending)" + } + } + }, + "LabelFilterParams": { + "type": "object", + "description": "Common label filtering parameters for Prometheus queries", + "properties": { + "label_filters": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Filter by label key-value pairs (exact match)" + }, + "label_match": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": "Match any of the values for a label" + } + } + }, + "QueryPaginationParams": { + "description": "Combined pagination, sorting, and label filtering for query requests", + "allOf": [ + { + "$ref": "#/components/schemas/PaginationParams" + }, + { + "$ref": "#/components/schemas/SortingParams" + }, + { + "$ref": "#/components/schemas/LabelFilterParams" + } + ] + }, + "QueryRequest": { + "description": "Request for instant Prometheus queries with pagination and filtering", + "allOf": [ + { + "type": "object", + "required": [ + "query" + ], + "properties": { + "query": { + "type": "string", + "description": "PromQL query string" + } + } + }, + { + "$ref": "#/components/schemas/QueryPaginationParams" + } + ] + }, + "QueryRangeRequest": { + "description": "Request for range Prometheus queries with time bounds, pagination and filtering", + "allOf": [ + { + "type": "object", + "required": [ + "query", + "start", + "end", + "step" + ], + "properties": { + "query": { + "type": "string", + "description": "PromQL query string" + }, + "start": { + "type": "integer", + "description": "Start timestamp" + }, + "end": { + "type": "integer", + "description": "End timestamp" + }, + "step": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ], + "description": "Query resolution step" + } + } + }, + { + "$ref": "#/components/schemas/QueryPaginationParams" + } + ] + }, + "LabelsRequest": { + "description": "Request for label queries with optional time bounds, pagination and sorting", + "allOf": [ + { + "type": "object", + "required": [ + "query" + ], + "properties": { + "query": { + "type": "string", + "description": "Label selector query" + }, + "start": { + "type": "integer", + "format": "int64", + "nullable": true, + "description": "Start timestamp for the query range" + }, + "end": { + "type": "integer", + "format": "int64", + "nullable": true, + "description": "End timestamp for the query range" + } + } + }, + { + "$ref": "#/components/schemas/PaginationParams" + }, + { + "$ref": "#/components/schemas/SortingParams" + } + ] + }, + "PrometheusResponse": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "data": { + "type": "object", + "additionalProperties": true + }, + "pagination": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "description": "Current page number" + }, + "page_size": { + "type": "integer", + "description": "Number of results per page" + }, + "total_items": { + "type": "integer", + "description": "Total number of items" + }, + "total_pages": { + "type": "integer", + "description": "Total number of pages" + }, + "has_more": { + "type": "boolean", + "description": "Whether there are more pages" + } + } + } + } + }, + "OtelLiteCollectorOverviewResponse": { + "type": "object", + "required": [ + "collected_at", + "scrape_ok", + "restarted", + "collector", + "receivers", + "exporters", + "summary" + ], + "properties": { + "collected_at": { + "type": "string", + "format": "date-time" + }, + "scrape_ok": { + "type": "boolean" + }, + "restarted": { + "type": "boolean" + }, + "collector": { + "$ref": "#/components/schemas/OtelLiteCollectorStats" + }, + "summary": { + "$ref": "#/components/schemas/OtelLiteSummaryStats" + }, + "receivers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OtelLiteReceiverStats" + } + }, + "exporters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OtelLiteExporterStats" + } + }, + "processors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OtelLiteProcessorStats" + } + } + } + }, + "OtelLiteCollectorStats": { + "type": "object", + "properties": { + "cpu_seconds_total": { + "type": "number", + "format": "double" + }, + "memory_rss_bytes": { + "type": "number", + "format": "double" + }, + "uptime_seconds_total": { + "type": "number", + "format": "double" + }, + "cpu_pct_last_interval": { + "type": "number", + "format": "double", + "nullable": true + }, + "memory_mib": { + "type": "number", + "format": "double" + } + } + }, + "OtelLiteReceiverStats": { + "type": "object", + "required": [ + "name", + "status" + ], + "properties": { + "name": { + "type": "string", + "description": "Receiver name (e.g. syslog/sslo_logs_udp_514)" + }, + "transport": { + "type": "string", + "description": "Transport protocol (e.g. udp, tcp, tcp+tls)" + }, + "accepted_total": { + "type": "integer", + "format": "int64" + }, + "refused_total": { + "type": "integer", + "format": "int64" + }, + "failed_total": { + "type": "integer", + "format": "int64" + }, + "accepted_delta": { + "type": "integer", + "format": "int64" + }, + "refused_delta": { + "type": "integer", + "format": "int64" + }, + "failed_delta": { + "type": "integer", + "format": "int64" + }, + "success_rate_pct": { + "type": "number", + "format": "double", + "nullable": true, + "description": "Success rate percentage for this interval" + }, + "status": { + "type": "string", + "enum": [ + "ACTIVE", + "IDLE", + "DEGRADED" + ] + } + } + }, + "OtelLiteExporterStats": { + "type": "object", + "required": [ + "name", + "status" + ], + "properties": { + "name": { + "type": "string", + "description": "Exporter name (e.g. otlp/f5-datafabric)" + }, + "type": { + "type": "string", + "description": "Exporter type (e.g. otlp, clickhouse, debug)" + }, + "destination": { + "type": "string", + "description": "Human-readable destination name" + }, + "sent_total": { + "type": "integer", + "format": "int64" + }, + "send_failed_total": { + "type": "integer", + "format": "int64" + }, + "enqueue_failed_total": { + "type": "integer", + "format": "int64" + }, + "sent_delta": { + "type": "integer", + "format": "int64" + }, + "send_failed_delta": { + "type": "integer", + "format": "int64" + }, + "enqueue_failed_delta": { + "type": "integer", + "format": "int64" + }, + "success_rate_pct": { + "type": "number", + "format": "double", + "nullable": true, + "description": "Success rate percentage for this interval" + }, + "status": { + "type": "string", + "enum": [ + "ACTIVE", + "IDLE", + "DEGRADED" + ] + } + } + }, + "OtelLiteSummaryStats": { + "type": "object", + "properties": { + "total_configured_receivers": { + "type": "integer", + "format": "int64", + "description": "Total number of configured receivers (including inactive ones)" + }, + "total_bigip_receivers": { + "type": "integer", + "format": "int64", + "description": "Number of BigIP-related receivers (f5_bigip_*)" + }, + "total_configured_exporters": { + "type": "integer", + "format": "int64", + "description": "Total number of configured exporters" + }, + "debug_exporters_count": { + "type": "integer", + "format": "int64", + "description": "Number of debug exporters" + }, + "bigip_exporters_count": { + "type": "integer", + "format": "int64", + "description": "Number of BigIP-specific exporters" + } + } + }, + "OtelLiteProcessorStats": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string", + "description": "Processor name (e.g. batch/logs)" + }, + "type": { + "type": "string", + "description": "Processor type (e.g. batch, memory_limiter)" + }, + "accepted_total": { + "type": "integer", + "format": "int64" + }, + "refused_total": { + "type": "integer", + "format": "int64" + }, + "dropped_total": { + "type": "integer", + "format": "int64" + }, + "accepted_delta": { + "type": "integer", + "format": "int64" + }, + "refused_delta": { + "type": "integer", + "format": "int64" + }, + "dropped_delta": { + "type": "integer", + "format": "int64" + }, + "batch_size_avg": { + "type": "number", + "format": "double", + "nullable": true, + "description": "Average batch size (batch processor only)" + }, + "batch_send_size_avg": { + "type": "number", + "format": "double", + "nullable": true, + "description": "Average batch send size (batch processor only)" + } + } + }, + "DeviceStatsRequest": { + "type": "object", + "properties": { + "device_name": { + "type": "string", + "default": "" + }, + "is_all_devices": { + "type": "boolean", + "default": false + }, + "page": { + "type": "integer", + "default": 0 + } + } + }, + "RangeQueryResponse": { + "type": "object", + "properties": { + "min": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ] + }, + "max": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ] + }, + "avg": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ] + }, + "current": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ] + } + } + }, + "DeviceStatsResponse": { + "type": "object", + "properties": { + "device_name": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "Up", + "Down", + "Unknown" + ] + }, + "cpu_stats": { + "$ref": "#/components/schemas/RangeQueryResponse" + }, + "memory_stats": { + "$ref": "#/components/schemas/RangeQueryResponse" + } + } + }, + "ListVirtualServersRequest": { + "type": "object", + "properties": { + "device_name": { + "type": "string", + "default": "" + }, + "is_all_devices": { + "type": "boolean", + "default": false + }, + "page": { + "type": "integer", + "default": 0 + } + } + }, + "ListVirtualServersResponse": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "VirtualServerStatsRequest": { + "type": "object", + "properties": { + "device_name": { + "type": "string", + "default": "" + }, + "virtual_server_name": { + "type": "string", + "default": "" + }, + "is_all_devices": { + "type": "boolean", + "default": false + }, + "page": { + "type": "integer", + "default": 0 + } + } + }, + "ListPoolsRequest": { + "type": "object", + "properties": { + "device_name": { + "type": "string", + "default": "" + }, + "is_all_devices": { + "type": "boolean", + "default": false + }, + "page": { + "type": "integer", + "default": 0 + } + } + }, + "ListPoolsResponse": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "PoolsStatsRequest": { + "type": "object", + "properties": { + "device_name": { + "type": "string", + "default": "" + }, + "pool_name": { + "type": "string", + "default": "" + }, + "is_all_devices": { + "type": "boolean", + "default": false + }, + "page": { + "type": "integer", + "default": 0 + } + } + }, + "WAFIncidentListRequest": { + "type": "object", + "properties": { + "device_name": { + "type": "string", + "default": "" + }, + "is_all_devices": { + "type": "boolean", + "default": false + }, + "page": { + "type": "integer", + "default": 0 + } + } + }, + "WAFEventSummaryRequest": { + "type": "object", + "properties": { + "device_name": { + "type": "string", + "default": "" + }, + "time_period_in_days": { + "type": "integer", + "default": 7 + }, + "is_all_devices": { + "type": "boolean", + "default": false + }, + "page": { + "type": "integer", + "default": 0 + } + } + }, + "BigIPHeapStatusRequest": { + "type": "object", + "properties": { + "device_name": { + "type": "string", + "default": "", + "description": "Specific BIG-IP device. Mutually exclusive with data_center." + }, + "data_center": { + "type": "string", + "default": "", + "description": "Datacenter name. Returns status for every device in it." + } + } + }, + "ApplyBigIPHeapTuningRequest": { + "type": "object", + "required": [ + "device_name", + "confirm_restart" + ], + "properties": { + "device_name": { + "type": "string", + "description": "BIG-IP device to tune." + }, + "extra_mb": { + "type": "integer", + "default": 0, + "description": "Override for provision.extramb (MB). 0 means use recommended (2048)." + }, + "tomcat_extra_mb": { + "type": "integer", + "default": 0, + "description": "Override for provision.tomcat.extramb (MB). 0 means use recommended (256)." + }, + "confirm_restart": { + "type": "boolean", + "default": false, + "description": "MUST be true. Acknowledges restjavad will be restarted (~60s outage)." + } + } + }, + "ListConnectionPoliciesRequest": { + "type": "object", + "properties": { + "device_name": { + "type": "string", + "default": "" + }, + "is_all_devices": { + "type": "boolean", + "default": false + }, + "page": { + "type": "integer", + "default": 0 + } + } + }, + "VirtualServerConnectionPolicyRequest": { + "type": "object", + "required": [ + "device_name", + "virtual_server_name" + ], + "properties": { + "device_name": { + "type": "string" + }, + "virtual_server_name": { + "type": "string" + } + } + }, + "NetworkTopologyRequest": { + "type": "object", + "properties": { + "device_name": { + "type": "string", + "default": "" + }, + "include_disabled": { + "type": "boolean", + "default": false + } + } + }, + "ToolsListResponse": { + "type": "object", + "properties": { + "tools": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true + } + } + } + }, + "ValidateAIProviderRequest": { + "type": "object", + "required": [ + "provider_name" + ], + "properties": { + "provider_name": { + "type": "string", + "description": "AI provider name (e.g., openai, claude, local)" + }, + "api_token": { + "type": "string", + "description": "API token for the provider. Required for 'openai' and 'claude' providers, optional for 'local' provider." + }, + "base_url": { + "type": "string", + "description": "Base URL for the provider. Required for 'local' provider, optional for 'openai' and 'claude'." + }, + "model": { + "type": "string", + "description": "Model name to use. Required for 'local' provider, optional for others." + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "Optional CA certificate UUID from trust store" + }, + "skip_tls_verify": { + "type": "boolean", + "description": "Indicates if TLS verification should be skipped for this provider" + } + } + }, + "ValidateAIDFRequest": { + "type": "object", + "required": [ + "endpoint", + "tenant_id", + "tenant_token" + ], + "properties": { + "endpoint": { + "type": "string" + }, + "tenant_id": { + "type": "string" + }, + "tenant_token": { + "type": "string" + } + } + }, + "ValidationResponse": { + "type": "object", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "validation_success", + "validation_error", + "internal_error" + ] + }, + "error": { + "type": "string" + } + } + }, + "LicenseHealthResponse": { + "type": "object", + "required": [ + "status", + "license", + "storage" + ], + "properties": { + "status": { + "$ref": "#/components/schemas/ServiceStatus" + }, + "license": { + "$ref": "#/components/schemas/LicenseInfo" + }, + "storage": { + "$ref": "#/components/schemas/StorageInfo" + } + } + }, + "ServiceStatus": { + "type": "object", + "required": [ + "health", + "message", + "errors" + ], + "properties": { + "health": { + "type": "string", + "enum": [ + "green", + "yellow", + "red" + ], + "description": "Overall system health determined by used_percent thresholds (green <75%, yellow 75\u201390%, red >90%)", + "example": "green" + }, + "message": { + "type": "string", + "description": "Additional details about the present license status of the device", + "example": "Activation service healthy" + }, + "errors": { + "type": "array", + "items": { + "type": "string" + }, + "description": "If any occurred while licensing the device", + "example": [] + } + } + }, + "LicenseInfo": { + "type": "object", + "required": [ + "activation_timestamp", + "license_sub_status", + "status", + "expiry_date", + "mode_of_operation" + ], + "properties": { + "activation_timestamp": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the license was registered/activated", + "example": "2025-12-03T07:18:11Z" + }, + "license_sub_status": { + "type": "string", + "description": "Activation status", + "example": "Active" + }, + "status": { + "type": "string", + "enum": [ + "Invalid", + "Active", + "Terminated", + "Unlicensed" + ], + "description": "Invalid/Active/Terminated/Unlicensed etc...", + "example": "Active" + }, + "expiry_date": { + "type": "string", + "format": "date-time", + "description": "License subscription expiry date", + "example": "2026-11-29T00:00:32Z" + }, + "telemetry_status": { + "type": "string", + "description": "Telemetry status", + "example": "Enabled" + }, + "telemetry_last_verified": { + "type": "string", + "format": "date-time", + "description": "Last telemetry verification timestamp", + "example": "2025-12-10T05:12:45Z" + }, + "telemetry_error": { + "type": "string", + "description": "Telemetry error message if any", + "example": "if any error while sending telemetry" + }, + "mode_of_operation": { + "type": "string", + "description": "Mode of operation", + "enum": [ + "connected", + "disconnected" + ] + } + } + }, + "StorageInfo": { + "type": "object", + "required": [ + "used_percent", + "used_gb", + "entitled_gb" + ], + "properties": { + "used_percent": { + "type": "number", + "format": "float", + "description": "Percentage of storage currently consumed", + "example": 15.7 + }, + "used_gb": { + "type": "integer", + "description": "Actual used storage in gigabytes", + "example": 500 + }, + "entitled_gb": { + "type": "integer", + "description": "Licensed storage capacity allowed", + "example": 300 + } + } + }, + "LoginRequest": { + "type": "object", + "required": [ + "username", + "password" + ], + "properties": { + "username": { + "type": "string", + "example": "admin", + "description": "Username for authentication" + }, + "password": { + "type": "string", + "format": "password", + "example": "password123", + "description": "User password" + } + } + }, + "ChangePasswordRequest": { + "type": "object", + "required": [ + "username", + "old_password", + "new_password" + ], + "properties": { + "username": { + "type": "string", + "example": "admin", + "description": "Username" + }, + "old_password": { + "type": "string", + "format": "password", + "example": "oldpassword123", + "description": "Current password" + }, + "new_password": { + "type": "string", + "format": "password", + "example": "newpassword123", + "description": "New password" + } + } + }, + "TokenResponse": { + "type": "object", + "required": [ + "access_token", + "token_type", + "expires_in" + ], + "properties": { + "access_token": { + "type": "string", + "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "description": "JWT access token (short-lived)" + }, + "token_type": { + "type": "string", + "example": "Bearer", + "description": "Token type (always Bearer)" + }, + "expires_in": { + "type": "integer", + "format": "int64", + "example": 900, + "description": "Access token expiration time in seconds" + } + }, + "description": "Login and refresh responses. Refresh token is now sent as httpOnly cookie\nfor security (not in JSON response).\n" + }, + "OIDCSessionResponse": { + "type": "object", + "required": [ + "access_token", + "token_type", + "expires_in" + ], + "properties": { + "access_token": { + "type": "string", + "description": "F5 Insight access token returned after external login" + }, + "id_token": { + "type": "string", + "description": "Optional OIDC ID token when returned by the server" + }, + "refresh_token": { + "type": "string", + "description": "Optional refresh token when returned by the server" + }, + "token_type": { + "type": "string", + "example": "Bearer" + }, + "expires_in": { + "type": "integer", + "format": "int64", + "description": "Access token lifetime in seconds" + } + }, + "description": "Session token response returned by GET /api/auth/session after the\nauthorization code flow with PKCE.\n" + }, + "RefreshTokenRequest": { + "type": "object", + "required": [ + "refresh_token" + ], + "properties": { + "refresh_token": { + "type": "string", + "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "description": "REFRESH TOKEN from login response.\nSend this in REQUEST BODY only (not in Authorization header).\nThis endpoint returns a new access + refresh token pair.\n" + } + } + }, + "LogoutRequest": { + "type": "object", + "required": [ + "refresh_token" + ], + "properties": { + "refresh_token": { + "type": "string", + "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "description": "Refresh token to revoke" + } + } + }, + "StorageMetricsResponse": { + "type": "object", + "required": [ + "total_storage_bytes", + "victoriametrics_storage", + "clickhouse_storage", + "timestamp" + ], + "properties": { + "total_storage_bytes": { + "type": "integer", + "description": "Total storage used by both services in bytes", + "example": 5234567890 + }, + "victoriametrics_storage": { + "type": "object", + "required": [ + "storage_bytes" + ], + "properties": { + "storage_bytes": { + "type": "integer", + "description": "Storage used by VictoriaMetrics in bytes", + "example": 1234567890 + } + } + }, + "clickhouse_storage": { + "type": "object", + "required": [ + "storage_bytes" + ], + "properties": { + "storage_bytes": { + "type": "integer", + "description": "Storage used by ClickHouse in bytes", + "example": 4000000000 + } + } + }, + "timestamp": { + "type": "string", + "format": "date-time", + "description": "When the metrics were collected", + "example": "2025-12-11T10:30:00Z" + } + } + }, + "StorageAllocationConfigRequest": { + "type": "object", + "required": [ + "clickhouse_allocation_percent", + "victoriametrics_allocation_percent" + ], + "description": "Request body for updating storage allocation config. Only accepts 4 fields - allocation percentages (mandatory) and cleanup percentages (optional). All percentages support up to 2 decimal places (e.g., 70.50).", + "properties": { + "clickhouse_allocation_percent": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 100, + "description": "Percentage of total storage allocated to ClickHouse (mandatory, must sum to 100 with victoriametrics_allocation_percent). Supports up to 2 decimal places.", + "example": 70.5 + }, + "victoriametrics_allocation_percent": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 100, + "description": "Percentage of total storage allocated to VictoriaMetrics (mandatory, must sum to 100 with clickhouse_allocation_percent). Supports up to 2 decimal places.", + "example": 29.5 + }, + "cleanup_threshold_percent": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 100, + "description": "Threshold percentage at which cleanup is triggered (optional). Supports up to 2 decimal places.", + "example": 80 + }, + "cleanup_data_percent": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 100, + "description": "Percentage of data to delete during cleanup (optional). Supports up to 2 decimal places.", + "example": 70 + } + } + }, + "StorageAllocationConfigResponse": { + "type": "object", + "required": [ + "id", + "clickhouse_allocation_percent", + "victoriametrics_allocation_percent", + "cleanup_threshold_percent", + "cleanup_data_percent", + "sslo_logs_ttl_days", + "irule_logs_ttl_days", + "victoriametrics_retention", + "created_at", + "updated_at" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Configuration ID" + }, + "clickhouse_allocation_percent": { + "type": "number", + "format": "double", + "description": "Percentage of total storage allocated to ClickHouse. Supports up to 2 decimal places.", + "example": 70.5 + }, + "victoriametrics_allocation_percent": { + "type": "number", + "format": "double", + "description": "Percentage of total storage allocated to VictoriaMetrics. Supports up to 2 decimal places.", + "example": 29.5 + }, + "cleanup_threshold_percent": { + "type": "number", + "format": "double", + "description": "Threshold percentage at which cleanup is triggered. Supports up to 2 decimal places.", + "example": 80 + }, + "cleanup_data_percent": { + "type": "number", + "format": "double", + "description": "Percentage of data to delete during cleanup. Supports up to 2 decimal places.", + "example": 70 + }, + "sslo_logs_ttl_days": { + "type": "integer", + "description": "TTL for SSLO logs in days", + "example": 7 + }, + "irule_logs_ttl_days": { + "type": "integer", + "description": "TTL for iRule logs in days", + "example": 7 + }, + "victoriametrics_retention": { + "type": "string", + "description": "VictoriaMetrics retention period", + "example": "12M" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Configuration creation timestamp" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Last update timestamp" + } + } + }, + "StorageCleanupHistory": { + "type": "object", + "required": [ + "id", + "database_name", + "storage_bytes", + "allocated_bytes", + "usage_percent", + "cleanup_triggered", + "cleanup_status", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Cleanup record ID" + }, + "database_name": { + "type": "string", + "enum": [ + "clickhouse", + "victoriametrics" + ], + "description": "Database name", + "example": "clickhouse" + }, + "storage_bytes": { + "type": "integer", + "format": "int64", + "description": "Storage usage at cleanup time in bytes", + "example": 300000000000 + }, + "allocated_bytes": { + "type": "integer", + "format": "int64", + "description": "Allocated storage in bytes", + "example": 360777252864 + }, + "usage_percent": { + "type": "number", + "format": "float", + "description": "Usage percentage at cleanup time", + "example": 83.16 + }, + "cleanup_triggered": { + "type": "boolean", + "description": "Whether cleanup was triggered", + "example": true + }, + "data_deleted_percent": { + "type": "number", + "format": "float", + "description": "Percentage of data deleted", + "example": 70 + }, + "old_ttl_days": { + "type": "integer", + "description": "Original TTL in days before cleanup", + "example": 7 + }, + "new_ttl_days": { + "type": "integer", + "description": "New TTL in days after cleanup", + "example": 2 + }, + "old_retention": { + "type": "string", + "description": "Original VictoriaMetrics retention", + "example": "12M" + }, + "new_retention": { + "type": "string", + "description": "New VictoriaMetrics retention", + "example": "3.6M" + }, + "cleanup_status": { + "type": "string", + "enum": [ + "success", + "failed", + "in_progress" + ], + "description": "Cleanup operation status", + "example": "success" + }, + "error_message": { + "type": "string", + "description": "Error message if cleanup failed" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Cleanup execution timestamp" + } + } + }, + "MessageResponse": { + "type": "object", + "properties": { + "message": { + "type": "string", + "example": "Operation successful" + } + } + }, + "PatchStagingDeviceResponse": { + "type": "object", + "required": [ + "message", + "staging_device_id" + ], + "properties": { + "message": { + "type": "string", + "description": "Success message", + "example": "Staging device updated and committed successfully" + }, + "staging_device_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the staging device that was updated" + } + } + }, + "PatchStagingCABundleResponse": { + "type": "object", + "required": [ + "message", + "staging_ca_id" + ], + "properties": { + "message": { + "type": "string", + "description": "Success message", + "example": "Staging CA bundle updated and committed successfully" + }, + "staging_ca_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the staging CA bundle that was updated" + } + } + }, + "AddDataCenterResponse": { + "type": "object", + "required": [ + "message", + "id" + ], + "properties": { + "message": { + "type": "string", + "description": "Success message", + "example": "Data center added successfully" + }, + "id": { + "type": "string", + "format": "uuid", + "description": "UUID of the data center that was created" + } + } + }, + "AddDeviceResponse": { + "type": "object", + "required": [ + "message", + "id" + ], + "properties": { + "message": { + "type": "string", + "description": "Success message", + "example": "Device added successfully" + }, + "id": { + "type": "string", + "format": "uuid", + "description": "UUID of the device that was created" + } + } + }, + "UpdateDeviceResponse": { + "type": "object", + "required": [ + "message", + "id" + ], + "properties": { + "message": { + "type": "string", + "description": "Success message", + "example": "Device updated successfully" + }, + "id": { + "type": "string", + "description": "Identifier of the device that was updated" + } + } + }, + "ConnectionValidationResponse": { + "type": "object", + "required": [ + "reachable", + "authenticated" + ], + "properties": { + "reachable": { + "type": "boolean", + "description": "Indicates if the device is reachable." + }, + "authenticated": { + "type": "boolean", + "description": "Indicates if authentication succeeded." + }, + "message": { + "type": "string", + "description": "Additional details about the validation result." + } + } + }, + "LicenseActivationRequest": { + "type": "object", + "required": [ + "jwt", + "modeOfOperation" + ], + "properties": { + "jwt": { + "type": "string", + "description": "JWT token for license activation", + "example": "your-jwt-token" + }, + "customId": { + "type": "string", + "description": "Optional custom identifier for the device" + }, + "modeOfOperation": { + "type": "string", + "description": "Mode of operation for license activation", + "enum": [ + "connected", + "disconnected" + ], + "example": "connected" + } + } + }, + "LicenseActivationResponse": { + "type": "object", + "required": [ + "status", + "message" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "Activation status", + "example": "success" + }, + "message": { + "type": "string", + "description": "Activation result message", + "example": "License activated successfully" + }, + "digitalAssetId": { + "type": "string", + "description": "Digital asset ID assigned by F5 TEEM", + "example": "DA-12345-67890" + }, + "licenseStatus": { + "type": "string", + "description": "Current license status", + "example": "Active" + }, + "activatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the license was activated", + "example": "2025-12-03T07:18:11Z" + }, + "hostLicense": { + "$ref": "#/components/schemas/HostLicenseDetails" + }, + "entitlements": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EntitledFeature" + }, + "description": "List of entitled features for this license" + }, + "subscriptionType": { + "type": "string", + "description": "Type of subscription (e.g., trial, paid, enterprise)", + "example": "trial" + }, + "expiryDate": { + "type": "string", + "format": "date-time", + "description": "License subscription expiry date", + "example": "2026-11-29T00:00:32Z" + } + } + }, + "HostLicenseDetails": { + "type": "object", + "description": "Detailed information about the host license", + "properties": { + "licenseId": { + "type": "string", + "description": "Unique license identifier", + "example": "LIC-12345-ABCDE" + }, + "subscriptionType": { + "type": "string", + "description": "Subscription type", + "example": "trial" + }, + "orderType": { + "type": "string", + "description": "Order type", + "example": "subscription" + }, + "expiryDate": { + "type": "string", + "format": "date-time", + "description": "License expiry date", + "example": "2026-11-29T00:00:32Z" + }, + "isActive": { + "type": "boolean", + "description": "Whether the license is currently active", + "example": true + } + } + }, + "EntitledFeature": { + "type": "object", + "description": "A single entitled feature within the license", + "properties": { + "featureId": { + "type": "string", + "description": "Unique feature identifier", + "example": "FEAT-001" + }, + "featureName": { + "type": "string", + "description": "Human-readable feature name", + "example": "AI-Driven Forecasting" + }, + "featurePermitted": { + "type": "integer", + "description": "Maximum permitted usage for this feature", + "example": 1000 + }, + "featureRemain": { + "type": "integer", + "description": "Remaining usage available", + "example": 750 + }, + "featureUnlimited": { + "type": "boolean", + "description": "Whether this feature has unlimited usage", + "example": false + }, + "featureUsed": { + "type": "integer", + "description": "Amount of feature already consumed", + "example": 250 + }, + "featureValueType": { + "type": "string", + "description": "Type of the feature value", + "enum": [ + "integral", + "boolean", + "string" + ], + "example": "integral" + }, + "uomCode": { + "type": "string", + "description": "Unit of measure code", + "example": "GB" + }, + "uomTerm": { + "type": "string", + "description": "Unit of measure term", + "example": "gigabytes" + }, + "uomTermStart": { + "type": "integer", + "description": "Starting value for unit of measure", + "example": 0 + } + } + }, + "LicenseDeactivationResponse": { + "type": "object", + "required": [ + "status", + "message" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "Deactivation status", + "example": "success" + }, + "message": { + "type": "string", + "description": "Deactivation result message", + "example": "License deactivated successfully" + }, + "digitalAssetId": { + "type": "string", + "description": "Digital asset ID" + }, + "licenseStatus": { + "type": "string", + "description": "License status", + "example": "Terminated" + }, + "deactivatedAt": { + "type": "string", + "format": "date-time", + "description": "Deactivation timestamp" + } + } + }, + "LicenseReportResponse": { + "type": "object", + "required": [ + "report" + ], + "properties": { + "report": { + "type": "string", + "description": "Base64 encoded license report (JSON content)", + "example": "eyJyZXBvcnROYW1lIjoibXktcmVwb3J0IiwidGVsZW1ldHJ5UmVjb3JkcyI6W119" + } + } + }, + "LicenseEntitlementsResponse": { + "type": "object", + "required": [ + "entitlements" + ], + "properties": { + "entitlements": { + "type": "object", + "additionalProperties": true, + "description": "License entitlements data." + }, + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "Response status", + "example": "success" + } + } + }, + "VerifyReportRequest": { + "type": "object", + "required": [ + "manifest" + ], + "properties": { + "manifest": { + "type": "string", + "description": "Base64 encoded signed report acknowledgment from F5 TEEM", + "example": "eyJzaWduZWRBY2siOiJ0ZXN0In0=" + } + } + }, + "DataCenter": { + "type": "object", + "additionalProperties": false, + "required": [ + "name" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the data center" + }, + "name": { + "type": "string", + "description": "Name of the Data Center.", + "maxLength": 255 + } + } + }, + "ListOfDataCenters": { + "type": "object", + "additionalProperties": false, + "properties": { + "data_centers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DataCenter" + } + } + } + }, + "Retention": { + "type": "string", + "pattern": "^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$", + "description": "ISO 8601 duration (e.g., P1Y for 1 year, P30D for 30 days).Supported units are Y (years), M (months), D (days), H (hours), M (minutes), S (seconds). Internally converted and rounded up to whole days. Maximum allowed retention is 1 year (P1Y)." + }, + "GlobalSettings": { + "type": "object", + "properties": { + "retention": { + "$ref": "#/components/schemas/Retention" + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "collection_interval": { + "type": "integer", + "minimum": 1, + "description": "Collection interval in seconds" + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean", + "default": false + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from trust store" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean", + "default": false + }, + "cgnat": { + "type": "boolean", + "default": false + }, + "dns": { + "type": "boolean", + "default": false + }, + "dos": { + "type": "boolean", + "default": false + }, + "firewall": { + "type": "boolean", + "default": false + }, + "gtm": { + "type": "boolean", + "default": false + }, + "policy_api_protection": { + "type": "boolean", + "default": false + }, + "policy_asm": { + "type": "boolean", + "default": false + }, + "policy_firewall": { + "type": "boolean", + "default": false + }, + "policy_ip_intelligence": { + "type": "boolean", + "default": false + }, + "policy_nat": { + "type": "boolean", + "default": false + }, + "profile_dos": { + "type": "boolean", + "default": false + } + } + } + } + }, + "BasicSettings": { + "type": "object", + "required": [ + "username", + "password", + "data_center", + "endpoint" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the device" + }, + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string", + "description": "Device endpoint in format ip:port or hostname:port (e.g., 192.168.1.100:443, bigip.example.com:8443)." + } + } + }, + "DevicePatchRequest": { + "type": "object", + "description": "Partial device update - only include fields you want to update.", + "properties": { + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string" + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "retention": { + "$ref": "#/components/schemas/Retention" + }, + "collection_interval": { + "type": "integer", + "minimum": 1 + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean" + }, + "ca": { + "type": "string", + "format": "uuid" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean" + }, + "cgnat": { + "type": "boolean" + }, + "dns": { + "type": "boolean" + }, + "dos": { + "type": "boolean" + }, + "firewall": { + "type": "boolean" + }, + "gtm": { + "type": "boolean" + }, + "profile_dos": { + "type": "boolean" + }, + "policy_api_protection": { + "type": "boolean" + }, + "policy_asm": { + "type": "boolean" + }, + "policy_firewall": { + "type": "boolean" + }, + "policy_ip_intelligence": { + "type": "boolean" + }, + "policy_nat": { + "type": "boolean" + } + } + } + } + }, + "DeviceType": { + "type": "string", + "enum": [ + "bigip", + "f5os" + ], + "default": "bigip", + "description": "Discriminates the kind of device. `bigip` (default) is a BIG-IP device;\n`f5os` is an F5OS platform provider (e.g. rSeries). When omitted the\ndevice is treated as a BIG-IP for backward compatibility.\n" + }, + "F5OSDevice": { + "type": "object", + "required": [ + "endpoint", + "username", + "password", + "data_center", + "tls_enabled" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the F5OS provider (response only)." + }, + "alias_name": { + "type": "string", + "maxLength": 255, + "description": "Unique, user-supplied label for the device." + }, + "type": { + "type": "string", + "enum": [ + "RSERIES" + ], + "default": "RSERIES", + "description": "F5OS platform type." + }, + "endpoint": { + "type": "string", + "description": "Device endpoint URL with scheme, host and port (e.g. https://10.1.1.5:443)." + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255, + "description": "Data center the device belongs to." + }, + "tls_enabled": { + "type": "boolean", + "description": "When true, the server certificate is verified against `ca`. When false, TLS verification is skipped." + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from the trust store. Required when `tls_enabled` is true." + }, + "cert_fingerprint": { + "type": "string", + "description": "Optional SHA-256 certificate fingerprint pin. When set, the server certificate must match this fingerprint." + } + } + }, + "AddDeviceRequest": { + "description": "Unified add-device request. The `deviceType` field selects how the\nbody is interpreted. For `bigip` (default) the existing flat BIG-IP\nfields apply (backward compatible). For `f5os` the `f5os` object is\nrequired. Exactly one variant applies per request.\n", + "oneOf": [ + { + "$ref": "#/components/schemas/BigIPAddRequest" + }, + { + "$ref": "#/components/schemas/F5OSAddRequest" + } + ], + "discriminator": { + "propertyName": "deviceType", + "mapping": { + "bigip": "#/components/schemas/BigIPAddRequest", + "f5os": "#/components/schemas/F5OSAddRequest" + } + } + }, + "BigIPAddRequest": { + "description": "BIG-IP add request. `deviceType` must be set to `bigip` so the\nunified add-device endpoint can dispatch to the BIG-IP onboarding\npath; the default in the schema is `bigip` for documentation\npurposes, but callers should still send the field explicitly.\n", + "allOf": [ + { + "type": "object", + "required": [ + "deviceType" + ], + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "bigip" + ], + "default": "bigip" + } + } + }, + { + "$ref": "#/components/schemas/Device" + } + ] + }, + "F5OSAddRequest": { + "description": "F5OS add request. All F5OS device fields are merged at the top\nlevel alongside the deviceType discriminator, mirroring the flat\nshape of BigIPAddRequest. No nested `f5os` object.\n", + "allOf": [ + { + "type": "object", + "required": [ + "deviceType" + ], + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "f5os" + ] + } + } + }, + { + "$ref": "#/components/schemas/F5OSDevice" + } + ] + }, + "DeviceResponse": { + "allOf": [ + { + "$ref": "#/components/schemas/Device" + }, + { + "type": "object", + "properties": { + "deviceName": { + "type": "string", + "description": "Display name for the device. For BIG-IP this is the hostname\nfetched from the BIG-IP system; for F5OS it mirrors the\nuser-supplied `alias_name`. Always populated.\n" + }, + "deviceVersion": { + "type": "string", + "description": "BIG-IP software version (bigip only)." + }, + "devicePlatform": { + "type": "string", + "description": "BIG-IP platform/marketing name (bigip only)." + }, + "deviceType": { + "$ref": "#/components/schemas/DeviceType" + }, + "schema": { + "type": "string", + "description": "Protocol schema (http or https) inferred from endpoint or URL scheme.\nExample: \"https\"\n", + "enum": [ + "http", + "https" + ] + }, + "type": { + "type": "string", + "description": "F5OS platform type (f5os only)." + }, + "host": { + "type": "string", + "description": "IP address or hostname extracted from endpoint. For BIG-IP devices,\nthis is parsed from the endpoint field. For F5OS, this is the provider host.\nExample: \"192.168.1.100\" or \"bigip.example.com\"\n" + }, + "port": { + "type": "integer", + "description": "Port number extracted from endpoint. For BIG-IP devices, defaults to 443\nfor https or 80 for http if not specified. For F5OS, this is the provider port.\nExample: 443\n" + }, + "status": { + "type": "string", + "description": "Device connectivity status. For BIG-IP, derived from Prometheus (`READY` when reachable, `UNREACHABLE` when not). For F5OS, reflects the provider status. Omitted when status data is unavailable.\n" + }, + "hardwareModel": { + "type": "string", + "description": "F5OS hardware model (f5os only)." + }, + "serialNumber": { + "type": "string", + "description": "F5OS serial number (f5os only)." + }, + "osVersion": { + "type": "string", + "description": "F5OS OS version (f5os only)." + }, + "osBuild": { + "type": "string", + "description": "F5OS OS build (f5os only)." + }, + "lastSeenAt": { + "type": "string", + "format": "date-time", + "description": "When the F5OS provider was last reachable (f5os only)." + } + } + } + ] + }, + "Device": { + "allOf": [ + { + "$ref": "#/components/schemas/GlobalSettings" + }, + { + "$ref": "#/components/schemas/BasicSettings" + }, + { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the device" + } + } + } + ] + }, + "ListOfDevices": { + "type": "object", + "additionalProperties": false, + "properties": { + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DeviceResponse" + } + }, + "pagination": { + "type": "object", + "additionalProperties": false, + "description": "Pagination metadata for the devices list.", + "properties": { + "page": { + "type": "integer", + "description": "Current page number.", + "minimum": 1 + }, + "pageSize": { + "type": "integer", + "description": "Number of devices per page.", + "minimum": 1 + }, + "totalDevices": { + "type": "integer", + "description": "Total number of devices matching the filter criteria.", + "minimum": 0 + }, + "totalPages": { + "type": "integer", + "description": "Total number of pages available.", + "minimum": 0 + } + } + } + } + }, + "DataCenterWithDevices": { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the data center" + }, + "name": { + "type": "string", + "description": "Name of the data center", + "maxLength": 255 + }, + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DeviceResponse" + } + }, + "device_count": { + "type": "integer", + "description": "Total number of devices in this data center", + "minimum": 0 + } + } + }, + "DataCentersWithDevicesResponse": { + "type": "object", + "additionalProperties": false, + "properties": { + "data_centers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DataCenterWithDevices" + } + }, + "total_data_centers": { + "type": "integer", + "description": "Total number of data centers", + "minimum": 0 + }, + "total_devices": { + "type": "integer", + "description": "Total number of devices across all data centers", + "minimum": 0 + } + } + }, + "AddTrustStoreRequest": { + "type": "object", + "required": [ + "name", + "certificate_content" + ], + "properties": { + "name": { + "type": "string", + "maxLength": 255, + "description": "Name of the certificate" + }, + "description": { + "type": "string", + "description": "Description of the certificate" + }, + "certificate_content": { + "type": "string", + "description": "PEM encoded certificate content" + } + } + }, + "TrustStore": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the certificate" + }, + "name": { + "type": "string", + "maxLength": 255, + "description": "Name of the certificate" + }, + "description": { + "type": "string", + "description": "Description of the certificate" + }, + "certificate_content": { + "type": "string", + "description": "PEM encoded certificate content" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp" + }, + "last_modified": { + "type": "string", + "format": "date-time", + "description": "Last modification timestamp" + } + } + }, + "TrustStoreResponse": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the certificate" + }, + "name": { + "type": "string", + "description": "Name of the certificate" + }, + "description": { + "type": "string", + "description": "Description of the certificate" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp" + } + } + }, + "ListOfTrustStores": { + "type": "object", + "additionalProperties": false, + "properties": { + "trust_stores": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TrustStore" + } + } + } + }, + "OnboardingStatus": { + "type": "object", + "properties": { + "license_status": { + "type": "string", + "enum": [ + "ACTIVE", + "INACTIVE" + ], + "description": "Current license status" + }, + "custom_llm_integration": { + "type": "string", + "enum": [ + "NOT_CONFIGURED", + "CONFIGURED", + "SKIPPED" + ], + "description": "Custom LLM integration status", + "example": "NOT_CONFIGURED" + }, + "f5_aidf_integration": { + "type": "string", + "enum": [ + "NOT_CONFIGURED", + "CONFIGURED", + "SKIPPED" + ], + "description": "F5 AIDF integration status", + "example": "NOT_CONFIGURED" + }, + "devices_onboarded": { + "type": "string", + "enum": [ + "NOT_CONFIGURED", + "CONFIGURED", + "SKIPPED" + ], + "description": "Device onboarding status", + "example": "NOT_CONFIGURED" + } + } + }, + "BulkImportResponse": { + "type": "object", + "required": [ + "total", + "successful", + "failed" + ], + "properties": { + "total": { + "type": "integer", + "description": "Total number of devices in the import request", + "example": 10 + }, + "successful": { + "type": "integer", + "description": "Number of devices successfully imported", + "example": 8 + }, + "failed": { + "type": "integer", + "description": "Number of devices that failed to import", + "example": 2 + }, + "results": { + "type": "array", + "description": "Detailed results for each device", + "items": { + "type": "object", + "properties": { + "device_name": { + "type": "string", + "description": "Device identifier (alias_name or endpoint)", + "example": "bigip-prod-01" + }, + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "Import status for this device", + "example": "success" + }, + "message": { + "type": "string", + "description": "Success message or error details", + "example": "Device imported successfully" + }, + "device_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the imported device (only present on success)", + "example": "123e4567-e89b-12d3-a456-426614174000" + } + } + } + } + } + }, + "ImportTaskAccepted": { + "type": "object", + "required": [ + "task_id" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Identifier to poll via GET /device-management/devices/import/status/{task_id}." + }, + "message": { + "type": "string", + "example": "Import task accepted" + } + } + }, + "ImportTaskItem": { + "type": "object", + "required": [ + "device_type", + "status" + ], + "properties": { + "device_type": { + "type": "string", + "enum": [ + "bigip", + "f5os" + ], + "description": "Discriminator for the input item." + }, + "alias_name": { + "type": "string", + "description": "User-supplied alias (or server default) for the device." + }, + "endpoint": { + "type": "string", + "description": "Endpoint URL of the device as supplied in the request." + }, + "status": { + "type": "string", + "enum": [ + "pending", + "success", + "failed" + ], + "description": "Per-device result. `pending` while the worker has not processed the item yet." + }, + "device_id": { + "type": "string", + "format": "uuid", + "description": "Present on success \u2014 UUID of the persisted device." + }, + "error_message": { + "type": "string", + "description": "Present on failure \u2014 human-readable cause." + } + } + }, + "ImportTaskStatus": { + "type": "object", + "required": [ + "task_id", + "state", + "status", + "progress", + "total", + "successful", + "failed", + "items" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "state": { + "type": "string", + "enum": [ + "INIT", + "IN_PROGRESS", + "COMPLETED", + "FAILED" + ], + "description": "Lifecycle state of the task.\n * INIT \u2014 task created, worker not yet started.\n * IN_PROGRESS \u2014 worker iterating items.\n * COMPLETED \u2014 every item processed (some may have failed; see `status`).\n * FAILED \u2014 task aborted before completing every item.\n" + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "SUCCESS", + "ERROR" + ], + "description": "Outcome summary.\n * RUNNING \u2014 while state is IN_PROGRESS.\n * SUCCESS \u2014 state=COMPLETED with zero failures.\n * ERROR \u2014 state=COMPLETED with at least one failure, or state=FAILED.\n" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100 + }, + "total": { + "type": "integer", + "description": "Number of devices in the original request." + }, + "successful": { + "type": "integer", + "description": "Number of devices that were imported successfully so far." + }, + "failed": { + "type": "integer", + "description": "Number of devices that failed to import so far." + }, + "error_message": { + "type": "string", + "description": "Populated when state=FAILED with a task-level error." + }, + "items": { + "type": "array", + "description": "Per-device result list, in the same order as the request body.", + "items": { + "$ref": "#/components/schemas/ImportTaskItem" + } + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "MigrationTaskResponse": { + "type": "object", + "required": [ + "task_id", + "status", + "message" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the migration task", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "status": { + "type": "string", + "enum": [ + "INIT", + "IN_PROGRESS" + ], + "description": "Initial status of the task", + "example": "INIT" + }, + "message": { + "type": "string", + "description": "Human-readable message about the task", + "example": "Migration task created successfully. Use the task_id to query status." + } + } + }, + "CleanupMigrationTaskResponse": { + "type": "object", + "required": [ + "task_id", + "deleted_devices", + "deleted_trust_stores", + "message" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "The task ID that was cleaned up", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "deleted_devices": { + "type": "integer", + "description": "Number of staging devices deleted", + "example": 10 + }, + "deleted_trust_stores": { + "type": "integer", + "description": "Number of staging trust store entries deleted", + "example": 5 + }, + "message": { + "type": "string", + "description": "Success message", + "example": "Successfully cleaned up migration task staging data" + } + } + }, + "CleanupImportTaskResponse": { + "type": "object", + "required": [ + "task_id", + "message" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "The import task ID that was cleaned up", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "message": { + "type": "string", + "description": "Success message", + "example": "Successfully cleaned up import task" + } + } + }, + "RetryFailedMigrationDevicesResponse": { + "type": "object", + "required": [ + "message", + "task_id" + ], + "properties": { + "message": { + "type": "string", + "description": "Success message", + "example": "Retry task initiated successfully" + }, + "task_id": { + "type": "string", + "format": "uuid", + "description": "The same task ID (reused for retry)", + "example": "123e4567-e89b-12d3-a456-426614174000" + } + } + }, + "MigrationStatusResponse": { + "type": "object", + "required": [ + "task_id", + "task_type", + "state", + "status", + "progress", + "total_devices", + "pending_devices", + "validated_devices", + "failed_devices", + "created_at", + "updated_at" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the migration task", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "task_type": { + "type": "string", + "enum": [ + "DEVICE_IMPORT", + "MIGRATION", + "BULK_IMPORT", + "SYNC" + ], + "description": "Type of the task", + "example": "MIGRATION" + }, + "state": { + "type": "string", + "enum": [ + "INIT", + "IN_PROGRESS", + "COMPLETED", + "FAILED" + ], + "description": "Current state of the task", + "example": "IN_PROGRESS" + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "SUCCESS", + "ERROR" + ], + "description": "Overall status of the task", + "example": "RUNNING" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Overall progress percentage", + "example": 45 + }, + "total_devices": { + "type": "integer", + "description": "Total number of devices in the migration", + "example": 100 + }, + "pending_devices": { + "type": "integer", + "description": "Number of devices pending validation", + "example": 55 + }, + "validated_devices": { + "type": "integer", + "description": "Number of devices successfully validated", + "example": 40 + }, + "failed_devices": { + "type": "integer", + "description": "Number of devices that failed validation", + "example": 5 + }, + "error_message": { + "type": "string", + "nullable": true, + "description": "Error message if the task failed", + "example": null + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "When the task was created", + "example": "2026-01-29T10:30:00Z" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "When the task was last updated", + "example": "2026-01-29T10:35:00Z" + }, + "devices": { + "type": "array", + "description": "Individual device status details (included if include_devices=true)", + "items": { + "$ref": "#/components/schemas/DeviceStatusDetail" + } + } + } + }, + "DeviceStatusDetail": { + "type": "object", + "required": [ + "device_name", + "endpoint", + "validation_status", + "created_at", + "updated_at" + ], + "properties": { + "device_name": { + "type": "string", + "description": "Device name/identifier", + "example": "bigip/prod-01" + }, + "endpoint": { + "type": "string", + "description": "Device endpoint URL", + "example": "https://10.1.1.100" + }, + "validation_status": { + "type": "string", + "enum": [ + "PENDING", + "VALIDATING", + "SUCCESS", + "FAILED" + ], + "description": "Validation status for this device", + "example": "SUCCESS" + }, + "error_message": { + "type": "string", + "nullable": true, + "description": "Error message if validation failed", + "example": null + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "When the device entry was created", + "example": "2026-01-29T10:30:00Z" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "When the device status was last updated", + "example": "2026-01-29T10:32:00Z" + } + } + }, + "DeviceProgressResponse": { + "type": "object", + "required": [ + "task_id", + "task_status", + "task_progress", + "page", + "size", + "total", + "devices" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the migration task", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "task_status": { + "type": "string", + "enum": [ + "RUNNING", + "SUCCESS", + "ERROR" + ], + "description": "Overall task status", + "example": "RUNNING" + }, + "task_progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Overall task completion percentage (0-100)", + "example": 45 + }, + "page": { + "type": "integer", + "description": "Current page number (1-based)", + "example": 1 + }, + "size": { + "type": "integer", + "description": "Number of devices per page", + "example": 20 + }, + "total": { + "type": "integer", + "format": "int64", + "description": "Total number of devices matching filters", + "example": 45 + }, + "last_sync": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of the most recently modified device in this response.\nUse this value as 'since' parameter in next poll for delta updates.\n", + "example": "2026-01-30T12:12:30Z" + }, + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DeviceProgressItem" + }, + "description": "List of device progress items" + } + } + }, + "DeviceProgressItem": { + "type": "object", + "required": [ + "id", + "device_name", + "status", + "last_modified" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the staging device", + "example": "660e8400-e29b-41d4-a716-446655440001" + }, + "device_name": { + "type": "string", + "description": "Name of the device being migrated", + "example": "bigip-prod-01.example.com" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "VALIDATING", + "SUCCESS", + "FAILED", + "SKIPPED", + "SKIPPED" + ], + "description": "Current validation status of the device", + "example": "SUCCESS" + }, + "error_message": { + "type": "string", + "nullable": true, + "description": "Error message if status is FAILED", + "example": "Invalid credentials" + }, + "last_modified": { + "type": "string", + "format": "date-time", + "description": "Timestamp when this device was last updated", + "example": "2026-01-30T12:12:00Z" + } + } + }, + "CABundleListResponse": { + "type": "object", + "required": [ + "task_id", + "page", + "size", + "total", + "ca_bundles" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the migration task", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "page": { + "type": "integer", + "description": "Current page number (1-based)", + "example": 1 + }, + "size": { + "type": "integer", + "description": "Number of CA bundles per page", + "example": 20 + }, + "total": { + "type": "integer", + "format": "int64", + "description": "Total number of CA bundles in the task", + "example": 5 + }, + "ca_bundles": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StagingCABundle" + }, + "description": "List of staging CA bundles" + } + } + }, + "StagingCABundle": { + "type": "object", + "required": [ + "id", + "name", + "certificate_content" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the staging CA bundle", + "example": "660e8400-e29b-41d4-a716-446655440000" + }, + "name": { + "type": "string", + "description": "Name of the CA certificate", + "example": "Production Root CA" + }, + "description": { + "type": "string", + "nullable": true, + "description": "Description of the CA certificate", + "example": "Root CA for production environment" + }, + "certificate_content": { + "type": "string", + "description": "PEM-encoded certificate content", + "example": "-----BEGIN CERTIFICATE-----\nMIIDXTCCAkWgA...\n-----END CERTIFICATE-----" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp", + "example": "2026-01-30T10:00:00Z" + }, + "last_modified": { + "type": "string", + "format": "date-time", + "description": "Last modification timestamp", + "example": "2026-01-30T12:00:00Z" + } + } + }, + "InitializeHARequest": { + "type": "object", + "required": [ + "primary_node", + "standby_node" + ], + "properties": { + "primary_node": { + "$ref": "#/components/schemas/PrimaryNodeConfig" + }, + "standby_node": { + "$ref": "#/components/schemas/StandbyNodeConfig" + } + } + }, + "PrimaryNodeConfig": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string", + "description": "Primary node address in format http://hostname:port or https://hostname:port", + "example": "http://primary-node:30227" + }, + "node_name": { + "type": "string", + "description": "Optional primary node name. Auto-generated from address if not provided.", + "example": "primary-node" + }, + "site": { + "type": "string", + "description": "Optional site name for the primary node. Defaults to 'primary-site' if not provided.", + "example": "primary-site" + } + } + }, + "StandbyNodeConfig": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string", + "description": "Standby node address in format http://hostname:port or https://hostname:port", + "example": "http://standby-node:30227" + }, + "node_name": { + "type": "string", + "description": "Optional standby node name. Auto-generated from address if not provided.", + "example": "standby-node" + }, + "site": { + "type": "string", + "description": "Optional site name for the standby node. Defaults to 'standby-site' if not provided.", + "example": "standby-site" + } + } + }, + "InitializeHAResponse": { + "type": "object", + "required": [ + "task_id", + "status", + "message", + "created_at" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the asynchronous initialization task", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "status": { + "type": "string", + "description": "Current task status", + "example": "pending" + }, + "message": { + "type": "string", + "description": "Human-readable message with instructions for polling task status", + "example": "HA initialization task created. Poll /api/dr-ha/tasks/550e8400-e29b-41d4-a716-446655440000 for progress." + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created", + "example": "2026-01-30T10:00:00Z" + } + } + }, + "GetTaskStatusResponse": { + "type": "object", + "required": [ + "task_id", + "task_type", + "status", + "current_step", + "total_steps", + "completed_steps", + "progress_pct", + "started_at" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the task", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "task_type": { + "type": "string", + "description": "Type of task being performed", + "enum": [ + "initialize", + "failover", + "failback" + ], + "example": "initialize" + }, + "status": { + "type": "string", + "description": "Current task status", + "enum": [ + "pending", + "in_progress", + "validating", + "compatibility_check", + "node1_configuring", + "node2_configuring", + "finalizing", + "completed", + "failed", + "node2_unreachable", + "rolling_back" + ], + "example": "in_progress" + }, + "current_step": { + "type": "string", + "description": "Description of the current step being executed", + "example": "Configuring PostgreSQL replication on standby node" + }, + "total_steps": { + "type": "integer", + "description": "Total number of steps to complete the task", + "example": 8 + }, + "completed_steps": { + "type": "integer", + "description": "Number of steps completed so far", + "example": 3 + }, + "progress_pct": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Overall progress as a percentage (0-100)", + "example": 37 + }, + "error_message": { + "type": "string", + "nullable": true, + "description": "Error message if the task failed or encountered an issue", + "example": null + }, + "sub_tasks": { + "type": "array", + "description": "Detailed information about sub-tasks being executed", + "items": { + "$ref": "#/components/schemas/SubTaskInfo" + } + }, + "started_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task started execution", + "example": "2026-01-30T10:00:05Z" + }, + "completed_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp when the task completed (null if still running)", + "example": null + }, + "duration": { + "type": "string", + "nullable": true, + "description": "Human-readable duration (e.g., '2h 30m 45s'). Null if still running.", + "example": null + } + } + }, + "SubTaskInfo": { + "type": "object", + "required": [ + "component", + "role", + "status", + "description" + ], + "properties": { + "component": { + "type": "string", + "description": "The type of component being configured", + "enum": [ + "postgres", + "vault", + "victoriametrics", + "clickhouse", + "otel" + ], + "example": "postgres" + }, + "role": { + "type": "string", + "description": "The role of the node for this component", + "enum": [ + "primary", + "standby" + ], + "example": "primary" + }, + "status": { + "type": "string", + "description": "Status of this sub-task", + "enum": [ + "pending", + "running", + "completed", + "failed", + "skipped" + ], + "example": "completed" + }, + "description": { + "type": "string", + "description": "Human-readable description of what this sub-task is doing", + "example": "Setting up PostgreSQL replication user" + }, + "error_detail": { + "type": "string", + "nullable": true, + "description": "Detailed error information if the sub-task failed", + "example": null + } + } + }, + "HAStatusResponse": { + "type": "object", + "required": [ + "cluster_id", + "cluster_name", + "status", + "site", + "nodes" + ], + "properties": { + "cluster_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier of the HA cluster", + "example": "660e8400-e29b-41d4-a716-446655440001" + }, + "cluster_name": { + "type": "string", + "description": "Name of the HA cluster", + "example": "primary-standby-cluster" + }, + "status": { + "type": "string", + "description": "Overall health status of the HA cluster", + "enum": [ + "initializing", + "active", + "failed", + "degraded" + ], + "example": "active" + }, + "site": { + "type": "string", + "description": "Primary site name", + "example": "primary-site" + }, + "nodes": { + "type": "array", + "description": "Status of each node in the cluster", + "items": { + "$ref": "#/components/schemas/NodeStatusInfo" + } + }, + "initialized_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp when the cluster was initialized", + "example": "2026-01-30T10:05:00Z" + }, + "last_failover_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of the last failover operation", + "example": null + } + } + }, + "NodeStatusInfo": { + "type": "object", + "required": [ + "node_id", + "node_name", + "role", + "status", + "services" + ], + "properties": { + "node_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the node", + "example": "770e8400-e29b-41d4-a716-446655440002" + }, + "node_name": { + "type": "string", + "description": "Name of the node", + "example": "primary-node" + }, + "role": { + "type": "string", + "description": "Role of the node in the cluster", + "enum": [ + "primary", + "standby" + ], + "example": "primary" + }, + "status": { + "type": "string", + "description": "Health status of the node", + "enum": [ + "healthy", + "degraded", + "unhealthy" + ], + "example": "healthy" + }, + "services": { + "type": "object", + "description": "Health status of services on this node (component -> status)", + "additionalProperties": { + "type": "string", + "enum": [ + "healthy", + "degraded", + "unhealthy" + ] + }, + "example": { + "postgres": "healthy", + "vault": "healthy", + "victoriametrics": "healthy", + "clickhouse": "healthy", + "otel": "healthy" + } + }, + "last_checked": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of the last health check", + "example": "2026-01-30T12:15:00Z" + } + } + }, + "FailoverRequest": { + "type": "object", + "properties": { + "force": { + "type": "boolean", + "description": "Skip health checks and force failover (use with caution)", + "default": false, + "example": false + }, + "timeout_seconds": { + "type": "integer", + "minimum": 60, + "description": "Maximum time to wait for failover to complete (in seconds)", + "default": 300, + "example": 300 + } + } + }, + "FailbackRequest": { + "type": "object", + "required": [ + "new_primary_address" + ], + "properties": { + "new_primary_address": { + "type": "string", + "description": "Address of the new primary node in format http://hostname:port", + "example": "http://new-primary:30227" + }, + "new_primary_node_name": { + "type": "string", + "description": "Name of the new primary node", + "example": "new-primary-node" + }, + "force": { + "type": "boolean", + "description": "Skip health checks and force failback (use with caution)", + "default": false, + "example": false + } + } + }, + "StagingDeviceResponse": { + "type": "object", + "required": [ + "id", + "task_id", + "device_name", + "endpoint", + "validation_status", + "created_at", + "last_modified" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the staging device", + "example": "660e8400-e29b-41d4-a716-446655440001" + }, + "task_id": { + "type": "string", + "format": "uuid", + "description": "Migration task ID this device belongs to", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "device_name": { + "type": "string", + "description": "Name of the device", + "example": "bigip-prod-01.example.com" + }, + "endpoint": { + "type": "string", + "description": "Device endpoint URL", + "example": "https://192.168.1.100:443" + }, + "username": { + "type": "string", + "nullable": true, + "description": "Device username", + "example": "admin" + }, + "data_center": { + "type": "string", + "nullable": true, + "description": "Data center assignment", + "example": "US-EAST-1" + }, + "tls_enabled": { + "type": "boolean", + "nullable": true, + "description": "Whether TLS is enabled", + "example": true + }, + "ca_bundle_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "Associated CA bundle ID", + "example": "660e8400-e29b-41d4-a716-446655440002" + }, + "collection_interval": { + "type": "integer", + "nullable": true, + "description": "Collection interval in seconds", + "example": 60 + }, + "max_concurrent_connections": { + "type": "integer", + "nullable": true, + "description": "Maximum concurrent HTTP connections per device", + "example": 5 + }, + "validation_status": { + "type": "string", + "enum": [ + "PENDING", + "VALIDATING", + "SUCCESS", + "FAILED", + "SKIPPED" + ], + "description": "Current validation status", + "example": "SUCCESS" + }, + "error_message": { + "type": "string", + "nullable": true, + "description": "Error message if validation failed", + "example": "Connection timeout" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp", + "example": "2026-01-30T10:00:00Z" + }, + "last_modified": { + "type": "string", + "format": "date-time", + "description": "Last modification timestamp", + "example": "2026-01-30T12:00:00Z" + } + } + }, + "FqdnConfigRequest": { + "type": "object", + "required": [ + "target" + ], + "properties": { + "target": { + "type": "string", + "description": "External FQDN target. May include https scheme and port.", + "example": "f5insights.example.com" + } + } + }, + "FqdnConfigResponse": { + "type": "object", + "required": [ + "task_id", + "target", + "status" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the FQDN configuration task", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "target": { + "type": "string", + "description": "Normalized FQDN target submitted to the configuration script", + "example": "https://f5insights.example.com" + }, + "status": { + "type": "string", + "enum": [ + "submitted" + ], + "description": "Initial status of the task", + "example": "submitted" + } + } + }, + "FqdnConfigCurrentResponse": { + "type": "object", + "required": [ + "configured", + "current_url" + ], + "properties": { + "configured": { + "type": "boolean", + "description": "Whether an external URL is currently configured.", + "example": true + }, + "current_url": { + "type": "string", + "description": "Current canonical external URL used for identity provider redirects.", + "example": "https://f5insights.example.com" + } + } + }, + "FqdnStatusResponse": { + "type": "object", + "required": [ + "task_id", + "state", + "status", + "progress" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Task identifier", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "state": { + "type": "string", + "enum": [ + "INIT", + "VALIDATE", + "APPLY", + "COMPLETED", + "FAILED" + ], + "description": "Current FSM state of the task", + "example": "APPLY" + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "SUCCESS", + "ERROR" + ], + "description": "Task execution status", + "example": "RUNNING" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Progress percentage (0-100)", + "example": 60 + }, + "error_message": { + "type": "string", + "description": "Error message if task failed", + "example": "FQDN configuration failed: helm upgrade failed" + } + } + }, + "SystemAPIError": { + "type": "object", + "required": [ + "code", + "status", + "message" + ], + "properties": { + "code": { + "type": "string", + "example": "SYSTEM-0001" + }, + "status": { + "type": "integer", + "example": 400 + }, + "message": { + "type": "string", + "example": "Invalid request body" + }, + "help": { + "type": "string", + "nullable": true, + "example": "Use a valid FQDN such as f5insights.example.com" + } + } + }, + "SystemAPIErrorResponse": { + "type": "object", + "required": [ + "success", + "error" + ], + "properties": { + "success": { + "type": "boolean", + "example": false + }, + "error": { + "$ref": "#/components/schemas/SystemAPIError" + } + } + }, + "ModeSwitchRequest": { + "type": "object", + "required": [ + "target_mode" + ], + "properties": { + "target_mode": { + "type": "string", + "enum": [ + "lite", + "full" + ], + "description": "Target mode to switch to", + "example": "full" + } + } + }, + "ModeSwitchResponse": { + "type": "object", + "required": [ + "task_id", + "target_mode", + "status" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the mode switch task", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "target_mode": { + "type": "string", + "enum": [ + "lite", + "full" + ], + "description": "Target mode requested", + "example": "full" + }, + "status": { + "type": "string", + "enum": [ + "submitted" + ], + "description": "Initial status of the task", + "example": "submitted" + } + } + }, + "ModeStatusResponse": { + "type": "object", + "required": [ + "task_id", + "current_mode", + "state", + "status", + "progress" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Task identifier", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "current_mode": { + "type": "string", + "enum": [ + "lite", + "full", + "unknown" + ], + "description": "Current system mode detected from pod state", + "example": "lite" + }, + "target_mode": { + "type": "string", + "enum": [ + "lite", + "full" + ], + "description": "Target mode (only present when task is in progress)", + "example": "full" + }, + "state": { + "type": "string", + "enum": [ + "INIT", + "IN_PROGRESS", + "COMPLETED", + "FAILED" + ], + "description": "Current FSM state of the task", + "example": "IN_PROGRESS" + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "SUCCESS", + "ERROR" + ], + "description": "Task execution status", + "example": "RUNNING" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Progress percentage (0-100)", + "example": 60 + }, + "error_message": { + "type": "string", + "nullable": true, + "description": "Error message if task failed", + "example": "Failed to scale deployment: timeout" + } + } + }, + "ModeCapabilitiesResponse": { + "type": "object", + "required": [ + "current_mode", + "message" + ], + "properties": { + "current_mode": { + "type": "string", + "enum": [ + "lite", + "full", + "unknown" + ], + "description": "Current system mode", + "example": "lite" + }, + "message": { + "type": "string", + "description": "Optional additional information", + "example": "" + } + } + }, + "TelemetryTypeConfig": { + "type": "object", + "required": [ + "name", + "enabled" + ], + "properties": { + "name": { + "type": "string", + "enum": [ + "API_Discovery", + "Application_Telemetry" + ], + "description": "Telemetry type name", + "example": "API_Discovery" + }, + "enabled": { + "type": "boolean", + "description": "Whether this telemetry type is enabled for AIDF forwarding", + "example": true + }, + "description": { + "type": "string", + "description": "Human-readable description of the telemetry type", + "example": "API discovery telemetry from iRule" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of last update", + "example": "2026-05-13T10:30:00Z" + } + } + }, + "TelemetryTypesResponse": { + "type": "object", + "required": [ + "types" + ], + "properties": { + "types": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TelemetryTypeConfig" + }, + "description": "List of all telemetry types with their configuration" + } + } + }, + "UpdateTelemetryTypesRequest": { + "type": "object", + "required": [ + "enabled_types" + ], + "properties": { + "enabled_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "API_Discovery", + "Application_Telemetry" + ] + }, + "description": "List of telemetry types to enable (all others will be disabled)", + "example": [ + "API_Discovery", + "Application_Telemetry" + ], + "minItems": 0 + } + } + }, + "ChatConversation": { + "type": "object", + "required": [ + "id", + "user_id", + "created_at", + "last_msg_at", + "expires_at", + "message_count" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique conversation identifier", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "user_id": { + "type": "string", + "description": "Authenticated user ID that owns this conversation", + "example": "user-123" + }, + "title": { + "type": "string", + "nullable": true, + "maxLength": 500, + "description": "Conversation title (auto-generated from first message or user-provided)", + "example": "Deploy failure on prod-cluster-3" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "When the conversation was created" + }, + "last_msg_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent message (drives TTL)" + }, + "expires_at": { + "type": "string", + "format": "date-time", + "description": "When this conversation will expire (last_msg_at + 24 hours rolling)" + }, + "deleted_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Soft-delete timestamp (null if active)" + }, + "message_count": { + "type": "integer", + "description": "Total number of messages in this conversation", + "example": 14 + } + } + }, + "ChatMessage": { + "type": "object", + "required": [ + "id", + "conversation_id", + "user_id", + "role", + "content", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique message identifier" + }, + "conversation_id": { + "type": "string", + "format": "uuid", + "description": "Parent conversation ID" + }, + "user_id": { + "type": "string", + "description": "User who sent or received this message" + }, + "role": { + "type": "string", + "enum": [ + "user", + "assistant" + ], + "description": "Message sender role" + }, + "content": { + "type": "string", + "description": "Message content", + "example": "What's the current pool status on prod-cluster-3?" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "When the message was created" + }, + "is_summarized": { + "type": "boolean", + "default": false, + "description": "Whether this message has been included in a context summary" + } + } + }, + "ConversationWithMessages": { + "type": "object", + "required": [ + "conversation", + "messages", + "context_summarized" + ], + "properties": { + "conversation": { + "$ref": "#/components/schemas/ChatConversation" + }, + "messages": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ChatMessage" + } + }, + "context_summarized": { + "type": "boolean", + "description": "Whether older messages have been summarized to fit context window" + } + } + }, + "CreateConversationRequest": { + "type": "object", + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "description": "Optional conversation title", + "example": "Troubleshoot VIP latency" + } + } + }, + "PDFExportRequest": { + "type": "object", + "required": [ + "type", + "conversation_id" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "single", + "conversation" + ], + "description": "`conversation` \u2014 export all messages in the thread (up to 200). `single` \u2014 export one assistant response and its preceding user prompt.\n", + "example": "conversation" + }, + "conversation_id": { + "type": "string", + "format": "uuid", + "description": "ID of the conversation to export", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "message_id": { + "type": "string", + "format": "uuid", + "description": "Required when `type` is `single`. ID of the target assistant message. The preceding user prompt is automatically included in the PDF.\n", + "example": "7cb94d21-1234-4321-abcd-9f8e7d6c5b4a" + }, + "session_id": { + "type": "string", + "description": "Browser/session identifier from the chat session that triggered the export. Used to correlate the PDF export audit event with the originating chat session.\n", + "example": "session_1717600000000_abc1234" + } + } + }, + "AddMessageRequest": { + "type": "object", + "required": [ + "role", + "content" + ], + "properties": { + "role": { + "type": "string", + "enum": [ + "user", + "assistant" + ], + "description": "Message sender role" + }, + "content": { + "type": "string", + "description": "Message content", + "example": "Can you check the pool member health?" + } + } + }, + "CreateCloudEnvironmentRequest": { + "type": "object", + "required": [ + "name", + "providerReference", + "deviceTemplateReference", + "vmwProperties" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the cloud environment", + "minLength": 1, + "maxLength": 255 + }, + "providerReference": { + "$ref": "#/components/schemas/Reference" + }, + "deviceTemplateReference": { + "$ref": "#/components/schemas/Reference" + }, + "isVmwCluster": { + "type": "boolean", + "description": "Indicates if VMware cluster is being used", + "default": true + }, + "vmwProperties": { + "$ref": "#/components/schemas/VMwareEnvironmentProperties" + } + } + }, + "UpdateCloudEnvironmentRequest": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "isVmwCluster": { + "type": "boolean" + }, + "vmwProperties": { + "$ref": "#/components/schemas/VMwareEnvironmentProperties" + } + } + }, + "VMwareEnvironmentProperties": { + "type": "object", + "required": [ + "cluster", + "datacenter", + "user", + "password", + "vmImage", + "networkInterfaceMapping" + ], + "properties": { + "cluster": { + "type": "string", + "description": "VMware cluster name" + }, + "datacenter": { + "type": "string", + "description": "VMware datacenter name" + }, + "user": { + "type": "string", + "description": "vCenter username (can include domain)" + }, + "password": { + "type": "string", + "format": "password", + "description": "vCenter password" + }, + "vmImage": { + "type": "string", + "description": "BIG-IP VM image template name" + }, + "networkInterfaceMapping": { + "type": "array", + "description": "Network interface mappings for VM deployment", + "minItems": 1, + "items": { + "type": "object", + "required": [ + "network" + ], + "properties": { + "network": { + "type": "string", + "description": "Network name in vCenter" + } + } + } + }, + "ipPoolAliasMapping": { + "type": "array", + "description": "IP pool alias mappings", + "items": { + "type": "object", + "required": [ + "alias", + "ipPoolReference" + ], + "properties": { + "alias": { + "type": "string", + "description": "Alias name" + }, + "ipPoolReference": { + "type": "string", + "description": "IP pool reference link" + } + } + } + } + } + }, + "VMwareEnvironmentPropertiesResponse": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "datacenter": { + "type": "string" + }, + "user": { + "type": "string" + }, + "password": { + "type": "string", + "description": "Encrypted password (base64-encoded). Frontend should pass this through as-is without decrypting." + }, + "vmImage": { + "type": "string" + }, + "networkInterfaceMapping": { + "type": "array", + "items": { + "type": "object", + "properties": { + "network": { + "type": "string" + } + } + } + }, + "ipPoolAliasMapping": { + "type": "array", + "items": { + "type": "object", + "properties": { + "alias": { + "type": "string" + }, + "ipPoolReference": { + "type": "string" + } + } + } + } + } + }, + "CloudEnvironment": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "providerReference": { + "$ref": "#/components/schemas/Reference" + }, + "deviceTemplateReference": { + "$ref": "#/components/schemas/Reference" + }, + "isVmwCluster": { + "type": "boolean" + }, + "vmwProperties": { + "$ref": "#/components/schemas/VMwareEnvironmentPropertiesResponse" + }, + "validationStatus": { + "type": "string", + "enum": [ + "PENDING", + "VALIDATED", + "FAILED" + ] + }, + "validationErrors": { + "type": "array", + "items": { + "type": "string" + } + }, + "selfLink": { + "type": "string", + "format": "uri" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "Reference": { + "type": "object", + "required": [ + "link" + ], + "properties": { + "link": { + "type": "string", + "format": "uri" + }, + "fullPath": { + "type": "string" + } + } + }, + "ValidationError": { + "type": "object", + "properties": { + "code": { + "type": "integer" + }, + "message": { + "type": "string" + }, + "validationType": { + "type": "string", + "enum": [ + "CLUSTER_VALIDATION", + "CONNECTION_TEST", + "DATACENTER_VALIDATION", + "NETWORK_VALIDATION", + "VMIMAGE_VALIDATION" + ] + }, + "details": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + } + } + }, + "CreateCloudProviderRequest": { + "type": "object", + "required": [ + "providerType", + "name" + ], + "properties": { + "providerType": { + "type": "string", + "enum": [ + "VMware" + ], + "description": "Type of cloud provider" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "Name of the cloud provider" + }, + "vmwProperties": { + "$ref": "#/components/schemas/VMwareProviderProperties" + } + } + }, + "UpdateCloudProviderRequest": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "Name of the cloud provider" + }, + "vmwProperties": { + "$ref": "#/components/schemas/VMwareProviderProperties" + } + } + }, + "VMwareProviderProperties": { + "type": "object", + "required": [ + "vCenterHostname" + ], + "properties": { + "vCenterHostname": { + "type": "string", + "format": "hostname", + "description": "Hostname or IP address of vCenter server" + } + } + }, + "CloudProvider": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier of the cloud provider" + }, + "providerType": { + "type": "string", + "enum": [ + "VMware" + ], + "description": "Type of cloud provider" + }, + "name": { + "type": "string", + "description": "Name of the cloud provider" + }, + "vmwProperties": { + "$ref": "#/components/schemas/VMwareProviderProperties" + }, + "selfLink": { + "type": "string", + "format": "uri", + "description": "Self-referencing link to the cloud provider" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the provider was created" + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the provider was last updated" + } + } + }, + "VMTaskRequest": { + "type": "object", + "required": [ + "envReference" + ], + "properties": { + "envReference": { + "type": "string", + "description": "ID (UUID) or name of the cloud environment to use for this VM task.\n" + }, + "vmName": { + "type": "string", + "description": "For create-vm only: optional name for the created VM. If omitted,\na name is generated automatically using the configured naming\nprefix (default: \"autoscale-bigip-\"). Ignored by delete-vm.\n" + }, + "vmIP": { + "type": "string", + "description": "IP address of the VM. For delete-vm, either vmIP or vmUuid must be\nsupplied; vmIP takes precedence when both are present.\n" + }, + "vmUuid": { + "type": "string", + "description": "vCenter Managed Object Reference (MoRef) of the VM. For delete-vm,\neither vmIP or vmUuid must be supplied. Recommended for cleaning up\norphaned clones that never acquired an IP \u2014 the create-vm response\nreturns vmUuid as soon as the clone succeeds.\n" + } + } + }, + "VMTaskResponse": { + "type": "object", + "properties": { + "taskId": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "IN_PROGRESS", + "COMPLETED", + "FAILED" + ] + }, + "envReference": { + "type": "string", + "description": "Environment name used for this task" + }, + "taskType": { + "type": "string", + "enum": [ + "CREATE_VM", + "DELETE_VM" + ] + }, + "message": { + "type": "string" + }, + "vmName": { + "type": "string", + "description": "Name of the created/cloned VM" + }, + "vmUuid": { + "type": "string", + "description": "vCenter Managed Object Reference (MoRef) of the created/cloned VM.\nPopulated as soon as the clone succeeds, so it is available even\nfor tasks that later fail during power-on or IP acquisition.\n" + }, + "vmIP": { + "type": "string", + "description": "IP address of the created/deleted VM" + }, + "selfLink": { + "type": "string", + "format": "uri" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "DatacenterInfo": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the datacenter" + }, + "datacenter": { + "type": "string", + "description": "Managed Object Reference (datacenter ID)" + } + } + }, + "ClusterInfo": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the cluster" + }, + "cluster": { + "type": "string", + "description": "Managed Object Reference (cluster ID)" + } + } + }, + "HostInfo": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the host" + }, + "host": { + "type": "string", + "description": "Managed Object Reference (host ID)" + } + } + }, + "NetworkInfo": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the network" + }, + "network": { + "type": "string", + "description": "Managed Object Reference (network ID)" + } + } + }, + "DatastoreInfo": { + "type": "object", + "properties": { + "datastore": { + "type": "string", + "description": "Managed Object Reference (datastore ID)" + }, + "name": { + "type": "string", + "description": "Name of the datastore" + } + } + }, + "VMInfo": { + "type": "object", + "properties": { + "vm": { + "type": "string", + "description": "Managed Object Reference (VM ID)" + }, + "name": { + "type": "string", + "description": "Name of the virtual machine" + } + } + }, + "ConnectRequest": { + "type": "object", + "required": [ + "username", + "password", + "providerName" + ], + "properties": { + "username": { + "type": "string", + "description": "vSphere username" + }, + "password": { + "type": "string", + "description": "vSphere password" + }, + "providerName": { + "type": "string", + "description": "Name of the provider (used to resolve vSphere hostname)" + } + } + }, + "ConnectResponse": { + "type": "object", + "properties": { + "connId": { + "type": "string", + "description": "Connection ID to use for subsequent discovery API calls" + }, + "message": { + "type": "string", + "description": "Connection status message" + } + } + }, + "DeviceTemplateWriteRequest": { + "type": "object", + "description": "Payload for creating (POST) or fully replacing (PUT) a device template.\n", + "required": [ + "name", + "provider", + "definition" + ], + "properties": { + "name": { + "type": "string", + "description": "Human-readable name for the device template. Must be unique.", + "minLength": 1, + "maxLength": 255, + "example": "BIG-IP Standard Template" + }, + "provider": { + "type": "string", + "description": "Provider or vendor (e.g. VMware, AWS, Azure).", + "minLength": 1, + "maxLength": 255, + "example": "VMware" + }, + "description": { + "type": "string", + "description": "Optional human-readable description.", + "nullable": true, + "maxLength": 1000, + "example": "Standard VMware configuration for production workloads" + }, + "draft": { + "type": "boolean", + "description": "When `true`, the template is created/kept in DRAFT state.\nWhen `false` or omitted, a DRAFT template is promoted to NEW.\n", + "default": false + }, + "definition": { + "$ref": "#/components/schemas/DeviceTemplateDefinition" + } + } + }, + "DeviceTemplatePatchRequest": { + "type": "object", + "description": "Payload for partially updating a device template (PATCH).\nAll fields are optional \u2014 only provided fields are modified.\nFor `definition`, merge-patch semantics apply.\n", + "properties": { + "name": { + "type": "string", + "description": "Human-readable name. Must be unique.", + "minLength": 1, + "maxLength": 255, + "example": "BIG-IP Standard Template v2" + }, + "provider": { + "type": "string", + "description": "Provider or vendor.", + "minLength": 1, + "maxLength": 255, + "example": "VMware" + }, + "description": { + "type": "string", + "description": "Optional description. Set to `null` to clear.", + "nullable": true, + "maxLength": 1000, + "example": "Updated description" + }, + "draft": { + "type": "boolean", + "description": "Controls DRAFT state on partial update." + }, + "definition": { + "$ref": "#/components/schemas/PatchDeviceTemplateDefinition" + } + } + }, + "DeviceTemplateCloneRequest": { + "type": "object", + "description": "Payload for cloning an existing device template.", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "Name for the cloned template. Must be unique.", + "minLength": 1, + "maxLength": 255, + "example": "BIG-IP Standard Template (Copy)" + } + } + }, + "DeviceTemplateDeployRequest": { + "type": "object", + "description": "Payload for deploying a device template to a target BIG-IP device.", + "required": [ + "mgmtIp", + "encodedBasicAuth" + ], + "properties": { + "mgmtIp": { + "type": "string", + "format": "ipv4", + "description": "Management IP address of the target BIG-IP device.", + "example": "192.168.1.100" + }, + "username": { + "type": "string", + "description": "Username for the BIG-IP device (optional, for display/logging purposes).", + "minLength": 1, + "maxLength": 255, + "example": "admin" + }, + "encodedBasicAuth": { + "type": "string", + "description": "Base64-encoded basic authentication credentials (username:password).", + "minLength": 1, + "example": "YWRtaW46YWRtaW5QYXNzd29yZDEyMw==" + } + } + }, + "DeviceTemplateDeployResponse": { + "type": "object", + "description": "Response returned after initiating deployment.", + "required": [ + "status", + "deviceTemplateId", + "deploymentTaskId", + "selfLink" + ], + "properties": { + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 202 + }, + "deviceTemplateId": { + "type": "string", + "format": "uuid", + "description": "UUID of the device template being deployed.", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "deploymentTaskId": { + "type": "string", + "format": "uuid", + "description": "UUID of the deployment task for tracking progress.", + "example": "c3d4e5f6-a7b8-4012-8def-123456789012" + }, + "selfLink": { + "type": "string", + "description": "URI path to the deployment task resource.", + "example": "/api/device-templates/tasks/c3d4e5f6-a7b8-4012-8def-123456789012" + }, + "warning": { + "type": "string", + "description": "Optional warning from the onboarding service. Present when the declaration\ncontains restart-causing resources (e.g., sys:license, sys:provision,\nshared:licensing:registration).\n", + "nullable": true, + "example": "Onboarding operation might cause a BIG-IP system restart." + } + } + }, + "HostnameComponent": { + "type": "object", + "description": "A hostname building block.", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "description": "Component type.", + "enum": [ + "STATIC_TEXT", + "SERIAL_NUMBER" + ], + "example": "STATIC_TEXT" + }, + "value": { + "type": "string", + "description": "Value for the component. Required for STATIC_TEXT, null for SERIAL_NUMBER.", + "nullable": true, + "example": "bigip-" + } + } + }, + "UserAccount": { + "type": "object", + "description": "A BIG-IP user account definition with required credentials and role assignment.", + "required": [ + "username", + "password", + "role" + ], + "properties": { + "username": { + "type": "string", + "description": "Username for the BIG-IP account. Must start with a letter or underscore,\nand contain only letters, digits, hyphens, dots, or underscores.\n", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z_][-a-zA-Z_.0-9]*$", + "example": "admin" + }, + "password": { + "type": "string", + "description": "Password for the BIG-IP account. Must be at least 8 characters.", + "minLength": 8, + "maxLength": 255, + "example": "adminP@ss!" + }, + "role": { + "type": "string", + "description": "User role on the BIG-IP device. Defines the access level and permissions\nfor the user account. Common roles include 'admin', 'operator', 'guest', etc.\n", + "minLength": 1, + "maxLength": 255, + "example": "admin" + }, + "shell": { + "type": "string", + "description": "Shell access level for the user (e.g., 'bash', 'tmsh', 'none').", + "example": "bash" + } + } + }, + "ProvisionedModule": { + "type": "object", + "description": "A BIG-IP module provisioning entry.", + "required": [ + "module", + "level" + ], + "properties": { + "module": { + "type": "string", + "description": "BIG-IP module name.", + "enum": [ + "AFM", + "AM", + "APM", + "ASM", + "AVR", + "DOS", + "FPS", + "GTM", + "ILX", + "LC", + "LTM", + "PEM", + "SWG", + "URLDB" + ], + "example": "LTM" + }, + "level": { + "type": "string", + "description": "Provisioning level.", + "enum": [ + "DEDICATED", + "MINIMUM", + "NOMINAL", + "NONE" + ], + "example": "NOMINAL" + } + } + }, + "NetworkRoute": { + "type": "object", + "description": "A network route definition.", + "required": [ + "name", + "gatewayAddress", + "destination" + ], + "properties": { + "name": { + "type": "string", + "example": "default" + }, + "gatewayAddress": { + "type": "string", + "example": "10.0.0.1" + }, + "destination": { + "type": "string", + "example": "0.0.0.0/0" + } + } + }, + "VlanDefinition": { + "type": "object", + "description": "A VLAN definition.", + "required": [ + "name", + "nic" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "example": "external" + }, + "nic": { + "type": "string", + "description": "Network interface card identifier (e.g., \"1.1\", \"1.2\").", + "pattern": "^[0-9]+\\.[0-9]+$", + "example": "1.1" + }, + "mtu": { + "type": "integer", + "description": "Maximum transmission unit size in bytes.", + "minimum": 576, + "maximum": 9198, + "example": 1500 + }, + "tag": { + "type": "integer", + "description": "VLAN tag identifier.", + "minimum": 1, + "maximum": 4094, + "example": 100 + } + } + }, + "SelfIpDefinition": { + "type": "object", + "description": "A self-IP definition for the BIG-IP device.\n\nSelf IPs are allocated from an IP pool specified by `ipPoolReference`.\n", + "required": [ + "name", + "vlanName", + "ipPoolReference" + ], + "properties": { + "name": { + "type": "string", + "description": "Self-IP name. Must be unique within the template.", + "example": "external-self" + }, + "ipPoolReference": { + "type": "string", + "format": "uuid", + "description": "UUID referencing an existing IP pool for self-IP allocation.\n", + "example": "c3d4e5f6-a7b8-4890-8bcd-ef1234567892" + }, + "vlanName": { + "type": "string", + "description": "Name of the VLAN this self-IP is associated with.", + "example": "external" + }, + "portLockdown": { + "type": "string", + "description": "Port lockdown mode.", + "enum": [ + "none", + "default", + "all", + "custom", + "custom-default" + ], + "default": "none", + "example": "default" + }, + "allowServices": { + "type": "array", + "description": "Allowed services when portLockdown is custom/custom-default.", + "nullable": true, + "items": { + "type": "string" + }, + "example": null + } + } + }, + "ManagementIp": { + "type": "object", + "description": "Management IP configuration.\n\nThe management IP is configured via DHCP. This field is reserved for future use.\n\nThe field should be omitted or set to `null`.\n", + "properties": {} + }, + "BFDTimers": { + "type": "object", + "description": "Bidirectional Forwarding Detection (BFD) timer configuration.\nAll values are specified in milliseconds (ms).\n", + "required": [ + "transmitInterval", + "receiveInterval", + "detectionMultiplier" + ], + "properties": { + "transmitInterval": { + "type": "integer", + "description": "BFD transmission interval in milliseconds.\nThe time interval between BFD control packets sent to the peer.\n", + "minimum": 1, + "maximum": 60000, + "example": 300 + }, + "receiveInterval": { + "type": "integer", + "description": "BFD reception interval in milliseconds.\nThe time interval expected between BFD control packets received from the peer.\n", + "minimum": 1, + "maximum": 60000, + "example": 300 + }, + "detectionMultiplier": { + "type": "integer", + "description": "BFD detection multiplier.\nThe number of BFD packets that must be missed to declare the session down.\nDetection time = transmitInterval \u00d7 detectionMultiplier.\n", + "minimum": 1, + "maximum": 50, + "example": 3 + } + } + }, + "BgpNeighbor": { + "type": "object", + "description": "A BGP neighbor configuration.", + "required": [ + "name", + "remoteAs" + ], + "properties": { + "name": { + "type": "string", + "description": "IP address of the BGP neighbor.", + "example": "10.0.1.1" + }, + "description": { + "type": "string", + "description": "Optional description of the neighbor.", + "nullable": true, + "example": "Upstream BGP neighbor" + }, + "remoteAs": { + "type": "integer", + "description": "Remote AS number of the neighbor.", + "minimum": 1, + "maximum": 4294967295, + "example": 65002 + }, + "password": { + "type": "string", + "description": "Optional password for BGP authentication.", + "nullable": true, + "minLength": 1, + "maxLength": 255, + "example": "SecureBGPPassword" + }, + "ebgpMultihop": { + "type": "integer", + "description": "Allow EBGP neighbors not on directly connected networks.\nSpecifies the maximum number of hops allowed to reach the neighbor.\n", + "nullable": true, + "minimum": 1, + "maximum": 255, + "default": 1, + "example": 1 + }, + "fallOver": { + "type": "string", + "description": "Fall-over detection method for BGP neighbor.\n- \"bfd\": Bidirectional Forwarding Detection (BFD)\n- \"bfd-multihop\": BFD for multihop neighbors\n- \"none\": No fall-over detection\n", + "enum": [ + "bfd", + "bfd-multihop", + "none" + ], + "default": "none", + "example": "bfd", + "nullable": true + }, + "bfdTimers": { + "$ref": "#/components/schemas/BFDTimers", + "description": "BFD timer configuration (required if fallOver is \"bfd\" or \"bfd-multihop\").\n", + "nullable": true + }, + "enabled": { + "type": "boolean", + "description": "Whether the neighbor is enabled.", + "default": true, + "example": true + } + } + }, + "BgpConfig": { + "type": "object", + "description": "BGP routing configuration for the BIG-IP device.", + "required": [ + "name", + "localAs", + "routerId", + "routeDomain", + "addressFamilies" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the BGP configuration.", + "example": "my_bgp" + }, + "description": { + "type": "string", + "description": "Optional description of the BGP configuration.", + "nullable": true, + "example": "Example BGP configuration" + }, + "localAs": { + "type": "integer", + "description": "Local AS number.", + "minimum": 1, + "maximum": 4294967295, + "example": 65001 + }, + "routerId": { + "type": "string", + "description": "Router ID reference. Must be the name of a self IP defined in the selfIpList.\nThe actual router ID (IP address) will be resolved from the referenced self IP's address at deployment time.\n", + "example": "external-self" + }, + "routeDomain": { + "type": "string", + "description": "Route domain for the BGP configuration.", + "example": "/Common/0" + }, + "enabled": { + "type": "boolean", + "description": "Whether BGP is enabled.", + "default": true, + "example": true + }, + "defaultLocalPreference": { + "type": "integer", + "description": "Default local preference value.", + "default": 100, + "example": 100 + }, + "holdTime": { + "type": "integer", + "description": "BGP hold time in seconds.", + "default": 90, + "example": 90 + }, + "keepAlive": { + "type": "integer", + "description": "BGP keepalive interval in seconds.", + "default": 30, + "example": 30 + }, + "neighbor": { + "type": "array", + "description": "List of BGP neighbors.", + "items": { + "$ref": "#/components/schemas/BgpNeighbor" + }, + "example": [ + { + "name": "10.0.1.1", + "description": "Upstream BGP neighbor", + "remoteAs": 65002, + "password": "bgpSecretKey123", + "ebgpMultihop": 1, + "fallOver": "bfd", + "bfdTimers": { + "transmitInterval": 300, + "receiveInterval": 300, + "detectionMultiplier": 3 + }, + "enabled": true + } + ] + }, + "addressFamilies": { + "type": "array", + "description": "List of address family configurations for BGP.\nEach entry defines an internet protocol (e.g. `ipv4`) and an optional\nlist of routing protocols to redistribute into BGP.\nIf omitted, a default `ipv4` address family with `kernel` and `connected`\nredistribution is applied automatically.\n", + "items": { + "$ref": "#/components/schemas/BgpAddressFamily" + }, + "example": [ + { + "internetProtocol": "ipv4", + "redistributionList": [ + { + "routingProtocol": "connected" + }, + { + "routingProtocol": "kernel" + } + ] + } + ] + } + } + }, + "BgpRedistribution": { + "type": "object", + "description": "A routing protocol redistribution entry for a BGP address family.", + "required": [ + "routingProtocol" + ], + "properties": { + "routingProtocol": { + "type": "string", + "description": "The routing protocol to redistribute into BGP (e.g. `connected`, `kernel`).\nThe accepted values depend on the BIG-IP version and configuration.\n", + "example": "connected" + } + } + }, + "BgpAddressFamily": { + "type": "object", + "description": "An address family configuration for BGP.\nDefines the internet protocol and the list of routing protocols\nto redistribute into BGP for that address family.\nOnly `ipv4` is currently supported for `internetProtocol`.\n", + "required": [ + "internetProtocol", + "redistributionList" + ], + "properties": { + "internetProtocol": { + "type": "string", + "description": "The internet protocol for this address family.\nCurrently only `ipv4` is supported.\n", + "example": "ipv4" + }, + "redistributionList": { + "type": "array", + "description": "List of routing protocols to redistribute into BGP for this address family.\nIf omitted or empty, no redistribution is configured.\n", + "items": { + "$ref": "#/components/schemas/BgpRedistribution" + }, + "example": [ + { + "routingProtocol": "connected" + }, + { + "routingProtocol": "kernel" + } + ] + } + } + }, + "DeviceTemplateDefinition": { + "type": "object", + "description": "Template definition containing all BIG-IP device configuration parameters.", + "required": [ + "rootPassword" + ], + "properties": { + "rootPassword": { + "type": "string", + "description": "BIG-IP root password. Must be at least 8 characters.", + "minLength": 8, + "example": "s3cur3P@ss!" + }, + "timeZone": { + "type": "string", + "description": "NTP timezone string applied to the BIG-IP device.", + "nullable": true, + "maxLength": 100, + "example": "America/Los_Angeles" + }, + "defaultRoute": { + "type": "string", + "description": "Default network gateway route for the BIG-IP device. Must be a valid IP address without prefix.", + "nullable": true, + "example": "10.0.0.1" + }, + "managementSslPort": { + "type": "integer", + "description": "BIG-IP management SSL port. If omitted, the device default is used.", + "nullable": true, + "minimum": 0, + "maximum": 65535, + "example": 443 + }, + "managementIp": { + "$ref": "#/components/schemas/ManagementIp" + }, + "hostnameComponents": { + "type": "array", + "description": "Ordered array of hostname building blocks.", + "items": { + "$ref": "#/components/schemas/HostnameComponent" + }, + "example": [ + { + "type": "STATIC_TEXT", + "value": "bigip-" + }, + { + "type": "SERIAL_NUMBER", + "value": null + } + ] + }, + "lookupServerList": { + "type": "array", + "description": "List of DNS lookup server addresses.", + "items": { + "type": "string" + }, + "example": [ + "8.8.8.8", + "8.8.4.4" + ] + }, + "ntpServerList": { + "type": "array", + "description": "List of NTP server addresses.", + "items": { + "type": "string" + }, + "example": [ + "0.pool.ntp.org" + ] + }, + "userAccountList": { + "type": "array", + "description": "Array of BIG-IP user accounts to create.", + "items": { + "$ref": "#/components/schemas/UserAccount" + } + }, + "provisionedModuleList": { + "type": "array", + "description": "Array of BIG-IP modules to provision.", + "items": { + "$ref": "#/components/schemas/ProvisionedModule" + } + }, + "networkRouteList": { + "type": "array", + "description": "Array of network interface routes.", + "items": { + "$ref": "#/components/schemas/NetworkRoute" + } + }, + "vlanList": { + "type": "array", + "description": "Array of VLAN definitions.", + "items": { + "$ref": "#/components/schemas/VlanDefinition" + } + }, + "selfIpList": { + "type": "array", + "description": "Array of self-IP definitions for the BIG-IP device.", + "items": { + "$ref": "#/components/schemas/SelfIpDefinition" + } + }, + "bgpConfig": { + "$ref": "#/components/schemas/BgpConfig" + } + } + }, + "PatchDeviceTemplateDefinition": { + "type": "object", + "description": "Partial template definition for merge-patching (used by PATCH).\nAll fields are optional \u2014 only provided fields are updated.\nOmitted fields retain their current values.\nTo explicitly clear a nullable field, set it to `null`.\n", + "properties": { + "rootPassword": { + "type": "string", + "description": "BIG-IP root password.", + "nullable": true, + "minLength": 1, + "example": "s3cur3P@ss!" + }, + "timeZone": { + "type": "string", + "description": "NTP timezone string.", + "nullable": true, + "example": "America/Los_Angeles" + }, + "defaultRoute": { + "type": "string", + "description": "Default network gateway route.", + "nullable": true, + "example": "10.0.0.1" + }, + "managementSslPort": { + "type": "integer", + "description": "BIG-IP management SSL port.", + "nullable": true, + "example": 443 + }, + "managementIp": { + "$ref": "#/components/schemas/ManagementIp" + }, + "hostnameComponents": { + "type": "array", + "description": "Ordered array of hostname building blocks.", + "items": { + "$ref": "#/components/schemas/HostnameComponent" + } + }, + "lookupServerList": { + "type": "array", + "description": "List of DNS lookup server addresses.", + "items": { + "type": "string" + } + }, + "ntpServerList": { + "type": "array", + "description": "List of NTP server addresses.", + "items": { + "type": "string" + } + }, + "userAccountList": { + "type": "array", + "description": "Array of BIG-IP user accounts.", + "items": { + "$ref": "#/components/schemas/UserAccount" + } + }, + "provisionedModuleList": { + "type": "array", + "description": "Array of BIG-IP modules to provision.", + "items": { + "$ref": "#/components/schemas/ProvisionedModule" + } + }, + "networkRouteList": { + "type": "array", + "description": "Array of network interface routes.", + "items": { + "$ref": "#/components/schemas/NetworkRoute" + } + }, + "vlanList": { + "type": "array", + "description": "Array of VLAN definitions.", + "items": { + "$ref": "#/components/schemas/VlanDefinition" + } + }, + "selfIpList": { + "type": "array", + "description": "Array of self-IP definitions. Replaces the entire selfIpList on PATCH.\n", + "items": { + "$ref": "#/components/schemas/SelfIpDefinition" + } + }, + "bgpConfig": { + "$ref": "#/components/schemas/BgpConfig" + } + } + }, + "DeviceTemplate": { + "type": "object", + "description": "Full device template resource representation.\nIncludes identity, lifecycle state, lock state, the template definition,\nvalidation tracking, and audit timestamps.\n", + "required": [ + "id", + "name", + "provider", + "state", + "locked", + "lockReason", + "definition", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Server-generated UUID of the device template.", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "name": { + "type": "string", + "description": "Unique human-readable name.", + "example": "BIG-IP Standard Template" + }, + "provider": { + "type": "string", + "description": "Provider or vendor.", + "example": "VMware" + }, + "description": { + "type": "string", + "description": "Optional description.", + "nullable": true, + "example": "Standard VMware configuration for production workloads" + }, + "state": { + "type": "string", + "description": "Current lifecycle state: DRAFT \u2192 NEW \u2192 DEPLOYING \u2192 DEPLOYED.", + "enum": [ + "DRAFT", + "NEW", + "DEPLOYING", + "DEPLOYED" + ], + "example": "DRAFT" + }, + "locked": { + "type": "boolean", + "description": "When true, the template cannot be modified until unlocked.", + "example": false + }, + "lockReason": { + "type": "string", + "description": "Reason the record is locked: NONE (unlocked), DEPLOYMENT, READ_ONLY.", + "enum": [ + "NONE", + "DEPLOYMENT", + "READ_ONLY" + ], + "example": "NONE" + }, + "definition": { + "$ref": "#/components/schemas/DeviceTemplateDefinition" + }, + "lastValidatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent successful validation. Null if never validated.", + "nullable": true, + "example": null + }, + "validatedAgainstLiveVm": { + "type": "boolean", + "description": "True if the last validation was against a live BIG-IP VM.", + "example": false + }, + "lastDeployedVersion": { + "type": "integer", + "description": "Deploy counter. Reserved for future versioning.", + "nullable": true, + "example": null + }, + "selfLink": { + "type": "string", + "description": "URI path to this device template resource.", + "readOnly": true, + "example": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp (UTC) when the template was created.", + "readOnly": true, + "example": "2026-01-15T09:23:41Z" + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp (UTC) when the template was last modified.", + "readOnly": true, + "example": "2026-01-15T09:23:41Z" + } + } + }, + "DeviceTemplateListResponse": { + "type": "object", + "description": "Paginated list response for device templates.", + "required": [ + "status", + "count", + "items", + "selfLink" + ], + "properties": { + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 200 + }, + "count": { + "type": "integer", + "description": "Number of items in the current response.", + "example": 2 + }, + "totalItems": { + "type": "integer", + "description": "Total matching records. Only present when `$count=true`.", + "example": 2 + }, + "items": { + "type": "array", + "description": "Array of device template resources.", + "items": { + "$ref": "#/components/schemas/DeviceTemplate" + } + }, + "selfLink": { + "type": "string", + "description": "URI path to this list resource.", + "example": "/api/device-templates" + } + } + }, + "DeviceTemplateGetResponse": { + "description": "Response for GET by ID. Extends DeviceTemplate with a `status` field.", + "allOf": [ + { + "$ref": "#/components/schemas/DeviceTemplate" + }, + { + "type": "object", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 200 + } + } + } + ] + }, + "DeviceTemplateMutationResponse": { + "type": "object", + "description": "Response returned after creating, updating, or cloning a device template.\n- **200**: Synchronous save completed.\n- **201**: Created in DRAFT state.\n", + "required": [ + "id", + "state", + "status", + "selfLink", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "UUID of the device template.", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "state": { + "type": "string", + "description": "Current lifecycle state after the operation.", + "enum": [ + "DRAFT", + "NEW", + "DEPLOYED" + ], + "example": "NEW" + }, + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 200 + }, + "selfLink": { + "type": "string", + "description": "URI path to the device template resource.", + "example": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp (UTC) when the template was created.", + "example": "2026-01-15T09:23:41Z" + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp (UTC) when the template was last modified.", + "example": "2026-03-22T14:45:10Z" + } + } + }, + "DeviceTemplateDeleteResponse": { + "type": "object", + "description": "Response returned after deleting a device template.", + "required": [ + "id", + "status", + "deletedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "UUID of the deleted device template.", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 200 + }, + "deletedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp (UTC) when the template was deleted.", + "example": "2026-04-10T16:00:00Z" + } + } + }, + "DeviceTemplateLockResponse": { + "type": "object", + "description": "Response returned after locking or unlocking a device template.", + "required": [ + "id", + "locked", + "lockReason", + "status", + "selfLink", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "UUID of the device template.", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "locked": { + "type": "boolean", + "description": "Current lock state after the operation.", + "example": true + }, + "lockReason": { + "type": "string", + "description": "Current lock reason: NONE (unlocked), READ_ONLY (manually locked).", + "enum": [ + "NONE", + "READ_ONLY" + ], + "example": "READ_ONLY" + }, + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 200 + }, + "selfLink": { + "type": "string", + "description": "URI path to the device template resource.", + "example": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000" + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp (UTC) when the lock state was changed.", + "example": "2026-04-15T08:20:00Z" + } + } + }, + "DeviceTemplateValidationResponse": { + "type": "object", + "description": "Response returned after validating a device template.\nAlways HTTP 200 \u2014 inspect `valid` and each tier's result for pass/fail.\n", + "required": [ + "id", + "status", + "valid", + "validatedAt", + "dataSanity", + "templateSchema", + "selfLink" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "UUID of the validated device template.", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 200 + }, + "valid": { + "type": "boolean", + "description": "Overall validation result \u2014 `true` only if all tiers pass.", + "example": false + }, + "validatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp (UTC) when validation was performed.", + "example": "2026-04-15T10:30:00Z" + }, + "dataSanity": { + "type": "object", + "description": "Tier 1 \u2014 Data & Sanity validation results.", + "required": [ + "valid", + "errors", + "warnings" + ], + "properties": { + "valid": { + "type": "boolean", + "example": true + }, + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ValidationIssue" + } + }, + "warnings": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ValidationIssue" + } + } + } + }, + "templateSchema": { + "type": "object", + "description": "Tier 2 \u2014 Template / Schema validation results.", + "required": [ + "valid", + "errors", + "warnings" + ], + "properties": { + "valid": { + "type": "boolean", + "example": false + }, + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ValidationIssue" + } + }, + "warnings": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ValidationIssue" + } + } + } + }, + "selfLink": { + "type": "string", + "description": "URI path to the validated device template resource.", + "example": "/api/device-templates/550e8400-e29b-41d4-a716-446655440000" + } + } + }, + "ValidationIssue": { + "type": "object", + "description": "A single validation error or warning.", + "required": [ + "field", + "message" + ], + "properties": { + "field": { + "type": "string", + "description": "Dot-notation path to the problematic field.", + "example": "definition.managementSslPort" + }, + "message": { + "type": "string", + "description": "Human-readable description of the issue.", + "example": "Value must be between 1 and 65535" + } + } + }, + "DeviceTemplateTask": { + "type": "object", + "description": "A task associated with a device template lifecycle operation (e.g., deployment).\n", + "required": [ + "id", + "deviceTemplateId", + "type", + "status", + "taskStatus", + "createdAt", + "selfLink" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Server-generated UUID of the task.", + "example": "660e8400-e29b-41d4-a716-446655440001" + }, + "deviceTemplateId": { + "type": "string", + "format": "uuid", + "description": "UUID of the device template this task belongs to.", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "type": { + "type": "string", + "description": "Type of task operation.", + "enum": [ + "DEPLOYMENT" + ], + "example": "DEPLOYMENT" + }, + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 200 + }, + "taskStatus": { + "type": "string", + "description": "Current status of the task.", + "enum": [ + "PENDING", + "IN_PROGRESS", + "COMPLETED", + "FAILED", + "UNKNOWN" + ], + "example": "IN_PROGRESS" + }, + "state": { + "type": "string", + "description": "Current state from the external service (e.g., \"onboarding\", \"licensing\").", + "nullable": true, + "example": "onboarding" + }, + "failureReason": { + "type": "string", + "description": "Reason for task failure. Only present when taskStatus is FAILED.", + "nullable": true, + "example": null + }, + "startedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task started execution.", + "nullable": true, + "example": "2026-04-20T12:00:00Z" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created.", + "example": "2026-04-20T12:00:00Z" + }, + "completedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task completed.", + "nullable": true, + "example": "2026-04-20T12:05:00Z" + }, + "selfLink": { + "type": "string", + "description": "URI path to this task resource.", + "example": "/api/device-templates/tasks/660e8400-e29b-41d4-a716-446655440001" + } + } + }, + "DeviceTemplateError": { + "type": "object", + "description": "Error response returned by the Device Template API.", + "required": [ + "status", + "message" + ], + "properties": { + "status": { + "type": "integer", + "format": "int32", + "description": "HTTP status code.", + "example": 400 + }, + "message": { + "type": "string", + "description": "Short human-readable error summary.", + "example": "Bad Request \u2014 request validation failed" + }, + "details": { + "type": "string", + "description": "Detailed explanation of the error cause and suggested resolution.", + "nullable": true, + "example": "failed to create device template" + } + } + }, + "IPPool": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z_][a-zA-Z0-9_.\\-]*$", + "description": "Pool name. Rules:\n- Minimum length: 1 character\n- Maximum length: 255 characters\n- First character must be a letter (a-z, A-Z) or underscore (_)\n- Remaining characters may be letters, digits, hyphens (-), underscores (_), or dots (.)\n- The following reserved words are not allowed: all, delete, disable, enable, help, list, none, show, None\n" + }, + "description": { + "type": "string" + }, + "addressFamily": { + "type": "string", + "enum": [ + "IPv4", + "IPv6" + ] + }, + "address": { + "type": "string", + "description": "Pool network expressed in CIDR notation.", + "example": "10.0.0.0/24" + }, + "gateway": { + "type": "string", + "nullable": true, + "example": "10.0.0.1" + }, + "addressRanges": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AddressRange" + } + }, + "totalAddressCount": { + "type": "integer", + "minimum": 0 + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "deletedAt": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "required": [ + "id", + "name", + "addressFamily", + "address", + "addressRanges", + "totalAddressCount", + "createdAt", + "updatedAt" + ] + }, + "IPPoolCreateRequest": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z_][a-zA-Z0-9_.\\-]*$", + "description": "Pool name. Rules:\n- Minimum length: 1 character\n- Maximum length: 255 characters\n- First character must be a letter (a-z, A-Z) or underscore (_)\n- Remaining characters may be letters, digits, hyphens (-), underscores (_), or dots (.)\n- The following reserved words are not allowed: all, delete, disable, enable, help, list, none, show, None\n" + }, + "description": { + "type": "string" + }, + "addressFamily": { + "type": "string", + "enum": [ + "IPv4", + "IPv6" + ], + "description": "Address family of the pool. When omitted, it is inferred from the CIDR (IPv4 or IPv6)." + }, + "address": { + "type": "string", + "example": "10.0.0.0/24" + }, + "gateway": { + "type": "string", + "nullable": true + }, + "addressRanges": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/AddressRange" + } + } + }, + "required": [ + "name", + "address", + "addressRanges" + ] + }, + "IPPoolUpdateRequest": { + "allOf": [ + { + "$ref": "#/components/schemas/IPPoolCreateRequest" + } + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Should match the path parameter; the server overwrites mismatched values." + } + } + }, + "AddressRange": { + "type": "object", + "properties": { + "firstAddress": { + "type": "string", + "example": "10.0.0.10" + }, + "lastAddress": { + "type": "string", + "example": "10.0.0.100" + } + }, + "required": [ + "firstAddress", + "lastAddress" + ] + }, + "IPPoolListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IPPool" + } + }, + "totalItems": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "items", + "totalItems" + ] + }, + "IPLease": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "poolId": { + "type": "string", + "format": "uuid" + }, + "address": { + "type": "string", + "example": "10.0.0.10" + }, + "gateway": { + "type": "string", + "nullable": true + }, + "allocationId": { + "type": "string", + "nullable": true + }, + "deviceId": { + "type": "string", + "format": "uuid", + "nullable": true + }, + "leaseTags": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Tag" + } + }, + "metadata": { + "type": "object", + "additionalProperties": true + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "deletedAt": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "required": [ + "id", + "poolId", + "address", + "createdAt", + "updatedAt" + ] + }, + "IPLeaseListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IPLease" + } + }, + "totalItems": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "items", + "totalItems" + ] + }, + "AllocationRequest": { + "type": "object", + "properties": { + "allocationId": { + "type": "string", + "description": "Identifier used to make allocation idempotent." + }, + "leaseTags": { + "type": "array", + "description": "Optional labels applied to the resulting lease.", + "items": { + "$ref": "#/components/schemas/Tag" + } + } + }, + "required": [ + "allocationId" + ] + }, + "GlobalReleaseRequest": { + "type": "object", + "description": "Release IPs across all pools by allocation ID and optional lease tags. Allocation ID is required.", + "properties": { + "allocationId": { + "type": "string", + "description": "Identifier of the allocation to release. This field is required and used to search across all pools." + }, + "leaseTags": { + "type": "array", + "description": "Optional labels to further filter leases. When provided, all tags must match (AND logic) for a lease to be released.", + "items": { + "$ref": "#/components/schemas/Tag" + } + } + }, + "required": [ + "allocationId" + ] + }, + "AllocationResponse": { + "type": "object", + "properties": { + "lease": { + "$ref": "#/components/schemas/IPLease" + }, + "poolId": { + "type": "string", + "format": "uuid" + }, + "allocationId": { + "type": "string" + } + }, + "required": [ + "lease", + "poolId", + "allocationId" + ] + }, + "ReleaseRequest": { + "type": "object", + "description": "At least one criterion must be supplied (allocationId, address, or leaseTags). When leaseTags are used as a release filter, each tag must include a non-empty name and value.", + "properties": { + "allocationId": { + "type": "string", + "nullable": true + }, + "address": { + "type": "string", + "nullable": true, + "example": "10.0.0.10" + }, + "leaseTags": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Tag" + } + } + }, + "anyOf": [ + { + "required": [ + "allocationId" + ] + }, + { + "required": [ + "address" + ] + }, + { + "required": [ + "leaseTags" + ] + } + ] + }, + "ReleaseResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IPLease" + } + }, + "totalItems": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "items", + "totalItems" + ] + }, + "Tag": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "Tag name. Duplicate names and special characters are allowed." + }, + "value": { + "type": "string", + "nullable": true + } + }, + "required": [ + "name" + ] + }, + "LicensePool": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier of the license pool", + "example": "7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + "name": { + "type": "string", + "description": "Name of the license pool", + "example": "test" + }, + "description": { + "type": "string", + "description": "Description of the license pool", + "example": "" + }, + "type": { + "type": "string", + "enum": [ + "Registration Key Pool" + ], + "description": "Type of license pool", + "example": "Registration Key Pool" + }, + "selfLink": { + "type": "string", + "format": "uri", + "description": "Self-referencing link to the license pool", + "example": "https://localhost/api/licensing/pool/regkey/licenses/7dd7b971-6eb8-4b9e-995b-1dcb1287d65f" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the pool was created" + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the pool was last updated" + } + } + }, + "LicenseOffering": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier of the license offering", + "example": "f1e2d3c4-b5a6-7890-cdef-123456789abc" + }, + "regKey": { + "type": "string", + "description": "Registration key", + "example": "U5939-99933-49705-74523-4841009" + }, + "name": { + "type": "string", + "description": "Name of the license offering", + "example": "" + }, + "description": { + "type": "string", + "description": "Description of the license offering", + "example": "" + }, + "status": { + "type": "string", + "enum": [ + "ACTIVATING_AUTOMATIC", + "ACTIVATING_MANUAL", + "ACTIVATING_MANUAL_NEED_LICENSE_TEXT", + "ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED", + "ACTIVATION_FAILED", + "READY" + ], + "description": "Current activation status of the license offering. ACTIVATING_AUTOMATIC - automatic activation in progress via F5 license server. ACTIVATING_MANUAL - manual activation flow initiated. ACTIVATING_MANUAL_NEED_LICENSE_TEXT - manual activation awaiting license text input from user. ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED - manual activation with license text supplied by user. ACTIVATION_FAILED - activation attempt failed. READY - activation completed successfully and offering is ready for use.\n", + "example": "READY" + }, + "taskId": { + "type": "string", + "format": "uuid", + "description": "ID of the async task processing this offering activation", + "example": "d4e5f6a7-b8c9-0123-defg-456789abcdef" + }, + "licenseText": { + "type": "string", + "description": "Full license text returned by F5 license server" + }, + "licenseState": { + "$ref": "#/components/schemas/LicenseState" + }, + "dossier": { + "type": "string", + "description": "Dossier string generated during activation. Present when status is ACTIVATING_MANUAL_NEED_LICENSE_TEXT. User should submit this to F5 license server to obtain the license text.\n", + "example": "1ac56379204d679f59524f2e64300d03b91b4b9ff08225ce0087d91b6cf061227610" + }, + "publicKey": { + "type": "array", + "items": { + "type": "integer" + }, + "description": "Public key bytes used for license encryption (base64 encoded in JSON)" + }, + "encryptedPrivateKey": { + "type": "array", + "items": { + "type": "integer" + }, + "description": "Encrypted private key bytes (base64 encoded in JSON)" + }, + "message": { + "type": "string", + "description": "Status message providing guidance on next steps", + "example": "You must obtain license text and supply it here" + }, + "selfLink": { + "type": "string", + "format": "uri", + "description": "Self-referencing link", + "example": "https://localhost/api/licensing/pool/regkey/licenses/7dd7b971-6eb8-4b9e-995b-1dcb1287d65f/offerings/U5939-99933-49705-74523-4841009" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the offering was created" + }, + "activatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the offering was activated" + }, + "isAssigned": { + "type": "boolean", + "description": "Indicates whether this offering has been assigned to a device.\ntrue = offering is assigned to a member device\nfalse = offering is available for assignment\n", + "example": false + } + } + }, + "LicenseMember": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier of the license member", + "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" + }, + "deviceAddress": { + "type": "string", + "format": "ipv4", + "description": "IP address of the BIG-IP device", + "example": "192.168.1.100" + }, + "deviceName": { + "type": "string", + "description": "Hostname/name of the BIG-IP device", + "example": "bigip-ve-001.local" + }, + "deviceMacAddress": { + "type": "string", + "pattern": "^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$", + "description": "MAC address of the BIG-IP device", + "example": "00:1A:2B:3C:4D:5E" + }, + "deviceLicenseText": { + "type": "string", + "description": "License text that was installed on the BIG-IP device" + }, + "status": { + "type": "string", + "enum": [ + "INSTALLING", + "INSTALLATION_FAILED", + "LICENSED" + ], + "description": "Current status of the license assignment to the member device. INSTALLING - license installation on the BIG-IP device is in progress. INSTALLATION_FAILED - license installation on the device failed. LICENSED - license has been successfully installed and the device is licensed.\n", + "example": "LICENSED" + }, + "taskId": { + "type": "string", + "format": "uuid", + "description": "ID of the async task processing this member assignment", + "example": "d4e5f6a7-b8c9-0123-defg-456789abcdef" + }, + "selfLink": { + "type": "string", + "format": "uri", + "description": "Self-referencing link", + "example": "https://localhost/api/licensing/pool/regkey/licenses/7dd7b971-6eb8-4b9e-995b-1dcb1287d65f/offerings/U5939-99933-49705-74523-4841009/members/a1b2c3d4-e5f6-7890-abcd-ef1234567890" + }, + "assignedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the license was assigned" + }, + "revokedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the license was revoked (if applicable)" + } + } + }, + "LicenseState": { + "type": "object", + "description": "Parsed license state information from the F5 license server", + "properties": { + "usage": { + "type": "string", + "description": "License usage description", + "example": "F5 Internal Product Development" + }, + "vendor": { + "type": "string", + "description": "License vendor", + "example": "F5 Networks, Inc." + }, + "dossier": { + "type": "string", + "description": "Dossier string used for license activation", + "example": "1a6806020f683204a3bbb8f3b0cf93c8f61be328908e76b0a570d2b992b0fb300e0c" + }, + "authVers": { + "type": "string", + "description": "Authorization version", + "example": "5b" + }, + "generation": { + "type": "integer", + "description": "License generation number", + "example": 0 + }, + "platformId": { + "type": "string", + "description": "Platform identifier", + "example": "Z100" + }, + "skipLicense": { + "type": "boolean", + "description": "Whether to skip license check", + "example": false + }, + "featureFlags": { + "type": "array", + "description": "List of licensed feature flags", + "items": { + "$ref": "#/components/schemas/FeatureFlag" + } + }, + "activeModules": { + "type": "array", + "description": "List of active licensed modules", + "items": { + "type": "string" + }, + "example": [ + "BIG-IP, LAB (LTM,APM,ASM,AM, GTM), VE|D826541-4208201|IPV6 Gateway|Rate Shaping", + "CGN, VE (LAB)|T172156-2328256|Routing Bundle, VE", + "DNSSEC|M275558-6506420" + ] + }, + "authorization": { + "type": "string", + "description": "License authorization signature" + }, + "serviceStatus": { + "type": "string", + "description": "Current service contract status", + "example": "As of 2026-05-14 there is no active service contract." + }, + "licensedVersion": { + "type": "string", + "description": "Licensed software version", + "example": "8.4.1" + }, + "optionalModules": { + "type": "array", + "description": "List of optional modules available for licensing", + "items": { + "type": "string" + }, + "example": [ + "App Mode (TMSH Only, No Root/Bash)", + "BIG-IP VE, Multicast Routing", + "PEM, VE", + "Routing Bundle, VE" + ] + }, + "registrationKey": { + "type": "string", + "description": "Registration key associated with this license", + "example": "W5778-33088-84412-26046-5913991" + }, + "lastUpdateMicros": { + "type": "integer", + "format": "int64", + "description": "Last update timestamp in microseconds", + "example": 0 + }, + "licensedDateTime": { + "type": "string", + "format": "date-time", + "description": "Date and time when license was issued" + }, + "exclusivePlatform": { + "type": "array", + "description": "List of exclusive platform identifiers", + "items": { + "type": "string" + }, + "example": [ + "Z100", + "Z100A", + "Z100H", + "Z100K", + "Z100x" + ] + }, + "licenseEndDateTime": { + "type": "string", + "format": "date-time", + "description": "License end date and time" + }, + "licenseStartDateTime": { + "type": "string", + "format": "date-time", + "description": "License start date and time" + }, + "serviceCheckDateTime": { + "type": "string", + "format": "date-time", + "description": "Service check date and time" + }, + "evaluationEndDateTime": { + "type": "string", + "format": "date-time", + "description": "Evaluation period end date and time" + }, + "evaluationStartDateTime": { + "type": "string", + "format": "date-time", + "description": "Evaluation period start date and time" + } + } + }, + "TaskListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Task" + } + }, + "totalItems": { + "type": "integer", + "description": "Total number of tasks matching the filter criteria", + "example": 42 + }, + "page": { + "type": "integer", + "description": "Current page number", + "example": 1 + }, + "size": { + "type": "integer", + "description": "Number of items per page", + "example": 20 + }, + "totalPages": { + "type": "integer", + "description": "Total number of pages", + "example": 3 + } + } + }, + "TaskReference": { + "type": "object", + "description": "Reference link to an async task for polling status", + "properties": { + "taskLink": { + "type": "string", + "format": "uri", + "description": "Link to the task status endpoint for polling", + "example": "https://localhost/api/licensing/pool/tasks/d4e5f6a7-b8c9-0123-defg-456789abcdef" + } + } + }, + "Task": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier of the task", + "example": "d4e5f6a7-b8c9-0123-defg-456789abcdef" + }, + "type": { + "type": "string", + "enum": [ + "ADD_OFFERING", + "REACTIVATE_OFFERING", + "ASSIGN_LICENSE", + "REVOKE_LICENSE" + ], + "description": "Type of the async operation", + "example": "ASSIGN_LICENSE" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "IN_PROGRESS", + "COMPLETED", + "FAILED" + ], + "description": "Current status of the task", + "example": "IN_PROGRESS" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Progress percentage (0-100)", + "example": 50 + }, + "resourceType": { + "type": "string", + "enum": [ + "LicenseOffering", + "LicenseMember" + ], + "description": "Type of resource this task operates on", + "example": "LicenseMember" + }, + "resourceId": { + "type": "string", + "format": "uuid", + "description": "ID of the resource being operated on", + "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" + }, + "resourceLink": { + "type": "string", + "format": "uri", + "description": "Link to the resource once task completes", + "example": "https://localhost/api/licensing/pool/regkey/licenses/7dd7b971-6eb8-4b9e-995b-1dcb1287d65f/offerings/U5939-99933-49705-74523-4841009/members/a1b2c3d4-e5f6-7890-abcd-ef1234567890" + }, + "error": { + "$ref": "#/components/schemas/Error" + }, + "selfLink": { + "type": "string", + "format": "uri", + "description": "Self-referencing link to this task", + "example": "https://localhost/api/licensing/pool/tasks/d4e5f6a7-b8c9-0123-defg-456789abcdef" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + }, + "startedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task started processing" + }, + "completedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task completed (success or failure)" + } + } + }, + "PoolLicenseOperationRequest": { + "type": "object", + "description": "Request body for pool-level license operations (assign, reactivate, revoke)", + "required": [ + "deviceAddress", + "deviceUsername", + "devicePassword" + ], + "properties": { + "deviceAddress": { + "type": "string", + "format": "ipv4", + "description": "IP address of the BIG-IP device", + "example": "192.168.1.100" + }, + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + }, + "UpdateLicenseOfferingRequest": { + "type": "object", + "description": "Request to update or reactivate a license offering. The operation performed depends on the `status` field:\n\n- `ACTIVATING_AUTOMATIC`: Triggers automatic reactivation (async, returns 202 with TaskReference)\n- `ACTIVATING_MANUAL`: Triggers manual reactivation (sync, returns 200 with new dossier)\n- `ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED`: Completes manual activation with license text (sync, returns 200)\n", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "ACTIVATING_AUTOMATIC", + "ACTIVATING_MANUAL", + "ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED" + ], + "description": "The operation to perform:\n- `ACTIVATING_AUTOMATIC`: Trigger automatic reactivation via F5 license server (async)\n- `ACTIVATING_MANUAL`: Trigger manual reactivation, regenerates dossier (sync)\n- `ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED`: Complete manual activation with provided license text (sync)\n", + "example": "ACTIVATING_AUTOMATIC" + }, + "licenseText": { + "type": "string", + "description": "License text obtained from F5 license server. \n**Required** when status is `ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED`.\nThe user obtains this by submitting the dossier to the F5 license server UI.\n", + "example": "Auth vers : 5b\nRegistration key : W5778-33088-84412-26046-5913991\nLicensed date : 20260525\n..." + } + } + }, + "Pagination": { + "type": "object", + "properties": { + "page": { + "type": "integer" + }, + "page_size": { + "type": "integer" + }, + "total": { + "type": "integer" + }, + "total_pages": { + "type": "integer" + } + } + }, + "ProductFamily": { + "type": "string", + "enum": [ + "BIG-IP", + "F5OS-C", + "F5OS-A" + ] + }, + "SortByImages": { + "type": "string", + "enum": [ + "version" + ], + "description": "Field to sort images by" + }, + "SortOrder": { + "type": "string", + "enum": [ + "asc", + "desc" + ], + "description": "Sort direction (shared schema, reusable across endpoints)" + }, + "ImageType": { + "type": "string", + "enum": [ + "FULL_ISO", + "FULL_VE", + "HOTFIX" + ], + "default": "FULL_ISO" + }, + "ImageStatus": { + "type": "string", + "description": "Lifecycle status of a software image during upload and verification", + "enum": [ + "UPLOADING", + "PENDING_VERIFICATION", + "VERIFYING", + "AVAILABLE", + "VERIFICATION_FAILED" + ], + "default": "UPLOADING" + }, + "SoftwareImage": { + "type": "object", + "required": [ + "id", + "file_name", + "product_family", + "version", + "image_type", + "file_size_bytes", + "storage_path", + "status", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "file_name": { + "type": "string" + }, + "product_family": { + "$ref": "#/components/schemas/ProductFamily" + }, + "image_type": { + "$ref": "#/components/schemas/ImageType" + }, + "status": { + "$ref": "#/components/schemas/ImageStatus" + }, + "version": { + "type": "string" + }, + "build": { + "type": "string" + }, + "base_build": { + "type": "string", + "nullable": true, + "description": "The base BIG-IP build required by a hotfix image, extracted from VERSION.LTM inside the ISO during verification. May be null for non-hotfix images or when the ISO does not include usable hotfix metadata.\n" + }, + "file_size_bytes": { + "type": "integer", + "format": "int64" + }, + "storage_path": { + "type": "string" + }, + "md5_checksum": { + "type": "string" + }, + "md5_verified": { + "type": "boolean" + }, + "sig_pem_verified": { + "type": "boolean" + }, + "md5_expected": { + "type": "string" + }, + "md5_actual": { + "type": "string" + }, + "verification_output": { + "type": "string", + "description": "Raw copy-able verification proof output" + }, + "verified_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when verification completed (set only when status is AVAILABLE or VERIFICATION_FAILED)" + }, + "uploaded_by": { + "type": "string" + }, + "uploaded_at": { + "type": "string", + "format": "date-time" + }, + "build_date": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "The build date of the software image, extracted from metadata.xml inside the ISO during verification. May be null for non-ISO images or ISOs without metadata.xml.\n" + }, + "created_at": { + "type": "string", + "format": "date-time" + } + } + }, + "ImageListResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SoftwareImage" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + } + }, + "ImageUploadAcceptedResponse": { + "type": "object", + "required": [ + "success", + "data" + ], + "properties": { + "success": { + "type": "boolean", + "example": true + }, + "data": { + "type": "object", + "required": [ + "image_id", + "file_name", + "status", + "message" + ], + "properties": { + "image_id": { + "type": "string", + "format": "uuid" + }, + "file_name": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/ImageStatus" + }, + "message": { + "type": "string", + "example": "File upload received. Processing will continue in the background." + } + } + } + } + }, + "BulkDeleteImagesRequest": { + "type": "object", + "required": [ + "image_ids" + ], + "properties": { + "image_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + }, + "minItems": 1, + "maxItems": 100 + } + } + }, + "BulkDeleteImagesResponse": { + "type": "object", + "required": [ + "results" + ], + "properties": { + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkDeleteImageResult" + } + } + } + }, + "BulkDeleteImageResult": { + "type": "object", + "required": [ + "image_id", + "status" + ], + "properties": { + "image_id": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "enum": [ + "DELETED", + "FAILED" + ] + }, + "error": { + "$ref": "#/components/schemas/Error" + } + } + }, + "FleetSummary": { + "type": "object", + "properties": { + "total_devices": { + "type": "integer" + }, + "bigip_count": { + "type": "integer" + }, + "f5os_count": { + "type": "integer" + }, + "version_distribution": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "status_distribution": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + } + } + }, + "FleetDevice": { + "type": "object", + "required": [ + "id", + "device_type", + "endpoint" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "device_type": { + "type": "string", + "enum": [ + "BIGIP", + "RSERIES", + "VELOS" + ] + }, + "name": { + "type": "string", + "description": "Alias name from the device store" + }, + "device_name": { + "type": "string" + }, + "endpoint": { + "type": "string", + "description": "Management address (host:port or IP)" + }, + "data_center_id": { + "type": "string", + "format": "uuid", + "description": "Data centre UUID this device belongs to" + }, + "current_version": { + "type": "string", + "example": "17.1.2" + }, + "current_build": { + "type": "string", + "example": "0.0.13" + }, + "edition": { + "type": "string", + "example": "Final" + }, + "platform": { + "type": "string", + "example": "Z100" + }, + "marketing_name": { + "type": "string", + "example": "BIG-IP i5800" + }, + "chassis_serial": { + "type": "string" + }, + "ha_pair_id": { + "type": "string", + "format": "uuid", + "description": "Stable UUID shared by both members of an HA pair; null for standalone devices" + }, + "ha_peer_device_id": { + "type": "string", + "format": "uuid" + }, + "ha_state": { + "type": "string", + "enum": [ + "ACTIVE", + "STANDBY", + "UNKNOWN", + "STANDALONE" + ] + }, + "device_group": { + "type": "string" + }, + "sync_status": { + "type": "string", + "example": "In Sync" + }, + "hosted_on_provider_id": { + "type": "string", + "format": "uuid", + "description": "F5OS provider UUID; null for standalone BIG-IP" + }, + "active_volume": { + "type": "string", + "description": "BIG-IP: name of the currently active boot volume (e.g. HD1.1). Null for F5OS.", + "example": "HD1.1" + }, + "inactive_volumes": { + "description": "BIG-IP only: array of non-active software boot volumes.\nNull for F5OS (RSERIES/VELOS) \u2014 F5OS uses an ISO image model with no boot-volume concept.\n", + "nullable": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/VolumeInfo" + } + }, + "disk_available_gb": { + "type": "number", + "format": "float", + "description": "Total free disk space in GB across all partitions (BIG-IP only)", + "example": 42.5 + }, + "license_edition": { + "type": "string" + }, + "license_check_date": { + "type": "string", + "format": "date" + }, + "service_check_date": { + "type": "string", + "format": "date" + }, + "last_seen_at": { + "type": "string", + "format": "date-time" + }, + "last_refresh_at": { + "type": "string", + "format": "date-time" + }, + "eligibility_status": { + "type": "string", + "enum": [ + "ELIGIBLE", + "INELIGIBLE", + "UNKNOWN" + ] + }, + "recommended_version": { + "type": "string", + "example": "17.1.3" + }, + "is_payg_license": { + "type": "boolean", + "description": "True when the device runs a PAYG cloud marketplace license (F5 KB K82564652).\nPAYG devices do not enforce the Service Check Date on upgrade.\nNull when the device has not yet been refreshed after this field was introduced.\n" + } + } + }, + "VolumeInfo": { + "type": "object", + "description": "A single non-active BIG-IP software boot volume. Always represents an inactive volume.", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "Volume slot name (e.g. \"HD1.2\")" + }, + "version": { + "type": "string", + "description": "Software version installed on this volume (e.g. \"17.1.2\")" + }, + "build": { + "type": "string", + "description": "Build number (e.g. \"0.0.13\")" + }, + "status": { + "type": "string", + "description": "Volume status (e.g. \"complete\", \"installing\")" + } + } + }, + "FleetDeviceListResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FleetDevice" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + } + }, + "DiskAnalysisBatchRequest": { + "type": "object", + "required": [ + "required_size_bytes", + "devices" + ], + "properties": { + "required_size_bytes": { + "type": "integer", + "format": "int64", + "minimum": 1, + "description": "Required disk size per device, in bytes" + }, + "devices": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/DiskAnalysisBatchDeviceInput" + } + } + } + }, + "DiskAnalysisBatchDeviceInput": { + "type": "object", + "required": [ + "device_id" + ], + "properties": { + "device_id": { + "type": "string", + "format": "uuid" + } + } + }, + "DiskAnalysisTaskStatus": { + "type": "string", + "enum": [ + "QUEUED", + "RUNNING", + "COMPLETED", + "FAILED", + "CANCELLED" + ] + }, + "DiskAnalysisTaskAcceptedResponse": { + "type": "object", + "required": [ + "task_id", + "status", + "created_at" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "status": { + "$ref": "#/components/schemas/DiskAnalysisTaskStatus" + }, + "created_at": { + "type": "string", + "format": "date-time" + } + } + }, + "DiskAnalysisTaskStatusResponse": { + "type": "object", + "required": [ + "task_id", + "status", + "created_at" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "status": { + "$ref": "#/components/schemas/DiskAnalysisTaskStatus" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "started_at": { + "type": "string", + "format": "date-time" + }, + "completed_at": { + "type": "string", + "format": "date-time" + }, + "progress": { + "$ref": "#/components/schemas/DiskAnalysisTaskProgress" + }, + "result": { + "$ref": "#/components/schemas/DiskAnalysisTaskResult" + }, + "error": { + "$ref": "#/components/schemas/Error" + } + } + }, + "DiskAnalysisTaskProgress": { + "type": "object", + "properties": { + "total_devices": { + "type": "integer", + "minimum": 0 + }, + "analyzed_devices": { + "type": "integer", + "minimum": 0 + }, + "sufficient_count": { + "type": "integer", + "minimum": 0 + }, + "insufficient_count": { + "type": "integer", + "minimum": 0 + } + } + }, + "DiskAnalysisTaskResult": { + "type": "object", + "required": [ + "required_size_bytes", + "data", + "summary" + ], + "properties": { + "required_size_bytes": { + "type": "integer", + "format": "int64" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DiskAnalysisBatchResult" + } + }, + "summary": { + "$ref": "#/components/schemas/DiskAnalysisBatchSummary" + } + } + }, + "DiskAnalysisBatchResult": { + "type": "object", + "description": "Per-device disk analysis result. Field presence depends on analysis_status:\n- SUFFICIENT / INSUFFICIENT: available_disk_bytes and has_sufficient_space are always present; error_message is absent.\n- NO_DATA / ERROR: error_message is always present; has_sufficient_space is null; available_disk_bytes is null.\n", + "required": [ + "device_id", + "host", + "analysis_status" + ], + "properties": { + "device_id": { + "type": "string", + "format": "uuid" + }, + "host": { + "type": "string" + }, + "analysis_status": { + "type": "string", + "description": "Result status for this device analysis", + "enum": [ + "SUFFICIENT", + "INSUFFICIENT", + "NO_DATA", + "ERROR" + ] + }, + "available_disk_bytes": { + "type": "integer", + "format": "int64", + "nullable": true, + "description": "Available disk space in bytes. Guaranteed non-null when analysis_status is SUFFICIENT or INSUFFICIENT. Null when analysis_status is NO_DATA or ERROR.\n" + }, + "has_sufficient_space": { + "type": "boolean", + "nullable": true, + "description": "Whether the device meets the required disk space threshold. Guaranteed non-null when analysis_status is SUFFICIENT or INSUFFICIENT. Null when analysis_status is NO_DATA or ERROR.\n" + }, + "error_message": { + "type": "string", + "description": "Human-readable error details. Present when analysis_status is NO_DATA or ERROR. Absent when analysis_status is SUFFICIENT or INSUFFICIENT.\n" + } + } + }, + "DiskAnalysisBatchSummary": { + "type": "object", + "required": [ + "sufficient_count", + "insufficient_count" + ], + "properties": { + "sufficient_count": { + "type": "integer", + "minimum": 0 + }, + "insufficient_count": { + "type": "integer", + "minimum": 0 + } + } + }, + "UpgradeJobStatus": { + "type": "string", + "description": "Lifecycle status of an upgrade job. The job is a long-lived\nre-activatable definition; per-run outcomes (success/fail/abort)\nare recorded on the execution row, NOT here. Operator-driven\ncancel converges back to READY at the job level; CANCELLED is\nrecorded on the execution row only.\n", + "enum": [ + "DRAFT", + "READY", + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED" + ] + }, + "InstallationType": { + "type": "string", + "description": "Controls which devices are targeted and how they are treated during upgrade.\nSerial (batchSize=1) or batch (batchSize>1) execution is determined by the batchSize field,\nnot by this enum.\n- STANDALONE: upgrade independent BIG-IP or F5OS devices\n- HA: upgrade HA pairs, maintaining HA continuity during the upgrade [E7 scope]\n", + "enum": [ + "STANDALONE", + "HA" + ] + }, + "VolumeStrategy": { + "type": "string", + "description": "Determines which boot volume to install the new software on.\nThis is a job-level setting applied to all devices.\nA per-device volumeOverride takes precedence over this field for that specific device.\n- NEXT_INACTIVE: install on the next available inactive volume numerically\n- LAST_INACTIVE: install on the last available inactive volume numerically\n- NEXT_SEQUENTIAL_NEW: create a new volume with the next sequential identifier\n", + "enum": [ + "NEXT_INACTIVE", + "LAST_INACTIVE", + "NEXT_SEQUENTIAL_NEW" + ] + }, + "DeviceKind": { + "type": "string", + "description": "Canonical type of the target device", + "enum": [ + "BIGIP", + "RSERIES", + "VELOS" + ] + }, + "SoftwareDistributionDeviceTarget": { + "type": "object", + "description": "A single device targeted by a software distribution job.", + "required": [ + "deviceId" + ], + "properties": { + "deviceId": { + "type": "string", + "format": "uuid", + "description": "ID of the device in the fleet inventory." + } + } + }, + "SoftwareInstallationDeviceTarget": { + "type": "object", + "description": "A single device targeted by a software installation job.\nVolume selection uses the job-level volumeStrategy by default.\nAn optional per-device volumeOverride names an explicit volume (e.g. \"HD1.2\")\nand takes precedence over the job-level strategy for that device only.\n", + "required": [ + "deviceId" + ], + "properties": { + "deviceId": { + "type": "string", + "format": "uuid", + "description": "ID of the device in the fleet inventory." + }, + "volumeOverride": { + "type": "string", + "description": "Optional explicit volume name for this device (e.g. \"HD1.2\", \"HD1.3\"). When set, overrides both strategyOverride and the job-level volumeStrategy for this device only. If omitted, strategyOverride (then the job-level volumeStrategy) is used.\n" + }, + "strategyOverride": { + "$ref": "#/components/schemas/VolumeStrategy", + "description": "Optional per-device volume-selection strategy that overrides the job-level volumeStrategy for this device only. Ignored when volumeOverride is set. Typical use (ARGUSTELEM-4382): a device whose job-level strategy is not NEXT_SEQUENTIAL_NEW can set strategyOverride=NEXT_SEQUENTIAL_NEW so a brand-new volume is created instead of failing when no inactive volume exists. If omitted, the job-level volumeStrategy is used.\n" + }, + "configSourceVolume": { + "type": "string", + "readOnly": true, + "description": "Volume whose configuration is copied onto the newly-installed volume when installConfig is enabled. MVP: locked to the device's active volume and resolved server-side at create/update time; clients should not set this. Empty when installConfig is disabled or the active volume is not yet resolvable.\n" + } + } + }, + "SoftwareDistributionImage": { + "type": "object", + "description": "A single software image to include in a software distribution job.", + "required": [ + "imageId" + ], + "properties": { + "imageId": { + "type": "string", + "format": "uuid", + "description": "ID of the software image to distribute. Must exist in the image registry." + }, + "imageFileName": { + "type": "string", + "description": "Image filename (read-only, populated from image record on create).", + "readOnly": true + } + } + }, + "SoftwareDistributionConfig": { + "type": "object", + "required": [ + "configType" + ], + "properties": { + "configType": { + "type": "string", + "enum": [ + "SOFTWARE_DISTRIBUTION" + ], + "description": "Config type discriminator" + } + } + }, + "FlightCheckCoreSelection": { + "type": "object", + "description": "Selection of the fixed core checks to capture in each flight snapshot.\nThis is a flat UNION across platforms (BIG-IP and F5OS): the orchestrator\nconsults only the fields relevant to the target device's type and ignores\nthe rest, so default-true checks for the \"other\" platform are harmless.\nEach field defaults to true (the check is captured unless explicitly disabled).\n", + "properties": { + "trunkStatus": { + "type": "boolean", + "default": true, + "description": "[BIG-IP] Capture trunk status." + }, + "interfaceStatus": { + "type": "boolean", + "default": true, + "description": "[BIG-IP & F5OS] Capture interface status (shared across platforms)." + }, + "virtualServerState": { + "type": "boolean", + "default": true, + "description": "[BIG-IP] Capture virtual server state." + }, + "poolHealth": { + "type": "boolean", + "default": true, + "description": "[BIG-IP] Capture aggregate pool health." + }, + "poolMemberHealth": { + "type": "boolean", + "default": true, + "description": "[BIG-IP] Capture pool member health." + }, + "performanceAllStats": { + "type": "boolean", + "default": true, + "description": "[BIG-IP] Capture system performance all-stats (/mgmt/tm/sys/performance/all-stats). Parsed with a duplicate-key-tolerant reader to work around BIG-IP bug ID 1060769, where the Throughput(bits)/Throughput(packets) rows share a duplicate JSON key that standard JSON parsers silently collapse." + }, + "lagStatus": { + "type": "boolean", + "default": true, + "description": "[F5OS] Capture LAG status (F5OS trunk equivalent / LACP LAGs)." + }, + "alarms": { + "type": "boolean", + "default": true, + "description": "[F5OS] Capture active system alarms." + }, + "healthSummary": { + "type": "boolean", + "default": true, + "description": "[F5OS] Capture per-component system health roll-up (top-level components only)." + }, + "cluster": { + "type": "boolean", + "default": true, + "description": "[F5OS] Capture cluster readiness (node health and install-stage convergence)." + }, + "firmwareStatus": { + "type": "boolean", + "default": true, + "description": "[F5OS] Capture active subordinate firmware-update state across platform components." + }, + "fpgaStatus": { + "type": "boolean", + "default": true, + "description": "[F5OS] Capture FPGA / DMA / DPSM / VF readiness per node." + }, + "cores": { + "type": "boolean", + "default": true, + "description": "[F5OS] Capture core/crash-dump file presence." + }, + "tenantStatus": { + "type": "boolean", + "default": true, + "description": "[F5OS] Capture tenant deployment/runtime health." + }, + "servicePods": { + "type": "boolean", + "default": true, + "description": "[F5OS] Capture infrastructure service pod health." + } + } + }, + "FlightChecksConfig": { + "type": "object", + "description": "Pre/post-flight check configuration carried inside a software installation\njob config. When `enabled` is true, the installation flow captures a PRE\nsnapshot before install and a POST snapshot after install for each device.\n", + "properties": { + "enabled": { + "type": "boolean", + "default": true, + "description": "When true, flight checks (PRE and POST) are captured for this job." + }, + "coreChecks": { + "$ref": "#/components/schemas/FlightCheckCoreSelection" + } + } + }, + "FlightCheckStatus": { + "type": "string", + "description": "Outcome of a single core check within a snapshot.", + "enum": [ + "OK", + "DEGRADED", + "ERROR", + "NOT_COLLECTED" + ] + }, + "FlightCheckResult": { + "type": "object", + "description": "Generic result envelope for a single core check within a snapshot.", + "properties": { + "status": { + "$ref": "#/components/schemas/FlightCheckStatus" + }, + "details": { + "type": "object", + "additionalProperties": true, + "description": "Check-specific structured details (raw collected state)." + }, + "error": { + "type": "string", + "description": "Collection error message, when status is ERROR." + } + } + }, + "FlightSnapshot": { + "type": "object", + "description": "A first-class, independently-addressable capture of device state for one\nphase (PRE or POST), holding the core check results. Addressed by its own\n\n`id` via GET /flight-checks/snapshots/{snapshotId}. A device accumulates many\nsnapshots over time (one PRE + one POST per installation job it participates\nin), so each snapshot carries its own deviceId, jobId, phase and capturedAt.\n\nCore-check result fields are a flat UNION across platforms: BIG-IP snapshots\npopulate trunkStatus/interfaceStatus/virtualServerState/poolHealth/\npoolMemberHealth; F5OS snapshots populate interfaceStatus (shared)/lagStatus/\nalarms/healthSummary/cluster/firmwareStatus/fpgaStatus/cores/tenantStatus/\nservicePods. Fields not relevant to the captured device's type are omitted.\n", + "required": [ + "id", + "jobId", + "deviceId", + "phase", + "capturedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique snapshot ID (addressing key)." + }, + "jobId": { + "type": "string", + "format": "uuid", + "description": "Installation job execution this snapshot was captured under." + }, + "deviceId": { + "type": "string", + "format": "uuid", + "description": "Device this snapshot was captured from." + }, + "phase": { + "type": "string", + "enum": [ + "PRE", + "POST" + ], + "description": "Whether captured before (PRE) or after (POST) install." + }, + "capturedAt": { + "type": "string", + "format": "date-time", + "description": "When the snapshot was captured." + }, + "trunkStatus": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "interfaceStatus": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "virtualServerState": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "poolHealth": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "poolMemberHealth": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "performanceAllStats": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "lagStatus": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "alarms": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "healthSummary": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "cluster": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "firmwareStatus": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "fpgaStatus": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "cores": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "tenantStatus": { + "$ref": "#/components/schemas/FlightCheckResult" + }, + "servicePods": { + "$ref": "#/components/schemas/FlightCheckResult" + } + } + }, + "FlightCheckDiffEntry": { + "type": "object", + "description": "Structured PRE-vs-POST comparison for a single core check.", + "properties": { + "check": { + "type": "string", + "description": "Core check key (e.g. virtualServerState)." + }, + "outcome": { + "type": "string", + "description": "Result of comparing the PRE and POST values for this check.", + "enum": [ + "SAME", + "IMPROVED", + "DEGRADED", + "CHANGED", + "MISSING_DATA" + ] + }, + "before": { + "type": "object", + "additionalProperties": true, + "description": "Relevant PRE-phase status summary." + }, + "after": { + "type": "object", + "additionalProperties": true, + "description": "Relevant POST-phase status summary." + }, + "details": { + "type": "string", + "description": "Human-readable explanation of the difference." + } + } + }, + "FlightCheckDiff": { + "type": "object", + "description": "A first-class, independently-addressable result of comparing a device's PRE\nsnapshot with its matching POST snapshot. Addressed by its own `id` via\nGET /flight-checks/diffs/{diffId}. Carries back-links to the two snapshots it\nwas computed from (preSnapshotUrl / postSnapshotUrl), each resolvable via\nGET /api/v1/fleet/upgrade/flight-checks/snapshots/{snapshotId}.\n\npreSnapshotUrl / postSnapshotUrl are optional: a diff is its own\nfirst-class entity and outlives the snapshots it was derived from, so a\nback-link is omitted once the corresponding snapshot has been pruned.\n", + "required": [ + "id", + "jobId", + "deviceId", + "computedAt", + "degraded" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique diff ID (addressing key)." + }, + "jobId": { + "type": "string", + "format": "uuid", + "description": "Installation job execution this diff belongs to." + }, + "deviceId": { + "type": "string", + "format": "uuid", + "description": "Device this diff was computed for." + }, + "degraded": { + "type": "boolean", + "description": "Quick \"needs attention\" flag: true when any entry has a DEGRADED\noutcome (POST is worse than PRE). Always present; materialized from\nthe diff entries at compute time.\n" + }, + "preSnapshotUrl": { + "type": "string", + "description": "Optional back-link to the PRE snapshot used in the comparison.\nOmitted when that snapshot has been pruned. Resolves via\nGET /api/v1/fleet/upgrade/flight-checks/snapshots/{snapshotId}.\n" + }, + "postSnapshotUrl": { + "type": "string", + "description": "Optional back-link to the POST snapshot used in the comparison.\nOmitted when that snapshot has been pruned. Resolves via\nGET /api/v1/fleet/upgrade/flight-checks/snapshots/{snapshotId}.\n" + }, + "computedAt": { + "type": "string", + "format": "date-time", + "description": "When the diff was computed." + }, + "entries": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FlightCheckDiffEntry" + } + } + } + }, + "FlightSnapshotListResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FlightSnapshot" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + } + }, + "FlightCheckDiffListResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FlightCheckDiff" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + } + }, + "SoftwareInstallationExecution": { + "type": "object", + "description": "Operator-facing execution controls for a software installation job. Each\nfield defaults to true when omitted (see ResolveExecution server-side).\n", + "properties": { + "hitlPauseBetweenBatches": { + "type": "boolean", + "description": "When true, the job pauses after each batch completes and waits for the\noperator to call /resume before starting the next batch. The only HITL\ncontrol that applies to STANDALONE jobs; all hitlPause* controls below\nare HA-only and ignored for STANDALONE.\nDefault is false for HA installations.\n" + }, + "hitlPauseAfterStandbyInstallBeforeReboot": { + "type": "boolean", + "default": true, + "description": "HA only. Pause #1: after software is installed on the standby node but\nBEFORE that node is rebooted onto the new version. This is an explicit\nstandby-only gate (it is NOT shared with the ex-active node \u2014 see\nhitlPauseAfterSecondInstallBeforeReboot). Ignored for STANDALONE jobs.\n" + }, + "hitlPauseAfterStandbyRebootBeforeFailover": { + "type": "boolean", + "default": true, + "description": "HA only. Pause #2: after the standby node has rebooted onto the new\nversion but BEFORE the coordinator forces failover onto it. Lets the\noperator confirm the upgraded standby is healthy before disrupting the\nactive node. Ignored for STANDALONE jobs.\n" + }, + "hitlPauseAfterFailoverBeforeSecondInstall": { + "type": "boolean", + "default": true, + "description": "HA only. Pause #3: after failover (the upgraded ex-standby is now\nactive) but BEFORE installing software on the new standby (the ex-active\nnode). Ignored for STANDALONE jobs.\n" + }, + "hitlPauseAfterSecondInstallBeforeReboot": { + "type": "boolean", + "default": true, + "description": "HA only. Pause #4: after software is installed on the ex-active node\n(now the new standby) but BEFORE that node is rebooted onto the new\nversion. Explicit ex-active gate, distinct from pause #1\n(hitlPauseAfterStandbyInstallBeforeReboot). Ignored for STANDALONE jobs.\n" + }, + "automaticFailback": { + "type": "boolean", + "default": true, + "description": "HA only. When true, after BOTH nodes of the pair are upgraded the\ncoordinator performs a final failover to restore the originally-active\nnode as the active node (failback). When false, the pair is left with\nthe originally-standby node as active. Ignored for STANDALONE jobs.\n" + }, + "hitlPauseBeforeFailback": { + "type": "boolean", + "default": false, + "description": "HA only, optional. When true AND automaticFailback is true, the\ncoordinator pauses for operator confirmation BEFORE performing the\nfinal failback. Has no effect when automaticFailback is false (there is\nno failback to gate). Defaults to false (failback proceeds without a\npause). Ignored for STANDALONE jobs.\n" + }, + "disableAutoConfigSync": { + "type": "boolean", + "default": false, + "description": "Disable BIG-IP CM auto config-sync on the device-group for the\nduration of the install. When true, the workflow disables auto\nconfig-sync before upgrading the standby, then restores the\noriginal setting and pushes a fresh config-sync after both\nnodes are upgraded. Mirrors F5's HA-upgrade best practice \u2014\nleaving auto config-sync on during the version-mismatch window\ncan hang failover or cause an outage. Defaults to false.\nIgnored for STANDALONE jobs.\n" + }, + "reboot": { + "type": "boolean", + "default": true, + "description": "When true, the device is rebooted after installation and post-flight\nchecks run. When false, the per-device flow stops after INSTALL \u2014 the\njob completes as \"installed, pending manual reboot\" and post-flight\nchecks are skipped.\n" + } + } + }, + "SoftwareInstallationConfig": { + "type": "object", + "required": [ + "configType" + ], + "properties": { + "configType": { + "type": "string", + "enum": [ + "SOFTWARE_INSTALLATION" + ], + "description": "Config type discriminator" + } + } + }, + "JobExecution": { + "type": "object", + "description": "Current execution state of a running or completed upgrade job.", + "properties": { + "executionId": { + "type": "string", + "format": "uuid", + "description": "ID of the workflow execution record." + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "COMPLETED", + "FAILED", + "CANCELLED" + ] + }, + "startedAt": { + "type": "string", + "format": "date-time" + }, + "endedAt": { + "type": "string", + "format": "date-time" + }, + "currentBatch": { + "type": "integer", + "description": "The batch number currently being processed (1-based)." + }, + "totalBatches": { + "type": "integer", + "description": "Total number of batches this execution is divided into." + }, + "batches": { + "type": "array", + "description": "Per-batch execution summary.", + "items": { + "$ref": "#/components/schemas/BatchStatus" + } + } + } + }, + "InstallStep": { + "type": "string", + "description": "Current step of a single device's installation FSM. Written verbatim\nfrom the per-node state machine; identical for standalone and for each\nnode of an HA pair (BIG-IP and F5OS alike).\n\nOPTIONAL / TIMING: this value is OPTIONAL on a per-device row. A device\nwhose status is RUNNING may carry NO currentStep at all \u2014 the column is\nunset until the per-node FSM checkpoints its first state, so callers must\ntreat \"RUNNING with no currentStep\" as \"starting, step not yet recorded\"\n(do NOT assume PENDING). In HA the two nodes of a pair are driven\nSEQUENTIALLY (standby first, then active), so it is expected for the\nstandby to report an advanced step (e.g. REBOOT) while the active node of\nthe SAME pair is still RUNNING with no currentStep yet. On successful\ncompletion the FSM writes COMPLETE.\n\nENTRY-TIME LABELING: currentStep names the FSM state the device has\nENTERED, not the one it has finished. The step is stamped on state entry\n(before the state's work \u2014 including its wait loops \u2014 runs), so a device\nreporting REBOOT is \"in the reboot phase\", which still includes waiting\nfor the device to go down and come back up on the target version. Do not\nread a step as \"this phase is done\".\n\nINSTALL / HOTFIX / REBOOT notes:\n * BIG-IP full-image installs report INSTALL while the target image is\n being installed to the chosen volume.\n * BIG-IP hotfix installs split the install into two operator-visible\n phases: BASE_IMAGE_INSTALL while the matching base image is installed\n (real device progress is available), then WAIT_HOTFIX_INSTALL while\n BIG-IP applies the hotfix (no device-reported percentage, so progress\n is time-based).\n * ATOMIC path (standalone, reboot=true, NO HITL gate): there is NO\n separate REBOOT step. INSTALL issues a fused install+reboot on the\n device and folds BOTH the install-complete wait AND the reboot wait\n into the INSTALL step; on F5OS the FSM may then run\n POST_INSTALL_SETTLE before POST_FLIGHT so transient platform startup\n conditions do not taint the POST snapshot. You will never see REBOOT\n on this path.\n * GATED / HA path (HITL gate requested, or any HA pair node): install\n and reboot are DISCRETE. INSTALL writes software to the inactive\n volume, then the FSM enters REBOOT and (entry-time labeling) reports\n REBOOT before the reboot wait finishes. On F5OS the install RPC itself\n embeds the reboot, so the device may still be writing/applying\n software while currentStep already reads REBOOT \u2014 this is expected,\n not a stuck or mislabeled state.\n", + "enum": [ + "PENDING", + "IMAGE_PRESENT_CHECK", + "VALIDATION", + "PRE_FLIGHT", + "VOLUME_PLAN", + "INSTALL", + "BASE_IMAGE_INSTALL", + "WAIT_HOTFIX_INSTALL", + "HITL_PAUSE_BEFORE_REBOOT", + "REBOOT", + "FIRMWARE_UPGRADE", + "POST_INSTALL_SETTLE", + "POST_FLIGHT", + "COMPLETE", + "FAILED", + "CANCELLED" + ] + }, + "InstallStepStatus": { + "type": "string", + "description": "Lifecycle status of a single step within a device's installation\ntimeline. Distinct from InstallStep (which names *which* step) and from\nthe device-level status. Used to render the completed/current/upcoming\nper-device step timeline.\n", + "enum": [ + "PENDING", + "RUNNING", + "COMPLETED", + "FAILED", + "CANCELLED", + "SKIPPED" + ] + }, + "InstallStepDetail": { + "type": "object", + "description": "One step in a device's installation timeline. The ORDERED list of steps\nis derived from the per-device FSM plan (identical for standalone and for\neach node of an HA pair) and enriched with live persisted runtime state\n(upgrade.activity_steps + the device's current step/progress). This lets\nthe UI render every step \u2014 those already DONE, the one IN PROGRESS, and\nthe upcoming/PENDING ones \u2014 on a single per-device timeline.\n\nStatus semantics:\n * COMPLETED \u2014 step ran and finished (carries startedAt/completedAt).\n * RUNNING \u2014 the device's current step (carries startedAt).\n * PENDING \u2014 planned but not yet reached (\"next/upcoming\"); no times.\n * FAILED \u2014 this step errored; carries errorCode/errorMessage.\n * CANCELLED \u2014 the device terminated (FAILED/CANCELLED) before reaching\n this planned step, so it will never run.\n * SKIPPED \u2014 intentionally omitted for this device's plan (rare on the\n per-device timeline since plan() already omits skipped steps).\n", + "required": [ + "step", + "status" + ], + "properties": { + "step": { + "allOf": [ + { + "$ref": "#/components/schemas/InstallStep" + } + ], + "description": "Which FSM step this row represents." + }, + "status": { + "$ref": "#/components/schemas/InstallStepStatus" + }, + "sequence": { + "type": "integer", + "description": "0-based position of this step within the device's plan." + }, + "startedAt": { + "type": "string", + "format": "date-time", + "description": "When the step entered RUNNING. Omitted for PENDING steps." + }, + "completedAt": { + "type": "string", + "format": "date-time", + "description": "When the step left RUNNING (COMPLETED/FAILED). Omitted otherwise." + }, + "durationMs": { + "type": "integer", + "format": "int64", + "description": "Step duration in milliseconds, when known." + }, + "retryCount": { + "type": "integer", + "description": "Number of retries recorded for this step." + }, + "errorCode": { + "type": "string", + "description": "Machine-readable error category, present on FAILED steps." + }, + "errorMessage": { + "type": "string", + "description": "Human-readable error detail, present on FAILED steps." + } + } + }, + "BatchStatus": { + "type": "object", + "description": "Per-batch execution summary.", + "properties": { + "batchNumber": { + "type": "integer", + "description": "Batch sequence number (1-based)." + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "COMPLETED", + "FAILED", + "CANCELLED" + ] + }, + "currentStep": { + "allOf": [ + { + "$ref": "#/components/schemas/InstallStep" + } + ], + "description": "Current pipeline step for this batch." + }, + "deviceIds": { + "type": "array", + "description": "IDs of devices in this batch.", + "items": { + "type": "string", + "format": "uuid" + } + }, + "startedAt": { + "type": "string", + "format": "date-time" + }, + "endedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "DeviceInstallState": { + "type": "object", + "description": "Per-device installation tracking. Populated once the device's batch starts execution.\nOnly present on software installation jobs.\n", + "properties": { + "deviceId": { + "type": "string", + "format": "uuid" + }, + "device_name": { + "type": "string" + }, + "currentVersion": { + "type": "string", + "description": "Software version on the device before the upgrade." + }, + "targetVersion": { + "type": "string", + "description": "Software version being installed." + }, + "plannedVolume": { + "type": "string", + "description": "The boot volume selected for installation (e.g. \"HD1.2\")." + }, + "haRole": { + "type": "string", + "description": "HA role for this device (populated for HA installationType jobs).\nNOTE: an HA pair surfaces as TWO independent per-node entries here \u2014\none per node \u2014 each carrying its own currentStep. Pair-level\ncoordination phases (failover/failback/cross-node gates) are tracked\non a separate pair cursor and are NOT reflected in currentStep.\n", + "enum": [ + "ACTIVE", + "STANDBY" + ] + }, + "currentStep": { + "allOf": [ + { + "$ref": "#/components/schemas/InstallStep" + } + ], + "description": "Current step of this device's installation FSM (same value the\nexecution endpoint reports under instanceProgress.devices[].currentStep).\n" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "COMPLETED", + "FAILED", + "CANCELLED" + ] + }, + "errorMessage": { + "type": "string", + "description": "Error detail if the device installation failed." + }, + "errorCategory": { + "type": "string", + "description": "Category of failure for diagnostics.", + "enum": [ + "CONNECTIVITY", + "CREDENTIAL", + "COMPATIBILITY", + "DISK_SPACE", + "IMAGE_VERIFY", + "INSTALL", + "REBOOT", + "POST_FLIGHT", + "FAILOVER", + "FAILBACK" + ] + }, + "preSnapshotUrl": { + "type": "string", + "description": "Back-link to this device's PRE flight-check snapshot for this job. Null\nuntil captured. Resolves via\nGET /api/v1/fleet/upgrade/flight-checks/snapshots/{snapshotId}.\n" + }, + "postSnapshotUrl": { + "type": "string", + "description": "Back-link to this device's POST flight-check snapshot for this job. Null\nuntil captured. Resolves via\nGET /api/v1/fleet/upgrade/flight-checks/snapshots/{snapshotId}.\n" + }, + "diffUrl": { + "type": "string", + "description": "Back-link to this device's PRE-vs-POST flight-check diff for this job. Null\nuntil both snapshots exist. Resolves via\nGET /api/v1/fleet/upgrade/flight-checks/diffs/{diffId}.\n" + }, + "startedAt": { + "type": "string", + "format": "date-time" + }, + "completedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "PerDeviceDistributionStatus": { + "type": "object", + "description": "Runtime status of one device within a software distribution job execution.", + "required": [ + "deviceId", + "deviceKind", + "status", + "transferProgress", + "retryCount", + "checksumVerified" + ], + "properties": { + "deviceId": { + "type": "string", + "format": "uuid" + }, + "deviceName": { + "type": "string", + "description": "Display name resolved from `upgrade.device_upgrade_metadata.device_name`\n(mirrored from `public.devices.device_name` for BIG-IP and\n`public.f5os_providers.name` for F5OS). Empty when the metadata row\nis missing or has no name \u2014 clients should fall back to `deviceId`\nfor display. Best-effort batch lookup; failures don't fail the\nstatus response.\n" + }, + "deviceKind": { + "$ref": "#/components/schemas/DeviceKind" + }, + "status": { + "type": "string", + "description": "PENDING \u2014 waiting for a worker to claim.\nTRANSFERRING \u2014 chunks being pushed to the device.\nVERIFYING \u2014 waiting for on-device verification.\nCOMPLETED \u2014 success.\nFAILED \u2014 retries exhausted.\nCANCELLED \u2014 operator-initiated cancel.\nSKIPPED \u2014 device was locked by another execution at activate time.\n", + "enum": [ + "PENDING", + "TRANSFERRING", + "VERIFYING", + "COMPLETED", + "FAILED", + "CANCELLED", + "SKIPPED" + ] + }, + "transferProgress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Percent of bytes pushed to the device. Debounced; updated at most every few seconds per device." + }, + "retryCount": { + "type": "integer", + "minimum": 0, + "description": "Number of whole-device retries spent. Independent of chunk-level retries inside the BIG-IP client." + }, + "checksumVerified": { + "type": "boolean" + }, + "errorMessage": { + "type": "string", + "nullable": true + }, + "startedAt": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "completedAt": { + "type": "string", + "format": "date-time", + "nullable": true + } + } + }, + "SoftwareDistributionExecution": { + "type": "object", + "description": "Software distribution execution record. Field names + types match\nthe generic workflow Execution schema so the cross-feature UI can\nrender distribution and autoscale / installation executions with\nthe same panel.\n\nOn single-execution GET (`/executions/{executionId}`) the response\nadditionally embeds `instanceProgress` \u2014 the per-device runtime\nrollup scoped to this execution. The executions LIST endpoint\nstays lean and never populates that field.\n", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "jobId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "jobName": { + "type": "string", + "readOnly": true, + "description": "Parent software distribution job name." + }, + "jobDescription": { + "type": "string", + "readOnly": true, + "description": "Parent software distribution job description." + }, + "trigger": { + "type": "string", + "enum": [ + "USER", + "ALERT", + "SYSTEM", + "SCHEDULE" + ], + "readOnly": true + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED", + "CANCELLED", + "TIMEOUT" + ], + "readOnly": true + }, + "reason": { + "type": "string", + "description": "Human-readable trigger reason" + }, + "startedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "completedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "durationMs": { + "type": "integer", + "readOnly": true + }, + "activityCount": { + "type": "integer", + "readOnly": true, + "description": "Number of activities (per-device rows) recorded under this execution" + }, + "retryCount": { + "type": "integer", + "readOnly": true + }, + "currentStep": { + "type": "string", + "readOnly": true + }, + "lastError": { + "type": "string", + "readOnly": true + }, + "changeRequest": { + "type": "string", + "nullable": true, + "maxLength": 255, + "description": "Optional change-request identifier supplied at activation time.\nNull when no change request was provided.\n", + "readOnly": true + }, + "correlationId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "createdBy": { + "type": "string", + "nullable": true, + "readOnly": true, + "description": "Username of the operator who created (activated) this execution." + }, + "modifiedBy": { + "type": "string", + "nullable": true, + "readOnly": true, + "description": "Username of the operator who last modified this execution." + }, + "instanceProgress": { + "$ref": "#/components/schemas/InstanceProgress", + "description": "Per-device runtime rollup scoped to this execution. Populated\nonly on the single-execution GET; absent on the executions LIST.\n" + } + } + }, + "InstanceProgress": { + "type": "object", + "description": "Per-device runtime rollup scoped to a single execution. Same numeric\nshape as `DistributionJobAggregate` minus the job-level `jobId` /\n`status` fields, since the parent execution already carries that\nidentity.\n", + "required": [ + "totalDevices", + "overallPercent", + "devices" + ], + "properties": { + "totalDevices": { + "type": "integer" + }, + "pending": { + "type": "integer" + }, + "transferring": { + "type": "integer" + }, + "verifying": { + "type": "integer" + }, + "completed": { + "type": "integer" + }, + "failed": { + "type": "integer" + }, + "cancelled": { + "type": "integer" + }, + "skipped": { + "type": "integer" + }, + "overallPercent": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Mean of per-device transferProgress within this execution." + }, + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PerDeviceDistributionStatus" + } + } + } + }, + "DistributionJobAggregate": { + "type": "object", + "description": "Per-device runtime status plus a roll-up summary for a software distribution job.", + "required": [ + "jobId", + "status", + "totalDevices", + "overallPercent", + "devices" + ], + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "description": "Roll-up job status derived from per-device states.", + "enum": [ + "RUNNING", + "COMPLETED", + "FAILED", + "CANCELLED" + ] + }, + "totalDevices": { + "type": "integer" + }, + "pending": { + "type": "integer" + }, + "transferring": { + "type": "integer" + }, + "verifying": { + "type": "integer" + }, + "completed": { + "type": "integer" + }, + "failed": { + "type": "integer" + }, + "cancelled": { + "type": "integer" + }, + "skipped": { + "type": "integer" + }, + "overallPercent": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Mean of per-device transferProgress." + }, + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PerDeviceDistributionStatus" + } + } + } + }, + "SoftwareDistributionJob": { + "type": "object", + "description": "Full software distribution job resource including config and execution state.", + "required": [ + "id", + "name", + "status", + "enabled", + "config", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique job identifier." + }, + "workflowId": { + "type": "string", + "format": "uuid", + "description": "Parent workflow entity ID." + }, + "name": { + "type": "string", + "description": "Unique human-readable job name." + }, + "description": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/UpgradeJobStatus" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether this job is enabled. A disabled job (false) cannot be activated,\npaused, or resumed. Defaults to true on creation.\n" + }, + "config": { + "$ref": "#/components/schemas/SoftwareDistributionConfig" + }, + "execution": { + "$ref": "#/components/schemas/JobExecution", + "description": "Present once the job has been activated at least once." + }, + "createdBy": { + "type": "string", + "nullable": true, + "description": "Username of the operator who created the job." + }, + "modifiedBy": { + "type": "string", + "nullable": true, + "description": "Username of the operator who last modified the job." + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "CompatUpgradePath": { + "type": "object", + "description": "A single BIG-IP upgrade path rule from upgrade.bigip_upgrade_paths.", + "required": [ + "id", + "target_major_version", + "min_source_version", + "source_kbase", + "is_operator_override" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "target_major_version": { + "type": "string", + "description": "Target BIG-IP major version, e.g. \"17\" or \"21\".", + "example": "21" + }, + "min_source_version": { + "type": "string", + "description": "Minimum source version required for this upgrade path (inclusive).", + "example": "17.1.0" + }, + "max_source_version": { + "type": "string", + "nullable": true, + "description": "Maximum source version (inclusive). Null means no upper bound." + }, + "notes": { + "type": "string", + "nullable": true + }, + "source_kbase": { + "type": "string", + "description": "K-article this row originates from.", + "example": "K13845" + }, + "is_operator_override": { + "type": "boolean", + "description": "True for API-managed rows (seeder never overwrites these)." + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "UpsertCompatUpgradePathRequest": { + "type": "object", + "description": "Request body for POST /compat/upgrade-paths.", + "required": [ + "target_major_version", + "min_source_version" + ], + "properties": { + "target_major_version": { + "type": "string", + "description": "Target BIG-IP major version, e.g. \"17\" or \"21\".", + "minLength": 1, + "example": "21" + }, + "min_source_version": { + "type": "string", + "description": "Minimum source version required (inclusive), e.g. \"17.1.0\".", + "minLength": 1, + "example": "14.0.0" + }, + "max_source_version": { + "type": "string", + "nullable": true, + "description": "Maximum source version (inclusive). Omit or null for no upper bound." + }, + "notes": { + "type": "string", + "nullable": true, + "description": "Optional human-readable note." + } + } + }, + "CompatUpgradePathListResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CompatUpgradePath" + } + }, + "total": { + "type": "integer" + } + } + }, + "SoftwareDistributionJobSummary": { + "type": "object", + "description": "Lightweight software distribution job summary for list responses.", + "required": [ + "id", + "name", + "status", + "enabled", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "workflowId": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/UpgradeJobStatus" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether this job is enabled." + }, + "batchSize": { + "type": "integer", + "description": "Configured batch size." + }, + "deviceCount": { + "type": "integer", + "description": "Number of target devices in this job." + }, + "createdBy": { + "type": "string", + "nullable": true, + "description": "Username of the operator who created the job. Absent when the X-Username header was not present at creation time." + }, + "modifiedBy": { + "type": "string", + "nullable": true, + "description": "Username of the operator who last modified the job. Absent when no modification has been made with an identified actor." + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "SoftwareDistributionJobListResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SoftwareDistributionJobSummary" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + } + }, + "SoftwareDistributionJobPayload": { + "type": "object", + "description": "Shared payload fields for creating or updating a software distribution job.\nAll fields are optional at this level; required constraints are applied by the\nCreate/Update wrappers that reference this schema via allOf.\n", + "properties": { + "name": { + "type": "string", + "description": "Unique name for this distribution job.", + "minLength": 1, + "maxLength": 255 + }, + "description": { + "type": "string", + "description": "Optional human-readable description." + }, + "enabled": { + "type": "boolean", + "description": "Whether this job is enabled. Set to false to disable the job.\nA disabled job cannot be activated, paused, or resumed.\nOmit on create to default to true.\n" + }, + "config": { + "$ref": "#/components/schemas/SoftwareDistributionConfig" + } + } + }, + "CreateSoftwareDistributionJobRequest": { + "description": "Request body for creating a new software distribution job. Name is required.", + "allOf": [ + { + "$ref": "#/components/schemas/SoftwareDistributionJobPayload" + }, + { + "required": [ + "name" + ] + } + ] + }, + "UpdateSoftwareDistributionJobRequest": { + "description": "Replaces the mutable fields of a software distribution job.\nOnly allowed when the job is in DRAFT or READY state.\nAll fields are optional \u2014 only the provided fields will be updated.\n", + "allOf": [ + { + "$ref": "#/components/schemas/SoftwareDistributionJobPayload" + } + ] + }, + "SoftwareInstallationJob": { + "type": "object", + "description": "Full software installation job resource including config, execution state,\nand per-device install tracking.\n", + "required": [ + "id", + "name", + "status", + "enabled", + "config", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique job identifier." + }, + "workflowId": { + "type": "string", + "format": "uuid", + "description": "Parent workflow entity ID." + }, + "name": { + "type": "string", + "description": "Unique human-readable job name." + }, + "description": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/UpgradeJobStatus" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether this job is enabled. A disabled job (false) cannot be activated,\npaused, or resumed. Defaults to true on creation.\n" + }, + "config": { + "$ref": "#/components/schemas/SoftwareInstallationConfig" + }, + "execution": { + "$ref": "#/components/schemas/JobExecution", + "description": "Present once the job has been activated at least once." + }, + "deviceInstallStates": { + "type": "array", + "description": "Per-device install tracking. Populated once a device's batch starts.", + "items": { + "$ref": "#/components/schemas/DeviceInstallState" + } + }, + "createdBy": { + "type": "string", + "nullable": true, + "description": "Username of the operator who created the job." + }, + "modifiedBy": { + "type": "string", + "nullable": true, + "description": "Username of the operator who last modified the job." + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "warnings": { + "type": "array", + "description": "Informational (non-blocking) warnings about the job configuration.\nPresent when HA-paired devices are included in a STANDALONE job.\nDoes not affect job status.\n\n**Availability:** Only populated on single-job GET responses\n(`GET /jobs/software-installation/{id}`). Not returned in list\nresponses (`GET /jobs/software-installation`). Use the single-job\nGET endpoint to retrieve warnings for a specific job.\n", + "items": { + "$ref": "#/components/schemas/JobWarning" + } + } + } + }, + "JobWarning": { + "type": "object", + "description": "An informational warning produced during job validation.", + "required": [ + "code", + "message", + "severity" + ], + "properties": { + "code": { + "type": "string", + "description": "Machine-readable warning code.", + "example": "HA_DEVICES_IN_STANDALONE_JOB" + }, + "message": { + "type": "string", + "description": "Human-readable warning description.", + "example": "Device bigip/10.0.0.1.bigip is the active node of an HA pair but will be installed independently without automatic failover sequencing." + }, + "severity": { + "type": "string", + "description": "Severity level of the warning.", + "enum": [ + "INFO" + ], + "example": "INFO" + } + } + }, + "SoftwareInstallationJobSummary": { + "type": "object", + "description": "Lightweight software installation job summary for list responses.", + "required": [ + "id", + "name", + "status", + "enabled", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "workflowId": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/UpgradeJobStatus" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether this job is enabled." + }, + "installationType": { + "$ref": "#/components/schemas/InstallationType", + "description": "STANDALONE or HA." + }, + "batchSize": { + "type": "integer", + "description": "Configured batch size (1=serial, >1=batch)." + }, + "deviceCount": { + "type": "integer", + "description": "Number of target devices in this job." + }, + "createdBy": { + "type": "string", + "nullable": true, + "description": "Username of the operator who created the job. Absent when the X-Username header was not present at creation time." + }, + "modifiedBy": { + "type": "string", + "nullable": true, + "description": "Username of the operator who last modified the job. Absent when no modification has been made with an identified actor." + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "SoftwareInstallationJobListResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SoftwareInstallationJobSummary" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + } + }, + "SoftwareInstallationJobPayload": { + "type": "object", + "description": "Shared payload fields for creating or updating a software installation job.\nAll fields are optional at this level; required constraints are applied by the\nCreate/Update wrappers that reference this schema via allOf.\n", + "properties": { + "name": { + "type": "string", + "description": "Unique name for this installation job.", + "minLength": 1, + "maxLength": 255 + }, + "description": { + "type": "string", + "description": "Optional human-readable description." + }, + "enabled": { + "type": "boolean", + "description": "Whether this job is enabled. Set to false to disable the job.\nA disabled job cannot be activated, paused, or resumed.\nOmit on create to default to true.\n" + }, + "config": { + "$ref": "#/components/schemas/SoftwareInstallationConfig" + } + } + }, + "CreateSoftwareInstallationJobRequest": { + "description": "Request body for creating a new software installation job. Name is required.", + "allOf": [ + { + "$ref": "#/components/schemas/SoftwareInstallationJobPayload" + }, + { + "required": [ + "name" + ] + } + ] + }, + "UpdateSoftwareInstallationJobRequest": { + "description": "Replaces the mutable fields of a software installation job.\nOnly allowed when the job is in DRAFT or READY state.\nAll fields are optional \u2014 only the provided fields will be updated.\n", + "allOf": [ + { + "$ref": "#/components/schemas/SoftwareInstallationJobPayload" + } + ] + }, + "ValidationDeviceTarget": { + "type": "object", + "description": "A single device target for the POST /validate request.", + "required": [ + "device_id" + ], + "properties": { + "device_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the device to validate." + }, + "volume_override": { + "type": "string", + "description": "Optional explicit volume name for this device (e.g. \"HD1.2\"). When set, pins this device to that specific volume slot and applies the existing-slot disk-space threshold (2 GB soft) rather than the new-slot threshold (15 GB soft). Mirrors SoftwareInstallationDeviceTarget.volumeOverride so callers can use the same configuration for both validation and job creation. Takes precedence over the top-level volume_strategy on the request for this device.\n" + } + } + }, + "ValidationTriggerRequest": { + "type": "object", + "description": "Request body for POST /validate.\nThe caller provides the list of device targets to validate and the target image UUID.\nNo job needs to exist \u2014 this is a pre-job eligibility check.\n", + "required": [ + "device_targets", + "image_id" + ], + "properties": { + "device_targets": { + "type": "array", + "description": "List of device targets (with optional per-device volume_override) to validate against the target image.", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/ValidationDeviceTarget" + } + }, + "image_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the target software image to validate against." + }, + "volume_strategy": { + "$ref": "#/components/schemas/VolumeStrategy", + "description": "Volume selection strategy applied to all devices in this validation request.\nA per-device volume_override (explicit slot name, e.g. \"HD1.2\") takes precedence\nover this field for that device. Defaults to NEXT_SEQUENTIAL_NEW when omitted.\n" + }, + "install_config": { + "type": "boolean", + "default": true, + "description": "Controls config carry-forward (BIG-IP cpcfg) for all devices in this\nvalidation request. Mirrors SoftwareInstallationConfig.installConfig.\nWhen true (or omitted), the install_config readiness check warns if the\ntarget version is older than the active version (a downgrade causes cpcfg\nto skip config copy). When false, the install_config check is skipped.\n" + } + } + }, + "ValidationTriggeredResponse": { + "type": "object", + "description": "Response body returned by POST /validate (202 Accepted).", + "required": [ + "validation_run_id", + "message" + ], + "properties": { + "validation_run_id": { + "type": "string", + "format": "uuid", + "description": "Unique ID for this validation run. Use with GET /validate/{validationRunId} to poll results." + }, + "message": { + "type": "string", + "example": "validation triggered" + } + } + }, + "ReadinessTriggerRequest": { + "type": "object", + "description": "Request body for POST /readiness.\nThe `context` object holds shared parameters (device targets and image IDs)\napplied to all checks. The `checks` array specifies which readiness check\ntypes to run.\n", + "required": [ + "context", + "checks" + ], + "properties": { + "context": { + "$ref": "#/components/schemas/ReadinessContext" + }, + "checks": { + "type": "array", + "description": "List of readiness check types to run.", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/ReadinessCheckEntry" + } + } + } + }, + "ReadinessContext": { + "type": "object", + "description": "Shared context for all readiness checks in a single run.", + "required": [ + "device_targets", + "image_ids" + ], + "properties": { + "device_targets": { + "type": "array", + "description": "Target devices to run readiness checks against.", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/ReadinessDeviceTarget" + } + }, + "image_ids": { + "type": "array", + "description": "UUIDs of the software images being distributed. Used by all checks to resolve image metadata.", + "minItems": 1, + "items": { + "type": "string", + "format": "uuid" + } + } + } + }, + "ReadinessDeviceTarget": { + "type": "object", + "description": "A single device target for readiness checks.", + "required": [ + "device_id" + ], + "properties": { + "device_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the device to check." + } + } + }, + "ReadinessCheckEntry": { + "type": "object", + "description": "A single readiness check to run. The `type` field selects the check\nimplementation.\n", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "description": "The readiness check type. Supported values:\n- `base_image_presence` \u2014 verifies required base OS image is on the device\n- `disk_space` \u2014 verifies sufficient free space for the image distribution\n- `image_compatibility` \u2014 verifies image product family is compatible with the target device type\n", + "enum": [ + "base_image_presence", + "disk_space", + "image_compatibility" + ] + } + } + }, + "ReadinessTriggeredResponse": { + "type": "object", + "description": "Response body returned by POST /readiness (202 Accepted).", + "required": [ + "run_id", + "message" + ], + "properties": { + "run_id": { + "type": "string", + "format": "uuid", + "description": "Unique ID for this readiness run. Use with GET /readiness/{runId} to poll results." + }, + "message": { + "type": "string", + "example": "readiness checks triggered" + } + } + }, + "ReadinessRunListResponse": { + "type": "object", + "description": "Paginated list of readiness check runs.", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReadinessRunListItem" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + } + }, + "ReadinessRunListItem": { + "type": "object", + "description": "Lightweight summary of a single readiness run (no per-device details).\nUse GET /readiness/{runId} for full per-device results.\n", + "required": [ + "run_id", + "status", + "device_count", + "pass_count", + "warn_count", + "fail_count", + "error_count", + "can_proceed" + ], + "properties": { + "run_id": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "description": "Rolled-up status across all devices in this run.", + "enum": [ + "PENDING", + "RUNNING", + "PASSED", + "WARNING", + "FAILED", + "ERROR" + ] + }, + "device_count": { + "type": "integer" + }, + "pass_count": { + "type": "integer" + }, + "warn_count": { + "type": "integer" + }, + "fail_count": { + "type": "integer" + }, + "error_count": { + "type": "integer" + }, + "can_proceed": { + "type": "boolean", + "description": "True when no device has a HARD-severity FAIL." + }, + "triggered_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "completed_at": { + "type": "string", + "format": "date-time", + "nullable": true + } + } + }, + "ReadinessSummary": { + "type": "object", + "description": "Aggregated readiness check results for a full run.\nReturned by GET /readiness/{runId}. Poll until status is no longer PENDING or RUNNING.\n", + "required": [ + "run_id", + "status", + "device_count", + "pass_count", + "warn_count", + "fail_count", + "error_count", + "can_proceed", + "devices" + ], + "properties": { + "run_id": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "description": "Rolled-up status across all devices:\n- RUNNING \u2014 at least one device is still being checked\n- PASSED \u2014 all devices pass cleanly\n- WARNING \u2014 at least one soft warning; no hard failures\n- FAILED \u2014 at least one hard check failed\n- ERROR \u2014 at least one device errored (unreachable, etc.)\n", + "enum": [ + "PENDING", + "RUNNING", + "PASSED", + "WARNING", + "FAILED", + "ERROR" + ] + }, + "device_count": { + "type": "integer" + }, + "pass_count": { + "type": "integer" + }, + "warn_count": { + "type": "integer" + }, + "fail_count": { + "type": "integer" + }, + "error_count": { + "type": "integer" + }, + "can_proceed": { + "type": "boolean", + "description": "True when no device has a HARD-severity FAIL. Always true for soft-only checks." + }, + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReadinessDeviceResult" + } + }, + "triggered_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "completed_at": { + "type": "string", + "format": "date-time", + "nullable": true + } + } + }, + "ReadinessDeviceResult": { + "type": "object", + "description": "Per-device readiness check outcome.", + "required": [ + "id", + "run_id", + "device_id", + "hostname", + "current_step", + "status", + "check_results" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "run_id": { + "type": "string", + "format": "uuid" + }, + "device_id": { + "type": "string", + "format": "uuid" + }, + "hostname": { + "type": "string" + }, + "device_type": { + "type": "string", + "description": "Device platform type (BIGIP, RSERIES, VELOS)." + }, + "ha_state": { + "type": "string", + "nullable": true, + "description": "HA failover role (ACTIVE, STANDBY, STANDALONE, UNKNOWN). Null for F5OS devices." + }, + "ha_pair_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "UUID of the HA pair group this device belongs to. Null for standalone/F5OS." + }, + "ha_peer_device_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "UUID of the peer device in the HA pair. Null for standalone/F5OS." + }, + "current_step": { + "type": "string", + "description": "Current FSM step (PENDING, CHECKING_, COMPLETE)." + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "PASSED", + "WARNING", + "FAILED", + "ERROR" + ] + }, + "check_results": { + "type": "array", + "description": "Per-check results \u2014 one entry per requested check type.", + "items": { + "$ref": "#/components/schemas/ReadinessCheckResult" + } + }, + "started_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "completed_at": { + "type": "string", + "format": "date-time", + "nullable": true + } + } + }, + "ReadinessCheckResult": { + "type": "object", + "description": "Outcome of a single readiness check for a device.", + "required": [ + "check_name", + "severity", + "status" + ], + "properties": { + "check_name": { + "type": "string", + "description": "Name of the check (e.g. \"base_image_pre_distribution\", \"disk_space\")." + }, + "severity": { + "type": "string", + "enum": [ + "SOFT", + "HARD" + ] + }, + "status": { + "type": "string", + "enum": [ + "PASS", + "WARN", + "FAIL", + "SKIP" + ] + }, + "message": { + "type": "string", + "description": "Human-readable explanation." + }, + "detail": { + "description": "Structured extra data relevant to the check outcome." + } + } + }, + "CheckSeverity": { + "type": "string", + "description": "Whether a check failure is advisory (SOFT) or blocking (HARD).\n- SOFT: warn operator; job can still proceed\n- HARD: a FAIL blocks the job; a WARN reports indeterminate live data without blocking\n", + "enum": [ + "SOFT", + "HARD" + ] + }, + "CheckStatus": { + "type": "string", + "description": "Outcome of a single validation check.", + "enum": [ + "PASS", + "WARN", + "FAIL", + "SKIP" + ] + }, + "ValidationStatus": { + "type": "string", + "description": "Rolled-up validation status for a device or a job.", + "enum": [ + "PENDING", + "RUNNING", + "PASSED", + "WARNING", + "FAILED", + "ERROR" + ] + }, + "CheckResult": { + "type": "object", + "description": "Outcome of a single named validation check.", + "required": [ + "check_name", + "severity", + "status" + ], + "properties": { + "check_name": { + "type": "string", + "description": "Unique identifier of the check. One of:\n ha_sync \u2014 HA sync status check for BIG-IP (HARD)\n image_presence \u2014 software image present on BIG-IP image store (HARD)\n f5os_image_presence \u2014 software image present on F5OS image catalog (HARD)\n f5os_check_version \u2014 F5OS check-version API readiness verification (HARD)\n disk_space \u2014 available disk GB vs 15 GB threshold (SOFT)\n f5os_disk \u2014 F5OS platform disk space check (SOFT)\n cpu_utilization \u2014 5-min avg CPU % (SOFT; Stage 1: always SKIP)\n memory_utilization \u2014 5-min avg memory % (SOFT; Stage 1: always SKIP)\n config_backup \u2014 recent F5OS config backup exists (SOFT)\n cluster \u2014 F5OS cluster nodes/stages healthy (SOFT)\n cores \u2014 no F5OS core/crash-dump files present (SOFT)\n tenant_status - deployed F5OS tenants must not be Pending (HARD); other unhealthy tenant or instance states warn\n service_pods - all F5OS infrastructure service pods are healthy (SOFT)\n fpga_status - F5OS FPGA / DMA / DPSM / VF readiness healthy (SOFT)\n upgrade_path \u2014 upgrade path compatibility check (K13845) (HARD)\n license_compatibility \u2014 license edition version ceiling (HARD)\n license_date \u2014 service check date vs license check date (SOFT)\n f5os_version_support \u2014 F5OS OS version support check (HARD)\n" + }, + "severity": { + "$ref": "#/components/schemas/CheckSeverity" + }, + "status": { + "$ref": "#/components/schemas/CheckStatus" + }, + "message": { + "type": "string", + "description": "Human-readable explanation. Always present when status is WARN, FAIL, or SKIP." + }, + "detail": { + "type": "object", + "additionalProperties": true, + "description": "Structured extra data relevant to the check result.\nExamples:\n disk_space: { available_gb: 8.2, threshold_gb: 15.0 }\n cluster: { healthy_nodes: 1, install_done: 2, install_total: 2 }\n cores: { count: 2, files: [\"core.123\", \"core.456\"] }\n fpga_status: { has_fpga: true, ready_nodes: 1, total_nodes: 1 }\n tenant_status: { blocking_tenants: [\"tenant-a: running-state=\\\"deployed\\\" status=\\\"Pending\\\"\"] }\n upgrade_path: { current_version: \"15.1.2\", target_version: \"17.1.5\", min_source_version: \"16.1.0\" }\n license_date: { license_check_date: \"2024-01-15\", service_check_date: \"2023-12-01\" }\n" + } + } + }, + "DeviceValidationResult": { + "type": "object", + "description": "Validation result for a single device within a job.\nOne row per device; updated in real-time as checks run.\n", + "required": [ + "device_id", + "hostname", + "status", + "current_step", + "check_results" + ], + "properties": { + "device_id": { + "type": "string", + "format": "uuid" + }, + "hostname": { + "type": "string", + "description": "Device hostname as known to fleet inventory." + }, + "status": { + "$ref": "#/components/schemas/ValidationStatus" + }, + "current_step": { + "type": "string", + "description": "Current FSM step for this device. Useful for polling progress mid-run.\nValues: PENDING | CHECKING_HA_SYNC | CHECKING_IMAGE_PRESENCE | CHECKING_F5OS_IMAGE_PRESENCE |\n CHECKING_F5OS_CHECK_VERSION | CHECKING_DISK | CHECKING_F5OS_DISK | CHECKING_F5OS_CONFIG_BACKUP |\n CHECKING_F5OS_CLUSTER | CHECKING_F5OS_CORES | CHECKING_F5OS_SERVICE_PODS |\n CHECKING_F5OS_FPGA | CHECKING_F5OS_TENANT_STATUS | CHECKING_UPGRADE_PATH |\n CHECKING_LICENSE | CHECKING_LICENSE_DATE | CHECKING_F5OS_VERSION_SUPPORT | COMPLETE\n" + }, + "check_results": { + "type": "array", + "description": "Ordered list of check outcomes. Empty until the device starts running.", + "items": { + "$ref": "#/components/schemas/CheckResult" + } + }, + "blocking_check": { + "type": "string", + "description": "Name of the first HARD check that returned FAIL.\nEmpty string if no HARD check failed.\n" + }, + "started_at": { + "type": "string", + "format": "date-time", + "description": "When the first check started for this device." + }, + "completed_at": { + "type": "string", + "format": "date-time", + "description": "When all checks completed (or an error stopped execution)." + } + } + }, + "ValidationSummary": { + "type": "object", + "description": "Aggregated validation results for a validation run.\nReturned by GET /validate/{validationRunId}.\nPoll until `status` is no longer PENDING or RUNNING.\n`can_proceed: true` means no HARD check failures exist across any device.\n", + "required": [ + "validation_run_id", + "image_id", + "status", + "device_count", + "pass_count", + "warn_count", + "fail_count", + "error_count", + "can_proceed", + "devices" + ], + "properties": { + "validation_run_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for this validation run." + }, + "image_id": { + "type": "string", + "format": "uuid", + "description": "The target image UUID this run validated against." + }, + "status": { + "$ref": "#/components/schemas/ValidationStatus", + "description": "Rolled-up status across all devices.\nFAILED if any device has a HARD failure; WARNING if any device has a SOFT warning and no\nHARD failures; PASSED if all devices pass cleanly; ERROR if any device errored.\n" + }, + "device_count": { + "type": "integer", + "description": "Total number of devices being validated." + }, + "pass_count": { + "type": "integer", + "description": "Devices with status PASSED." + }, + "warn_count": { + "type": "integer", + "description": "Devices with status WARNING." + }, + "fail_count": { + "type": "integer", + "description": "Devices with status FAILED." + }, + "error_count": { + "type": "integer", + "description": "Devices with status ERROR." + }, + "can_proceed": { + "type": "boolean", + "description": "True when no device has a HARD-severity FAIL.\nThe operator may still choose to proceed despite SOFT warnings.\n" + }, + "devices": { + "type": "array", + "description": "Per-device validation results.", + "items": { + "$ref": "#/components/schemas/DeviceValidationResult" + } + }, + "triggered_at": { + "type": "string", + "format": "date-time", + "description": "When this validation run was triggered." + }, + "completed_at": { + "type": "string", + "format": "date-time", + "description": "When all devices finished (or errored). Null while status is PENDING or RUNNING." + } + } + }, + "InstallationActivityResponse": { + "type": "object", + "description": "Response returned by the per-device activity resume endpoint.\nContains the activity ID, job ID, device ID, and updated status.\n", + "required": [ + "id", + "jobId", + "deviceId", + "status" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique activity identifier." + }, + "jobId": { + "type": "string", + "format": "uuid", + "description": "Parent job ID." + }, + "executionId": { + "type": "string", + "format": "uuid", + "description": "Parent execution ID." + }, + "deviceId": { + "type": "string", + "format": "uuid", + "description": "ID of the device this activity is tracking." + }, + "deviceKind": { + "$ref": "#/components/schemas/DeviceKind", + "description": "Kind of device (e.g. BIGIP)." + }, + "batchNumber": { + "type": "integer", + "description": "Batch this activity belongs to." + }, + "status": { + "type": "string", + "description": "Updated activity status after resume.", + "enum": [ + "RUNNING", + "PAUSED_PENDING_REBOOT", + "COMPLETED", + "FAILED" + ] + }, + "currentStep": { + "type": "string", + "description": "Current step the activity is on." + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "UpgradeJob": { + "type": "object", + "description": "Generic job response returned by lifecycle action endpoints\n(/activate, /pause, /resume, /cancel). Contains the job id, status, and type\nso the caller can fetch full details from the appropriate typed endpoint.\n", + "required": [ + "id", + "jobType", + "status" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique job identifier." + }, + "workflowId": { + "type": "string", + "format": "uuid", + "description": "Parent workflow entity ID." + }, + "name": { + "type": "string" + }, + "jobType": { + "type": "string", + "description": "Identifies whether this is a software distribution or software installation job.", + "enum": [ + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION" + ] + }, + "status": { + "$ref": "#/components/schemas/UpgradeJobStatus" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "SoftwareInstallationExecutionRecord": { + "type": "object", + "description": "Software installation execution record. Field names + types match\nthe generic workflow Execution schema so the cross-feature UI can\nrender installation and distribution / autoscale executions with\nthe same panel.\n\nOn single-execution GET (`/executions/{executionId}`) the response\nadditionally embeds `instanceProgress` \u2014 the per-device runtime\nrollup scoped to this execution. The executions LIST endpoint\nstays lean and never populates that field.\n", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "jobId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "jobName": { + "type": "string", + "readOnly": true, + "description": "Parent software installation job name." + }, + "jobDescription": { + "type": "string", + "readOnly": true, + "description": "Parent software installation job description." + }, + "trigger": { + "type": "string", + "enum": [ + "USER", + "ALERT", + "SYSTEM", + "SCHEDULE" + ], + "readOnly": true + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "PAUSED", + "COMPLETED", + "FAILED", + "CANCELLED" + ], + "readOnly": true + }, + "reason": { + "type": "string", + "description": "Human-readable trigger reason" + }, + "startedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "completedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "durationMs": { + "type": "integer", + "readOnly": true + }, + "activityCount": { + "type": "integer", + "readOnly": true, + "description": "Number of activities (per-device rows) recorded under this execution" + }, + "retryCount": { + "type": "integer", + "readOnly": true + }, + "currentStep": { + "type": "string", + "readOnly": true + }, + "lastError": { + "type": "string", + "readOnly": true + }, + "changeRequest": { + "type": "string", + "nullable": true, + "maxLength": 255, + "description": "Optional change-request identifier supplied at activation time.\nNull when no change request was provided.\n", + "readOnly": true + }, + "correlationId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "createdBy": { + "type": "string", + "nullable": true, + "readOnly": true, + "description": "Username of the operator who created (activated) this execution." + }, + "modifiedBy": { + "type": "string", + "nullable": true, + "readOnly": true, + "description": "Username of the operator who last modified this execution." + }, + "instanceProgress": { + "$ref": "#/components/schemas/InstallInstanceProgress", + "description": "Per-device runtime rollup scoped to this execution. Populated\nonly on the single-execution GET; absent on the executions LIST.\n" + }, + "configSnapshot": { + "$ref": "#/components/schemas/SoftwareInstallationConfig", + "readOnly": true, + "description": "Immutable snapshot of the resolved SoftwareInstallationConfig\n(including per-device volume overrides) captured at activation\ntime. Lets clients inspect the exact config this execution ran\nwith, independent of any post-activation reset of the job config.\nPopulated only on the single-execution GET; absent on the\nexecutions LIST to keep that response lean.\n" + }, + "readinessWarnDeviceCount": { + "type": "integer", + "minimum": 0, + "readOnly": true, + "description": "Number of devices in this execution whose post-upgrade readiness\nroll-up contains at least one WARN finding and no CRITICAL finding.\nDevices are counted by highest severity, so a device with any\nCRITICAL finding is excluded from this WARN count.\n" + }, + "readinessCriticalDeviceCount": { + "type": "integer", + "minimum": 0, + "readOnly": true, + "description": "Number of devices in this execution whose post-upgrade readiness\nroll-up contains at least one CRITICAL finding.\n" + }, + "haCoordination": { + "$ref": "#/components/schemas/HACoordination", + "description": "Cross-node HA orchestration timeline for this execution. Surfaces\nthe pair-level coordinator phases (validate-pair, failover, the\nHITL gates, failback, ...) that belong to NEITHER node alone and\nso are not represented in any single device's per-step timeline.\nPopulated only on the single-execution GET, and only for\nHA-topology executions; absent for STANDALONE executions or when\nno pair cursor exists yet.\n" + } + } + }, + "HACoordination": { + "type": "object", + "description": "Cross-node HA orchestration rollup for an execution. Holds one entry\nper HA pair participating in the execution. This is a derived READ\nMODEL (the pair-level analogue of the per-device step timeline), not a\nnew source of truth: it is projected from the persisted pair cursors.\n", + "required": [ + "pairs" + ], + "properties": { + "pairs": { + "type": "array", + "description": "One coordination timeline per HA pair in this execution.", + "items": { + "$ref": "#/components/schemas/HAPairCoordination" + } + } + } + }, + "HAPairCoordination": { + "type": "object", + "description": "The orchestration timeline for a single HA pair. The plan is derived\nfrom the SAME resolved controls the coordinator persisted on the pair\ncursor (pause-before-failover / pause-before-second-install /\nautomatic-failback / pause-before-failback), so a gate the operator\ndisabled is simply omitted from the timeline \u2014 mirroring how the\ncoordinator skips it at runtime.\n", + "required": [ + "pairId", + "standbyDeviceId", + "activeDeviceId", + "currentPhase", + "phases" + ], + "properties": { + "pairId": { + "type": "string", + "format": "uuid", + "description": "Identifier of the HA pair this timeline describes." + }, + "standbyDeviceId": { + "type": "string", + "format": "uuid", + "description": "Device that STARTED as standby (upgraded first, ha_order 0).\n" + }, + "standbyDeviceName": { + "type": "string", + "description": "Human-readable name of the standby device, projected when\navailable so the UI need not re-resolve it. Omitted when unknown.\n" + }, + "activeDeviceId": { + "type": "string", + "format": "uuid", + "description": "Device that STARTED as active (upgraded second, ha_order 1).\n" + }, + "activeDeviceName": { + "type": "string", + "description": "Human-readable name of the active device, projected when\navailable so the UI need not re-resolve it. Omitted when unknown.\n" + }, + "currentPhase": { + "$ref": "#/components/schemas/HAPhase", + "description": "The live coordinator phase taken from the pair cursor." + }, + "lastError": { + "type": "string", + "description": "Failure context for the pair, carried when currentPhase is FAILED.\nOmitted otherwise.\n" + }, + "phases": { + "type": "array", + "description": "The ordered, IN-PLAN coordination phases (disabled gates are\nomitted), each classified against the live cursor.\n", + "items": { + "$ref": "#/components/schemas/HAPhaseStep" + } + } + } + }, + "HAPhaseStep": { + "type": "object", + "description": "One coordination phase in a pair's timeline, classified against the\nlive cursor using the same vocabulary as the per-device step timeline\n(COMPLETED / RUNNING / FAILED / PENDING), plus PAUSED for an AWAIT gate\nthe coordinator is currently holding for HITL confirmation.\n", + "required": [ + "phase", + "status" + ], + "properties": { + "phase": { + "$ref": "#/components/schemas/HAPhase", + "description": "Which coordination phase this entry represents." + }, + "status": { + "$ref": "#/components/schemas/InstallStepStatus", + "description": "Lifecycle status of this phase against the live cursor. PAUSED is\nadditionally used for an AWAIT gate the coordinator is holding on.\n" + }, + "sequence": { + "type": "integer", + "description": "0-based position of this phase within the pair's IN-PLAN timeline,\nmirroring InstallStepDetail.sequence on the per-device step timeline.\nLets the UI render phases in coordinator order without hardcoding the\nHAPhase ordering. Because disabled HITL gates are omitted from the\nplan, sequence is contiguous over the phases actually present (it is\nNOT the device's position in the full HAPhase enum).\n" + } + } + }, + "HAPhase": { + "type": "string", + "description": "A pair-level phase walked by the HA coordinator. These belong to the\nPAIR (not to either node alone): VALIDATE_PAIR validates both nodes\ntogether, the AWAIT_* phases are durable HITL gates the coordinator\nPAUSES on, FAILOVER/FAILBACK move traffic between nodes, and STANDBY/\nACTIVE are the per-node install phases surfaced here so the pair\ntimeline reads end-to-end. DONE/FAILED are terminal cursor states.\n", + "enum": [ + "VALIDATE_PAIR", + "DISABLE_SYNC", + "STANDBY", + "AWAIT_FAILOVER_GATE", + "FAILOVER", + "AWAIT_SECOND_INSTALL_GATE", + "ACTIVE", + "AWAIT_FAILBACK_GATE", + "FAILBACK", + "RESTORE_SYNC", + "DONE", + "FAILED" + ] + }, + "InstallInstanceProgress": { + "type": "object", + "description": "Per-device runtime rollup scoped to a single installation execution.\nSame numeric shape as the distribution InstanceProgress but uses\ninstallation-specific per-device status values.\n", + "required": [ + "totalDevices", + "devices" + ], + "properties": { + "totalDevices": { + "type": "integer" + }, + "pending": { + "type": "integer" + }, + "running": { + "type": "integer" + }, + "completed": { + "type": "integer" + }, + "failed": { + "type": "integer" + }, + "cancelled": { + "type": "integer" + }, + "devices": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PerDeviceInstallStatus" + } + } + } + }, + "PerDeviceInstallStatus": { + "type": "object", + "description": "Runtime status of one device within a software installation job execution.\nThis is the per-device row returned under\ninstanceProgress.devices[] on the single-execution GET\n(GET /jobs/software-installation/{jobId}/executions/{executionId}).\nFor an HA pair, each node appears as its own row here.\n", + "required": [ + "deviceId", + "status" + ], + "properties": { + "deviceId": { + "type": "string", + "format": "uuid" + }, + "deviceName": { + "type": "string", + "description": "Display name resolved from `upgrade.device_upgrade_metadata.device_name`\n(mirrored from `public.devices.device_name` for BIG-IP and\n`public.f5os_providers.name` for F5OS). Empty when the metadata row\nis missing or has no name \u2014 clients should fall back to `deviceId`\nfor display.\n" + }, + "deviceKind": { + "$ref": "#/components/schemas/DeviceKind" + }, + "haRole": { + "type": "string", + "description": "HA role resolved from `upgrade.device_upgrade_metadata.ha_state`\nfor this device within the execution rollup. Omitted when the\ndevice has no metadata row or no HA role is known.\n", + "enum": [ + "ACTIVE", + "STANDBY", + "STANDALONE", + "UNKNOWN" + ] + }, + "haPeerId": { + "type": "string", + "format": "uuid", + "description": "Peer device identifier resolved from\n`upgrade.device_upgrade_metadata.ha_peer_device_id`. Omitted for\nstandalone devices or when the peer is not onboarded / unknown.\n" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "COMPLETED", + "FAILED", + "CANCELLED" + ] + }, + "currentStep": { + "allOf": [ + { + "$ref": "#/components/schemas/InstallStep" + } + ], + "description": "Current step of this device's installation FSM. For an HA pair this is\nthe per-node step; pair-level coordination phases (failover/failback/\ncross-node gates) are not reflected here.\n" + }, + "steps": { + "type": "array", + "description": "Ordered per-device step timeline. Derived from the device's FSM plan\n(plan() \u2014 identical for standalone and for each node of an HA pair)\nand enriched with live persisted runtime state (upgrade.activity_steps\n+ the device's current step/progress). Each entry carries the step\nname plus its own status (COMPLETED / RUNNING / PENDING / FAILED /\nCANCELLED) so the UI can render the DONE steps, the IN-PROGRESS step,\nand the upcoming/PENDING steps on a single timeline. Populated only on\nthe single-execution GET; may be empty before the device's plan is\nknown.\n", + "items": { + "$ref": "#/components/schemas/InstallStepDetail" + } + }, + "retryCount": { + "type": "integer" + }, + "progressPct": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Live install-monitoring percentage (0\u2013100) for this device within\n*this* execution (ARGUSTELEM-5223). Read back from\nupgrade.installation_device_state.progress_pct, written by the install\nengine as the per-device install advances. Defaults to 0 when the\ndevice has no progress row yet (PENDING, before install starts), so\nclients can always render a progress bar. For an HA pair, each node\nreports its own percentage.\n" + }, + "lastError": { + "type": "string" + }, + "startedAt": { + "type": "string", + "format": "date-time" + }, + "completedAt": { + "type": "string", + "format": "date-time" + }, + "preSnapshotUrl": { + "type": "string", + "description": "API back-link to the PRE-install flight-check snapshot captured for\nthis device during *this* execution. The snapshot ID is embedded in\nthe URL (GET /flight-checks/snapshots/{snapshotId}). Omitted when no\nPRE snapshot was captured.\n" + }, + "postSnapshotUrl": { + "type": "string", + "description": "API back-link to the POST-install flight-check snapshot captured for\nthis device during *this* execution. The snapshot ID is embedded in\nthe URL (GET /flight-checks/snapshots/{snapshotId}). Omitted when no\nPOST snapshot was captured.\n" + }, + "diffUrl": { + "type": "string", + "description": "API back-link to the PRE-vs-POST flight-check diff\n(GET /flight-checks/diffs/{diffId}). Omitted when no diff was computed.\n" + }, + "readinessWarnings": { + "type": "array", + "description": "Post-upgrade readiness warning findings roll-up computed at POST_FLIGHT\n(F5OS devices only). Omitted when none or non-F5OS device.\n", + "items": { + "$ref": "#/components/schemas/ReadinessWarning" + } + } + } + }, + "ReadinessWarning": { + "type": "object", + "description": "A single graded post-upgrade readiness finding.\n", + "required": [ + "check", + "level", + "message" + ], + "properties": { + "check": { + "type": "string", + "description": "Stable check identifier (e.g. \"cluster\", \"firmwareStatus\")." + }, + "level": { + "type": "string", + "description": "Severity level (INFO, WARN, CRITICAL).", + "enum": [ + "INFO", + "WARN", + "CRITICAL" + ] + }, + "message": { + "type": "string", + "description": "Human-readable, operator-facing finding message." + } + } + }, + "ActivateDistributionJobRequest": { + "type": "object", + "description": "Optional request body for POST /jobs/software-distribution/{jobId}/activate.\nAll fields are optional; the endpoint may be called with no body at all.\n", + "properties": { + "changeRequest": { + "type": "string", + "nullable": true, + "maxLength": 255, + "description": "Optional change-request identifier (e.g. \"CHG0012345\") associated with\nthis specific activation/run. Persisted on the execution record so the\nUI can display it in the execution drawer. Each activation of the same\njob may carry a different change request.\n" + } + } + }, + "ActivateInstallationJobRequest": { + "type": "object", + "description": "Optional request body for POST /jobs/software-installation/{jobId}/activate.\nAll fields are optional; the endpoint may be called with no body at all.\n", + "properties": { + "changeRequest": { + "type": "string", + "nullable": true, + "maxLength": 255, + "description": "Optional change-request identifier (e.g. \"CHG0012345\") associated with\nthis specific activation/run. Persisted on the execution record so the\nUI can display it in the execution drawer. Each activation of the same\njob may carry a different change request.\n" + } + } + }, + "Workflow": { + "type": "object", + "required": [ + "id", + "name", + "type", + "executionMode", + "createdAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "name": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "executionMode": { + "type": "string", + "enum": [ + "CONTINUOUS", + "ON_DEMAND" + ], + "description": "CONTINUOUS \u2014 self-repeating, driven by policies/conditions (e.g. AutoScale).\nON_DEMAND \u2014 discrete runs triggered by user or scheduler (e.g. SOFTWARE_DISTRIBUTION, SOFTWARE_INSTALLATION, Backup).\n" + }, + "description": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + } + } + }, + "WorkflowListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Workflow" + } + }, + "total": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "limit": { + "type": "integer" + } + } + }, + "WorkflowConfig": { + "oneOf": [ + { + "$ref": "#/components/schemas/AutoScaleConfig" + }, + { + "$ref": "#/components/schemas/SoftwareInstallationConfig" + }, + { + "$ref": "#/components/schemas/SoftwareDistributionConfig" + }, + { + "$ref": "#/components/schemas/BackupConfig" + } + ], + "discriminator": { + "propertyName": "configType", + "mapping": { + "AUTO_SCALE": "#/components/schemas/AutoScaleConfig", + "SOFTWARE_INSTALLATION": "#/components/schemas/SoftwareInstallationConfig", + "SOFTWARE_DISTRIBUTION": "#/components/schemas/SoftwareDistributionConfig", + "BACKUP": "#/components/schemas/BackupConfig" + } + } + }, + "AutoScaleConfig": { + "type": "object", + "required": [ + "configType", + "environmentReference", + "minSize", + "maxSize" + ], + "properties": { + "configType": { + "type": "string", + "enum": [ + "AUTO_SCALE" + ] + }, + "environmentReference": { + "type": "string", + "description": "Reference to managed environment (UUID or alias string)" + }, + "templateReference": { + "type": "string", + "description": "Template for new instances (UUID or alias string)" + }, + "licensePoolReference": { + "type": "string", + "description": "License pool for allocation (UUID or alias string)" + }, + "providerType": { + "type": "string", + "description": "Cloud provider type (e.g. AWS, Azure, GCP)" + }, + "minSize": { + "type": "integer", + "minimum": 0, + "description": "Minimum pool size" + }, + "maxSize": { + "type": "integer", + "minimum": 1, + "description": "Maximum pool size" + }, + "desiredSize": { + "type": "integer", + "minimum": 0, + "description": "Current/target pool size" + }, + "evaluationPeriod": { + "type": "integer", + "description": "Seconds between policy evaluations", + "example": 300 + }, + "scaleInMethod": { + "type": "string", + "enum": [ + "NEWEST_FIRST", + "OLDEST_FIRST", + "RANDOM" + ], + "description": "Strategy for selecting instances to scale in" + }, + "scaleOutCooldownSeconds": { + "type": "integer", + "description": "Cooldown period after scale-out activity", + "example": 600 + }, + "scaleInCooldownSeconds": { + "type": "integer", + "description": "Cooldown period after scale-in activity", + "example": 900 + }, + "scalingPolicies": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ScalingPolicy" + }, + "description": "Array of scaling policies that trigger activities" + } + }, + "example": { + "configType": "AUTO_SCALE", + "environmentReference": "550e8400-e29b-41d4-a716-446655440000", + "templateReference": "550e8400-e29b-41d4-a716-446655440001", + "licensePoolReference": "550e8400-e29b-41d4-a716-446655440003", + "providerType": "AWS", + "minSize": 2, + "maxSize": 10, + "desiredSize": 3, + "evaluationPeriod": 300, + "scaleInMethod": "NEWEST_FIRST", + "scaleOutCooldownSeconds": 600, + "scaleInCooldownSeconds": 900, + "scalingPolicies": [ + { + "name": "scale-out-high-cpu", + "direction": "SCALE_OUT", + "metricName": "cpu_utilization", + "threshold": 80, + "operator": "GREATER_THAN", + "scalingStep": 1 + }, + { + "name": "scale-in-low-cpu", + "direction": "SCALE_IN", + "metricName": "cpu_utilization", + "threshold": 20, + "operator": "LESS_THAN", + "scalingStep": 1 + } + ] + } + }, + "ScalingPolicy": { + "type": "object", + "required": [ + "name", + "direction", + "metricName", + "threshold", + "operator", + "scalingStep" + ], + "properties": { + "name": { + "type": "string", + "description": "Unique policy identifier" + }, + "direction": { + "type": "string", + "enum": [ + "SCALE_OUT", + "SCALE_IN" + ], + "description": "Scaling direction triggered by this policy" + }, + "metricName": { + "type": "string", + "description": "Metric name to evaluate (e.g. cpu_utilization, memory_usage, connections)" + }, + "threshold": { + "type": "number", + "description": "Threshold value for metric comparison" + }, + "operator": { + "type": "string", + "enum": [ + "GREATER_THAN", + "LESS_THAN", + "GREATER_THAN_OR_EQUAL", + "LESS_THAN_OR_EQUAL", + "EQUAL" + ], + "description": "Comparison operator to evaluate against threshold" + }, + "scalingStep": { + "type": "integer", + "minimum": 1, + "description": "Number of instances to scale in/out" + } + }, + "examples": [ + { + "name": "example-scale-out", + "value": { + "name": "scale-out-high-cpu", + "direction": "SCALE_OUT", + "metricName": "cpu_utilization", + "threshold": 80, + "operator": "GREATER_THAN", + "scalingStep": 1 + } + }, + { + "name": "example-scale-in", + "value": { + "name": "scale-in-low-memory", + "direction": "SCALE_IN", + "metricName": "memory_usage", + "threshold": 30, + "operator": "LESS_THAN", + "scalingStep": 2 + } + } + ] + }, + "UpgradeConfig": { + "type": "object", + "required": [ + "configType", + "targetVersion" + ], + "properties": { + "configType": { + "type": "string", + "enum": [ + "UPGRADE" + ], + "description": "Config type discriminator" + }, + "targetVersion": { + "type": "string", + "description": "Target version to upgrade to (e.g. 17.1.2)" + }, + "rollbackOnFailure": { + "type": "boolean", + "default": true, + "description": "Automatically rollback if any step fails" + }, + "maxConcurrent": { + "type": "integer", + "minimum": 1, + "default": 1, + "description": "Maximum number of instances to upgrade simultaneously" + }, + "preCheckScript": { + "type": "string", + "description": "Script to execute before upgrade begins" + }, + "postCheckScript": { + "type": "string", + "description": "Script to execute after upgrade completes" + } + }, + "example": { + "configType": "UPGRADE", + "targetVersion": "17.1.2", + "rollbackOnFailure": true, + "maxConcurrent": 1 + } + }, + "BackupConfig": { + "type": "object", + "required": [ + "configType", + "storageTarget" + ], + "properties": { + "configType": { + "type": "string", + "enum": [ + "BACKUP" + ], + "description": "Config type discriminator" + }, + "storageTarget": { + "type": "string", + "description": "Storage destination (e.g. s3://my-bucket, gs://my-bucket)" + }, + "retentionDays": { + "type": "integer", + "minimum": 1, + "description": "Days to retain backups before automatic deletion" + }, + "compressionEnabled": { + "type": "boolean", + "default": true, + "description": "Enable compression for backup files" + }, + "encryptionEnabled": { + "type": "boolean", + "default": false, + "description": "Enable encryption for backup files" + } + }, + "example": { + "configType": "BACKUP", + "storageTarget": "s3://company-backups", + "retentionDays": 30, + "compressionEnabled": true, + "encryptionEnabled": true + } + }, + "Job": { + "type": "object", + "required": [ + "id", + "workflowId", + "type", + "name", + "status", + "config", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "workflowId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "name": { + "type": "string" + }, + "description": { + "type": "string", + "description": "Optional human-readable job description" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "INACTIVE", + "ERROR", + "COMPLETED", + "FAILED", + "CANCELLED", + "DELETING" + ] + }, + "enabled": { + "type": "boolean", + "description": "Whether the job can be activated, paused, or resumed." + }, + "config": { + "$ref": "#/components/schemas/JobConfig", + "description": "Job-level config for runtime behavior" + }, + "effectiveConfig": { + "$ref": "#/components/schemas/JobConfig", + "description": "Resolved config (workflow defaultConfig merged with job config)", + "readOnly": true + }, + "runtime": { + "$ref": "#/components/schemas/JobRuntime" + }, + "schedule": { + "$ref": "#/components/schemas/Schedule", + "description": "Only populated for ON_DEMAND jobs with a schedule configured" + }, + "jobUrl": { + "type": "string", + "readOnly": true, + "description": "Optional REST endpoint for this job. For AutoScale jobs this is the generic workflow job endpoint. Some feature-owned jobs may use a type-specific endpoint.", + "example": "/api/v1/workflows/b7e6a4ae-4cf9-4ad4-b8f9-9b5347300d73/jobs/114ca9f9-88a3-49e1-92f2-757d7fedde98" + }, + "version": { + "type": "string", + "readOnly": true + }, + "modifiedBy": { + "type": "string", + "description": "Username of the operator who last modified the job.", + "readOnly": true + }, + "runningExecutionsCount": { + "type": "integer", + "description": "Number of currently RUNNING executions for this job.", + "readOnly": true + }, + "triggerCount": { + "type": "integer", + "description": "Number of configured triggers for this job.", + "readOnly": true + }, + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + } + } + }, + "JobRuntime": { + "type": "object", + "description": "Live runtime state (populated for CONTINUOUS jobs)", + "properties": { + "currentSize": { + "type": "integer" + }, + "lastEvaluatedAt": { + "type": "string", + "format": "date-time" + }, + "lastExecutionId": { + "type": "string", + "format": "uuid" + }, + "lastExecutionStatus": { + "type": "string", + "enum": [ + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED", + "CANCELLED", + "TIMEOUT" + ] + } + } + }, + "JobCreateRequest": { + "type": "object", + "required": [ + "name", + "type", + "config" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "name": { + "type": "string" + }, + "description": { + "type": "string", + "description": "Optional human-readable job description" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "INACTIVE", + "ERROR", + "COMPLETED", + "FAILED", + "CANCELLED", + "DELETING" + ] + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether the job can be activated, paused, or resumed. Defaults to true when omitted." + }, + "config": { + "$ref": "#/components/schemas/JobConfig" + }, + "schedule": { + "$ref": "#/components/schemas/Schedule" + } + } + }, + "JobPatchRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "name": { + "type": "string" + }, + "description": { + "type": "string", + "description": "Optional human-readable job description. Set to empty string to clear." + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "INACTIVE", + "ERROR", + "COMPLETED", + "FAILED", + "CANCELLED", + "DELETING" + ] + }, + "enabled": { + "type": "boolean", + "description": "Whether the job can be activated, paused, or resumed." + }, + "config": { + "$ref": "#/components/schemas/JobConfig" + }, + "schedule": { + "$ref": "#/components/schemas/Schedule" + } + } + }, + "JobListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Job" + } + }, + "total": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "limit": { + "type": "integer" + } + } + }, + "PaginationMetadata": { + "type": "object", + "required": [ + "page", + "page_size", + "total", + "total_pages" + ], + "properties": { + "page": { + "type": "integer", + "minimum": 1 + }, + "page_size": { + "type": "integer", + "minimum": 1 + }, + "total": { + "type": "integer", + "minimum": 0 + }, + "total_pages": { + "type": "integer", + "minimum": 0 + } + } + }, + "JobListPaginatedResponse": { + "type": "object", + "required": [ + "items", + "pagination" + ], + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Job" + } + }, + "pagination": { + "$ref": "#/components/schemas/PaginationMetadata" + } + } + }, + "InstanceListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Instance" + } + }, + "totalItems": { + "type": "integer" + } + } + }, + "Instance": { + "type": "object", + "required": [ + "id", + "workflowId", + "jobId", + "status", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "workflowId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "jobId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "hostname": { + "type": "string" + }, + "ip": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "PROVISIONING", + "READY", + "ERROR", + "DEPROVISIONING", + "UNKNOWN" + ] + }, + "managementAddr": { + "type": "string" + }, + "providerGuestRef": { + "type": "string" + }, + "vmName": { + "type": "string", + "description": "Cloud provider VM name returned by create-vm." + }, + "statsDeviceId": { + "type": "string", + "format": "uuid", + "description": "Device identifier returned by stats collection/device management." + }, + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "deletedAt": { + "type": "string", + "format": "date-time", + "nullable": true, + "readOnly": true + } + } + }, + "JobConfig": { + "type": "object", + "description": "Job configuration (discriminated by workflow type - use AutoScaleConfig, UpgradeConfig, or BackupConfig)", + "discriminator": { + "propertyName": "configType", + "mapping": { + "AUTO_SCALE": "#/components/schemas/AutoScaleConfig", + "SOFTWARE_INSTALLATION": "#/components/schemas/SoftwareInstallationConfig", + "SOFTWARE_DISTRIBUTION": "#/components/schemas/SoftwareDistributionConfig", + "BACKUP": "#/components/schemas/BackupConfig" + } + }, + "properties": { + "configType": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_INSTALLATION", + "SOFTWARE_DISTRIBUTION", + "BACKUP" + ], + "description": "Configuration type that determines which config object to use" + }, + "environmentReference": { + "type": "string", + "description": "[AUTO_SCALE] Reference to managed environment (UUID or alias string)" + }, + "templateReference": { + "type": "string", + "description": "[AUTO_SCALE] Template for new instances (UUID or alias string)" + }, + "licensePoolReference": { + "type": "string", + "description": "[AUTO_SCALE] License pool for allocation (UUID or alias string)" + }, + "providerType": { + "type": "string", + "description": "[AUTO_SCALE] Cloud provider type" + }, + "minSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Minimum pool size" + }, + "maxSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Maximum pool size" + }, + "desiredSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Current/target pool size" + }, + "evaluationPeriod": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Seconds between policy evaluations" + }, + "scaleInMethod": { + "type": "string", + "enum": [ + "NEWEST_FIRST", + "OLDEST_FIRST", + "RANDOM" + ], + "description": "[AUTO_SCALE] Strategy for scaling in" + }, + "scaleOutCooldownSeconds": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Cooldown after scale-out" + }, + "scaleInCooldownSeconds": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Cooldown after scale-in" + }, + "scalingPolicies": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ScalingPolicy" + }, + "description": "[AUTO_SCALE] Scaling policies" + } + } + }, + "Schedule": { + "type": "object", + "properties": { + "cron": { + "type": "string", + "description": "Unix cron expression (e.g. \"0 2 * * *\" for 2 AM daily, \"0 2 * * 0\" for Sundays at 2 AM)", + "example": "0 2 * * *" + }, + "timezone": { + "type": "string", + "default": "UTC", + "description": "IANA timezone for cron evaluation (e.g. America/New_York, Europe/London)", + "example": "America/New_York" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether the schedule is active" + } + }, + "example": { + "cron": "0 2 * * 0", + "timezone": "America/New_York", + "enabled": true + } + }, + "Execution": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "jobId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "trigger": { + "type": "string", + "enum": [ + "USER", + "ALERT", + "SYSTEM", + "SCHEDULE" + ], + "readOnly": true + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED", + "CANCELLED", + "TIMEOUT" + ], + "readOnly": true + }, + "reason": { + "type": "string", + "description": "Human-readable trigger reason" + }, + "startedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "completedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "durationMs": { + "type": "integer", + "readOnly": true + }, + "activityCount": { + "type": "integer", + "readOnly": true, + "description": "Number of activities recorded under this execution" + }, + "retryCount": { + "type": "integer", + "readOnly": true + }, + "currentStep": { + "type": "string", + "readOnly": true + }, + "lastError": { + "type": "string", + "readOnly": true + }, + "correlationId": { + "type": "string", + "format": "uuid", + "readOnly": true + } + } + }, + "ExecutionDetail": { + "allOf": [ + { + "$ref": "#/components/schemas/Execution" + }, + { + "type": "object", + "properties": { + "activitySummary": { + "type": "object", + "properties": { + "total": { + "type": "integer" + }, + "running": { + "type": "integer" + }, + "completed": { + "type": "integer" + }, + "failed": { + "type": "integer" + } + } + }, + "latestActivityId": { + "type": "string", + "format": "uuid" + }, + "latestActivityType": { + "type": "string" + } + } + } + ] + }, + "ExecutionListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Execution" + } + }, + "total": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "limit": { + "type": "integer" + } + } + }, + "Activity": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "executionId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "activityType": { + "type": "string", + "description": "Logical action type (e.g. SCALE_OUT, SCALE_IN, UPGRADE)" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "COMPLETED", + "FAILED", + "SKIPPED", + "CANCELLED" + ] + }, + "trigger": { + "type": "string", + "enum": [ + "USER", + "ALERT", + "SYSTEM", + "SCHEDULE" + ] + }, + "reason": { + "type": "string" + }, + "startedAt": { + "type": "string", + "format": "date-time" + }, + "completedAt": { + "type": "string", + "format": "date-time" + }, + "durationMs": { + "type": "integer" + }, + "currentStep": { + "type": "string" + }, + "stepCount": { + "type": "integer" + }, + "correlationId": { + "type": "string", + "format": "uuid" + } + } + }, + "ActivityDetail": { + "allOf": [ + { + "$ref": "#/components/schemas/Activity" + }, + { + "type": "object", + "properties": { + "steps": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ActivityStep" + } + } + } + } + ] + }, + "ActivityListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Activity" + } + }, + "total": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "limit": { + "type": "integer" + } + } + }, + "ActivityStep": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "activityId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "stepName": { + "type": "string" + }, + "sequence": { + "type": "integer" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "COMPLETED", + "FAILED", + "SKIPPED" + ] + }, + "attempt": { + "type": "integer" + }, + "retryCount": { + "type": "integer" + }, + "previousAttempts": { + "type": "array", + "readOnly": true, + "description": "Earlier attempts for this same logical step. The top-level step represents the latest attempt.", + "items": { + "$ref": "#/components/schemas/ActivityStep" + } + }, + "startedAt": { + "type": "string", + "format": "date-time" + }, + "completedAt": { + "type": "string", + "format": "date-time" + }, + "durationMs": { + "type": "integer" + }, + "errorCode": { + "type": "string" + }, + "errorMessage": { + "type": "string" + }, + "metadata": { + "type": "object", + "additionalProperties": true + } + } + }, + "Event": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "jobId": { + "type": "string", + "format": "uuid", + "readOnly": true + }, + "source": { + "type": "string", + "description": "Component that generated the event (e.g. \"autoscale-engine\", \"user-api\")" + }, + "eventType": { + "type": "string", + "description": "Event classification (e.g. \"SCALE_OUT_TRIGGERED\", \"JOB_ACTIVATED\")" + }, + "message": { + "type": "string" + }, + "payload": { + "type": "object", + "additionalProperties": true + }, + "eventTime": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "correlationId": { + "type": "string", + "format": "uuid", + "description": "Links event to the Execution that caused it" + } + } + }, + "EventListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Event" + } + }, + "total": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "limit": { + "type": "integer" + } + } + }, + "JobSignalRequest": { + "type": "object", + "required": [ + "signalType" + ], + "properties": { + "signalId": { + "type": "string", + "description": "Unique external signal identifier (e.g. alert ID from monitoring system)" + }, + "signalType": { + "type": "string", + "description": "Signal category (METRIC_ALERT, POLICY_EVENT, EXTERNAL_EVENT, etc.)", + "example": "METRIC_ALERT" + }, + "source": { + "type": "string", + "description": "Signal producer component (e.g. monitoring-pipeline, slack-bot, event-engine)", + "example": "monitoring-pipeline" + }, + "reason": { + "type": "string", + "description": "Human-readable explanation for the signal", + "example": "CPU utilization exceeded threshold" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Key-value pairs for signal categorization and filtering", + "example": { + "cluster": "prod-a", + "environment": "production" + } + }, + "payload": { + "type": "object", + "additionalProperties": true, + "description": "Signal-specific data structure (interpreted by workflow type handler)" + } + } + }, + "JobSignalResponse": { + "type": "object", + "properties": { + "correlationId": { + "type": "string", + "format": "uuid" + }, + "message": { + "type": "string" + }, + "accepted": { + "type": "boolean", + "default": true + }, + "executionId": { + "type": "string", + "format": "uuid", + "description": "Execution created as a result of this signal (if applicable)" + } + } + }, + "BulkDeleteJobsRequest": { + "type": "object", + "required": [ + "job_ids" + ], + "properties": { + "job_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + }, + "minItems": 1, + "maxItems": 100, + "description": "List of job IDs to delete (1\u2013100 items)" + } + } + }, + "BulkDeleteJobsResponse": { + "type": "object", + "required": [ + "results" + ], + "properties": { + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkDeleteJobResult" + }, + "description": "Per-job deletion outcome" + } + } + }, + "BulkDeleteJobResult": { + "type": "object", + "required": [ + "job_id", + "status" + ], + "properties": { + "job_id": { + "type": "string", + "format": "uuid", + "description": "ID of the job this result applies to" + }, + "status": { + "$ref": "#/components/schemas/BulkDeleteJobResultStatus" + }, + "error": { + "type": "string", + "description": "Human-readable error message (only present when status=FAILED)" + } + } + }, + "BulkDeleteJobResultStatus": { + "type": "string", + "enum": [ + "DELETED", + "FAILED" + ], + "description": "DELETED \u2014 job was successfully deleted.\nFAILED \u2014 job could not be deleted (see error for reason).\n" + }, + "StorageTarget": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "storage_type": { + "type": "string", + "enum": [ + "local", + "nfs", + "smb" + ] + }, + "server": { + "type": "string" + }, + "share_path": { + "type": "string" + }, + "mount_options": { + "type": "string" + }, + "username": { + "type": "string" + }, + "is_default": { + "type": "boolean" + }, + "status": { + "type": "string", + "description": "Health-check status of the target (active, unreachable, unknown). Local targets are always active. Populated by background connectivity checks.", + "enum": [ + "active", + "unreachable", + "unknown" + ] + }, + "last_checked_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent health check (null until first check)." + }, + "latency": { + "type": "string", + "description": "Round-trip latency measured during the last successful health check, e.g. \"45ms\"." + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "last_modified": { + "type": "string", + "format": "date-time" + } + } + }, + "CreateStorageTargetRequest": { + "type": "object", + "required": [ + "name", + "storage_type" + ], + "properties": { + "name": { + "type": "string" + }, + "storage_type": { + "type": "string", + "enum": [ + "nfs", + "smb" + ] + }, + "server": { + "type": "string" + }, + "share_path": { + "type": "string" + }, + "mount_options": { + "type": "string" + }, + "username": { + "type": "string" + }, + "password": { + "type": "string", + "description": "SMB password (stored securely in Vault, never in DB)" + } + } + }, + "TestStorageTargetRequest": { + "type": "object", + "description": "Ad-hoc connectivity test for a storage target that has not been saved.\nNo name is required because nothing is persisted.\n", + "required": [ + "storage_type" + ], + "properties": { + "storage_type": { + "type": "string", + "enum": [ + "local", + "nfs", + "smb" + ] + }, + "server": { + "type": "string" + }, + "share_path": { + "type": "string" + }, + "mount_options": { + "type": "string" + }, + "username": { + "type": "string" + }, + "password": { + "type": "string", + "description": "SMB password (used only for the test, never persisted)" + } + } + }, + "UpdateStorageTargetRequest": { + "type": "object", + "description": "Partial update of a storage target. All fields are optional. Only the\nlisted fields are accepted; any other keys are ignored server-side.\nSensitive/internal fields (id, credentials_ref, status, last_checked_at,\nlatency, created_at, last_modified) cannot be set by clients.\n", + "properties": { + "name": { + "type": "string" + }, + "storage_type": { + "type": "string", + "enum": [ + "nfs", + "smb" + ] + }, + "server": { + "type": "string" + }, + "share_path": { + "type": "string" + }, + "mount_options": { + "type": "string" + }, + "username": { + "type": "string" + }, + "password": { + "type": "string", + "description": "SMB password (stored securely in Vault, never in DB)" + }, + "is_default": { + "type": "boolean", + "description": "When true, marks this target as the default for new backups." + } + } + }, + "StorageTargetResponse": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "$ref": "#/components/schemas/StorageTarget" + } + } + }, + "StorageTargetListResponse": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StorageTarget" + } + } + } + }, + "StorageTestResponse": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + }, + "message": { + "type": "string" + }, + "latency": { + "type": "string" + } + } + } + } + }, + "ScheduledTask": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "task_type": { + "type": "string" + }, + "cron_expression": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "last_run_at": { + "type": "string", + "format": "date-time" + }, + "last_status": { + "type": "string", + "enum": [ + "success", + "failed", + "skipped" + ] + }, + "next_run_at": { + "type": "string", + "format": "date-time" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "warning": { + "type": "string", + "description": "Non-blocking proximity warning. Set when this schedule's next run falls within a fixed window of another schedule's next run; omitted otherwise." + } + } + }, + "CreateScheduleRequest": { + "type": "object", + "required": [ + "name", + "cron", + "passphrase" + ], + "properties": { + "name": { + "type": "string", + "description": "Schedule name (e.g., \"daily-config\", \"weekly-full\")" + }, + "cron": { + "type": "string", + "description": "Standard 5-field cron expression", + "example": "0 2 * * *" + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ], + "default": "full" + }, + "storage_target": { + "type": "string" + }, + "passphrase": { + "type": "string", + "minLength": 12, + "description": "Encryption passphrase (stored in Vault). Must be at least 12 characters with uppercase, lowercase, digit, and special character. Max 2 consecutive identical characters." + } + } + }, + "UpdateBackupSettingsRequest": { + "type": "object", + "properties": { + "default_storage_target": { + "type": "string", + "description": "Name of the default storage target" + }, + "retention_count": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "description": "Maximum number of backups to retain" + } + } + }, + "BackupSettingsResponse": { + "type": "object", + "required": [ + "success", + "data" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "type": "object", + "properties": { + "default_storage_target": { + "type": "string" + }, + "retention_count": { + "type": "integer" + } + } + } + } + }, + "ScheduleResponse": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "$ref": "#/components/schemas/ScheduledTask" + } + } + }, + "ScheduleListResponse": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ScheduledTask" + } + } + } + }, + "HealthResponse": { + "type": "object", + "required": [ + "success", + "data" + ], + "properties": { + "success": { + "type": "boolean", + "example": true + }, + "data": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "healthy", + "unhealthy" + ], + "example": "healthy" + }, + "platform_manager": { + "type": "string", + "enum": [ + "available", + "unavailable" + ], + "example": "available" + } + } + } + } + }, + "VersionResponse": { + "type": "object", + "required": [ + "success", + "data" + ], + "properties": { + "success": { + "type": "boolean", + "example": true + }, + "data": { + "type": "object", + "properties": { + "version": { + "type": "string", + "example": "1.2.0" + }, + "build_date": { + "type": "string", + "example": "2025-01-14" + }, + "git_commit": { + "type": "string", + "example": "abc1234" + } + } + } + } + }, + "UploadResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "201" + }, + "data": { + "type": "object", + "required": [ + "version", + "size_bytes" + ], + "properties": { + "version": { + "type": "string", + "example": "f5-insight-patch-3.20" + }, + "size_bytes": { + "type": "integer", + "format": "int64", + "description": "Size of uploaded file in bytes", + "example": 41943040 + } + } + } + } + }, + "UploadInfoResponse": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "object", + "properties": { + "available": { + "type": "boolean", + "description": "Whether a bundle is available for upgrade", + "example": true + }, + "name": { + "type": "string", + "description": "Bundle filename", + "example": "f5insight-1.1.0-11-bundle.tar.gz" + }, + "version": { + "type": "string", + "description": "Bundle version from uploaded bundle metadata or manifest", + "example": "1.1.0-11" + }, + "size": { + "type": "integer", + "format": "int64", + "description": "Bundle file size in bytes", + "example": 1073741824 + }, + "message": { + "type": "string", + "example": "Bundle ready for upgrade" + } + } + } + } + }, + "UpgradeStatusResponse": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean", + "example": true + }, + "data": { + "oneOf": [ + { + "$ref": "#/components/schemas/IdleStatus" + }, + { + "$ref": "#/components/schemas/UpgradeOperationStatus" + } + ] + } + } + }, + "IdleStatus": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "idle" + ], + "example": "idle" + }, + "message": { + "type": "string", + "example": "no action in progress" + } + } + }, + "UpgradeOperationStatus": { + "type": "object", + "required": [ + "action", + "status" + ], + "properties": { + "action": { + "type": "string", + "enum": [ + "upgrade" + ], + "example": "upgrade" + }, + "status": { + "type": "string", + "enum": [ + "in_progress", + "completed", + "failed", + "rebooting" + ], + "x-enum-varnames": [ + "UpgradeOperationStatusStatusInProgress", + "UpgradeOperationStatusStatusCompleted", + "UpgradeOperationStatusStatusFailed", + "UpgradeOperationStatusStatusRebooting" + ], + "example": "in_progress" + }, + "phase": { + "type": "string", + "description": "Current phase of the upgrade", + "enum": [ + "init", + "platform_manager", + "k3s", + "images", + "helm", + "cleanup", + "complete" + ], + "example": "helm" + }, + "message": { + "type": "string", + "example": "Deploying application updates..." + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "example": 75 + }, + "started_at": { + "type": "string", + "format": "date-time", + "example": "2025-01-14T10:30:00Z" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "example": "2025-01-14T10:35:00Z" + }, + "result": { + "type": "object", + "properties": { + "version": { + "type": "string", + "description": "New version after successful upgrade", + "example": "1.2.0" + } + } + } + } + }, + "CreateBackupRequest": { + "type": "object", + "required": [ + "passphrase" + ], + "properties": { + "name": { + "type": "string", + "description": "Optional backup name. If omitted, auto-generated as backup-YYYYMMDD-HHMMSS." + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ], + "default": "full", + "description": "Type of backup to create. Full backups require a remote storage target and are not supported on local storage; config backups may be stored locally." + }, + "passphrase": { + "type": "string", + "minLength": 12, + "description": "Encryption passphrase. Must be at least 12 characters with uppercase, lowercase, digit, and special character. Max 2 consecutive identical characters." + }, + "storage_target": { + "type": "string", + "description": "Name of the storage target to associate with this backup. Required for full backups (must be a remote target). If omitted, a config backup is stored locally." + } + } + }, + "ImportBackupRequest": { + "type": "object", + "required": [ + "file_path" + ], + "properties": { + "storage_target": { + "type": "string", + "description": "Name of the storage target where the file resides. If omitted, looks in local backup directory." + }, + "file_path": { + "type": "string", + "description": "Filename on the remote share, or filename in local backup directory." + } + } + }, + "BackupJob": { + "type": "object", + "required": [ + "id", + "operation", + "backup_type", + "status" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string", + "description": "User-given or auto-generated backup name" + }, + "operation": { + "type": "string", + "enum": [ + "backup", + "restore" + ] + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ] + }, + "status": { + "type": "string", + "enum": [ + "pending", + "running", + "completed", + "failed", + "uploaded", + "imported" + ] + }, + "phase": { + "type": "string", + "description": "Current phase of the operation" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Progress percentage" + }, + "message": { + "type": "string", + "description": "Human-readable status message" + }, + "file_name": { + "type": "string" + }, + "file_size": { + "type": "integer", + "format": "int64" + }, + "storage_target_id": { + "type": "string", + "format": "uuid", + "description": "ID of the storage target where the backup is stored (null for local)" + }, + "storage_target_name": { + "type": "string", + "description": "Name of the storage target where the backup is stored" + }, + "encrypted": { + "type": "boolean" + }, + "error_message": { + "type": "string" + }, + "started_at": { + "type": "string", + "format": "date-time" + }, + "completed_at": { + "type": "string", + "format": "date-time" + }, + "created_at": { + "type": "string", + "format": "date-time" + } + } + }, + "BackupJobResponse": { + "type": "object", + "required": [ + "success", + "data" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "$ref": "#/components/schemas/BackupJob" + } + } + }, + "BackupListResponse": { + "type": "object", + "required": [ + "success", + "data" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BackupJob" + } + } + } + }, + "BackupSizeAnalysis": { + "type": "object", + "required": [ + "is_anomalous", + "recent_size_bytes", + "rolling_avg_bytes", + "pct_of_avg", + "sample_size" + ], + "properties": { + "is_anomalous": { + "type": "boolean", + "description": "True when the latest backup is more than 30% smaller than the rolling average.", + "example": false + }, + "recent_size_bytes": { + "type": "integer", + "format": "int64", + "description": "Size of the most recent completed backup.", + "example": 104857600 + }, + "rolling_avg_bytes": { + "type": "integer", + "format": "int64", + "description": "Average size of up to 3 completed backups before the most recent one.", + "example": 99614720 + }, + "pct_of_avg": { + "type": "integer", + "description": "Latest backup size as a percentage of rolling_avg_bytes.", + "example": 105 + }, + "sample_size": { + "type": "integer", + "description": "Number of previous backups used to calculate rolling_avg_bytes.", + "example": 3 + } + } + }, + "BackupSizeAnalysisResponse": { + "type": "object", + "required": [ + "success", + "data" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "$ref": "#/components/schemas/BackupSizeAnalysis" + } + } + }, + "SuccessResponse": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "APIErrorResponse": { + "type": "object", + "required": [ + "success", + "error" + ], + "properties": { + "success": { + "type": "boolean", + "example": false + }, + "error": { + "$ref": "#/components/schemas/APIError" + } + } + }, + "APIError": { + "type": "object", + "required": [ + "code", + "status", + "message" + ], + "properties": { + "code": { + "type": "string", + "description": "Error code (SYSTEM-XXXX format)", + "example": "SYSTEM-0002" + }, + "status": { + "type": "integer", + "description": "HTTP status code", + "example": 409 + }, + "message": { + "type": "string", + "description": "Human-readable error message", + "example": "An upgrade is already in progress" + }, + "help": { + "type": "string", + "description": "Guidance for resolving the error", + "example": "Wait for the current upgrade to complete or check status at /api/system/upgrade/status" + } + } + }, + "UpgradeCatalogResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "object", + "required": [ + "latest_patch", + "latest_full_upgrade", + "patches", + "full_upgrades" + ], + "properties": { + "latest_patch": { + "type": "string", + "description": "Latest available patch version", + "example": "f5insight-1.1.2-62" + }, + "latest_full_upgrade": { + "type": "string", + "description": "Latest available full upgrade version", + "example": "f5insight-1.2.0-1" + }, + "patches": { + "type": "array", + "description": "Latest available patch entry, or empty when none exists", + "items": { + "$ref": "#/components/schemas/UpgradeEntry" + } + }, + "full_upgrades": { + "type": "array", + "description": "Latest available full upgrade entry, or empty when none exists", + "items": { + "$ref": "#/components/schemas/UpgradeEntry" + } + } + } + } + } + }, + "F5DownloadsCredentialsRequest": { + "type": "object", + "required": [ + "client_id", + "client_secret" + ], + "properties": { + "client_id": { + "type": "string", + "description": "MyF5 OAuth client id." + }, + "client_secret": { + "type": "string", + "format": "password", + "description": "MyF5 OAuth client secret. Stored in Vault and never returned by APIs." + } + } + }, + "F5DownloadsCredentialsUpdateRequest": { + "type": "object", + "minProperties": 1, + "properties": { + "client_id": { + "type": "string", + "description": "Replacement MyF5 OAuth client id." + }, + "client_secret": { + "type": "string", + "format": "password", + "description": "Replacement MyF5 OAuth client secret. When omitted, the existing Vault secret is kept." + } + } + }, + "F5DownloadsCredentialStatus": { + "type": "object", + "required": [ + "configured", + "client_secret_configured" + ], + "properties": { + "configured": { + "type": "boolean", + "description": "True when F5 Downloads credentials have been saved through the credentials API." + }, + "client_id": { + "type": "string", + "description": "Configured client id. The client secret is never returned." + }, + "client_secret_configured": { + "type": "boolean", + "description": "True when a client secret is configured in Vault." + } + } + }, + "F5DownloadsCredentialsStatusResponse": { + "type": "object", + "required": [ + "success", + "data" + ], + "properties": { + "success": { + "type": "boolean" + }, + "data": { + "$ref": "#/components/schemas/F5DownloadsCredentialStatus" + } + } + }, + "CurrentVersionResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "object", + "required": [ + "version" + ], + "properties": { + "version": { + "type": "string", + "example": "f5-insight-patch-3.19" + } + } + } + } + }, + "UpgradeEntry": { + "type": "object", + "required": [ + "version", + "kind" + ], + "properties": { + "version": { + "type": "string", + "description": "Version string (e.g., f5-insight-patch-1.2.1)", + "example": "f5-insight-patch-1.2.1" + }, + "base_version": { + "type": "string", + "description": "Minimum required version for this patch", + "example": "f5-insight-1.2.0" + }, + "minimum_supported_version": { + "type": "string", + "description": "Minimum installed version required by this bundle manifest", + "example": "1.1.0" + }, + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade", + "release" + ], + "description": "Bundle type", + "example": "patch" + }, + "is_latest": { + "type": "boolean", + "description": "Whether this entry matches the latest version for its upgrade type", + "example": true + }, + "built_at": { + "type": "string", + "format": "date-time", + "description": "Build timestamp", + "example": "2026-05-15T10:30:00Z" + }, + "release_date": { + "type": "string", + "format": "date", + "description": "Release date for this catalog entry", + "example": "2026-05-15" + }, + "services": { + "type": "array", + "description": "Services included in this bundle", + "items": { + "type": "string" + }, + "example": [ + "backend", + "frontend", + "auth-service" + ] + }, + "filename": { + "type": "string", + "description": "Bundle filename", + "example": "f5insight-patch-1.2.1.tar.gz" + }, + "size_bytes": { + "type": "integer", + "format": "int64", + "description": "Bundle size in bytes", + "example": 41943040 + }, + "sha256": { + "type": "string", + "description": "SHA256 checksum", + "example": "abc123def456..." + }, + "cosign_signature": { + "type": "string", + "description": "Cosign signature for the bundle", + "example": "MEUCIQD..." + }, + "download_url": { + "type": "string", + "description": "Download URL used by system-manager for online F5 Downloads entries. Empty for offline bundles.", + "example": "" + }, + "security_fix": { + "type": "boolean", + "description": "Whether this bundle contains security fixes", + "example": true + }, + "severity": { + "type": "string", + "enum": [ + "critical", + "high", + "medium", + "low", + "" + ], + "description": "Security severity level", + "example": "high" + }, + "mrs": { + "type": "array", + "description": "Merge requests included in this bundle", + "items": { + "$ref": "#/components/schemas/MergeRequest" + } + }, + "cumulative_mrs": { + "type": "array", + "description": "All MRs since base_version (for patches)", + "items": { + "$ref": "#/components/schemas/MergeRequest" + } + } + } + }, + "MergeRequest": { + "type": "object", + "required": [ + "id", + "title" + ], + "properties": { + "id": { + "type": "string", + "description": "MR identifier (e.g., !847)", + "example": "!847" + }, + "title": { + "type": "string", + "description": "MR title", + "example": "Fix authentication timeout issue" + } + } + }, + "PreflightResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "object", + "required": [ + "can_proceed", + "checks" + ], + "properties": { + "can_proceed": { + "type": "boolean", + "description": "True only when all checks pass", + "example": true + }, + "checks": { + "type": "array", + "description": "Individual pre-upgrade health check results", + "items": { + "$ref": "#/components/schemas/PreflightCheck" + } + } + } + } + } + }, + "PreflightCheck": { + "type": "object", + "required": [ + "name", + "status", + "message", + "bypass_allowed" + ], + "properties": { + "name": { + "type": "string", + "example": "no_active_job" + }, + "status": { + "type": "string", + "enum": [ + "pass", + "fail" + ], + "example": "pass" + }, + "message": { + "type": "string", + "example": "No active patch job running" + }, + "bypass_allowed": { + "type": "boolean", + "description": "True when a failed check can be bypassed by an explicit user override. Always false for no_active_job, disk_space, and version_compatibility.", + "example": false + } + } + }, + "ApplyUpgradeRequest": { + "type": "object", + "required": [ + "version", + "kind" + ], + "properties": { + "version": { + "type": "string", + "description": "Target version to upgrade to", + "example": "3.2.1" + }, + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "description": "Upgrade kind to apply", + "example": "patch" + }, + "skip_backup": { + "type": "boolean", + "default": false, + "example": false + }, + "backup_passphrase": { + "type": "string", + "format": "password", + "description": "Required when skip_backup is false. Used only to create the pre-upgrade backup and never persisted in plaintext.", + "example": "MyStr0ng!Pass" + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ], + "description": "Required when skip_backup is false. Determines whether the pre-upgrade backup captures all components or config-only.", + "example": "full" + }, + "storage_target": { + "type": "string", + "description": "Required when skip_backup is false. Use \"local\" for local appliance storage or a configured storage target name.", + "example": "local" + }, + "bypass_preflight_checks": { + "type": "boolean", + "default": false, + "description": "Explicit user override for failed preflight checks that have bypass_allowed=true. no_active_job, disk_space, and version_compatibility failures always block apply.", + "example": false + } + } + }, + "ApplyAcceptedResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "202" + }, + "data": { + "type": "object", + "required": [ + "id", + "status" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "example": "d4e5f6a7-b8c9-4000-8000-000000000001" + }, + "status": { + "type": "string", + "enum": [ + "pending", + "running", + "done", + "failed" + ], + "example": "pending" + } + } + } + } + }, + "ScheduleUpgradeRequest": { + "type": "object", + "required": [ + "kind", + "version", + "scheduled_at" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "example": "patch" + }, + "version": { + "type": "string", + "example": "f5-insight-patch-3.20" + }, + "scheduled_at": { + "type": "string", + "format": "date-time", + "description": "Future UTC timestamp when the upgrade should run", + "example": "2026-05-12T02:00:00Z" + }, + "skip_backup": { + "type": "boolean", + "default": false, + "example": false + }, + "backup_passphrase": { + "type": "string", + "format": "password", + "description": "Required when skip_backup is false. Stored securely and used when the scheduled upgrade creates its pre-upgrade backup.", + "example": "MyStr0ng!Pass" + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ], + "description": "Required when skip_backup is false. Determines whether the scheduled pre-upgrade backup captures all components or config-only.", + "example": "full" + }, + "storage_target": { + "type": "string", + "description": "Required when skip_backup is false. Use \"local\" for local appliance storage or a configured storage target name.", + "example": "local" + }, + "bypass_preflight_checks": { + "type": "boolean", + "default": false, + "description": "Explicit user override for failed preflight checks that have bypass_allowed=true. no_active_job, disk_space, and version_compatibility failures always block scheduled apply." + } + } + }, + "ScheduledUpgradeEntry": { + "type": "object", + "required": [ + "id", + "version", + "scheduled_at", + "skip_backup", + "status" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "example": "770e8400-e29b-41d4-a716-446655440010" + }, + "version": { + "type": "string", + "example": "f5-insight-patch-3.20" + }, + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "example": "patch" + }, + "scheduled_at": { + "type": "string", + "format": "date-time", + "example": "2026-05-12T02:00:00Z" + }, + "skip_backup": { + "type": "boolean", + "example": false + }, + "status": { + "type": "string", + "enum": [ + "pending", + "triggered", + "done", + "failed", + "cancelled" + ], + "example": "pending" + }, + "upgrade_job_id": { + "type": "string", + "format": "uuid", + "description": "Created upgrade_history job ID after the schedule fires" + } + } + }, + "ScheduledUpgradeListResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ScheduledUpgradeEntry" + } + } + } + }, + "ScheduledUpgradeCreatedResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "201" + }, + "data": { + "type": "object", + "required": [ + "id", + "status", + "scheduled_at" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "example": "770e8400-e29b-41d4-a716-446655440010" + }, + "status": { + "type": "string", + "example": "pending" + }, + "scheduled_at": { + "type": "string", + "format": "date-time", + "example": "2026-05-12T02:00:00Z" + } + } + } + } + }, + "JobStatusResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "$ref": "#/components/schemas/JobStatusData" + } + } + }, + "JobStatusData": { + "type": "object", + "required": [ + "id", + "version", + "kind", + "status", + "progress", + "rollback_available" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Upgrade history record ID", + "example": "d4e5f6a7-0000-4000-8000-000000000001" + }, + "version": { + "type": "string", + "description": "Target version", + "example": "3.2.1" + }, + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "description": "Upgrade kind", + "example": "patch" + }, + "status": { + "type": "string", + "enum": [ + "pending", + "running", + "done", + "failed" + ], + "description": "Current upgrade status", + "example": "done" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Upgrade progress percentage", + "example": 100 + }, + "rollback_available": { + "type": "boolean", + "description": "True when this patch job can currently be rolled back manually. Manual rollback is available only for the latest successful patch completed within the last 72 hours; failed patch jobs use automatic rollback.", + "example": true + }, + "current_step": { + "type": "string", + "description": "Current upgrade step", + "example": "deployments_ready" + }, + "started_at": { + "type": "string", + "format": "date-time" + }, + "started_by": { + "type": "string", + "example": "admin@f5.com" + }, + "finished_at": { + "type": "string", + "format": "date-time" + }, + "platform_job_id": { + "type": "string", + "format": "uuid" + }, + "download": { + "$ref": "#/components/schemas/DownloadProgress" + }, + "error_message": { + "type": "string" + }, + "log": { + "type": "array", + "items": { + "$ref": "#/components/schemas/JobLogEntry" + } + } + } + }, + "DownloadProgress": { + "type": "object", + "required": [ + "bytes", + "total", + "pct", + "speed_bps", + "eta_sec" + ], + "properties": { + "bytes": { + "type": "integer", + "format": "int64", + "example": 26214400 + }, + "total": { + "type": "integer", + "format": "int64", + "example": 41943040 + }, + "pct": { + "type": "integer", + "example": 62 + }, + "speed_bps": { + "type": "integer", + "format": "int64", + "example": 5242880 + }, + "eta_sec": { + "type": "integer", + "example": 3 + } + } + }, + "JobLogEntry": { + "type": "object", + "required": [ + "ts", + "level", + "message" + ], + "properties": { + "ts": { + "type": "string", + "format": "date-time" + }, + "level": { + "type": "string", + "enum": [ + "info", + "success", + "warn", + "error" + ], + "example": "info" + }, + "message": { + "type": "string", + "example": "Starting patch job for f5-insight-patch-3.20" + } + } + }, + "ActiveJobResponse": { + "type": "object", + "required": [ + "status", + "dirty_state", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "dirty_state": { + "type": "boolean", + "example": false + }, + "data": { + "nullable": true, + "type": "object", + "required": [ + "id", + "status", + "progress" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "enum": [ + "pending", + "running", + "done", + "failed" + ] + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100 + } + } + } + } + }, + "PostflightResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "object", + "required": [ + "checks" + ], + "properties": { + "checks": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PostflightCheck" + } + } + } + } + } + }, + "RollbackAcceptedResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "202" + }, + "data": { + "type": "object", + "required": [ + "rollback_id" + ], + "properties": { + "rollback_id": { + "type": "string", + "format": "uuid", + "example": "770e8400-e29b-41d4-a716-446655440007" + } + } + } + } + }, + "RollbackStateResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "object", + "required": [ + "available", + "prev_images" + ], + "properties": { + "available": { + "type": "boolean", + "example": true + }, + "prev_images": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "example": { + "backend": "f5-insight-patch/backend:3.19", + "system-manager": "f5-insight-patch/system-manager:3.19", + "frontend": "f5-insight-patch/frontend:3.19" + } + } + } + } + } + }, + "RollbackStatusResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "object", + "required": [ + "id", + "status", + "progress", + "log" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "example": "770e8400-e29b-41d4-a716-446655440007" + }, + "status": { + "type": "string", + "enum": [ + "pending", + "running", + "done", + "failed" + ], + "example": "done" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "example": 100 + }, + "log": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RollbackLogEntry" + } + } + } + } + } + }, + "RollbackLogEntry": { + "type": "object", + "required": [ + "ts", + "level", + "message" + ], + "properties": { + "ts": { + "type": "string", + "format": "date-time", + "example": "2026-05-11T14:30:00Z" + }, + "level": { + "type": "string", + "enum": [ + "info", + "success", + "warn", + "error" + ], + "example": "success" + }, + "message": { + "type": "string", + "example": "Rolled back backend to f5-insight-patch/backend:3.19" + } + } + }, + "RollbackJobStatus": { + "type": "object", + "required": [ + "status", + "progress", + "log" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "idle", + "running", + "done", + "failed", + "admin_confirmed" + ], + "example": "idle" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "example": 0 + }, + "log": { + "type": "array", + "items": { + "type": "string" + }, + "example": [] + } + } + }, + "PostflightCheck": { + "type": "object", + "required": [ + "name", + "status", + "message" + ], + "properties": { + "name": { + "type": "string", + "example": "deployments_ready" + }, + "status": { + "type": "string", + "enum": [ + "pass", + "fail" + ], + "example": "pass" + }, + "message": { + "type": "string", + "example": "All deployments are Ready" + } + } + }, + "UpgradeHistoryResponse": { + "type": "object", + "required": [ + "status", + "dirty_state", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "dirty_state": { + "type": "boolean", + "example": false + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UpgradeHistoryEntry" + } + } + } + }, + "UpgradeHistoryEntry": { + "type": "object", + "required": [ + "job_id", + "version", + "kind", + "status", + "started_by", + "started_at", + "services", + "security_fix", + "rollback_available" + ], + "properties": { + "job_id": { + "type": "string", + "format": "uuid", + "example": "d4e5f6a7-b8c9-4000-8000-000000000001" + }, + "version": { + "type": "string", + "example": "f5-insight-patch-3.19" + }, + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "example": "patch" + }, + "status": { + "type": "string", + "enum": [ + "pending", + "running", + "done", + "failed" + ], + "example": "done" + }, + "started_by": { + "type": "string", + "example": "admin@f5.com" + }, + "started_at": { + "type": "string", + "format": "date-time" + }, + "finished_at": { + "type": "string", + "format": "date-time" + }, + "services": { + "type": "array", + "items": { + "type": "string" + } + }, + "security_fix": { + "type": "boolean", + "example": false + }, + "rollback_available": { + "type": "boolean", + "description": "True when this patch job can currently be rolled back manually. Manual rollback is available only for the latest successful patch completed within the last 72 hours; failed patch jobs use automatic rollback.", + "example": true + } + } + }, + "UpgradeHistoryStatsResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "object", + "required": [ + "total_applied", + "total_failed", + "total_rollbacks", + "avg_duration_sec", + "security_patches" + ], + "properties": { + "total_applied": { + "type": "integer", + "example": 19 + }, + "total_failed": { + "type": "integer", + "example": 2 + }, + "total_rollbacks": { + "type": "integer", + "example": 2 + }, + "avg_duration_sec": { + "type": "integer", + "example": 514 + }, + "security_patches": { + "type": "integer", + "example": 3 + } + } + } + } + }, + "ScheduleRecommendationResponse": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "status": { + "type": "string", + "example": "200" + }, + "data": { + "type": "object", + "required": [ + "has_data", + "message" + ], + "properties": { + "has_data": { + "type": "boolean", + "example": true + }, + "best_dow": { + "type": "string", + "example": "Sunday" + }, + "best_hour": { + "type": "integer", + "minimum": 0, + "maximum": 23, + "example": 2 + }, + "best_hour_end": { + "type": "integer", + "minimum": 0, + "maximum": 24, + "example": 4 + }, + "window_label": { + "type": "string", + "example": "Sunday 02:00-04:00 UTC" + }, + "avg_duration_sec": { + "type": "integer", + "example": 487 + }, + "sample_size": { + "type": "integer", + "example": 7 + }, + "message": { + "type": "string", + "example": "Lowest failure rate (0%) across 7 historical patches." + } + } + } + } + }, + "ActiveModeSwitchTaskResponse": { + "type": "object", + "required": [ + "task_id", + "state", + "status", + "progress" + ], + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier of the active mode switch task", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "state": { + "type": "string", + "description": "Current FSM state", + "example": "HELM_UPGRADE" + }, + "status": { + "type": "string", + "description": "Task execution status", + "example": "running" + }, + "progress": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Progress percentage (0-100)", + "example": 50 + }, + "error_message": { + "type": "string", + "nullable": true, + "description": "Error message if task failed", + "example": "Helm upgrade failed" + } + } + } + }, + "responses": { + "UnauthorizedError": { + "description": "Unauthorized - authentication required or token invalid", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "example": { + "status": 401, + "message": "Unauthorized" + } + } + } + }, + "InternalError": { + "description": "An unexpected error occurred.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "BadRequest": { + "description": "Invalid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "NotFound": { + "description": "Resource not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "Unauthorized": { + "description": "Authentication required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "Conflict": { + "description": "Conflict with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + }, + "parameters": { + "PageParam": { + "name": "page", + "in": "query", + "schema": { + "type": "integer", + "minimum": 1, + "default": 1 + } + }, + "SizeParam": { + "name": "size", + "in": "query", + "required": false, + "description": "Number of items per page.", + "schema": { + "type": "integer", + "minimum": 1 + } + }, + "SinceParam": { + "name": "since", + "in": "query", + "required": false, + "description": "Return only devices updated after this timestamp (ISO 8601 format).\nUse the lastSync value from previous response for delta updates.\n", + "schema": { + "type": "string", + "format": "date-time" + } + }, + "SearchParam": { + "name": "search", + "in": "query", + "description": "Search term to filter devices by name, alias, or endpoint", + "required": false, + "schema": { + "type": "string" + } + }, + "SortParam": { + "name": "sort", + "in": "query", + "description": "Sort order, e.g. 'name,-created_at' (prefix '-' for descending)", + "required": false, + "schema": { + "type": "string" + } + }, + "ProviderId": { + "name": "providerId", + "in": "path", + "description": "UUID of the cloud provider", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "DeviceTemplateIdParam": { + "name": "id", + "in": "path", + "required": true, + "description": "UUID of the device template.", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "TaskIdParam": { + "name": "taskId", + "in": "path", + "required": true, + "description": "UUID of the task.", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "660e8400-e29b-41d4-a716-446655440001" + }, + "ODataFilterParam": { + "name": "$filter", + "in": "query", + "required": false, + "description": "OData filter expression. Supported fields: `name`, `provider`, `state`, `locked`.\nExamples: `state eq 'DEPLOYED'`, `name eq 'BIG-IP Standard Template'`\n", + "schema": { + "type": "string" + }, + "example": "state eq 'DEPLOYED'" + }, + "ODataOrderByParam": { + "name": "$orderby", + "in": "query", + "required": false, + "description": "OData ordering expression. Supported fields: `name`, `provider`, `state`, `createdAt`, `updatedAt`.\nExamples: `name asc`, `createdAt desc`\n", + "schema": { + "type": "string" + }, + "example": "name asc" + }, + "ODataTopParam": { + "name": "$top", + "in": "query", + "required": false, + "description": "Maximum number of items to return (page size). Default 20, max 100.", + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 20 + }, + "example": 10 + }, + "ODataSkipParam": { + "name": "$skip", + "in": "query", + "required": false, + "description": "Number of items to skip for pagination. Default 0.", + "schema": { + "type": "integer", + "minimum": 0, + "default": 0 + }, + "example": 0 + }, + "ODataSelectParam": { + "name": "$select", + "in": "query", + "required": false, + "description": "Comma-separated list of fields to include in the response.\nExample: `id,name,state,definition`\n", + "schema": { + "type": "string" + }, + "example": "id,name,state" + }, + "ODataCountParam": { + "name": "$count", + "in": "query", + "required": false, + "description": "When `true`, includes `totalItems` in the response with the total count of matching records.", + "schema": { + "type": "boolean", + "default": false + }, + "example": true + }, + "PoolId": { + "name": "poolId", + "in": "path", + "description": "UUID of the IP pool.", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "PageSizeParam": { + "name": "page_size", + "in": "query", + "schema": { + "type": "integer", + "default": 20, + "minimum": 1, + "maximum": 500 + } + }, + "ImageIdParam": { + "name": "imageId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "DeviceIdParam": { + "name": "deviceId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "JobIdParam": { + "name": "jobId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "SnapshotIdParam": { + "name": "snapshotId", + "in": "path", + "required": true, + "description": "Unique ID of a flight-check snapshot.", + "schema": { + "type": "string", + "format": "uuid" + } + }, + "DiffIdParam": { + "name": "diffId", + "in": "path", + "required": true, + "description": "Unique ID of a flight-check diff.", + "schema": { + "type": "string", + "format": "uuid" + } + }, + "CompatIdParam": { + "name": "compatId", + "in": "path", + "required": true, + "description": "Unique ID of a compatibility matrix row.", + "schema": { + "type": "string", + "format": "uuid" + } + }, + "WorkflowId": { + "name": "workflowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "JobId": { + "name": "jobId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "DeviceId": { + "name": "deviceId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "ExecutionId": { + "name": "executionId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "ActivityId": { + "name": "activityId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + "LimitParam": { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + } + } + }, + "examples": {}, + "requestBodies": {}, + "headers": {}, + "securitySchemes": { + "BearerAuth": { + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT", + "description": "JWT ACCESS TOKEN for authenticated requests.\n\nIMPORTANT:\n- Use ACCESS TOKEN (short-lived, 5 min) in Authorization header: \"Bearer \"\n- Use REFRESH TOKEN (long-lived, 10 hrs) ONLY in request body for /auth/refresh endpoint\n- DO NOT use refresh token in Authorization header - it will fail!\n\nExample:\n Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\n" + }, + "bearerAuth": { + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT", + "description": "JWT token-based authentication" + }, + "basicAuth": { + "type": "http", + "scheme": "basic", + "description": "Basic authentication" + } + }, + "links": {}, + "callbacks": {} + }, + "security": [ + { + "bearerAuth": [] + }, + { + "basicAuth": [] + } + ] +} \ No newline at end of file diff --git a/F5/Insight/README.md b/F5/Insight/README.md new file mode 100644 index 0000000..22b4b91 --- /dev/null +++ b/F5/Insight/README.md @@ -0,0 +1,132 @@ +F5 Insight is F5's monitoring and analytics platform for device fleet management, providing unified visibility, software lifecycle management, and centralized configuration across F5 infrastructure. + +This project provides OpenAPI specs for automating against F5 Insight's REST API via an Integration Model, plus a Studio Project of ready-to-import CRUD workflows built on that model. + +## Table of Contents + +- [Contents](#contents) +- [Requirements](#requirements) +- [Integration Configuration](#integration-configuration) +- [OpenAPIs](#openapis) + - [`f5_insight-latest.json`](#f5_insight-latestjson) + - [`f5_insight-v1.2.2.json`](#f5_insight-v122json) +- [Studio Projects](#studio-projects) + - [F5 Insight Project](#f5-insight-project) + - [Folder Structure](#folder-structure) + - [Dependencies](#dependencies) + +## Contents + +| Asset | Description | +|---|---| +| [OpenAPIs/](./OpenAPIs/) | F5 Insight API OpenAPI specs — curated `-latest` plus the full vendor spec | +| [Studio Projects/](./Studio%20Projects/) | Itential Platform project containing all 227 workflows in 27 folders | + +## Requirements + +| Requirement | Version | +|---|---| +| Itential Platform | 6.x | +| `F5 Insight:latest` Integration Model | Required to build automation against the OpenAPI spec, and to run the Studio Project below | + +## Integration Configuration + +Import `f5_insight-latest.json` as an Integration Model in **Admin > Integrations**, then create an integration pointing at your F5 Insight instance. + +Authentication is HTTP Basic Auth, supported on every operation in this spec. + +The instance's `authentication`/`server` properties should look like this once configured: + +```json +{ + "authentication": { + "basicAuth": { + "username": "", + "password": "" + } + }, + "server": { + "protocol": "https", + "host": "", + "base_path": "" + } +} +``` + +Note the empty `base_path` — every operation's path already includes the full `/api/...` prefix literally, so a non-empty base path (e.g. `/api`) would double it up. + +## OpenAPIs + +| Spec | Version | Operations | Description | +|---|---|---|---| +| [`f5_insight-latest.json`](./OpenAPIs/f5_insight-latest.json) | latest (curated) | 227 | Curated to device management, software/upgrade lifecycle, and monitoring — see breakdown below | +| [`f5_insight-v1.2.2.json`](./OpenAPIs/f5_insight-v1.2.2.json) | v1.2.2 | 281 | Full spec for the F5 Insight API | + +### `f5_insight-latest.json` + +Built from F5's own published OpenAPI spec (embedded in their [API documentation site](https://clouddocs.f5.com/products/insight/latest/apis/api.html), extracted from the page's Redoc bundle), curated to the core fleet-management categories. + +Resources included, by category: + +- **Device Management**: devices, data centers, trust stores, device migration/import tasks +- **Device Templates**: template CRUD, attach/deploy/clone/lock +- **Inventory**, **Infrastructure Discovery**: fleet and discovered-resource inventory +- **Cloud Environments** / **Cloud Providers**: connection and environment configuration (vSphere, etc.) +- **Software Distribution** / **Software Installation** / **Upgrade**: job lifecycle, scheduling, compatibility and flight checks +- **Backup**, **Storage**: backup/restore, storage target configuration +- **Licensing**: license pools, offerings, members +- **Jobs**, **Observability**, **Health and Readiness**, **Audit Console**, **Telemetry Configuration**, **Validation**, **Workflows**, **Tasks**, **VM Tasks**, **Images**, **Schedule**, **Configuration**, **FQDN Configuration**, **Lifecycle**, **Compatibility Matrix** + +Excluded: authentication/authorization/identity-provider administration (one-time setup, not routine automation), AI-assistant chat history and insights, feature flags, and other internal admin tooling, plus 5 operations requiring multipart file uploads (image/backup/upgrade-bundle uploads, device migration bundles) — outside this repo's REST/JSON automation scope. Also excluded: OData-style query parameters (`$select`, `$filter`, `$orderby`, `$top`, `$skip`, `$count`) on 2 list operations — both work fine without them (unfiltered list results). + +A handful of workflow names (e.g. generic device/job/workflow CRUD) are prefixed with `F5 Insight` to avoid colliding with identically-named workflows already published for other products — workflow names are unique across the whole Itential Platform instance, not scoped per-project. + +### `f5_insight-v1.2.2.json` + +Full, unmodified vendor spec for the F5 Insight API, version 1.2.2. See `f5_insight-latest.json` above for the curated subset if you just need common fleet-management automation. + +## Studio Projects + +### F5 Insight Project + +Backed by the **`F5 Insight:latest`** Integration Model (see [`f5_insight-latest.json`](./OpenAPIs/f5_insight-latest.json) above). The project contains **227 workflows** organized into **27 folders**. + +#### Folder Structure + +| Folder | Workflows | Scope | +|---|---|---| +| Device Management | 42 | Devices, data centers, trust stores, migration/import tasks | +| Upgrade | 23 | Upgrade scheduling, jobs, rollback, compatibility | +| Licensing | 21 | License pools, offerings, members | +| Software Distribution | 13 | Distribution job lifecycle | +| Device Templates | 12 | Template CRUD, attach/deploy/clone/lock | +| Software Installation | 11 | Installation job lifecycle | +| Storage | 9 | Storage target configuration | +| Backup | 8 | Backup/restore, schedules | +| Infrastructure Discovery | 7 | Discovered resource inventory | +| Observability | 7 | Monitoring data | +| Jobs | 7 | Generic job tracking | +| Configuration | 6 | System configuration | +| Inventory | 6 | Fleet inventory | +| Cloud Environments | 5 | Environment configuration | +| Cloud Providers | 5 | Provider connections (vSphere, etc.) | +| Schedule | 5 | Backup/upgrade scheduling | +| Health and Readiness | 5 | Health checks, readiness runs | +| VM Tasks | 4 | VM provisioning tasks | +| Compatibility Matrix | 4 | Upgrade path compatibility | +| Flight Checks | 4 | Pre/post-flight validation | +| Images | 4 | Image management | +| Validation | 4 | Device/template validation | +| Audit Console | 3 | Audit event querying | +| Lifecycle | 3 | Continuous lifecycle operations | +| Telemetry Configuration | 3 | Telemetry type configuration | +| Tasks | 2 | Generic task tracking | +| Workflows | 2 | Workflow/execution tracking | +| FQDN Configuration | 2 | FQDN-based external auth configuration | + +#### Dependencies + +| Dependency | Notes | +|---|---| +| `F5 Insight:latest` Integration Model | Import from [`f5_insight-latest.json`](./OpenAPIs/f5_insight-latest.json) before importing the project | +| `F5 Insight` integration instance | Create in **Admin > Integrations** with the connection properties above. Workflows are wired to an integration instance named `F5 Insight` — update the `adapter_id` value in each workflow task if yours is named differently | diff --git a/F5/Insight/Studio Projects/F5 Insight.project.json b/F5/Insight/Studio Projects/F5 Insight.project.json new file mode 100644 index 0000000..42e2449 --- /dev/null +++ b/F5/Insight/Studio Projects/F5 Insight.project.json @@ -0,0 +1,40897 @@ +{ + "_id": "6a91a58d8a376fbbe14b8eb2", + "name": "F5 Insight", + "description": "F5 Insight monitoring and analytics platform automation workflows", + "components": [ + { + "iid": 0, + "reference": "416a5ce9-102b-4bdf-8136-0559ca38122f", + "type": "workflow", + "folder": "/Configuration", + "document": { + "name": "Delete AI Provider Config", + "description": "Delete AI Provider Config", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteAIProviderConfig", + "canvasName": "deleteAIProviderConfig", + "summary": "deleteAIProviderConfig", + "description": "deleteAIProviderConfig", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "87d30d04-6634-4bdf-8e22-14a125cd4582", + "created": "2026-08-28T15:12:55.661Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 1, + "reference": "951c90ad-b1fd-4863-ade5-e8187ce1b0e0", + "type": "workflow", + "folder": "/Configuration", + "document": { + "name": "Delete AIDF Config", + "description": "Delete AIDF Config", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteAIDFConfig", + "canvasName": "deleteAIDFConfig", + "summary": "deleteAIDFConfig", + "description": "deleteAIDFConfig", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "92df4436-d222-42b3-8c4a-8d1401973dd8", + "created": "2026-08-28T15:12:55.553Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 2, + "reference": "378abfe9-8804-40a8-ac7e-fe86118b641c", + "type": "workflow", + "folder": "/Configuration", + "document": { + "name": "Get Current AI Provider", + "description": "Get Current AI Provider", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getCurrentAIProvider", + "canvasName": "getCurrentAIProvider", + "summary": "getCurrentAIProvider", + "description": "getCurrentAIProvider", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "6f7e6a9f-6117-4cae-afde-bf513def0f08", + "created": "2026-08-28T15:12:55.594Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 3, + "reference": "863277f8-fc52-4334-acfc-8f1326fd7335", + "type": "workflow", + "folder": "/Configuration", + "document": { + "name": "Get Current AIDF Config", + "description": "Get Current AIDF Config", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getCurrentAIDFConfig", + "canvasName": "getCurrentAIDFConfig", + "summary": "getCurrentAIDFConfig", + "description": "getCurrentAIDFConfig", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "ae1fb694-896c-4743-b207-dc88e01631f2", + "created": "2026-08-28T15:12:55.462Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 4, + "reference": "4f516c90-e210-41f9-9e41-e8129741a1db", + "type": "workflow", + "folder": "/Configuration", + "document": { + "name": "Save AI Provider Config", + "description": "Save AI Provider Config", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "saveAIProviderConfig", + "canvasName": "saveAIProviderConfig", + "summary": "saveAIProviderConfig", + "description": "saveAIProviderConfig", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "provider_name" + ], + "properties": { + "provider_name": { + "type": "string", + "description": "AI provider name (e.g., openai, anthropic, local)" + }, + "api_token": { + "type": "string", + "description": "API token for the provider. Required for 'openai' and 'claude' providers, optional for 'local' provider." + }, + "base_url": { + "type": "string", + "description": "Base URL for the provider. Required for 'local' provider, optional for 'openai' and 'claude'." + }, + "model": { + "type": "string", + "description": "Model name to use. Required for 'local' provider, optional for others." + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "Optional CA certificate UUID from trust store for custom SSL/TLS connections" + }, + "skip_tls_verify": { + "type": "boolean", + "description": "Indicates if TLS verification should be skipped for this provider" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "provider_name" + ], + "properties": { + "provider_name": { + "type": "string", + "description": "AI provider name (e.g., openai, anthropic, local)" + }, + "api_token": { + "type": "string", + "description": "API token for the provider. Required for 'openai' and 'claude' providers, optional for 'local' provider." + }, + "base_url": { + "type": "string", + "description": "Base URL for the provider. Required for 'local' provider, optional for 'openai' and 'claude'." + }, + "model": { + "type": "string", + "description": "Model name to use. Required for 'local' provider, optional for others." + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "Optional CA certificate UUID from trust store for custom SSL/TLS connections" + }, + "skip_tls_verify": { + "type": "boolean", + "description": "Indicates if TLS verification should be skipped for this provider" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "1fd098f6-726e-4e93-b361-c83b423d0340", + "created": "2026-08-28T15:12:55.627Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 5, + "reference": "a601ac32-867b-4870-b226-e878815352fe", + "type": "workflow", + "folder": "/Configuration", + "document": { + "name": "Save AIDF Config", + "description": "Save AIDF Config", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "saveAIDFConfig", + "canvasName": "saveAIDFConfig", + "summary": "saveAIDFConfig", + "description": "saveAIDFConfig", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "endpoint", + "tenant_id", + "tenant_token" + ], + "properties": { + "endpoint": { + "type": "string", + "description": "AIDF endpoint URL" + }, + "tenant_id": { + "type": "string", + "description": "Tenant ID" + }, + "tenant_token": { + "type": "string", + "description": "Tenant authentication token" + }, + "data_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "logs", + "metrics" + ] + }, + "description": "Data types to send to AIDF (logs, metrics, or both). Defaults to [\"logs\", \"metrics\"] if not specified. Cannot be an empty array.", + "example": [ + "logs", + "metrics" + ], + "default": [ + "logs", + "metrics" + ], + "minItems": 1 + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "endpoint", + "tenant_id", + "tenant_token" + ], + "properties": { + "endpoint": { + "type": "string", + "description": "AIDF endpoint URL" + }, + "tenant_id": { + "type": "string", + "description": "Tenant ID" + }, + "tenant_token": { + "type": "string", + "description": "Tenant authentication token" + }, + "data_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "logs", + "metrics" + ] + }, + "description": "Data types to send to AIDF (logs, metrics, or both). Defaults to [\"logs\", \"metrics\"] if not specified. Cannot be an empty array.", + "example": [ + "logs", + "metrics" + ], + "default": [ + "logs", + "metrics" + ], + "minItems": 1 + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "d458058d-e44c-45c3-914a-c8f85120836e", + "created": "2026-08-28T15:12:55.507Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 6, + "reference": "59c080ec-a62e-492f-a4a0-0ccf6cd5f978", + "type": "workflow", + "folder": "/Audit Console", + "document": { + "name": "Download Audit Export", + "description": "Download Audit Export", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "downloadAuditExport", + "canvasName": "downloadAuditExport", + "summary": "downloadAuditExport", + "description": "downloadAuditExport", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "fc301c2d-d69e-4e73-ae44-f1c6f05c54b3", + "created": "2026-08-28T15:12:55.762Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 7, + "reference": "53badf1e-33df-4a82-ae58-5ee3749cdac1", + "type": "workflow", + "folder": "/Audit Console", + "document": { + "name": "List Audit Events", + "description": "List Audit Events", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listAuditEvents", + "canvasName": "listAuditEvents", + "summary": "listAuditEvents", + "description": "listAuditEvents", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "page": "$var.job.page", + "size": "$var.job.size", + "username": "$var.job.username", + "event_type": "$var.job.event_type", + "tool": "$var.job.tool", + "keyword": "$var.job.keyword", + "thread_id": "$var.job.thread_id", + "interaction_id": "$var.job.interaction_id", + "session_id": "$var.job.session_id", + "date_from": "$var.job.date_from", + "date_to": "$var.job.date_to", + "view_sensitive": "$var.job.view_sensitive" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "size": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 20 + }, + "username": { + "type": "string" + }, + "event_type": { + "type": "string", + "enum": [ + "user_message", + "assistant_response", + "tool_call", + "tool_result", + "error", + "data_access", + "pdf_export" + ] + }, + "tool": { + "type": "string" + }, + "keyword": { + "type": "string" + }, + "thread_id": { + "type": "string" + }, + "interaction_id": { + "type": "string" + }, + "session_id": { + "type": "string" + }, + "date_from": { + "type": "string", + "format": "date-time" + }, + "date_to": { + "type": "string", + "format": "date-time" + }, + "view_sensitive": { + "type": "boolean", + "default": false + } + }, + "required": [ + "page", + "size", + "username", + "event_type", + "tool", + "keyword", + "thread_id", + "interaction_id", + "session_id", + "date_from", + "date_to", + "view_sensitive" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "size": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 20 + }, + "username": { + "type": "string" + }, + "event_type": { + "type": "string", + "enum": [ + "user_message", + "assistant_response", + "tool_call", + "tool_result", + "error", + "data_access", + "pdf_export" + ] + }, + "tool": { + "type": "string" + }, + "keyword": { + "type": "string" + }, + "thread_id": { + "type": "string" + }, + "interaction_id": { + "type": "string" + }, + "session_id": { + "type": "string" + }, + "date_from": { + "type": "string", + "format": "date-time" + }, + "date_to": { + "type": "string", + "format": "date-time" + }, + "view_sensitive": { + "type": "boolean", + "default": false + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "f61b3ec9-fed3-4bb3-ada3-66b449432463", + "created": "2026-08-28T15:12:55.693Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 8, + "reference": "4c6b686d-4f73-4d11-b4a3-f8ef5f2abdb7", + "type": "workflow", + "folder": "/Audit Console", + "document": { + "name": "Request Audit Export", + "description": "Request Audit Export", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "requestAuditExport", + "canvasName": "requestAuditExport", + "summary": "requestAuditExport", + "description": "requestAuditExport", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "view_sensitive": "$var.job.view_sensitive", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "view_sensitive": { + "type": "boolean", + "default": false + }, + "spec": { + "type": "object", + "description": "Optional filter body for POST /audit/export. All fields correspond to the same query parameters accepted by GET /audit/events.\n", + "properties": { + "username": { + "type": "string" + }, + "event_type": { + "type": "string", + "enum": [ + "user_message", + "assistant_response", + "tool_call", + "tool_result", + "error", + "data_access", + "pdf_export" + ] + }, + "tool": { + "type": "string" + }, + "keyword": { + "type": "string" + }, + "thread_id": { + "type": "string" + }, + "session_id": { + "type": "string" + }, + "date_from": { + "type": "string", + "format": "date-time" + }, + "date_to": { + "type": "string", + "format": "date-time" + } + } + } + }, + "required": [ + "view_sensitive", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "view_sensitive": { + "type": "boolean", + "default": false + }, + "spec": { + "type": "object", + "description": "Optional filter body for POST /audit/export. All fields correspond to the same query parameters accepted by GET /audit/events.\n", + "properties": { + "username": { + "type": "string" + }, + "event_type": { + "type": "string", + "enum": [ + "user_message", + "assistant_response", + "tool_call", + "tool_result", + "error", + "data_access", + "pdf_export" + ] + }, + "tool": { + "type": "string" + }, + "keyword": { + "type": "string" + }, + "thread_id": { + "type": "string" + }, + "session_id": { + "type": "string" + }, + "date_from": { + "type": "string", + "format": "date-time" + }, + "date_to": { + "type": "string", + "format": "date-time" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "a16669a2-13e0-417d-a449-6288327b43a6", + "created": "2026-08-28T15:12:55.727Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 9, + "reference": "c9183901-2e8a-4048-9e04-784c02d012af", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Add Data Center", + "description": "Add Data Center", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "AddDataCenter", + "canvasName": "AddDataCenter", + "summary": "AddDataCenter", + "description": "AddDataCenter", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "additionalProperties": false, + "required": [ + "name" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the data center" + }, + "name": { + "type": "string", + "description": "Name of the Data Center.", + "maxLength": 255 + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "additionalProperties": false, + "required": [ + "name" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the data center" + }, + "name": { + "type": "string", + "description": "Name of the Data Center.", + "maxLength": 255 + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e18fa100-116f-4225-9468-f78135c9387a", + "created": "2026-08-28T15:12:55.807Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 10, + "reference": "15d9475e-ef99-4141-a801-9e9a99c0a6e2", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Add Device", + "description": "Add Device", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "AddDevice", + "canvasName": "AddDevice", + "summary": "AddDevice", + "description": "AddDevice", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "description": "Unified add-device request. The `deviceType` field selects how the\nbody is interpreted. For `bigip` (default) the existing flat BIG-IP\nfields apply (backward compatible). For `f5os` the `f5os` object is\nrequired. Exactly one variant applies per request.\n", + "oneOf": [ + { + "type": "object", + "required": [ + "data_center", + "deviceType", + "endpoint", + "password", + "username" + ], + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "bigip" + ], + "default": "bigip" + }, + "retention": { + "type": "string", + "pattern": "^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$", + "description": "ISO 8601 duration (e.g., P1Y for 1 year, P30D for 30 days).Supported units are Y (years), M (months), D (days), H (hours), M (minutes), S (seconds). Internally converted and rounded up to whole days. Maximum allowed retention is 1 year (P1Y)." + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "collection_interval": { + "type": "integer", + "minimum": 1, + "description": "Collection interval in seconds" + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean", + "default": false + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from trust store" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean", + "default": false + }, + "cgnat": { + "type": "boolean", + "default": false + }, + "dns": { + "type": "boolean", + "default": false + }, + "dos": { + "type": "boolean", + "default": false + }, + "firewall": { + "type": "boolean", + "default": false + }, + "gtm": { + "type": "boolean", + "default": false + }, + "policy_api_protection": { + "type": "boolean", + "default": false + }, + "policy_asm": { + "type": "boolean", + "default": false + }, + "policy_firewall": { + "type": "boolean", + "default": false + }, + "policy_ip_intelligence": { + "type": "boolean", + "default": false + }, + "policy_nat": { + "type": "boolean", + "default": false + }, + "profile_dos": { + "type": "boolean", + "default": false + } + } + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the device" + }, + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string", + "description": "Device endpoint in format ip:port or hostname:port (e.g., 192.168.1.100:443, bigip.example.com:8443)." + } + }, + "description": "BIG-IP add request. `deviceType` must be set to `bigip` so the\nunified add-device endpoint can dispatch to the BIG-IP onboarding\npath; the default in the schema is `bigip` for documentation\npurposes, but callers should still send the field explicitly.\n" + }, + { + "type": "object", + "required": [ + "data_center", + "deviceType", + "endpoint", + "password", + "tls_enabled", + "username" + ], + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "f5os" + ] + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the F5OS provider (response only)." + }, + "alias_name": { + "type": "string", + "maxLength": 255, + "description": "Unique, user-supplied label for the device." + }, + "type": { + "type": "string", + "enum": [ + "RSERIES" + ], + "default": "RSERIES", + "description": "F5OS platform type." + }, + "endpoint": { + "type": "string", + "description": "Device endpoint URL with scheme, host and port (e.g. https://10.1.1.5:443)." + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255, + "description": "Data center the device belongs to." + }, + "tls_enabled": { + "type": "boolean", + "description": "When true, the server certificate is verified against `ca`. When false, TLS verification is skipped." + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from the trust store. Required when `tls_enabled` is true." + }, + "cert_fingerprint": { + "type": "string", + "description": "Optional SHA-256 certificate fingerprint pin. When set, the server certificate must match this fingerprint." + } + }, + "description": "F5OS add request. All F5OS device fields are merged at the top\nlevel alongside the deviceType discriminator, mirroring the flat\nshape of BigIPAddRequest. No nested `f5os` object.\n" + } + ], + "discriminator": { + "propertyName": "deviceType", + "mapping": { + "bigip": "#/components/schemas/BigIPAddRequest", + "f5os": "#/components/schemas/F5OSAddRequest" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "description": "Unified add-device request. The `deviceType` field selects how the\nbody is interpreted. For `bigip` (default) the existing flat BIG-IP\nfields apply (backward compatible). For `f5os` the `f5os` object is\nrequired. Exactly one variant applies per request.\n", + "oneOf": [ + { + "type": "object", + "required": [ + "data_center", + "deviceType", + "endpoint", + "password", + "username" + ], + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "bigip" + ], + "default": "bigip" + }, + "retention": { + "type": "string", + "pattern": "^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$", + "description": "ISO 8601 duration (e.g., P1Y for 1 year, P30D for 30 days).Supported units are Y (years), M (months), D (days), H (hours), M (minutes), S (seconds). Internally converted and rounded up to whole days. Maximum allowed retention is 1 year (P1Y)." + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "collection_interval": { + "type": "integer", + "minimum": 1, + "description": "Collection interval in seconds" + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean", + "default": false + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from trust store" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean", + "default": false + }, + "cgnat": { + "type": "boolean", + "default": false + }, + "dns": { + "type": "boolean", + "default": false + }, + "dos": { + "type": "boolean", + "default": false + }, + "firewall": { + "type": "boolean", + "default": false + }, + "gtm": { + "type": "boolean", + "default": false + }, + "policy_api_protection": { + "type": "boolean", + "default": false + }, + "policy_asm": { + "type": "boolean", + "default": false + }, + "policy_firewall": { + "type": "boolean", + "default": false + }, + "policy_ip_intelligence": { + "type": "boolean", + "default": false + }, + "policy_nat": { + "type": "boolean", + "default": false + }, + "profile_dos": { + "type": "boolean", + "default": false + } + } + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the device" + }, + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string", + "description": "Device endpoint in format ip:port or hostname:port (e.g., 192.168.1.100:443, bigip.example.com:8443)." + } + }, + "description": "BIG-IP add request. `deviceType` must be set to `bigip` so the\nunified add-device endpoint can dispatch to the BIG-IP onboarding\npath; the default in the schema is `bigip` for documentation\npurposes, but callers should still send the field explicitly.\n" + }, + { + "type": "object", + "required": [ + "data_center", + "deviceType", + "endpoint", + "password", + "tls_enabled", + "username" + ], + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "f5os" + ] + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the F5OS provider (response only)." + }, + "alias_name": { + "type": "string", + "maxLength": 255, + "description": "Unique, user-supplied label for the device." + }, + "type": { + "type": "string", + "enum": [ + "RSERIES" + ], + "default": "RSERIES", + "description": "F5OS platform type." + }, + "endpoint": { + "type": "string", + "description": "Device endpoint URL with scheme, host and port (e.g. https://10.1.1.5:443)." + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255, + "description": "Data center the device belongs to." + }, + "tls_enabled": { + "type": "boolean", + "description": "When true, the server certificate is verified against `ca`. When false, TLS verification is skipped." + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from the trust store. Required when `tls_enabled` is true." + }, + "cert_fingerprint": { + "type": "string", + "description": "Optional SHA-256 certificate fingerprint pin. When set, the server certificate must match this fingerprint." + } + }, + "description": "F5OS add request. All F5OS device fields are merged at the top\nlevel alongside the deviceType discriminator, mirroring the flat\nshape of BigIPAddRequest. No nested `f5os` object.\n" + } + ], + "discriminator": { + "propertyName": "deviceType", + "mapping": { + "bigip": "#/components/schemas/BigIPAddRequest", + "f5os": "#/components/schemas/F5OSAddRequest" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "bfdad08f-a068-4ceb-b47c-a4d3bb97a548", + "created": "2026-08-28T15:12:55.932Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 11, + "reference": "cc999c12-d971-4e82-b93f-567842af19d9", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Add Trust Store", + "description": "Add Trust Store", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "AddTrustStore", + "canvasName": "AddTrustStore", + "summary": "AddTrustStore", + "description": "AddTrustStore", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "name", + "certificate_content" + ], + "properties": { + "name": { + "type": "string", + "maxLength": 255, + "description": "Name of the certificate" + }, + "description": { + "type": "string", + "description": "Description of the certificate" + }, + "certificate_content": { + "type": "string", + "description": "PEM encoded certificate content" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "name", + "certificate_content" + ], + "properties": { + "name": { + "type": "string", + "maxLength": 255, + "description": "Name of the certificate" + }, + "description": { + "type": "string", + "description": "Description of the certificate" + }, + "certificate_content": { + "type": "string", + "description": "PEM encoded certificate content" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "a5db0ab1-7fe8-4289-8d83-4fd1c165dfd1", + "created": "2026-08-28T15:12:56.692Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 12, + "reference": "465b4fb7-61b8-47c9-a76f-c8eee35507b8", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Allocate IP Pool Address", + "description": "Allocate IP Pool Address", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "postIpPoolsPoolIdAllocate", + "canvasName": "postIpPoolsPoolIdAllocate", + "summary": "postIpPoolsPoolIdAllocate", + "description": "postIpPoolsPoolIdAllocate", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "properties": { + "allocationId": { + "type": "string", + "description": "Identifier used to make allocation idempotent." + }, + "leaseTags": { + "type": "array", + "description": "Optional labels applied to the resulting lease.", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "Tag name. Duplicate names and special characters are allowed." + }, + "value": { + "type": "string", + "nullable": true + } + }, + "required": [ + "name" + ] + } + } + }, + "required": [ + "allocationId" + ] + } + }, + "required": [ + "poolId", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "properties": { + "allocationId": { + "type": "string", + "description": "Identifier used to make allocation idempotent." + }, + "leaseTags": { + "type": "array", + "description": "Optional labels applied to the resulting lease.", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "Tag name. Duplicate names and special characters are allowed." + }, + "value": { + "type": "string", + "nullable": true + } + }, + "required": [ + "name" + ] + } + } + }, + "required": [ + "allocationId" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "49dd6afe-025e-4a1b-a63f-07e1e9eb3942", + "created": "2026-08-28T15:12:58.304Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 13, + "reference": "467975c0-b896-4b8e-9be8-f961cf442fc9", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Bulk Import Devices", + "description": "Bulk Import Devices", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "BulkImportDevices", + "canvasName": "BulkImportDevices", + "summary": "BulkImportDevices", + "description": "BulkImportDevices", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "devices" + ], + "properties": { + "devices": { + "type": "array", + "items": { + "description": "Unified add-device request. The `deviceType` field selects how the\nbody is interpreted. For `bigip` (default) the existing flat BIG-IP\nfields apply (backward compatible). For `f5os` the `f5os` object is\nrequired. Exactly one variant applies per request.\n", + "oneOf": [ + { + "type": "object", + "required": [ + "data_center", + "deviceType", + "endpoint", + "password", + "username" + ], + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "bigip" + ], + "default": "bigip" + }, + "retention": { + "type": "string", + "pattern": "^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$", + "description": "ISO 8601 duration (e.g., P1Y for 1 year, P30D for 30 days).Supported units are Y (years), M (months), D (days), H (hours), M (minutes), S (seconds). Internally converted and rounded up to whole days. Maximum allowed retention is 1 year (P1Y)." + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "collection_interval": { + "type": "integer", + "minimum": 1, + "description": "Collection interval in seconds" + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean", + "default": false + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from trust store" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean", + "default": false + }, + "cgnat": { + "type": "boolean", + "default": false + }, + "dns": { + "type": "boolean", + "default": false + }, + "dos": { + "type": "boolean", + "default": false + }, + "firewall": { + "type": "boolean", + "default": false + }, + "gtm": { + "type": "boolean", + "default": false + }, + "policy_api_protection": { + "type": "boolean", + "default": false + }, + "policy_asm": { + "type": "boolean", + "default": false + }, + "policy_firewall": { + "type": "boolean", + "default": false + }, + "policy_ip_intelligence": { + "type": "boolean", + "default": false + }, + "policy_nat": { + "type": "boolean", + "default": false + }, + "profile_dos": { + "type": "boolean", + "default": false + } + } + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the device" + }, + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string", + "description": "Device endpoint in format ip:port or hostname:port (e.g., 192.168.1.100:443, bigip.example.com:8443)." + } + }, + "description": "BIG-IP add request. `deviceType` must be set to `bigip` so the\nunified add-device endpoint can dispatch to the BIG-IP onboarding\npath; the default in the schema is `bigip` for documentation\npurposes, but callers should still send the field explicitly.\n" + }, + { + "type": "object", + "required": [ + "data_center", + "deviceType", + "endpoint", + "password", + "tls_enabled", + "username" + ], + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "f5os" + ] + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the F5OS provider (response only)." + }, + "alias_name": { + "type": "string", + "maxLength": 255, + "description": "Unique, user-supplied label for the device." + }, + "type": { + "type": "string", + "enum": [ + "RSERIES" + ], + "default": "RSERIES", + "description": "F5OS platform type." + }, + "endpoint": { + "type": "string", + "description": "Device endpoint URL with scheme, host and port (e.g. https://10.1.1.5:443)." + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255, + "description": "Data center the device belongs to." + }, + "tls_enabled": { + "type": "boolean", + "description": "When true, the server certificate is verified against `ca`. When false, TLS verification is skipped." + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from the trust store. Required when `tls_enabled` is true." + }, + "cert_fingerprint": { + "type": "string", + "description": "Optional SHA-256 certificate fingerprint pin. When set, the server certificate must match this fingerprint." + } + }, + "description": "F5OS add request. All F5OS device fields are merged at the top\nlevel alongside the deviceType discriminator, mirroring the flat\nshape of BigIPAddRequest. No nested `f5os` object.\n" + } + ], + "discriminator": { + "propertyName": "deviceType", + "mapping": { + "bigip": "#/components/schemas/BigIPAddRequest", + "f5os": "#/components/schemas/F5OSAddRequest" + } + } + }, + "minItems": 1, + "description": "List of devices to import (BIG-IP or F5OS per item)" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "devices" + ], + "properties": { + "devices": { + "type": "array", + "items": { + "description": "Unified add-device request. The `deviceType` field selects how the\nbody is interpreted. For `bigip` (default) the existing flat BIG-IP\nfields apply (backward compatible). For `f5os` the `f5os` object is\nrequired. Exactly one variant applies per request.\n", + "oneOf": [ + { + "type": "object", + "required": [ + "data_center", + "deviceType", + "endpoint", + "password", + "username" + ], + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "bigip" + ], + "default": "bigip" + }, + "retention": { + "type": "string", + "pattern": "^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$", + "description": "ISO 8601 duration (e.g., P1Y for 1 year, P30D for 30 days).Supported units are Y (years), M (months), D (days), H (hours), M (minutes), S (seconds). Internally converted and rounded up to whole days. Maximum allowed retention is 1 year (P1Y)." + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "collection_interval": { + "type": "integer", + "minimum": 1, + "description": "Collection interval in seconds" + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean", + "default": false + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from trust store" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean", + "default": false + }, + "cgnat": { + "type": "boolean", + "default": false + }, + "dns": { + "type": "boolean", + "default": false + }, + "dos": { + "type": "boolean", + "default": false + }, + "firewall": { + "type": "boolean", + "default": false + }, + "gtm": { + "type": "boolean", + "default": false + }, + "policy_api_protection": { + "type": "boolean", + "default": false + }, + "policy_asm": { + "type": "boolean", + "default": false + }, + "policy_firewall": { + "type": "boolean", + "default": false + }, + "policy_ip_intelligence": { + "type": "boolean", + "default": false + }, + "policy_nat": { + "type": "boolean", + "default": false + }, + "profile_dos": { + "type": "boolean", + "default": false + } + } + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the device" + }, + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string", + "description": "Device endpoint in format ip:port or hostname:port (e.g., 192.168.1.100:443, bigip.example.com:8443)." + } + }, + "description": "BIG-IP add request. `deviceType` must be set to `bigip` so the\nunified add-device endpoint can dispatch to the BIG-IP onboarding\npath; the default in the schema is `bigip` for documentation\npurposes, but callers should still send the field explicitly.\n" + }, + { + "type": "object", + "required": [ + "data_center", + "deviceType", + "endpoint", + "password", + "tls_enabled", + "username" + ], + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "f5os" + ] + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the F5OS provider (response only)." + }, + "alias_name": { + "type": "string", + "maxLength": 255, + "description": "Unique, user-supplied label for the device." + }, + "type": { + "type": "string", + "enum": [ + "RSERIES" + ], + "default": "RSERIES", + "description": "F5OS platform type." + }, + "endpoint": { + "type": "string", + "description": "Device endpoint URL with scheme, host and port (e.g. https://10.1.1.5:443)." + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255, + "description": "Data center the device belongs to." + }, + "tls_enabled": { + "type": "boolean", + "description": "When true, the server certificate is verified against `ca`. When false, TLS verification is skipped." + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from the trust store. Required when `tls_enabled` is true." + }, + "cert_fingerprint": { + "type": "string", + "description": "Optional SHA-256 certificate fingerprint pin. When set, the server certificate must match this fingerprint." + } + }, + "description": "F5OS add request. All F5OS device fields are merged at the top\nlevel alongside the deviceType discriminator, mirroring the flat\nshape of BigIPAddRequest. No nested `f5os` object.\n" + } + ], + "discriminator": { + "propertyName": "deviceType", + "mapping": { + "bigip": "#/components/schemas/BigIPAddRequest", + "f5os": "#/components/schemas/F5OSAddRequest" + } + } + }, + "minItems": 1, + "description": "List of devices to import (BIG-IP or F5OS per item)" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "dcc34db9-e114-47bf-8a8b-3955c65d9363", + "created": "2026-08-28T15:12:56.036Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 14, + "reference": "6b656b5c-1f57-4d16-9579-3bb6b91a0ab5", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Cleanup Import Task", + "description": "Cleanup Import Task", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "CleanupImportTask", + "canvasName": "CleanupImportTask", + "summary": "CleanupImportTask", + "description": "CleanupImportTask", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "task_id": "$var.job.task_id", + "force": "$var.job.force" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "force": { + "type": "boolean", + "default": false + } + }, + "required": [ + "task_id", + "force" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "force": { + "type": "boolean", + "default": false + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "6fff0fc5-65de-42ef-86a1-d7c7bc67f730", + "created": "2026-08-28T15:12:56.191Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 15, + "reference": "8ba59709-9032-4082-a617-1c926fc4a4ef", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Cleanup Migration Task", + "description": "Cleanup Migration Task", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "CleanupMigrationTask", + "canvasName": "CleanupMigrationTask", + "summary": "CleanupMigrationTask", + "description": "CleanupMigrationTask", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "task_id": "$var.job.task_id", + "force": "$var.job.force" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "force": { + "type": "boolean", + "default": false + } + }, + "required": [ + "task_id", + "force" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "force": { + "type": "boolean", + "default": false + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e45b482b-4883-49f7-a0cb-2581b890eb51", + "created": "2026-08-28T15:12:56.281Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 16, + "reference": "4239aebb-1024-498f-ad66-8a22d1ea2e55", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Create IP Pool", + "description": "Create IP Pool", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "postIpPools", + "canvasName": "postIpPools", + "summary": "postIpPools", + "description": "postIpPools", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z_][a-zA-Z0-9_.\\-]*$", + "description": "Pool name. Rules:\n- Minimum length: 1 character\n- Maximum length: 255 characters\n- First character must be a letter (a-z, A-Z) or underscore (_)\n- Remaining characters may be letters, digits, hyphens (-), underscores (_), or dots (.)\n- The following reserved words are not allowed: all, delete, disable, enable, help, list, none, show, None\n" + }, + "description": { + "type": "string" + }, + "addressFamily": { + "type": "string", + "enum": [ + "IPv4", + "IPv6" + ], + "description": "Address family of the pool. When omitted, it is inferred from the CIDR (IPv4 or IPv6)." + }, + "address": { + "type": "string", + "example": "10.0.0.0/24" + }, + "gateway": { + "type": "string", + "nullable": true + }, + "addressRanges": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "firstAddress": { + "type": "string", + "example": "10.0.0.10" + }, + "lastAddress": { + "type": "string", + "example": "10.0.0.100" + } + }, + "required": [ + "firstAddress", + "lastAddress" + ] + } + } + }, + "required": [ + "name", + "address", + "addressRanges" + ] + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z_][a-zA-Z0-9_.\\-]*$", + "description": "Pool name. Rules:\n- Minimum length: 1 character\n- Maximum length: 255 characters\n- First character must be a letter (a-z, A-Z) or underscore (_)\n- Remaining characters may be letters, digits, hyphens (-), underscores (_), or dots (.)\n- The following reserved words are not allowed: all, delete, disable, enable, help, list, none, show, None\n" + }, + "description": { + "type": "string" + }, + "addressFamily": { + "type": "string", + "enum": [ + "IPv4", + "IPv6" + ], + "description": "Address family of the pool. When omitted, it is inferred from the CIDR (IPv4 or IPv6)." + }, + "address": { + "type": "string", + "example": "10.0.0.0/24" + }, + "gateway": { + "type": "string", + "nullable": true + }, + "addressRanges": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "firstAddress": { + "type": "string", + "example": "10.0.0.10" + }, + "lastAddress": { + "type": "string", + "example": "10.0.0.100" + } + }, + "required": [ + "firstAddress", + "lastAddress" + ] + } + } + }, + "required": [ + "name", + "address", + "addressRanges" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "0034b458-e5d9-44aa-84dc-b15d8f375251", + "created": "2026-08-28T15:12:58.121Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 17, + "reference": "e9b1b14b-727a-4fdf-9103-fa2550fbdc36", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Create IP Pool Lease", + "description": "Create IP Pool Lease", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "postIpPoolsLeases", + "canvasName": "postIpPoolsLeases", + "summary": "postIpPoolsLeases", + "description": "postIpPoolsLeases", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "poolId": { + "type": "string", + "format": "uuid" + }, + "address": { + "type": "string", + "example": "10.0.0.10" + }, + "gateway": { + "type": "string", + "nullable": true + }, + "allocationId": { + "type": "string", + "nullable": true + }, + "deviceId": { + "type": "string", + "format": "uuid", + "nullable": true + }, + "leaseTags": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "Tag name. Duplicate names and special characters are allowed." + }, + "value": { + "type": "string", + "nullable": true + } + }, + "required": [ + "name" + ] + } + }, + "metadata": { + "type": "object", + "additionalProperties": true + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "deletedAt": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "required": [ + "id", + "poolId", + "address", + "createdAt", + "updatedAt" + ] + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "poolId": { + "type": "string", + "format": "uuid" + }, + "address": { + "type": "string", + "example": "10.0.0.10" + }, + "gateway": { + "type": "string", + "nullable": true + }, + "allocationId": { + "type": "string", + "nullable": true + }, + "deviceId": { + "type": "string", + "format": "uuid", + "nullable": true + }, + "leaseTags": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "Tag name. Duplicate names and special characters are allowed." + }, + "value": { + "type": "string", + "nullable": true + } + }, + "required": [ + "name" + ] + } + }, + "metadata": { + "type": "object", + "additionalProperties": true + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "deletedAt": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "required": [ + "id", + "poolId", + "address", + "createdAt", + "updatedAt" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "fdcc5536-0cde-4a51-88e6-bf17a8c08370", + "created": "2026-08-28T15:12:58.151Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 18, + "reference": "7305851d-4470-43b5-b61d-4f29e41cdcf8", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Delete Data Center", + "description": "Delete Data Center", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "DeleteDataCenter", + "canvasName": "DeleteDataCenter", + "summary": "DeleteDataCenter", + "description": "DeleteDataCenter", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "dc1e7556-84ef-4f86-906a-0d53799d4816", + "created": "2026-08-28T15:12:55.898Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 19, + "reference": "f05ba9b7-8d77-40a0-9dd6-2244310003dc", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Delete IP Pool", + "description": "Delete IP Pool", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteIpPoolsPoolId", + "canvasName": "deleteIpPoolsPoolId", + "summary": "deleteIpPoolsPoolId", + "description": "deleteIpPoolsPoolId", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "poolId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "2f2db40b-be62-4171-9d15-2570ad606186", + "created": "2026-08-28T15:12:58.275Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 20, + "reference": "b1e10637-9f4a-4991-948f-aee494416577", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Delete Trust Store", + "description": "Delete Trust Store", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "DeleteTrustStore", + "canvasName": "DeleteTrustStore", + "summary": "DeleteTrustStore", + "description": "DeleteTrustStore", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "be1e17ed-13b4-4a19-93b7-92efb408c0cf", + "created": "2026-08-28T15:12:56.784Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 21, + "reference": "996a838c-be1c-4a2c-9d6a-0216215b786f", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "F5 Insight Delete Device", + "description": "F5 Insight Delete Device", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "DeleteDevice", + "canvasName": "DeleteDevice", + "summary": "DeleteDevice", + "description": "DeleteDevice", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "875cb8a6-b4e7-43dc-a150-61f4aa4af323", + "created": "2026-08-28T15:12:56.630Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 22, + "reference": "10353004-8d34-4d6b-a45f-885821580243", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "F5 Insight Get Device", + "description": "F5 Insight Get Device", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "GetDevice", + "canvasName": "GetDevice", + "summary": "GetDevice", + "description": "GetDevice", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "dfbc69fa-27a0-4f8e-a428-d5411f44e25b", + "created": "2026-08-28T15:12:56.585Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 23, + "reference": "2e1e8f6e-8761-44a3-b621-e9edc4a73130", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "F5 Insight Update Device", + "description": "F5 Insight Update Device", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "UpdateDevice", + "canvasName": "UpdateDevice", + "summary": "UpdateDevice", + "description": "UpdateDevice", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "spec": { + "type": "object", + "properties": { + "retention": { + "type": "string", + "pattern": "^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$", + "description": "ISO 8601 duration (e.g., P1Y for 1 year, P30D for 30 days).Supported units are Y (years), M (months), D (days), H (hours), M (minutes), S (seconds). Internally converted and rounded up to whole days. Maximum allowed retention is 1 year (P1Y)." + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "collection_interval": { + "type": "integer", + "minimum": 1, + "description": "Collection interval in seconds" + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean", + "default": false + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from trust store" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean", + "default": false + }, + "cgnat": { + "type": "boolean", + "default": false + }, + "dns": { + "type": "boolean", + "default": false + }, + "dos": { + "type": "boolean", + "default": false + }, + "firewall": { + "type": "boolean", + "default": false + }, + "gtm": { + "type": "boolean", + "default": false + }, + "policy_api_protection": { + "type": "boolean", + "default": false + }, + "policy_asm": { + "type": "boolean", + "default": false + }, + "policy_firewall": { + "type": "boolean", + "default": false + }, + "policy_ip_intelligence": { + "type": "boolean", + "default": false + }, + "policy_nat": { + "type": "boolean", + "default": false + }, + "profile_dos": { + "type": "boolean", + "default": false + } + } + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the device" + }, + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string", + "description": "Device endpoint in format ip:port or hostname:port (e.g., 192.168.1.100:443, bigip.example.com:8443)." + } + }, + "required": [ + "username", + "password", + "data_center", + "endpoint" + ] + } + }, + "required": [ + "id", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "spec": { + "type": "object", + "properties": { + "retention": { + "type": "string", + "pattern": "^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$", + "description": "ISO 8601 duration (e.g., P1Y for 1 year, P30D for 30 days).Supported units are Y (years), M (months), D (days), H (hours), M (minutes), S (seconds). Internally converted and rounded up to whole days. Maximum allowed retention is 1 year (P1Y)." + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "collection_interval": { + "type": "integer", + "minimum": 1, + "description": "Collection interval in seconds" + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean", + "default": false + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from trust store" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean", + "default": false + }, + "cgnat": { + "type": "boolean", + "default": false + }, + "dns": { + "type": "boolean", + "default": false + }, + "dos": { + "type": "boolean", + "default": false + }, + "firewall": { + "type": "boolean", + "default": false + }, + "gtm": { + "type": "boolean", + "default": false + }, + "policy_api_protection": { + "type": "boolean", + "default": false + }, + "policy_asm": { + "type": "boolean", + "default": false + }, + "policy_firewall": { + "type": "boolean", + "default": false + }, + "policy_ip_intelligence": { + "type": "boolean", + "default": false + }, + "policy_nat": { + "type": "boolean", + "default": false + }, + "profile_dos": { + "type": "boolean", + "default": false + } + } + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the device" + }, + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string", + "description": "Device endpoint in format ip:port or hostname:port (e.g., 192.168.1.100:443, bigip.example.com:8443)." + } + }, + "required": [ + "username", + "password", + "data_center", + "endpoint" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "3b9c7706-ec72-4101-9a4f-eb1887a67a26", + "created": "2026-08-28T15:12:56.519Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 24, + "reference": "0b91cc29-5238-47a3-b092-97e6e6c3858c", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Get CA Bundle Progress", + "description": "Get CA Bundle Progress", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "GetCABundleProgress", + "canvasName": "GetCABundleProgress", + "summary": "GetCABundleProgress", + "description": "GetCABundleProgress", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "task_id": "$var.job.task_id", + "page": "$var.job.page", + "size": "$var.job.size" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "size": { + "type": "integer", + "minimum": 1 + } + }, + "required": [ + "task_id", + "page", + "size" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "size": { + "type": "integer", + "minimum": 1 + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "59e97764-d9a2-4be5-b89f-4df1ba62a1ff", + "created": "2026-08-28T15:12:56.460Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 25, + "reference": "d2547998-ff61-4a5f-bf0e-3c7405f5b221", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Get Current Import Task", + "description": "Get Current Import Task", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "GetCurrentImportTask", + "canvasName": "GetCurrentImportTask", + "summary": "GetCurrentImportTask", + "description": "GetCurrentImportTask", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "7639a36d-7375-4da8-b0f4-086f97c33c07", + "created": "2026-08-28T15:12:56.112Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 26, + "reference": "8b06d8e7-f342-427a-8bed-10ee3ce799ee", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Get Current Migration Task", + "description": "Get Current Migration Task", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "GetCurrentMigrationTask", + "canvasName": "GetCurrentMigrationTask", + "summary": "GetCurrentMigrationTask", + "description": "GetCurrentMigrationTask", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "b9d7ab02-c874-433d-be98-477b6ff0d767", + "created": "2026-08-28T15:12:56.252Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 27, + "reference": "26d45aab-dc99-41d4-a79d-8be1986d9848", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Get Data Centers", + "description": "Get Data Centers", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "GetDataCenters", + "canvasName": "GetDataCenters", + "summary": "GetDataCenters", + "description": "GetDataCenters", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "fc3b6ea4-358d-4a42-aed3-3203fdb116c1", + "created": "2026-08-28T15:12:55.840Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 28, + "reference": "0cff59f2-4e64-4501-a847-45ff9ffae80a", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Get Data Centers Registered Devices", + "description": "Get Data Centers Registered Devices", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "GetDataCentersRegisteredDevices", + "canvasName": "GetDataCentersRegisteredDevices", + "summary": "GetDataCentersRegisteredDevices", + "description": "GetDataCentersRegisteredDevices", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "deviceType": "$var.job.deviceType" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "all", + "bigip", + "f5os" + ], + "default": "all" + } + }, + "required": [ + "deviceType" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "all", + "bigip", + "f5os" + ], + "default": "all" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "ae0cf68c-9906-4332-8862-a53b5de96f84", + "created": "2026-08-28T15:12:55.870Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 29, + "reference": "7b264fd7-d002-422d-a740-257fe989ba5a", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Get Device Progress", + "description": "Get Device Progress", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "GetDeviceProgress", + "canvasName": "GetDeviceProgress", + "summary": "GetDeviceProgress", + "description": "GetDeviceProgress", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "task_id": "$var.job.task_id", + "page": "$var.job.page", + "size": "$var.job.size", + "since": "$var.job.since", + "search": "$var.job.search", + "sort": "$var.job.sort" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "size": { + "type": "integer", + "minimum": 1 + }, + "since": { + "type": "string", + "format": "date-time" + }, + "search": { + "type": "string" + }, + "sort": { + "type": "string" + } + }, + "required": [ + "task_id", + "page", + "size", + "since", + "search", + "sort" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "size": { + "type": "integer", + "minimum": 1 + }, + "since": { + "type": "string", + "format": "date-time" + }, + "search": { + "type": "string" + }, + "sort": { + "type": "string" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "4f67df16-5ba7-4400-b266-7817416fb62e", + "created": "2026-08-28T15:12:56.488Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 30, + "reference": "8f0e5cc1-728e-4b3f-8b77-f7b01e5eca6a", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Get Devices", + "description": "Get Devices", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "GetDevices", + "canvasName": "GetDevices", + "summary": "GetDevices", + "description": "GetDevices", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "page": "$var.job.page", + "size": "$var.job.size", + "since": "$var.job.since", + "search": "$var.job.search", + "sort": "$var.job.sort", + "deviceType": "$var.job.deviceType" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "size": { + "type": "integer", + "minimum": 1 + }, + "since": { + "type": "string", + "format": "date-time" + }, + "search": { + "type": "string" + }, + "sort": { + "type": "string" + }, + "deviceType": { + "type": "string", + "enum": [ + "all", + "bigip", + "f5os" + ], + "default": "all" + } + }, + "required": [ + "page", + "size", + "since", + "search", + "sort", + "deviceType" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "size": { + "type": "integer", + "minimum": 1 + }, + "since": { + "type": "string", + "format": "date-time" + }, + "search": { + "type": "string" + }, + "sort": { + "type": "string" + }, + "deviceType": { + "type": "string", + "enum": [ + "all", + "bigip", + "f5os" + ], + "default": "all" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e48f17dd-4b34-455d-aa6c-cb7518c2399b", + "created": "2026-08-28T15:12:55.967Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 31, + "reference": "5f41254c-50fd-415c-8357-941c42b001cc", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Get Devices By Auto Scale Group", + "description": "Get Devices By Auto Scale Group", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "GetDevicesByAutoScaleGroup", + "canvasName": "GetDevicesByAutoScaleGroup", + "summary": "GetDevicesByAutoScaleGroup", + "description": "GetDevicesByAutoScaleGroup", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "autoScaleGroupId": "$var.job.autoScaleGroupId", + "page": "$var.job.page", + "size": "$var.job.size", + "since": "$var.job.since", + "sort": "$var.job.sort" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "autoScaleGroupId": { + "type": "string", + "format": "uuid" + }, + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "size": { + "type": "integer", + "minimum": 1 + }, + "since": { + "type": "string", + "format": "date-time" + }, + "sort": { + "type": "string" + } + }, + "required": [ + "autoScaleGroupId", + "page", + "size", + "since", + "sort" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "autoScaleGroupId": { + "type": "string", + "format": "uuid" + }, + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "size": { + "type": "integer", + "minimum": 1 + }, + "since": { + "type": "string", + "format": "date-time" + }, + "sort": { + "type": "string" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "b2600f2f-a7d3-401a-9a09-09a18d4571bd", + "created": "2026-08-28T15:12:55.996Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 32, + "reference": "666c7949-a86f-42cd-8bb8-c2538c3840b3", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Get IP Pool", + "description": "Get IP Pool", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getIpPoolsPoolId", + "canvasName": "getIpPoolsPoolId", + "summary": "getIpPoolsPoolId", + "description": "getIpPoolsPoolId", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "poolId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e2804c97-fd54-4330-9441-db4b1f0d07cc", + "created": "2026-08-28T15:12:58.211Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 33, + "reference": "9de497e5-b16d-410f-afaa-90327d9d4d29", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Get IP Pool Lease", + "description": "Get IP Pool Lease", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getIpPoolsPoolIdLeasesLeaseId", + "canvasName": "getIpPoolsPoolIdLeasesLeaseId", + "summary": "getIpPoolsPoolIdLeasesLeaseId", + "description": "getIpPoolsPoolIdLeasesLeaseId", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId", + "leaseId": "$var.job.leaseId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "leaseId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "poolId", + "leaseId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "leaseId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "004e503b-cb68-401e-af34-4a3aaafb0c35", + "created": "2026-08-28T15:12:58.368Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 34, + "reference": "a87b066d-f438-49ef-99ac-867ab03bffa9", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Get Import Task Status", + "description": "Get Import Task Status", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "GetImportTaskStatus", + "canvasName": "GetImportTaskStatus", + "summary": "GetImportTaskStatus", + "description": "GetImportTaskStatus", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "task_id": "$var.job.task_id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "task_id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "4ab83e91-0853-417c-98ee-2b1b8bd47dea", + "created": "2026-08-28T15:12:56.219Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 35, + "reference": "4601833e-a36c-40ef-bc36-85d323384862", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Get Migration Status", + "description": "Get Migration Status", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "GetMigrationStatus", + "canvasName": "GetMigrationStatus", + "summary": "GetMigrationStatus", + "description": "GetMigrationStatus", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "task_id": "$var.job.task_id", + "include_devices": "$var.job.include_devices", + "limit": "$var.job.limit", + "offset": "$var.job.offset", + "updated_since": "$var.job.updated_since" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "include_devices": { + "type": "boolean", + "default": true + }, + "limit": { + "type": "integer", + "default": 100, + "minimum": 1, + "maximum": 1000 + }, + "offset": { + "type": "integer", + "default": 0, + "minimum": 0 + }, + "updated_since": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "task_id", + "include_devices", + "limit", + "offset", + "updated_since" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "include_devices": { + "type": "boolean", + "default": true + }, + "limit": { + "type": "integer", + "default": 100, + "minimum": 1, + "maximum": 1000 + }, + "offset": { + "type": "integer", + "default": 0, + "minimum": 0 + }, + "updated_since": { + "type": "string", + "format": "date-time" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "55d84ad2-cc9d-4be2-8cbe-1ad47af329a5", + "created": "2026-08-28T15:12:56.428Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 36, + "reference": "e2e15260-a25b-4c3b-a643-a475f8931ad3", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Get Staging Device", + "description": "Get Staging Device", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "GetStagingDevice", + "canvasName": "GetStagingDevice", + "summary": "GetStagingDevice", + "description": "GetStagingDevice", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "staging_device_id": "$var.job.staging_device_id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "staging_device_id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "staging_device_id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "staging_device_id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "7ce2d10c-88dc-44d9-9158-48fa42a94ba6", + "created": "2026-08-28T15:12:56.370Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 37, + "reference": "85113494-9b0d-4a44-8a5e-4bc031e5ec45", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Get Trust Store", + "description": "Get Trust Store", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "GetTrustStore", + "canvasName": "GetTrustStore", + "summary": "GetTrustStore", + "description": "GetTrustStore", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "9f6e5970-1d77-4e7e-8e98-0a9abb82d45a", + "created": "2026-08-28T15:12:56.753Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 38, + "reference": "07d263a7-74be-445c-9cca-f9ba7d13ee20", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Get Trust Stores", + "description": "Get Trust Stores", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "GetTrustStores", + "canvasName": "GetTrustStores", + "summary": "GetTrustStores", + "description": "GetTrustStores", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "d1fbf89b-a63f-4c0c-b86d-835e08a9c2e2", + "created": "2026-08-28T15:12:56.721Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 39, + "reference": "62146cbd-c332-4931-93cc-c919cde74223", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Import Devices Async", + "description": "Import Devices Async", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "ImportDevicesAsync", + "canvasName": "ImportDevicesAsync", + "summary": "ImportDevicesAsync", + "description": "ImportDevicesAsync", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "devices" + ], + "properties": { + "devices": { + "type": "array", + "items": { + "description": "Unified add-device request. The `deviceType` field selects how the\nbody is interpreted. For `bigip` (default) the existing flat BIG-IP\nfields apply (backward compatible). For `f5os` the `f5os` object is\nrequired. Exactly one variant applies per request.\n", + "oneOf": [ + { + "type": "object", + "required": [ + "data_center", + "deviceType", + "endpoint", + "password", + "username" + ], + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "bigip" + ], + "default": "bigip" + }, + "retention": { + "type": "string", + "pattern": "^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$", + "description": "ISO 8601 duration (e.g., P1Y for 1 year, P30D for 30 days).Supported units are Y (years), M (months), D (days), H (hours), M (minutes), S (seconds). Internally converted and rounded up to whole days. Maximum allowed retention is 1 year (P1Y)." + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "collection_interval": { + "type": "integer", + "minimum": 1, + "description": "Collection interval in seconds" + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean", + "default": false + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from trust store" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean", + "default": false + }, + "cgnat": { + "type": "boolean", + "default": false + }, + "dns": { + "type": "boolean", + "default": false + }, + "dos": { + "type": "boolean", + "default": false + }, + "firewall": { + "type": "boolean", + "default": false + }, + "gtm": { + "type": "boolean", + "default": false + }, + "policy_api_protection": { + "type": "boolean", + "default": false + }, + "policy_asm": { + "type": "boolean", + "default": false + }, + "policy_firewall": { + "type": "boolean", + "default": false + }, + "policy_ip_intelligence": { + "type": "boolean", + "default": false + }, + "policy_nat": { + "type": "boolean", + "default": false + }, + "profile_dos": { + "type": "boolean", + "default": false + } + } + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the device" + }, + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string", + "description": "Device endpoint in format ip:port or hostname:port (e.g., 192.168.1.100:443, bigip.example.com:8443)." + } + }, + "description": "BIG-IP add request. `deviceType` must be set to `bigip` so the\nunified add-device endpoint can dispatch to the BIG-IP onboarding\npath; the default in the schema is `bigip` for documentation\npurposes, but callers should still send the field explicitly.\n" + }, + { + "type": "object", + "required": [ + "data_center", + "deviceType", + "endpoint", + "password", + "tls_enabled", + "username" + ], + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "f5os" + ] + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the F5OS provider (response only)." + }, + "alias_name": { + "type": "string", + "maxLength": 255, + "description": "Unique, user-supplied label for the device." + }, + "type": { + "type": "string", + "enum": [ + "RSERIES" + ], + "default": "RSERIES", + "description": "F5OS platform type." + }, + "endpoint": { + "type": "string", + "description": "Device endpoint URL with scheme, host and port (e.g. https://10.1.1.5:443)." + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255, + "description": "Data center the device belongs to." + }, + "tls_enabled": { + "type": "boolean", + "description": "When true, the server certificate is verified against `ca`. When false, TLS verification is skipped." + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from the trust store. Required when `tls_enabled` is true." + }, + "cert_fingerprint": { + "type": "string", + "description": "Optional SHA-256 certificate fingerprint pin. When set, the server certificate must match this fingerprint." + } + }, + "description": "F5OS add request. All F5OS device fields are merged at the top\nlevel alongside the deviceType discriminator, mirroring the flat\nshape of BigIPAddRequest. No nested `f5os` object.\n" + } + ], + "discriminator": { + "propertyName": "deviceType", + "mapping": { + "bigip": "#/components/schemas/BigIPAddRequest", + "f5os": "#/components/schemas/F5OSAddRequest" + } + } + }, + "minItems": 1, + "maxItems": 1000, + "description": "List of devices to import (BIG-IP or F5OS per item)." + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "devices" + ], + "properties": { + "devices": { + "type": "array", + "items": { + "description": "Unified add-device request. The `deviceType` field selects how the\nbody is interpreted. For `bigip` (default) the existing flat BIG-IP\nfields apply (backward compatible). For `f5os` the `f5os` object is\nrequired. Exactly one variant applies per request.\n", + "oneOf": [ + { + "type": "object", + "required": [ + "data_center", + "deviceType", + "endpoint", + "password", + "username" + ], + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "bigip" + ], + "default": "bigip" + }, + "retention": { + "type": "string", + "pattern": "^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$", + "description": "ISO 8601 duration (e.g., P1Y for 1 year, P30D for 30 days).Supported units are Y (years), M (months), D (days), H (hours), M (minutes), S (seconds). Internally converted and rounded up to whole days. Maximum allowed retention is 1 year (P1Y)." + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "collection_interval": { + "type": "integer", + "minimum": 1, + "description": "Collection interval in seconds" + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean", + "default": false + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from trust store" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean", + "default": false + }, + "cgnat": { + "type": "boolean", + "default": false + }, + "dns": { + "type": "boolean", + "default": false + }, + "dos": { + "type": "boolean", + "default": false + }, + "firewall": { + "type": "boolean", + "default": false + }, + "gtm": { + "type": "boolean", + "default": false + }, + "policy_api_protection": { + "type": "boolean", + "default": false + }, + "policy_asm": { + "type": "boolean", + "default": false + }, + "policy_firewall": { + "type": "boolean", + "default": false + }, + "policy_ip_intelligence": { + "type": "boolean", + "default": false + }, + "policy_nat": { + "type": "boolean", + "default": false + }, + "profile_dos": { + "type": "boolean", + "default": false + } + } + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the device" + }, + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string", + "description": "Device endpoint in format ip:port or hostname:port (e.g., 192.168.1.100:443, bigip.example.com:8443)." + } + }, + "description": "BIG-IP add request. `deviceType` must be set to `bigip` so the\nunified add-device endpoint can dispatch to the BIG-IP onboarding\npath; the default in the schema is `bigip` for documentation\npurposes, but callers should still send the field explicitly.\n" + }, + { + "type": "object", + "required": [ + "data_center", + "deviceType", + "endpoint", + "password", + "tls_enabled", + "username" + ], + "properties": { + "deviceType": { + "type": "string", + "enum": [ + "f5os" + ] + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the F5OS provider (response only)." + }, + "alias_name": { + "type": "string", + "maxLength": 255, + "description": "Unique, user-supplied label for the device." + }, + "type": { + "type": "string", + "enum": [ + "RSERIES" + ], + "default": "RSERIES", + "description": "F5OS platform type." + }, + "endpoint": { + "type": "string", + "description": "Device endpoint URL with scheme, host and port (e.g. https://10.1.1.5:443)." + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255, + "description": "Data center the device belongs to." + }, + "tls_enabled": { + "type": "boolean", + "description": "When true, the server certificate is verified against `ca`. When false, TLS verification is skipped." + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from the trust store. Required when `tls_enabled` is true." + }, + "cert_fingerprint": { + "type": "string", + "description": "Optional SHA-256 certificate fingerprint pin. When set, the server certificate must match this fingerprint." + } + }, + "description": "F5OS add request. All F5OS device fields are merged at the top\nlevel alongside the deviceType discriminator, mirroring the flat\nshape of BigIPAddRequest. No nested `f5os` object.\n" + } + ], + "discriminator": { + "propertyName": "deviceType", + "mapping": { + "bigip": "#/components/schemas/BigIPAddRequest", + "f5os": "#/components/schemas/F5OSAddRequest" + } + } + }, + "minItems": 1, + "maxItems": 1000, + "description": "List of devices to import (BIG-IP or F5OS per item)." + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "68492f38-ca07-45b7-8c2c-4ccf289b4f7e", + "created": "2026-08-28T15:12:56.158Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 40, + "reference": "6a84796c-33b4-43bd-90cf-f2ee292ad016", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "List IP Pool Leases", + "description": "List IP Pool Leases", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getIpPoolsPoolIdLeases", + "canvasName": "getIpPoolsPoolIdLeases", + "summary": "getIpPoolsPoolIdLeases", + "description": "getIpPoolsPoolIdLeases", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "poolId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "3f58da9b-bedc-4831-9055-5c757f728828", + "created": "2026-08-28T15:12:58.336Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 41, + "reference": "4f5f0bc0-3479-47db-98cd-acb7610a66e8", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "List IP Pools", + "description": "List IP Pools", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getIpPools", + "canvasName": "getIpPools", + "summary": "getIpPools", + "description": "getIpPools", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "$top": "$var.job.$top", + "$skip": "$var.job.$skip" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "": { + "type": [ + "array", + "boolean", + "null", + "number", + "object", + "string" + ] + } + }, + "required": [ + "" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "": { + "type": [ + "array", + "boolean", + "null", + "number", + "object", + "string" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "4dac42a4-b328-498e-9afc-0dbd29e27e4c", + "created": "2026-08-28T15:12:58.092Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 42, + "reference": "3f83e469-7d6f-4493-98dc-065d54a89ee1", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Partial Update Device", + "description": "Partial Update Device", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "PartialUpdateDevice", + "canvasName": "PartialUpdateDevice", + "summary": "PartialUpdateDevice", + "description": "PartialUpdateDevice", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "spec": { + "type": "object", + "description": "Partial device update - only include fields you want to update.", + "properties": { + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string" + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "retention": { + "type": "string", + "pattern": "^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$", + "description": "ISO 8601 duration (e.g., P1Y for 1 year, P30D for 30 days).Supported units are Y (years), M (months), D (days), H (hours), M (minutes), S (seconds). Internally converted and rounded up to whole days. Maximum allowed retention is 1 year (P1Y)." + }, + "collection_interval": { + "type": "integer", + "minimum": 1 + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean" + }, + "ca": { + "type": "string", + "format": "uuid" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean" + }, + "cgnat": { + "type": "boolean" + }, + "dns": { + "type": "boolean" + }, + "dos": { + "type": "boolean" + }, + "firewall": { + "type": "boolean" + }, + "gtm": { + "type": "boolean" + }, + "profile_dos": { + "type": "boolean" + }, + "policy_api_protection": { + "type": "boolean" + }, + "policy_asm": { + "type": "boolean" + }, + "policy_firewall": { + "type": "boolean" + }, + "policy_ip_intelligence": { + "type": "boolean" + }, + "policy_nat": { + "type": "boolean" + } + } + } + } + } + }, + "required": [ + "id", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "spec": { + "type": "object", + "description": "Partial device update - only include fields you want to update.", + "properties": { + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string" + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "retention": { + "type": "string", + "pattern": "^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$", + "description": "ISO 8601 duration (e.g., P1Y for 1 year, P30D for 30 days).Supported units are Y (years), M (months), D (days), H (hours), M (minutes), S (seconds). Internally converted and rounded up to whole days. Maximum allowed retention is 1 year (P1Y)." + }, + "collection_interval": { + "type": "integer", + "minimum": 1 + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean" + }, + "ca": { + "type": "string", + "format": "uuid" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean" + }, + "cgnat": { + "type": "boolean" + }, + "dns": { + "type": "boolean" + }, + "dos": { + "type": "boolean" + }, + "firewall": { + "type": "boolean" + }, + "gtm": { + "type": "boolean" + }, + "profile_dos": { + "type": "boolean" + }, + "policy_api_protection": { + "type": "boolean" + }, + "policy_asm": { + "type": "boolean" + }, + "policy_firewall": { + "type": "boolean" + }, + "policy_ip_intelligence": { + "type": "boolean" + }, + "policy_nat": { + "type": "boolean" + } + } + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "215a1c83-54a8-4c94-8fc7-febef4f7db26", + "created": "2026-08-28T15:12:56.552Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 43, + "reference": "12440000-87ef-4feb-8255-64b509180315", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Patch Staging CA Bundle", + "description": "Patch Staging CA Bundle", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "PatchStagingCABundle", + "canvasName": "PatchStagingCABundle", + "summary": "PatchStagingCABundle", + "description": "PatchStagingCABundle", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "staging_ca_id": "$var.job.staging_ca_id", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "staging_ca_id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "required": [ + "name", + "certificate_content" + ], + "properties": { + "name": { + "type": "string", + "maxLength": 255, + "description": "Name of the certificate" + }, + "description": { + "type": "string", + "description": "Description of the certificate" + }, + "certificate_content": { + "type": "string", + "description": "PEM encoded certificate content" + } + } + } + }, + "required": [ + "staging_ca_id", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "staging_ca_id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "required": [ + "name", + "certificate_content" + ], + "properties": { + "name": { + "type": "string", + "maxLength": 255, + "description": "Name of the certificate" + }, + "description": { + "type": "string", + "description": "Description of the certificate" + }, + "certificate_content": { + "type": "string", + "description": "PEM encoded certificate content" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "02b279b1-f0a8-44cc-bbd2-85bef5d73948", + "created": "2026-08-28T15:12:56.338Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 44, + "reference": "acfaa619-77ee-45e8-9e96-a3ed6dd743c0", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Patch Staging Device", + "description": "Patch Staging Device", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "PatchStagingDevice", + "canvasName": "PatchStagingDevice", + "summary": "PatchStagingDevice", + "description": "PatchStagingDevice", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "staging_device_id": "$var.job.staging_device_id", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "staging_device_id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Partial device update - only include fields you want to update.", + "properties": { + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string" + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "retention": { + "type": "string", + "pattern": "^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$", + "description": "ISO 8601 duration (e.g., P1Y for 1 year, P30D for 30 days).Supported units are Y (years), M (months), D (days), H (hours), M (minutes), S (seconds). Internally converted and rounded up to whole days. Maximum allowed retention is 1 year (P1Y)." + }, + "collection_interval": { + "type": "integer", + "minimum": 1 + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean" + }, + "ca": { + "type": "string", + "format": "uuid" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean" + }, + "cgnat": { + "type": "boolean" + }, + "dns": { + "type": "boolean" + }, + "dos": { + "type": "boolean" + }, + "firewall": { + "type": "boolean" + }, + "gtm": { + "type": "boolean" + }, + "profile_dos": { + "type": "boolean" + }, + "policy_api_protection": { + "type": "boolean" + }, + "policy_asm": { + "type": "boolean" + }, + "policy_firewall": { + "type": "boolean" + }, + "policy_ip_intelligence": { + "type": "boolean" + }, + "policy_nat": { + "type": "boolean" + } + } + } + } + } + }, + "required": [ + "staging_device_id", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "staging_device_id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Partial device update - only include fields you want to update.", + "properties": { + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string" + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "retention": { + "type": "string", + "pattern": "^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$", + "description": "ISO 8601 duration (e.g., P1Y for 1 year, P30D for 30 days).Supported units are Y (years), M (months), D (days), H (hours), M (minutes), S (seconds). Internally converted and rounded up to whole days. Maximum allowed retention is 1 year (P1Y)." + }, + "collection_interval": { + "type": "integer", + "minimum": 1 + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean" + }, + "ca": { + "type": "string", + "format": "uuid" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean" + }, + "cgnat": { + "type": "boolean" + }, + "dns": { + "type": "boolean" + }, + "dos": { + "type": "boolean" + }, + "firewall": { + "type": "boolean" + }, + "gtm": { + "type": "boolean" + }, + "profile_dos": { + "type": "boolean" + }, + "policy_api_protection": { + "type": "boolean" + }, + "policy_asm": { + "type": "boolean" + }, + "policy_firewall": { + "type": "boolean" + }, + "policy_ip_intelligence": { + "type": "boolean" + }, + "policy_nat": { + "type": "boolean" + } + } + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "7d5f17ba-25d6-4b13-b832-4ab94132d08b", + "created": "2026-08-28T15:12:56.399Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 45, + "reference": "ca5d8463-2cf0-4a7b-810d-0fda7d742830", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Refresh Device", + "description": "Refresh Device", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "RefreshDevice", + "canvasName": "RefreshDevice", + "summary": "RefreshDevice", + "description": "RefreshDevice", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "434acccf-8dc5-4455-81e5-b4c793a2e1e7", + "created": "2026-08-28T15:12:56.664Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 46, + "reference": "b1720dd6-099d-4719-9d98-10f0783fc361", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Release IP Pool Address", + "description": "Release IP Pool Address", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "postIpPoolsPoolIdRelease", + "canvasName": "postIpPoolsPoolIdRelease", + "summary": "postIpPoolsPoolIdRelease", + "description": "postIpPoolsPoolIdRelease", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "At least one criterion must be supplied (allocationId, address, or leaseTags). When leaseTags are used as a release filter, each tag must include a non-empty name and value.", + "properties": { + "allocationId": { + "type": "string", + "nullable": true + }, + "address": { + "type": "string", + "nullable": true, + "example": "10.0.0.10" + }, + "leaseTags": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "Tag name. Duplicate names and special characters are allowed." + }, + "value": { + "type": "string", + "nullable": true + } + }, + "required": [ + "name" + ] + } + } + }, + "anyOf": [ + { + "required": [ + "allocationId" + ] + }, + { + "required": [ + "address" + ] + }, + { + "required": [ + "leaseTags" + ] + } + ] + } + }, + "required": [ + "poolId", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "At least one criterion must be supplied (allocationId, address, or leaseTags). When leaseTags are used as a release filter, each tag must include a non-empty name and value.", + "properties": { + "allocationId": { + "type": "string", + "nullable": true + }, + "address": { + "type": "string", + "nullable": true, + "example": "10.0.0.10" + }, + "leaseTags": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "Tag name. Duplicate names and special characters are allowed." + }, + "value": { + "type": "string", + "nullable": true + } + }, + "required": [ + "name" + ] + } + } + }, + "anyOf": [ + { + "required": [ + "allocationId" + ] + }, + { + "required": [ + "address" + ] + }, + { + "required": [ + "leaseTags" + ] + } + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "16dd37b7-cdf1-44ab-9b99-66d3fc5e12f7", + "created": "2026-08-28T15:12:58.401Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 47, + "reference": "f4cf85fb-d69a-4c39-8192-48d5486ffe69", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Release IP Pool Lease By Address", + "description": "Release IP Pool Lease By Address", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "postRelease", + "canvasName": "postRelease", + "summary": "postRelease", + "description": "postRelease", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Release IPs across all pools by allocation ID and optional lease tags. Allocation ID is required.", + "properties": { + "allocationId": { + "type": "string", + "description": "Identifier of the allocation to release. This field is required and used to search across all pools." + }, + "leaseTags": { + "type": "array", + "description": "Optional labels to further filter leases. When provided, all tags must match (AND logic) for a lease to be released.", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "Tag name. Duplicate names and special characters are allowed." + }, + "value": { + "type": "string", + "nullable": true + } + }, + "required": [ + "name" + ] + } + } + }, + "required": [ + "allocationId" + ] + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Release IPs across all pools by allocation ID and optional lease tags. Allocation ID is required.", + "properties": { + "allocationId": { + "type": "string", + "description": "Identifier of the allocation to release. This field is required and used to search across all pools." + }, + "leaseTags": { + "type": "array", + "description": "Optional labels to further filter leases. When provided, all tags must match (AND logic) for a lease to be released.", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "Tag name. Duplicate names and special characters are allowed." + }, + "value": { + "type": "string", + "nullable": true + } + }, + "required": [ + "name" + ] + } + } + }, + "required": [ + "allocationId" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "475ac647-e06a-4810-b8fc-d0c7fc345ae9", + "created": "2026-08-28T15:12:58.183Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 48, + "reference": "4b20e80f-e0ad-4fe6-9af0-cdba5ee318b3", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Retry Failed Migration Devices", + "description": "Retry Failed Migration Devices", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "RetryFailedMigrationDevices", + "canvasName": "RetryFailedMigrationDevices", + "summary": "RetryFailedMigrationDevices", + "description": "RetryFailedMigrationDevices", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "task_id": "$var.job.task_id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "task_id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "d6e01521-ec65-4497-ac55-82683a86f871", + "created": "2026-08-28T15:12:56.310Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 49, + "reference": "b213db78-c56c-4414-8d1f-d06c99b8deb9", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Update IP Pool", + "description": "Update IP Pool", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "putIpPoolsPoolId", + "canvasName": "putIpPoolsPoolId", + "summary": "putIpPoolsPoolId", + "description": "putIpPoolsPoolId", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z_][a-zA-Z0-9_.\\-]*$", + "description": "Pool name. Rules:\n- Minimum length: 1 character\n- Maximum length: 255 characters\n- First character must be a letter (a-z, A-Z) or underscore (_)\n- Remaining characters may be letters, digits, hyphens (-), underscores (_), or dots (.)\n- The following reserved words are not allowed: all, delete, disable, enable, help, list, none, show, None\n" + }, + "description": { + "type": "string" + }, + "addressFamily": { + "type": "string", + "enum": [ + "IPv4", + "IPv6" + ], + "description": "Address family of the pool. When omitted, it is inferred from the CIDR (IPv4 or IPv6)." + }, + "address": { + "type": "string", + "example": "10.0.0.0/24" + }, + "gateway": { + "type": "string", + "nullable": true + }, + "addressRanges": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "firstAddress": { + "type": "string", + "example": "10.0.0.10" + }, + "lastAddress": { + "type": "string", + "example": "10.0.0.100" + } + }, + "required": [ + "firstAddress", + "lastAddress" + ] + } + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Should match the path parameter; the server overwrites mismatched values." + } + }, + "required": [ + "name", + "address", + "addressRanges" + ] + } + }, + "required": [ + "poolId", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z_][a-zA-Z0-9_.\\-]*$", + "description": "Pool name. Rules:\n- Minimum length: 1 character\n- Maximum length: 255 characters\n- First character must be a letter (a-z, A-Z) or underscore (_)\n- Remaining characters may be letters, digits, hyphens (-), underscores (_), or dots (.)\n- The following reserved words are not allowed: all, delete, disable, enable, help, list, none, show, None\n" + }, + "description": { + "type": "string" + }, + "addressFamily": { + "type": "string", + "enum": [ + "IPv4", + "IPv6" + ], + "description": "Address family of the pool. When omitted, it is inferred from the CIDR (IPv4 or IPv6)." + }, + "address": { + "type": "string", + "example": "10.0.0.0/24" + }, + "gateway": { + "type": "string", + "nullable": true + }, + "addressRanges": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "firstAddress": { + "type": "string", + "example": "10.0.0.10" + }, + "lastAddress": { + "type": "string", + "example": "10.0.0.100" + } + }, + "required": [ + "firstAddress", + "lastAddress" + ] + } + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Should match the path parameter; the server overwrites mismatched values." + } + }, + "required": [ + "name", + "address", + "addressRanges" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "78d0f65e-b97b-41ee-8013-b7265806de14", + "created": "2026-08-28T15:12:58.246Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 50, + "reference": "8354db70-d73a-4465-91fb-f9360594e9df", + "type": "workflow", + "folder": "/Device Management", + "document": { + "name": "Validate Device Connection", + "description": "Validate Device Connection", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "ValidateDeviceConnection", + "canvasName": "ValidateDeviceConnection", + "summary": "ValidateDeviceConnection", + "description": "ValidateDeviceConnection", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "properties": { + "retention": { + "type": "string", + "pattern": "^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$", + "description": "ISO 8601 duration (e.g., P1Y for 1 year, P30D for 30 days).Supported units are Y (years), M (months), D (days), H (hours), M (minutes), S (seconds). Internally converted and rounded up to whole days. Maximum allowed retention is 1 year (P1Y)." + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "collection_interval": { + "type": "integer", + "minimum": 1, + "description": "Collection interval in seconds" + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean", + "default": false + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from trust store" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean", + "default": false + }, + "cgnat": { + "type": "boolean", + "default": false + }, + "dns": { + "type": "boolean", + "default": false + }, + "dos": { + "type": "boolean", + "default": false + }, + "firewall": { + "type": "boolean", + "default": false + }, + "gtm": { + "type": "boolean", + "default": false + }, + "policy_api_protection": { + "type": "boolean", + "default": false + }, + "policy_asm": { + "type": "boolean", + "default": false + }, + "policy_firewall": { + "type": "boolean", + "default": false + }, + "policy_ip_intelligence": { + "type": "boolean", + "default": false + }, + "policy_nat": { + "type": "boolean", + "default": false + }, + "profile_dos": { + "type": "boolean", + "default": false + } + } + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the device" + }, + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string", + "description": "Device endpoint in format ip:port or hostname:port (e.g., 192.168.1.100:443, bigip.example.com:8443)." + } + }, + "required": [ + "username", + "password", + "data_center", + "endpoint" + ] + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "properties": { + "retention": { + "type": "string", + "pattern": "^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$", + "description": "ISO 8601 duration (e.g., P1Y for 1 year, P30D for 30 days).Supported units are Y (years), M (months), D (days), H (hours), M (minutes), S (seconds). Internally converted and rounded up to whole days. Maximum allowed retention is 1 year (P1Y)." + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "collection_interval": { + "type": "integer", + "minimum": 1, + "description": "Collection interval in seconds" + }, + "max_concurrent_connections": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "Maximum concurrent HTTP connections per device" + }, + "tls_enabled": { + "type": "boolean", + "default": false + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "CA certificate UUID from trust store" + }, + "modules": { + "type": "object", + "properties": { + "apm": { + "type": "boolean", + "default": false + }, + "cgnat": { + "type": "boolean", + "default": false + }, + "dns": { + "type": "boolean", + "default": false + }, + "dos": { + "type": "boolean", + "default": false + }, + "firewall": { + "type": "boolean", + "default": false + }, + "gtm": { + "type": "boolean", + "default": false + }, + "policy_api_protection": { + "type": "boolean", + "default": false + }, + "policy_asm": { + "type": "boolean", + "default": false + }, + "policy_firewall": { + "type": "boolean", + "default": false + }, + "policy_ip_intelligence": { + "type": "boolean", + "default": false + }, + "policy_nat": { + "type": "boolean", + "default": false + }, + "profile_dos": { + "type": "boolean", + "default": false + } + } + }, + "id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the device" + }, + "alias_name": { + "type": "string", + "maxLength": 100 + }, + "description": { + "type": "string", + "maxLength": 500 + }, + "username": { + "type": "string", + "maxLength": 255 + }, + "password": { + "type": "string", + "maxLength": 255 + }, + "data_center": { + "type": "string", + "maxLength": 255 + }, + "endpoint": { + "type": "string", + "description": "Device endpoint in format ip:port or hostname:port (e.g., 192.168.1.100:443, bigip.example.com:8443)." + } + }, + "required": [ + "username", + "password", + "data_center", + "endpoint" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "2d7c8a49-55b1-423d-a3bb-71016eef2103", + "created": "2026-08-28T15:12:56.067Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 51, + "reference": "f65d69c5-651b-464b-be94-683e81cf3511", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Activate License", + "description": "Activate License", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "activateLicense", + "canvasName": "activateLicense", + "summary": "activateLicense", + "description": "activateLicense", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "jwt", + "modeOfOperation" + ], + "properties": { + "jwt": { + "type": "string", + "description": "JWT token for license activation", + "example": "your-jwt-token" + }, + "customId": { + "type": "string", + "description": "Optional custom identifier for the device" + }, + "modeOfOperation": { + "type": "string", + "description": "Mode of operation for license activation", + "enum": [ + "connected", + "disconnected" + ], + "example": "connected" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "jwt", + "modeOfOperation" + ], + "properties": { + "jwt": { + "type": "string", + "description": "JWT token for license activation", + "example": "your-jwt-token" + }, + "customId": { + "type": "string", + "description": "Optional custom identifier for the device" + }, + "modeOfOperation": { + "type": "string", + "description": "Mode of operation for license activation", + "enum": [ + "connected", + "disconnected" + ], + "example": "connected" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e3797daf-4974-4c85-a845-aa1797696328", + "created": "2026-08-28T15:12:56.811Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 52, + "reference": "c5fce38f-1576-4203-aace-2bdbeae3c191", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Add License Offering", + "description": "Add License Offering", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "addLicenseOffering", + "canvasName": "addLicenseOffering", + "summary": "addLicenseOffering", + "description": "addLicenseOffering", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "required": [ + "regKey", + "status" + ], + "properties": { + "regKey": { + "type": "string", + "description": "F5 registration key", + "example": "U5939-99933-49705-74523-4841009" + }, + "status": { + "type": "string", + "enum": [ + "ACTIVATING_AUTOMATIC", + "ACTIVATING_MANUAL" + ], + "description": "Activation mode to use when adding the offering. ACTIVATING_AUTOMATIC - contacts F5 license server automatically. ACTIVATING_MANUAL - begins manual activation flow.\n", + "example": "ACTIVATING_AUTOMATIC" + }, + "name": { + "type": "string", + "description": "Optional name for the license offering", + "example": "" + }, + "description": { + "type": "string", + "description": "Optional description for the license offering", + "example": "" + } + } + } + }, + "required": [ + "poolId", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "required": [ + "regKey", + "status" + ], + "properties": { + "regKey": { + "type": "string", + "description": "F5 registration key", + "example": "U5939-99933-49705-74523-4841009" + }, + "status": { + "type": "string", + "enum": [ + "ACTIVATING_AUTOMATIC", + "ACTIVATING_MANUAL" + ], + "description": "Activation mode to use when adding the offering. ACTIVATING_AUTOMATIC - contacts F5 license server automatically. ACTIVATING_MANUAL - begins manual activation flow.\n", + "example": "ACTIVATING_AUTOMATIC" + }, + "name": { + "type": "string", + "description": "Optional name for the license offering", + "example": "" + }, + "description": { + "type": "string", + "description": "Optional description for the license offering", + "example": "" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "7bdc3efa-7923-48aa-bfec-4ce8c2f8909c", + "created": "2026-08-28T15:12:58.645Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 53, + "reference": "930bd73e-07f0-4c26-af47-4d3807848b3d", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Assign License Member", + "description": "Assign License Member", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "assignLicenseMember", + "canvasName": "assignLicenseMember", + "summary": "assignLicenseMember", + "description": "assignLicenseMember", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId", + "regKey": "$var.job.regKey", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "regKey": { + "type": "string" + }, + "spec": { + "type": "object", + "required": [ + "deviceAddress", + "deviceUsername", + "devicePassword" + ], + "properties": { + "deviceAddress": { + "type": "string", + "format": "ipv4", + "description": "IP address of the BIG-IP device", + "example": "192.168.1.100" + }, + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + } + }, + "required": [ + "poolId", + "regKey", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "regKey": { + "type": "string" + }, + "spec": { + "type": "object", + "required": [ + "deviceAddress", + "deviceUsername", + "devicePassword" + ], + "properties": { + "deviceAddress": { + "type": "string", + "format": "ipv4", + "description": "IP address of the BIG-IP device", + "example": "192.168.1.100" + }, + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "27453379-8f2b-4c66-95fc-e07fd7ffe5a5", + "created": "2026-08-28T15:12:58.790Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 54, + "reference": "21c36734-a61b-4c55-9697-b754d639dd76", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Assign Pool License", + "description": "Assign Pool License", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "assignPoolLicense", + "canvasName": "assignPoolLicense", + "summary": "assignPoolLicense", + "description": "assignPoolLicense", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Request body for pool-level license operations (assign, reactivate, revoke)", + "required": [ + "deviceAddress", + "deviceUsername", + "devicePassword" + ], + "properties": { + "deviceAddress": { + "type": "string", + "format": "ipv4", + "description": "IP address of the BIG-IP device", + "example": "192.168.1.100" + }, + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + } + }, + "required": [ + "poolId", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Request body for pool-level license operations (assign, reactivate, revoke)", + "required": [ + "deviceAddress", + "deviceUsername", + "devicePassword" + ], + "properties": { + "deviceAddress": { + "type": "string", + "format": "ipv4", + "description": "IP address of the BIG-IP device", + "example": "192.168.1.100" + }, + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "1b431e9d-0640-423c-8f07-227f4b70a7ec", + "created": "2026-08-28T15:12:58.613Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 55, + "reference": "d5f13f1a-6cf7-4db9-815c-f91677b44a81", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Create License Pool", + "description": "Create License Pool", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "createLicensePool", + "canvasName": "createLicensePool", + "summary": "createLicensePool", + "description": "createLicensePool", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the license pool", + "example": "test" + }, + "description": { + "type": "string", + "description": "Description of the license pool", + "example": "" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the license pool", + "example": "test" + }, + "description": { + "type": "string", + "description": "Description of the license pool", + "example": "" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "caab9c2f-14bf-485f-bcd8-3ba35f8f3996", + "created": "2026-08-28T15:12:58.521Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 56, + "reference": "172aed20-d66f-4a0e-a6ba-2dab48bf7554", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Deactivate License", + "description": "Deactivate License", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deactivateLicense", + "canvasName": "deactivateLicense", + "summary": "deactivateLicense", + "description": "deactivateLicense", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "ff9179d1-c055-48f8-920c-58f13da5697c", + "created": "2026-08-28T15:12:56.844Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 57, + "reference": "e03af3bb-0a16-471a-b3bd-314845f5f3e7", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Delete License Offering", + "description": "Delete License Offering", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteLicenseOffering", + "canvasName": "deleteLicenseOffering", + "summary": "deleteLicenseOffering", + "description": "deleteLicenseOffering", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId", + "regKey": "$var.job.regKey" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "regKey": { + "type": "string" + } + }, + "required": [ + "poolId", + "regKey" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "regKey": { + "type": "string" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "7fbfac59-db5f-4ef9-a640-8093214b742f", + "created": "2026-08-28T15:12:58.762Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 58, + "reference": "2269e583-4eaa-4e94-a6cc-ffc7fbf7b550", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Delete License Pool", + "description": "Delete License Pool", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteLicensePool", + "canvasName": "deleteLicensePool", + "summary": "deleteLicensePool", + "description": "deleteLicensePool", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "poolId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "2cfaa427-4005-4e27-b0fa-a58c4b125cb1", + "created": "2026-08-28T15:12:58.585Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 59, + "reference": "3827947d-97c6-49a0-a675-1f33bd41928c", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Download Report", + "description": "Download Report", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "downloadReport", + "canvasName": "downloadReport", + "summary": "downloadReport", + "description": "downloadReport", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "cdefceb6-59e8-4040-b163-0360650e1d4b", + "created": "2026-08-28T15:12:56.949Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 60, + "reference": "a1a24901-1320-49c6-93b1-9f07896c15c5", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Get License Entitlements", + "description": "Get License Entitlements", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getLicenseEntitlements", + "canvasName": "getLicenseEntitlements", + "summary": "getLicenseEntitlements", + "description": "getLicenseEntitlements", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "fcae7c15-06f1-42d4-b332-01993f2d675c", + "created": "2026-08-28T15:12:56.874Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 61, + "reference": "d3992cc1-54c7-4f78-8c69-e300a8c377b1", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Get License Health", + "description": "Get License Health", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getLicenseHealth", + "canvasName": "getLicenseHealth", + "summary": "getLicenseHealth", + "description": "getLicenseHealth", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "003b7840-99ce-479e-bc72-60a94963cfc5", + "created": "2026-08-28T15:12:56.901Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 62, + "reference": "b4de6f8b-d795-44b3-8102-a1d6dec44382", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Get License Members", + "description": "Get License Members", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getLicenseMembers", + "canvasName": "getLicenseMembers", + "summary": "getLicenseMembers", + "description": "getLicenseMembers", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId", + "regKey": "$var.job.regKey" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "regKey": { + "type": "string" + } + }, + "required": [ + "poolId", + "regKey" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "regKey": { + "type": "string" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "664fd592-48e6-4046-b1a5-a1f8f170a381", + "created": "2026-08-28T15:12:58.822Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 63, + "reference": "fa7295f9-9bc4-49c2-8272-d3cf7b6b6098", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Get License Offering", + "description": "Get License Offering", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getLicenseOffering", + "canvasName": "getLicenseOffering", + "summary": "getLicenseOffering", + "description": "getLicenseOffering", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId", + "regKey": "$var.job.regKey" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "regKey": { + "type": "string" + } + }, + "required": [ + "poolId", + "regKey" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "regKey": { + "type": "string" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "88e7dc98-5afe-47ed-a2bd-20f5d518e743", + "created": "2026-08-28T15:12:58.703Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 64, + "reference": "ceabb6a5-32a1-429d-816e-c93112328ef9", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Get License Offerings", + "description": "Get License Offerings", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getLicenseOfferings", + "canvasName": "getLicenseOfferings", + "summary": "getLicenseOfferings", + "description": "getLicenseOfferings", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId", + "$select": "$var.job.$select", + "$filter": "$var.job.$filter" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "": { + "type": [ + "array", + "boolean", + "null", + "number", + "object", + "string" + ] + } + }, + "required": [ + "poolId", + "" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "": { + "type": [ + "array", + "boolean", + "null", + "number", + "object", + "string" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "d82ead54-8b0d-49f3-9e22-70d65878a0e6", + "created": "2026-08-28T15:12:58.674Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 65, + "reference": "62da79ee-35c8-48b2-bc1c-380f1ae55864", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Get License Pool", + "description": "Get License Pool", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getLicensePool", + "canvasName": "getLicensePool", + "summary": "getLicensePool", + "description": "getLicensePool", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "poolId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "359719dc-b530-41ae-acc5-536658673746", + "created": "2026-08-28T15:12:58.554Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 66, + "reference": "126c1f0d-f01a-4950-b5e3-b909142535cd", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Get License Pools", + "description": "Get License Pools", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getLicensePools", + "canvasName": "getLicensePools", + "summary": "getLicensePools", + "description": "getLicensePools", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "$select": "$var.job.$select" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "": { + "type": [ + "array", + "boolean", + "null", + "number", + "object", + "string" + ] + } + }, + "required": [ + "" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "": { + "type": [ + "array", + "boolean", + "null", + "number", + "object", + "string" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "68b8ac12-4b6c-472a-92dd-c00a18636b5c", + "created": "2026-08-28T15:12:58.494Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 67, + "reference": "a55822f1-547f-4385-8d48-ba1025c37398", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Reactivate License Member", + "description": "Reactivate License Member", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "reactivateLicenseMember", + "canvasName": "reactivateLicenseMember", + "summary": "reactivateLicenseMember", + "description": "reactivateLicenseMember", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId", + "regKey": "$var.job.regKey", + "memberId": "$var.job.memberId", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "regKey": { + "type": "string" + }, + "memberId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "properties": { + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + } + }, + "required": [ + "poolId", + "regKey", + "memberId", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "regKey": { + "type": "string" + }, + "memberId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "properties": { + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "ef6bb41e-f032-4782-b868-ce7d8a65e2e3", + "created": "2026-08-28T15:12:58.880Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 68, + "reference": "54c21281-8893-4802-b518-9a84e3bead37", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Revoke License Member", + "description": "Revoke License Member", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "revokeLicenseMember", + "canvasName": "revokeLicenseMember", + "summary": "revokeLicenseMember", + "description": "revokeLicenseMember", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId", + "regKey": "$var.job.regKey", + "memberId": "$var.job.memberId", + "force": "$var.job.force", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "regKey": { + "type": "string" + }, + "memberId": { + "type": "string", + "format": "uuid" + }, + "force": { + "type": "boolean", + "default": false + }, + "spec": { + "type": "object", + "required": [ + "deviceUsername", + "devicePassword" + ], + "properties": { + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + } + }, + "required": [ + "poolId", + "regKey", + "memberId", + "force", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "regKey": { + "type": "string" + }, + "memberId": { + "type": "string", + "format": "uuid" + }, + "force": { + "type": "boolean", + "default": false + }, + "spec": { + "type": "object", + "required": [ + "deviceUsername", + "devicePassword" + ], + "properties": { + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "7ac947b6-fd6f-4927-94c0-53e1d494195a", + "created": "2026-08-28T15:12:58.852Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 69, + "reference": "4ce715f5-88bd-4825-8341-dd992abb5bf0", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Revoke Pool License", + "description": "Revoke Pool License", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "revokePoolLicense", + "canvasName": "revokePoolLicense", + "summary": "revokePoolLicense", + "description": "revokePoolLicense", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId", + "force": "$var.job.force", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "force": { + "type": "boolean", + "default": false + }, + "spec": { + "type": "object", + "description": "Request body for pool-level license operations (assign, reactivate, revoke)", + "required": [ + "deviceAddress", + "deviceUsername", + "devicePassword" + ], + "properties": { + "deviceAddress": { + "type": "string", + "format": "ipv4", + "description": "IP address of the BIG-IP device", + "example": "192.168.1.100" + }, + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + } + }, + "required": [ + "poolId", + "force", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "force": { + "type": "boolean", + "default": false + }, + "spec": { + "type": "object", + "description": "Request body for pool-level license operations (assign, reactivate, revoke)", + "required": [ + "deviceAddress", + "deviceUsername", + "devicePassword" + ], + "properties": { + "deviceAddress": { + "type": "string", + "format": "ipv4", + "description": "IP address of the BIG-IP device", + "example": "192.168.1.100" + }, + "deviceUsername": { + "type": "string", + "description": "Username for BIG-IP device authentication", + "example": "admin" + }, + "devicePassword": { + "type": "string", + "description": "Password for BIG-IP device authentication", + "example": "admin" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e66d42d1-9798-4ccb-8759-dd07a3455c29", + "created": "2026-08-28T15:12:58.913Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 70, + "reference": "b966c2b3-12dc-452c-aab9-d62e20d21815", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Update License Offering", + "description": "Update License Offering", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "updateLicenseOffering", + "canvasName": "updateLicenseOffering", + "summary": "updateLicenseOffering", + "description": "updateLicenseOffering", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "poolId": "$var.job.poolId", + "regKey": "$var.job.regKey", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "regKey": { + "type": "string" + }, + "spec": { + "type": "object", + "description": "Request to update or reactivate a license offering. The operation performed depends on the `status` field:\n\n- `ACTIVATING_AUTOMATIC`: Triggers automatic reactivation (async, returns 202 with TaskReference)\n- `ACTIVATING_MANUAL`: Triggers manual reactivation (sync, returns 200 with new dossier)\n- `ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED`: Completes manual activation with license text (sync, returns 200)\n", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "ACTIVATING_AUTOMATIC", + "ACTIVATING_MANUAL", + "ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED" + ], + "description": "The operation to perform:\n- `ACTIVATING_AUTOMATIC`: Trigger automatic reactivation via F5 license server (async)\n- `ACTIVATING_MANUAL`: Trigger manual reactivation, regenerates dossier (sync)\n- `ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED`: Complete manual activation with provided license text (sync)\n", + "example": "ACTIVATING_AUTOMATIC" + }, + "licenseText": { + "type": "string", + "description": "License text obtained from F5 license server. \n**Required** when status is `ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED`.\nThe user obtains this by submitting the dossier to the F5 license server UI.\n", + "example": "Auth vers : 5b\nRegistration key : W5778-33088-84412-26046-5913991\nLicensed date : 20260525\n..." + } + } + } + }, + "required": [ + "poolId", + "regKey", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "poolId": { + "type": "string", + "format": "uuid" + }, + "regKey": { + "type": "string" + }, + "spec": { + "type": "object", + "description": "Request to update or reactivate a license offering. The operation performed depends on the `status` field:\n\n- `ACTIVATING_AUTOMATIC`: Triggers automatic reactivation (async, returns 202 with TaskReference)\n- `ACTIVATING_MANUAL`: Triggers manual reactivation (sync, returns 200 with new dossier)\n- `ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED`: Completes manual activation with license text (sync, returns 200)\n", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "ACTIVATING_AUTOMATIC", + "ACTIVATING_MANUAL", + "ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED" + ], + "description": "The operation to perform:\n- `ACTIVATING_AUTOMATIC`: Trigger automatic reactivation via F5 license server (async)\n- `ACTIVATING_MANUAL`: Trigger manual reactivation, regenerates dossier (sync)\n- `ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED`: Complete manual activation with provided license text (sync)\n", + "example": "ACTIVATING_AUTOMATIC" + }, + "licenseText": { + "type": "string", + "description": "License text obtained from F5 license server. \n**Required** when status is `ACTIVATING_MANUAL_LICENSE_TEXT_PROVIDED`.\nThe user obtains this by submitting the dossier to the F5 license server UI.\n", + "example": "Auth vers : 5b\nRegistration key : W5778-33088-84412-26046-5913991\nLicensed date : 20260525\n..." + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "68416edd-bf25-4d5c-a05c-4a5fae582de5", + "created": "2026-08-28T15:12:58.734Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 71, + "reference": "dd2e97ab-576f-4f47-b66d-de4b984d8aa9", + "type": "workflow", + "folder": "/Licensing", + "document": { + "name": "Verify Report", + "description": "Verify Report", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "verifyReport", + "canvasName": "verifyReport", + "summary": "verifyReport", + "description": "verifyReport", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "manifest" + ], + "properties": { + "manifest": { + "type": "string", + "description": "Base64 encoded signed report acknowledgment from F5 TEEM", + "example": "eyJzaWduZWRBY2siOiJ0ZXN0In0=" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "manifest" + ], + "properties": { + "manifest": { + "type": "string", + "description": "Base64 encoded signed report acknowledgment from F5 TEEM", + "example": "eyJzaWduZWRBY2siOiJ0ZXN0In0=" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "ae8e3471-94f5-4ae9-b45e-33bca69eaf0d", + "created": "2026-08-28T15:12:56.992Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 72, + "reference": "3bae1c67-fe99-4db3-b643-1bf7a3acfd02", + "type": "workflow", + "folder": "/Infrastructure Discovery", + "document": { + "name": "Connect to vSphere", + "description": "Connect to vSphere", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "connectToVSphere", + "canvasName": "connectToVSphere", + "summary": "connectToVSphere", + "description": "connectToVSphere", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "username", + "password", + "providerName" + ], + "properties": { + "username": { + "type": "string", + "description": "vSphere username" + }, + "password": { + "type": "string", + "description": "vSphere password" + }, + "providerName": { + "type": "string", + "description": "Name of the provider (used to resolve vSphere hostname)" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "username", + "password", + "providerName" + ], + "properties": { + "username": { + "type": "string", + "description": "vSphere username" + }, + "password": { + "type": "string", + "description": "vSphere password" + }, + "providerName": { + "type": "string", + "description": "Name of the provider (used to resolve vSphere hostname)" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "325c1d89-5d75-4793-99dd-d1a92e19e082", + "created": "2026-08-28T15:12:57.052Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 73, + "reference": "e752584e-c391-4c7b-b034-39808bd545d2", + "type": "workflow", + "folder": "/Infrastructure Discovery", + "document": { + "name": "F5 Insight List Networks", + "description": "F5 Insight List Networks", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listNetworks", + "canvasName": "listNetworks", + "summary": "listNetworks", + "description": "listNetworks", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "connId": "$var.job.connId", + "datacenter": "$var.job.datacenter" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "connId": { + "type": "string" + }, + "datacenter": { + "type": "string" + } + }, + "required": [ + "connId", + "datacenter" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "connId": { + "type": "string" + }, + "datacenter": { + "type": "string" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "82f48057-0fd2-40bd-9c2b-258d472edbe4", + "created": "2026-08-28T15:12:57.325Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 74, + "reference": "9a6a5453-c8d0-4c97-876e-56ee056ec7a3", + "type": "workflow", + "folder": "/Infrastructure Discovery", + "document": { + "name": "List Clusters", + "description": "List Clusters", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listClusters", + "canvasName": "listClusters", + "summary": "listClusters", + "description": "listClusters", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "connId": "$var.job.connId", + "datacenter": "$var.job.datacenter" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "connId": { + "type": "string" + }, + "datacenter": { + "type": "string" + } + }, + "required": [ + "connId", + "datacenter" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "connId": { + "type": "string" + }, + "datacenter": { + "type": "string" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "df430db8-4a86-4781-9eea-86bc62a00c09", + "created": "2026-08-28T15:12:57.022Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 75, + "reference": "f3f54f16-f9a0-4b5a-ac0a-2372163adf10", + "type": "workflow", + "folder": "/Infrastructure Discovery", + "document": { + "name": "List Datacenters", + "description": "List Datacenters", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listDatacenters", + "canvasName": "listDatacenters", + "summary": "listDatacenters", + "description": "listDatacenters", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "connId": "$var.job.connId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "connId": { + "type": "string" + } + }, + "required": [ + "connId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "connId": { + "type": "string" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "ce8122f0-eceb-4d2f-be0d-62b6cf9e26aa", + "created": "2026-08-28T15:12:57.083Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 76, + "reference": "28a74995-90c0-4e91-bb9a-1e61b9189a77", + "type": "workflow", + "folder": "/Infrastructure Discovery", + "document": { + "name": "List Datastores", + "description": "List Datastores", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listDatastores", + "canvasName": "listDatastores", + "summary": "listDatastores", + "description": "listDatastores", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "connId": "$var.job.connId", + "datacenter": "$var.job.datacenter" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "connId": { + "type": "string" + }, + "datacenter": { + "type": "string" + } + }, + "required": [ + "connId", + "datacenter" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "connId": { + "type": "string" + }, + "datacenter": { + "type": "string" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "a6a4bc16-db4d-4b18-8afc-d699e69803bd", + "created": "2026-08-28T15:12:57.116Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 77, + "reference": "6a42a83a-d1ec-46d7-bb70-57f102b32de4", + "type": "workflow", + "folder": "/Infrastructure Discovery", + "document": { + "name": "List Hosts", + "description": "List Hosts", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listHosts", + "canvasName": "listHosts", + "summary": "listHosts", + "description": "listHosts", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "connId": "$var.job.connId", + "datacenter": "$var.job.datacenter", + "cluster": "$var.job.cluster" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "connId": { + "type": "string" + }, + "datacenter": { + "type": "string" + }, + "cluster": { + "type": "string" + } + }, + "required": [ + "connId", + "datacenter", + "cluster" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "connId": { + "type": "string" + }, + "datacenter": { + "type": "string" + }, + "cluster": { + "type": "string" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "4f4d4dc8-f259-4a8a-b3ef-c6ef1e6b604f", + "created": "2026-08-28T15:12:57.297Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 78, + "reference": "7303bbd2-0585-4af2-904f-bb153c341b47", + "type": "workflow", + "folder": "/Infrastructure Discovery", + "document": { + "name": "List VM Images", + "description": "List VM Images", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listVMImages", + "canvasName": "listVMImages", + "summary": "listVMImages", + "description": "listVMImages", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "connId": "$var.job.connId", + "datacenter": "$var.job.datacenter" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "connId": { + "type": "string" + }, + "datacenter": { + "type": "string" + } + }, + "required": [ + "connId", + "datacenter" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "connId": { + "type": "string" + }, + "datacenter": { + "type": "string" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "f3f8dafd-60f1-465f-91bf-796f1366862c", + "created": "2026-08-28T15:12:57.614Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 79, + "reference": "1dc386db-759f-48f2-a142-b937772e7661", + "type": "workflow", + "folder": "/Cloud Environments", + "document": { + "name": "Create Cloud Environment", + "description": "Create Cloud Environment", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "createCloudEnvironment", + "canvasName": "createCloudEnvironment", + "summary": "createCloudEnvironment", + "description": "createCloudEnvironment", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "name", + "providerReference", + "deviceTemplateReference", + "vmwProperties" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the cloud environment", + "minLength": 1, + "maxLength": 255 + }, + "providerReference": { + "type": "object", + "required": [ + "link" + ], + "properties": { + "link": { + "type": "string", + "format": "uri" + }, + "fullPath": { + "type": "string" + } + } + }, + "deviceTemplateReference": { + "type": "object", + "required": [ + "link" + ], + "properties": { + "link": { + "type": "string", + "format": "uri" + }, + "fullPath": { + "type": "string" + } + } + }, + "isVmwCluster": { + "type": "boolean", + "description": "Indicates if VMware cluster is being used", + "default": true + }, + "vmwProperties": { + "type": "object", + "required": [ + "cluster", + "datacenter", + "user", + "password", + "vmImage", + "networkInterfaceMapping" + ], + "properties": { + "cluster": { + "type": "string", + "description": "VMware cluster name" + }, + "datacenter": { + "type": "string", + "description": "VMware datacenter name" + }, + "user": { + "type": "string", + "description": "vCenter username (can include domain)" + }, + "password": { + "type": "string", + "format": "password", + "description": "vCenter password" + }, + "vmImage": { + "type": "string", + "description": "BIG-IP VM image template name" + }, + "networkInterfaceMapping": { + "type": "array", + "description": "Network interface mappings for VM deployment", + "minItems": 1, + "items": { + "type": "object", + "required": [ + "network" + ], + "properties": { + "network": { + "type": "string", + "description": "Network name in vCenter" + } + } + } + }, + "ipPoolAliasMapping": { + "type": "array", + "description": "IP pool alias mappings", + "items": { + "type": "object", + "required": [ + "alias", + "ipPoolReference" + ], + "properties": { + "alias": { + "type": "string", + "description": "Alias name" + }, + "ipPoolReference": { + "type": "string", + "description": "IP pool reference link" + } + } + } + } + } + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "name", + "providerReference", + "deviceTemplateReference", + "vmwProperties" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the cloud environment", + "minLength": 1, + "maxLength": 255 + }, + "providerReference": { + "type": "object", + "required": [ + "link" + ], + "properties": { + "link": { + "type": "string", + "format": "uri" + }, + "fullPath": { + "type": "string" + } + } + }, + "deviceTemplateReference": { + "type": "object", + "required": [ + "link" + ], + "properties": { + "link": { + "type": "string", + "format": "uri" + }, + "fullPath": { + "type": "string" + } + } + }, + "isVmwCluster": { + "type": "boolean", + "description": "Indicates if VMware cluster is being used", + "default": true + }, + "vmwProperties": { + "type": "object", + "required": [ + "cluster", + "datacenter", + "user", + "password", + "vmImage", + "networkInterfaceMapping" + ], + "properties": { + "cluster": { + "type": "string", + "description": "VMware cluster name" + }, + "datacenter": { + "type": "string", + "description": "VMware datacenter name" + }, + "user": { + "type": "string", + "description": "vCenter username (can include domain)" + }, + "password": { + "type": "string", + "format": "password", + "description": "vCenter password" + }, + "vmImage": { + "type": "string", + "description": "BIG-IP VM image template name" + }, + "networkInterfaceMapping": { + "type": "array", + "description": "Network interface mappings for VM deployment", + "minItems": 1, + "items": { + "type": "object", + "required": [ + "network" + ], + "properties": { + "network": { + "type": "string", + "description": "Network name in vCenter" + } + } + } + }, + "ipPoolAliasMapping": { + "type": "array", + "description": "IP pool alias mappings", + "items": { + "type": "object", + "required": [ + "alias", + "ipPoolReference" + ], + "properties": { + "alias": { + "type": "string", + "description": "Alias name" + }, + "ipPoolReference": { + "type": "string", + "description": "IP pool reference link" + } + } + } + } + } + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e3523ba1-5b64-400d-bcaf-056a4bfc23b1", + "created": "2026-08-28T15:12:57.174Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 80, + "reference": "c553bcd0-9c12-455e-bc36-c16cfb91b263", + "type": "workflow", + "folder": "/Cloud Environments", + "document": { + "name": "Delete Cloud Environment", + "description": "Delete Cloud Environment", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteCloudEnvironment", + "canvasName": "deleteCloudEnvironment", + "summary": "deleteCloudEnvironment", + "description": "deleteCloudEnvironment", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "environmentId": "$var.job.environmentId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "environmentId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "environmentId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "environmentId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "dfea6db0-4c47-4238-85f1-6257288d3e6e", + "created": "2026-08-28T15:12:57.266Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 81, + "reference": "761717ff-edf9-4cf7-83b7-cd8aef2f6886", + "type": "workflow", + "folder": "/Cloud Environments", + "document": { + "name": "Get Cloud Environment By ID", + "description": "Get Cloud Environment By ID", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getCloudEnvironmentByID", + "canvasName": "getCloudEnvironmentByID", + "summary": "getCloudEnvironmentByID", + "description": "getCloudEnvironmentByID", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "environmentId": "$var.job.environmentId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "environmentId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "environmentId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "environmentId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "dfeeee75-ca33-4713-bb60-d9e1af8857f4", + "created": "2026-08-28T15:12:57.209Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 82, + "reference": "e97754d5-b09d-491a-82f0-67bbb72916b9", + "type": "workflow", + "folder": "/Cloud Environments", + "document": { + "name": "Get Cloud Environments", + "description": "Get Cloud Environments", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getCloudEnvironments", + "canvasName": "getCloudEnvironments", + "summary": "getCloudEnvironments", + "description": "getCloudEnvironments", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "6b09e304-0162-4e23-b93e-121a4bde0223", + "created": "2026-08-28T15:12:57.143Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 83, + "reference": "69296107-642c-49a8-ba84-2365e60b1e54", + "type": "workflow", + "folder": "/Cloud Environments", + "document": { + "name": "Update Cloud Environment", + "description": "Update Cloud Environment", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "updateCloudEnvironment", + "canvasName": "updateCloudEnvironment", + "summary": "updateCloudEnvironment", + "description": "updateCloudEnvironment", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "environmentId": "$var.job.environmentId", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "environmentId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "isVmwCluster": { + "type": "boolean" + }, + "vmwProperties": { + "type": "object", + "required": [ + "cluster", + "datacenter", + "user", + "password", + "vmImage", + "networkInterfaceMapping" + ], + "properties": { + "cluster": { + "type": "string", + "description": "VMware cluster name" + }, + "datacenter": { + "type": "string", + "description": "VMware datacenter name" + }, + "user": { + "type": "string", + "description": "vCenter username (can include domain)" + }, + "password": { + "type": "string", + "format": "password", + "description": "vCenter password" + }, + "vmImage": { + "type": "string", + "description": "BIG-IP VM image template name" + }, + "networkInterfaceMapping": { + "type": "array", + "description": "Network interface mappings for VM deployment", + "minItems": 1, + "items": { + "type": "object", + "required": [ + "network" + ], + "properties": { + "network": { + "type": "string", + "description": "Network name in vCenter" + } + } + } + }, + "ipPoolAliasMapping": { + "type": "array", + "description": "IP pool alias mappings", + "items": { + "type": "object", + "required": [ + "alias", + "ipPoolReference" + ], + "properties": { + "alias": { + "type": "string", + "description": "Alias name" + }, + "ipPoolReference": { + "type": "string", + "description": "IP pool reference link" + } + } + } + } + } + } + } + } + }, + "required": [ + "environmentId", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "environmentId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "isVmwCluster": { + "type": "boolean" + }, + "vmwProperties": { + "type": "object", + "required": [ + "cluster", + "datacenter", + "user", + "password", + "vmImage", + "networkInterfaceMapping" + ], + "properties": { + "cluster": { + "type": "string", + "description": "VMware cluster name" + }, + "datacenter": { + "type": "string", + "description": "VMware datacenter name" + }, + "user": { + "type": "string", + "description": "vCenter username (can include domain)" + }, + "password": { + "type": "string", + "format": "password", + "description": "vCenter password" + }, + "vmImage": { + "type": "string", + "description": "BIG-IP VM image template name" + }, + "networkInterfaceMapping": { + "type": "array", + "description": "Network interface mappings for VM deployment", + "minItems": 1, + "items": { + "type": "object", + "required": [ + "network" + ], + "properties": { + "network": { + "type": "string", + "description": "Network name in vCenter" + } + } + } + }, + "ipPoolAliasMapping": { + "type": "array", + "description": "IP pool alias mappings", + "items": { + "type": "object", + "required": [ + "alias", + "ipPoolReference" + ], + "properties": { + "alias": { + "type": "string", + "description": "Alias name" + }, + "ipPoolReference": { + "type": "string", + "description": "IP pool reference link" + } + } + } + } + } + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "c18e6b4b-13c6-409c-aa33-62d94f05fc99", + "created": "2026-08-28T15:12:57.238Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 84, + "reference": "9f1f33c4-2338-4559-af84-b479f6e97f7e", + "type": "workflow", + "folder": "/Cloud Providers", + "document": { + "name": "Create Cloud Provider", + "description": "Create Cloud Provider", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "createCloudProvider", + "canvasName": "createCloudProvider", + "summary": "createCloudProvider", + "description": "createCloudProvider", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "providerType", + "name" + ], + "properties": { + "providerType": { + "type": "string", + "enum": [ + "VMware" + ], + "description": "Type of cloud provider" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "Name of the cloud provider" + }, + "vmwProperties": { + "type": "object", + "required": [ + "vCenterHostname" + ], + "properties": { + "vCenterHostname": { + "type": "string", + "format": "hostname", + "description": "Hostname or IP address of vCenter server" + } + } + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "providerType", + "name" + ], + "properties": { + "providerType": { + "type": "string", + "enum": [ + "VMware" + ], + "description": "Type of cloud provider" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "Name of the cloud provider" + }, + "vmwProperties": { + "type": "object", + "required": [ + "vCenterHostname" + ], + "properties": { + "vCenterHostname": { + "type": "string", + "format": "hostname", + "description": "Hostname or IP address of vCenter server" + } + } + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "ab5c1114-b270-4d40-ad10-aec2a635abda", + "created": "2026-08-28T15:12:57.382Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 85, + "reference": "c0ffe7ff-294a-4ad8-a101-abfbb59f2d3f", + "type": "workflow", + "folder": "/Cloud Providers", + "document": { + "name": "Delete Cloud Provider", + "description": "Delete Cloud Provider", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteCloudProvider", + "canvasName": "deleteCloudProvider", + "summary": "deleteCloudProvider", + "description": "deleteCloudProvider", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "providerId": "$var.job.providerId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "providerId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "providerId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "providerId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "7c489861-fb7a-49b1-9cc6-829a09cf414f", + "created": "2026-08-28T15:12:57.465Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 86, + "reference": "2023f46a-d485-4670-941c-631c904d7dd3", + "type": "workflow", + "folder": "/Cloud Providers", + "document": { + "name": "Get Cloud Provider", + "description": "Get Cloud Provider", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getCloudProvider", + "canvasName": "getCloudProvider", + "summary": "getCloudProvider", + "description": "getCloudProvider", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "providerId": "$var.job.providerId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "providerId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "providerId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "providerId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "eb916529-9516-4ec1-a348-12aa2e827a22", + "created": "2026-08-28T15:12:57.410Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 87, + "reference": "278910bb-ad8c-491f-bf45-7f485238b3d9", + "type": "workflow", + "folder": "/Cloud Providers", + "document": { + "name": "Get Cloud Providers", + "description": "Get Cloud Providers", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getCloudProviders", + "canvasName": "getCloudProviders", + "summary": "getCloudProviders", + "description": "getCloudProviders", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "1b506ae4-9e0b-4f92-bde8-d60a1f987d58", + "created": "2026-08-28T15:12:57.352Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 88, + "reference": "e2a3c61f-be39-4061-ab58-72be011f42ac", + "type": "workflow", + "folder": "/Cloud Providers", + "document": { + "name": "Update Cloud Provider", + "description": "Update Cloud Provider", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "updateCloudProvider", + "canvasName": "updateCloudProvider", + "summary": "updateCloudProvider", + "description": "updateCloudProvider", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "providerId": "$var.job.providerId", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "providerId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "Name of the cloud provider" + }, + "vmwProperties": { + "type": "object", + "required": [ + "vCenterHostname" + ], + "properties": { + "vCenterHostname": { + "type": "string", + "format": "hostname", + "description": "Hostname or IP address of vCenter server" + } + } + } + } + } + }, + "required": [ + "providerId", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "providerId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "Name of the cloud provider" + }, + "vmwProperties": { + "type": "object", + "required": [ + "vCenterHostname" + ], + "properties": { + "vCenterHostname": { + "type": "string", + "format": "hostname", + "description": "Hostname or IP address of vCenter server" + } + } + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "20690eb5-b4a0-49a7-ac36-08f11ae95e93", + "created": "2026-08-28T15:12:57.436Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 89, + "reference": "66b774d8-8536-40eb-b2f8-996072d962fa", + "type": "workflow", + "folder": "/VM Tasks", + "document": { + "name": "Create VM Task", + "description": "Create VM Task", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "createVMTask", + "canvasName": "createVMTask", + "summary": "createVMTask", + "description": "createVMTask", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "envReference" + ], + "properties": { + "envReference": { + "type": "string", + "description": "ID (UUID) or name of the cloud environment to use for this VM task.\n" + }, + "vmName": { + "type": "string", + "description": "For create-vm only: optional name for the created VM. If omitted,\na name is generated automatically using the configured naming\nprefix (default: \"autoscale-bigip-\"). Ignored by delete-vm.\n" + }, + "vmIP": { + "type": "string", + "description": "IP address of the VM. For delete-vm, either vmIP or vmUuid must be\nsupplied; vmIP takes precedence when both are present.\n" + }, + "vmUuid": { + "type": "string", + "description": "vCenter Managed Object Reference (MoRef) of the VM. For delete-vm,\neither vmIP or vmUuid must be supplied. Recommended for cleaning up\norphaned clones that never acquired an IP \u2014 the create-vm response\nreturns vmUuid as soon as the clone succeeds.\n" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "envReference" + ], + "properties": { + "envReference": { + "type": "string", + "description": "ID (UUID) or name of the cloud environment to use for this VM task.\n" + }, + "vmName": { + "type": "string", + "description": "For create-vm only: optional name for the created VM. If omitted,\na name is generated automatically using the configured naming\nprefix (default: \"autoscale-bigip-\"). Ignored by delete-vm.\n" + }, + "vmIP": { + "type": "string", + "description": "IP address of the VM. For delete-vm, either vmIP or vmUuid must be\nsupplied; vmIP takes precedence when both are present.\n" + }, + "vmUuid": { + "type": "string", + "description": "vCenter Managed Object Reference (MoRef) of the VM. For delete-vm,\neither vmIP or vmUuid must be supplied. Recommended for cleaning up\norphaned clones that never acquired an IP \u2014 the create-vm response\nreturns vmUuid as soon as the clone succeeds.\n" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "a0edb385-9702-4f46-8321-98b990f03f15", + "created": "2026-08-28T15:12:57.496Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 90, + "reference": "a47e170c-4ea2-4f54-9883-c5520984011e", + "type": "workflow", + "folder": "/VM Tasks", + "document": { + "name": "Delete VM Task", + "description": "Delete VM Task", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteVMTask", + "canvasName": "deleteVMTask", + "summary": "deleteVMTask", + "description": "deleteVMTask", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "envReference" + ], + "properties": { + "envReference": { + "type": "string", + "description": "ID (UUID) or name of the cloud environment to use for this VM task.\n" + }, + "vmName": { + "type": "string", + "description": "For create-vm only: optional name for the created VM. If omitted,\na name is generated automatically using the configured naming\nprefix (default: \"autoscale-bigip-\"). Ignored by delete-vm.\n" + }, + "vmIP": { + "type": "string", + "description": "IP address of the VM. For delete-vm, either vmIP or vmUuid must be\nsupplied; vmIP takes precedence when both are present.\n" + }, + "vmUuid": { + "type": "string", + "description": "vCenter Managed Object Reference (MoRef) of the VM. For delete-vm,\neither vmIP or vmUuid must be supplied. Recommended for cleaning up\norphaned clones that never acquired an IP \u2014 the create-vm response\nreturns vmUuid as soon as the clone succeeds.\n" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "envReference" + ], + "properties": { + "envReference": { + "type": "string", + "description": "ID (UUID) or name of the cloud environment to use for this VM task.\n" + }, + "vmName": { + "type": "string", + "description": "For create-vm only: optional name for the created VM. If omitted,\na name is generated automatically using the configured naming\nprefix (default: \"autoscale-bigip-\"). Ignored by delete-vm.\n" + }, + "vmIP": { + "type": "string", + "description": "IP address of the VM. For delete-vm, either vmIP or vmUuid must be\nsupplied; vmIP takes precedence when both are present.\n" + }, + "vmUuid": { + "type": "string", + "description": "vCenter Managed Object Reference (MoRef) of the VM. For delete-vm,\neither vmIP or vmUuid must be supplied. Recommended for cleaning up\norphaned clones that never acquired an IP \u2014 the create-vm response\nreturns vmUuid as soon as the clone succeeds.\n" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "677f44fe-f06e-44b1-8ac4-6ac74eabbbca", + "created": "2026-08-28T15:12:57.551Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 91, + "reference": "3bd36f6f-26d2-4153-bc32-3e100cbd35a1", + "type": "workflow", + "folder": "/VM Tasks", + "document": { + "name": "Get Create VM Task", + "description": "Get Create VM Task", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getCreateVMTask", + "canvasName": "getCreateVMTask", + "summary": "getCreateVMTask", + "description": "getCreateVMTask", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "taskId": "$var.job.taskId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "taskId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "taskId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "taskId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "010b6a2b-005c-4c2f-83a4-dbcbd5fe9cc7", + "created": "2026-08-28T15:12:57.524Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 92, + "reference": "040a382f-a16d-4887-a32f-fbf786757b69", + "type": "workflow", + "folder": "/VM Tasks", + "document": { + "name": "Get Delete VM Task", + "description": "Get Delete VM Task", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getDeleteVMTask", + "canvasName": "getDeleteVMTask", + "summary": "getDeleteVMTask", + "description": "getDeleteVMTask", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "taskId": "$var.job.taskId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "taskId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "taskId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "taskId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "89107be2-3e4b-4db5-80c4-9ef5184ebf71", + "created": "2026-08-28T15:12:57.583Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 93, + "reference": "56c51f18-c0ec-435f-b945-4487cc254c87", + "type": "workflow", + "folder": "/Device Templates", + "document": { + "name": "Clone Device Template", + "description": "Clone Device Template", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "CloneDeviceTemplate", + "canvasName": "CloneDeviceTemplate", + "summary": "CloneDeviceTemplate", + "description": "CloneDeviceTemplate", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Payload for cloning an existing device template.", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "Name for the cloned template. Must be unique.", + "minLength": 1, + "maxLength": 255, + "example": "BIG-IP Standard Template (Copy)" + } + } + } + }, + "required": [ + "id", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Payload for cloning an existing device template.", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "Name for the cloned template. Must be unique.", + "minLength": 1, + "maxLength": 255, + "example": "BIG-IP Standard Template (Copy)" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "5c069a69-f212-4ccd-ac67-55f7c2f88358", + "created": "2026-08-28T15:12:57.894Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 94, + "reference": "9f80ffa7-8aed-48d3-b720-75821e35ecdc", + "type": "workflow", + "folder": "/Device Templates", + "document": { + "name": "Create Device Template", + "description": "Create Device Template", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "CreateDeviceTemplate", + "canvasName": "CreateDeviceTemplate", + "summary": "CreateDeviceTemplate", + "description": "CreateDeviceTemplate", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Payload for creating (POST) or fully replacing (PUT) a device template.\n", + "required": [ + "name", + "provider", + "definition" + ], + "properties": { + "name": { + "type": "string", + "description": "Human-readable name for the device template. Must be unique.", + "minLength": 1, + "maxLength": 255, + "example": "BIG-IP Standard Template" + }, + "provider": { + "type": "string", + "description": "Provider or vendor (e.g. VMware, AWS, Azure).", + "minLength": 1, + "maxLength": 255, + "example": "VMware" + }, + "description": { + "type": "string", + "description": "Optional human-readable description.", + "nullable": true, + "maxLength": 1000, + "example": "Standard VMware configuration for production workloads" + }, + "draft": { + "type": "boolean", + "description": "When `true`, the template is created/kept in DRAFT state.\nWhen `false` or omitted, a DRAFT template is promoted to NEW.\n", + "default": false + }, + "definition": { + "type": "object", + "description": "Template definition containing all BIG-IP device configuration parameters.", + "required": [ + "rootPassword" + ], + "properties": { + "rootPassword": { + "type": "string", + "description": "BIG-IP root password. Must be at least 8 characters.", + "minLength": 8, + "example": "s3cur3P@ss!" + }, + "timeZone": { + "type": "string", + "description": "NTP timezone string applied to the BIG-IP device.", + "nullable": true, + "maxLength": 100, + "example": "America/Los_Angeles" + }, + "defaultRoute": { + "type": "string", + "description": "Default network gateway route for the BIG-IP device. Must be a valid IP address without prefix.", + "nullable": true, + "example": "10.0.0.1" + }, + "managementSslPort": { + "type": "integer", + "description": "BIG-IP management SSL port. If omitted, the device default is used.", + "nullable": true, + "minimum": 0, + "maximum": 65535, + "example": 443 + }, + "managementIp": { + "type": "object", + "description": "Management IP configuration.\n\nThe management IP is configured via DHCP. This field is reserved for future use.\n\nThe field should be omitted or set to `null`.\n", + "properties": {} + }, + "hostnameComponents": { + "type": "array", + "description": "Ordered array of hostname building blocks.", + "items": { + "type": "object", + "description": "A hostname building block.", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "description": "Component type.", + "enum": [ + "STATIC_TEXT", + "SERIAL_NUMBER" + ], + "example": "STATIC_TEXT" + }, + "value": { + "type": "string", + "description": "Value for the component. Required for STATIC_TEXT, null for SERIAL_NUMBER.", + "nullable": true, + "example": "bigip-" + } + } + }, + "example": [ + { + "type": "STATIC_TEXT", + "value": "bigip-" + }, + { + "type": "SERIAL_NUMBER", + "value": null + } + ] + }, + "lookupServerList": { + "type": "array", + "description": "List of DNS lookup server addresses.", + "items": { + "type": "string" + }, + "example": [ + "8.8.8.8", + "8.8.4.4" + ] + }, + "ntpServerList": { + "type": "array", + "description": "List of NTP server addresses.", + "items": { + "type": "string" + }, + "example": [ + "0.pool.ntp.org" + ] + }, + "userAccountList": { + "type": "array", + "description": "Array of BIG-IP user accounts to create.", + "items": { + "type": "object", + "description": "A BIG-IP user account definition with required credentials and role assignment.", + "required": [ + "username", + "password", + "role" + ], + "properties": { + "username": { + "type": "string", + "description": "Username for the BIG-IP account. Must start with a letter or underscore,\nand contain only letters, digits, hyphens, dots, or underscores.\n", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z_][-a-zA-Z_.0-9]*$", + "example": "admin" + }, + "password": { + "type": "string", + "description": "Password for the BIG-IP account. Must be at least 8 characters.", + "minLength": 8, + "maxLength": 255, + "example": "adminP@ss!" + }, + "role": { + "type": "string", + "description": "User role on the BIG-IP device. Defines the access level and permissions\nfor the user account. Common roles include 'admin', 'operator', 'guest', etc.\n", + "minLength": 1, + "maxLength": 255, + "example": "admin" + }, + "shell": { + "type": "string", + "description": "Shell access level for the user (e.g., 'bash', 'tmsh', 'none').", + "example": "bash" + } + } + } + }, + "provisionedModuleList": { + "type": "array", + "description": "Array of BIG-IP modules to provision.", + "items": { + "type": "object", + "description": "A BIG-IP module provisioning entry.", + "required": [ + "module", + "level" + ], + "properties": { + "module": { + "type": "string", + "description": "BIG-IP module name.", + "enum": [ + "AFM", + "AM", + "APM", + "ASM", + "AVR", + "DOS", + "FPS", + "GTM", + "ILX", + "LC", + "LTM", + "PEM", + "SWG", + "URLDB" + ], + "example": "LTM" + }, + "level": { + "type": "string", + "description": "Provisioning level.", + "enum": [ + "DEDICATED", + "MINIMUM", + "NOMINAL", + "NONE" + ], + "example": "NOMINAL" + } + } + } + }, + "networkRouteList": { + "type": "array", + "description": "Array of network interface routes.", + "items": { + "type": "object", + "description": "A network route definition.", + "required": [ + "name", + "gatewayAddress", + "destination" + ], + "properties": { + "name": { + "type": "string", + "example": "default" + }, + "gatewayAddress": { + "type": "string", + "example": "10.0.0.1" + }, + "destination": { + "type": "string", + "example": "0.0.0.0/0" + } + } + } + }, + "vlanList": { + "type": "array", + "description": "Array of VLAN definitions.", + "items": { + "type": "object", + "description": "A VLAN definition.", + "required": [ + "name", + "nic" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "example": "external" + }, + "nic": { + "type": "string", + "description": "Network interface card identifier (e.g., \"1.1\", \"1.2\").", + "pattern": "^[0-9]+\\.[0-9]+$", + "example": "1.1" + }, + "mtu": { + "type": "integer", + "description": "Maximum transmission unit size in bytes.", + "minimum": 576, + "maximum": 9198, + "example": 1500 + }, + "tag": { + "type": "integer", + "description": "VLAN tag identifier.", + "minimum": 1, + "maximum": 4094, + "example": 100 + } + } + } + }, + "selfIpList": { + "type": "array", + "description": "Array of self-IP definitions for the BIG-IP device.", + "items": { + "type": "object", + "description": "A self-IP definition for the BIG-IP device.\n\nSelf IPs are allocated from an IP pool specified by `ipPoolReference`.\n", + "required": [ + "name", + "vlanName", + "ipPoolReference" + ], + "properties": { + "name": { + "type": "string", + "description": "Self-IP name. Must be unique within the template.", + "example": "external-self" + }, + "ipPoolReference": { + "type": "string", + "format": "uuid", + "description": "UUID referencing an existing IP pool for self-IP allocation.\n", + "example": "c3d4e5f6-a7b8-4890-8bcd-ef1234567892" + }, + "vlanName": { + "type": "string", + "description": "Name of the VLAN this self-IP is associated with.", + "example": "external" + }, + "portLockdown": { + "type": "string", + "description": "Port lockdown mode.", + "enum": [ + "none", + "default", + "all", + "custom", + "custom-default" + ], + "default": "none", + "example": "default" + }, + "allowServices": { + "type": "array", + "description": "Allowed services when portLockdown is custom/custom-default.", + "nullable": true, + "items": { + "type": "string" + }, + "example": null + } + } + } + }, + "bgpConfig": { + "type": "object", + "description": "BGP routing configuration for the BIG-IP device.", + "required": [ + "name", + "localAs", + "routerId", + "routeDomain", + "addressFamilies" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the BGP configuration.", + "example": "my_bgp" + }, + "description": { + "type": "string", + "description": "Optional description of the BGP configuration.", + "nullable": true, + "example": "Example BGP configuration" + }, + "localAs": { + "type": "integer", + "description": "Local AS number.", + "minimum": 1, + "maximum": 4294967295, + "example": 65001 + }, + "routerId": { + "type": "string", + "description": "Router ID reference. Must be the name of a self IP defined in the selfIpList.\nThe actual router ID (IP address) will be resolved from the referenced self IP's address at deployment time.\n", + "example": "external-self" + }, + "routeDomain": { + "type": "string", + "description": "Route domain for the BGP configuration.", + "example": "/Common/0" + }, + "enabled": { + "type": "boolean", + "description": "Whether BGP is enabled.", + "default": true, + "example": true + }, + "defaultLocalPreference": { + "type": "integer", + "description": "Default local preference value.", + "default": 100, + "example": 100 + }, + "holdTime": { + "type": "integer", + "description": "BGP hold time in seconds.", + "default": 90, + "example": 90 + }, + "keepAlive": { + "type": "integer", + "description": "BGP keepalive interval in seconds.", + "default": 30, + "example": 30 + }, + "neighbor": { + "type": "array", + "description": "List of BGP neighbors.", + "items": { + "type": "object", + "description": "A BGP neighbor configuration.", + "required": [ + "name", + "remoteAs" + ], + "properties": { + "name": { + "type": "string", + "description": "IP address of the BGP neighbor.", + "example": "10.0.1.1" + }, + "description": { + "type": "string", + "description": "Optional description of the neighbor.", + "nullable": true, + "example": "Upstream BGP neighbor" + }, + "remoteAs": { + "type": "integer", + "description": "Remote AS number of the neighbor.", + "minimum": 1, + "maximum": 4294967295, + "example": 65002 + }, + "password": { + "type": "string", + "description": "Optional password for BGP authentication.", + "nullable": true, + "minLength": 1, + "maxLength": 255, + "example": "SecureBGPPassword" + }, + "ebgpMultihop": { + "type": "integer", + "description": "Allow EBGP neighbors not on directly connected networks.\nSpecifies the maximum number of hops allowed to reach the neighbor.\n", + "nullable": true, + "minimum": 1, + "maximum": 255, + "default": 1, + "example": 1 + }, + "fallOver": { + "type": "string", + "description": "Fall-over detection method for BGP neighbor.\n- \"bfd\": Bidirectional Forwarding Detection (BFD)\n- \"bfd-multihop\": BFD for multihop neighbors\n- \"none\": No fall-over detection\n", + "enum": [ + "bfd", + "bfd-multihop", + "none" + ], + "default": "none", + "example": "bfd", + "nullable": true + }, + "bfdTimers": { + "description": "BFD timer configuration (required if fallOver is \"bfd\" or \"bfd-multihop\").\n", + "nullable": true, + "type": "object", + "required": [ + "transmitInterval", + "receiveInterval", + "detectionMultiplier" + ], + "properties": { + "transmitInterval": { + "type": "integer", + "description": "BFD transmission interval in milliseconds.\nThe time interval between BFD control packets sent to the peer.\n", + "minimum": 1, + "maximum": 60000, + "example": 300 + }, + "receiveInterval": { + "type": "integer", + "description": "BFD reception interval in milliseconds.\nThe time interval expected between BFD control packets received from the peer.\n", + "minimum": 1, + "maximum": 60000, + "example": 300 + }, + "detectionMultiplier": { + "type": "integer", + "description": "BFD detection multiplier.\nThe number of BFD packets that must be missed to declare the session down.\nDetection time = transmitInterval \u00d7 detectionMultiplier.\n", + "minimum": 1, + "maximum": 50, + "example": 3 + } + } + }, + "enabled": { + "type": "boolean", + "description": "Whether the neighbor is enabled.", + "default": true, + "example": true + } + } + }, + "example": [ + { + "name": "10.0.1.1", + "description": "Upstream BGP neighbor", + "remoteAs": 65002, + "password": "bgpSecretKey123", + "ebgpMultihop": 1, + "fallOver": "bfd", + "bfdTimers": { + "transmitInterval": 300, + "receiveInterval": 300, + "detectionMultiplier": 3 + }, + "enabled": true + } + ] + }, + "addressFamilies": { + "type": "array", + "description": "List of address family configurations for BGP.\nEach entry defines an internet protocol (e.g. `ipv4`) and an optional\nlist of routing protocols to redistribute into BGP.\nIf omitted, a default `ipv4` address family with `kernel` and `connected`\nredistribution is applied automatically.\n", + "items": { + "type": "object", + "description": "An address family configuration for BGP.\nDefines the internet protocol and the list of routing protocols\nto redistribute into BGP for that address family.\nOnly `ipv4` is currently supported for `internetProtocol`.\n", + "required": [ + "internetProtocol", + "redistributionList" + ], + "properties": { + "internetProtocol": { + "type": "string", + "description": "The internet protocol for this address family.\nCurrently only `ipv4` is supported.\n", + "example": "ipv4" + }, + "redistributionList": { + "type": "array", + "description": "List of routing protocols to redistribute into BGP for this address family.\nIf omitted or empty, no redistribution is configured.\n", + "items": { + "type": "object", + "description": "A routing protocol redistribution entry for a BGP address family.", + "required": [ + "routingProtocol" + ], + "properties": { + "routingProtocol": { + "type": "string", + "description": "The routing protocol to redistribute into BGP (e.g. `connected`, `kernel`).\nThe accepted values depend on the BIG-IP version and configuration.\n", + "example": "connected" + } + } + }, + "example": [ + { + "routingProtocol": "connected" + }, + { + "routingProtocol": "kernel" + } + ] + } + } + }, + "example": [ + { + "internetProtocol": "ipv4", + "redistributionList": [ + { + "routingProtocol": "connected" + }, + { + "routingProtocol": "kernel" + } + ] + } + ] + } + } + } + } + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Payload for creating (POST) or fully replacing (PUT) a device template.\n", + "required": [ + "name", + "provider", + "definition" + ], + "properties": { + "name": { + "type": "string", + "description": "Human-readable name for the device template. Must be unique.", + "minLength": 1, + "maxLength": 255, + "example": "BIG-IP Standard Template" + }, + "provider": { + "type": "string", + "description": "Provider or vendor (e.g. VMware, AWS, Azure).", + "minLength": 1, + "maxLength": 255, + "example": "VMware" + }, + "description": { + "type": "string", + "description": "Optional human-readable description.", + "nullable": true, + "maxLength": 1000, + "example": "Standard VMware configuration for production workloads" + }, + "draft": { + "type": "boolean", + "description": "When `true`, the template is created/kept in DRAFT state.\nWhen `false` or omitted, a DRAFT template is promoted to NEW.\n", + "default": false + }, + "definition": { + "type": "object", + "description": "Template definition containing all BIG-IP device configuration parameters.", + "required": [ + "rootPassword" + ], + "properties": { + "rootPassword": { + "type": "string", + "description": "BIG-IP root password. Must be at least 8 characters.", + "minLength": 8, + "example": "s3cur3P@ss!" + }, + "timeZone": { + "type": "string", + "description": "NTP timezone string applied to the BIG-IP device.", + "nullable": true, + "maxLength": 100, + "example": "America/Los_Angeles" + }, + "defaultRoute": { + "type": "string", + "description": "Default network gateway route for the BIG-IP device. Must be a valid IP address without prefix.", + "nullable": true, + "example": "10.0.0.1" + }, + "managementSslPort": { + "type": "integer", + "description": "BIG-IP management SSL port. If omitted, the device default is used.", + "nullable": true, + "minimum": 0, + "maximum": 65535, + "example": 443 + }, + "managementIp": { + "type": "object", + "description": "Management IP configuration.\n\nThe management IP is configured via DHCP. This field is reserved for future use.\n\nThe field should be omitted or set to `null`.\n", + "properties": {} + }, + "hostnameComponents": { + "type": "array", + "description": "Ordered array of hostname building blocks.", + "items": { + "type": "object", + "description": "A hostname building block.", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "description": "Component type.", + "enum": [ + "STATIC_TEXT", + "SERIAL_NUMBER" + ], + "example": "STATIC_TEXT" + }, + "value": { + "type": "string", + "description": "Value for the component. Required for STATIC_TEXT, null for SERIAL_NUMBER.", + "nullable": true, + "example": "bigip-" + } + } + }, + "example": [ + { + "type": "STATIC_TEXT", + "value": "bigip-" + }, + { + "type": "SERIAL_NUMBER", + "value": null + } + ] + }, + "lookupServerList": { + "type": "array", + "description": "List of DNS lookup server addresses.", + "items": { + "type": "string" + }, + "example": [ + "8.8.8.8", + "8.8.4.4" + ] + }, + "ntpServerList": { + "type": "array", + "description": "List of NTP server addresses.", + "items": { + "type": "string" + }, + "example": [ + "0.pool.ntp.org" + ] + }, + "userAccountList": { + "type": "array", + "description": "Array of BIG-IP user accounts to create.", + "items": { + "type": "object", + "description": "A BIG-IP user account definition with required credentials and role assignment.", + "required": [ + "username", + "password", + "role" + ], + "properties": { + "username": { + "type": "string", + "description": "Username for the BIG-IP account. Must start with a letter or underscore,\nand contain only letters, digits, hyphens, dots, or underscores.\n", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z_][-a-zA-Z_.0-9]*$", + "example": "admin" + }, + "password": { + "type": "string", + "description": "Password for the BIG-IP account. Must be at least 8 characters.", + "minLength": 8, + "maxLength": 255, + "example": "adminP@ss!" + }, + "role": { + "type": "string", + "description": "User role on the BIG-IP device. Defines the access level and permissions\nfor the user account. Common roles include 'admin', 'operator', 'guest', etc.\n", + "minLength": 1, + "maxLength": 255, + "example": "admin" + }, + "shell": { + "type": "string", + "description": "Shell access level for the user (e.g., 'bash', 'tmsh', 'none').", + "example": "bash" + } + } + } + }, + "provisionedModuleList": { + "type": "array", + "description": "Array of BIG-IP modules to provision.", + "items": { + "type": "object", + "description": "A BIG-IP module provisioning entry.", + "required": [ + "module", + "level" + ], + "properties": { + "module": { + "type": "string", + "description": "BIG-IP module name.", + "enum": [ + "AFM", + "AM", + "APM", + "ASM", + "AVR", + "DOS", + "FPS", + "GTM", + "ILX", + "LC", + "LTM", + "PEM", + "SWG", + "URLDB" + ], + "example": "LTM" + }, + "level": { + "type": "string", + "description": "Provisioning level.", + "enum": [ + "DEDICATED", + "MINIMUM", + "NOMINAL", + "NONE" + ], + "example": "NOMINAL" + } + } + } + }, + "networkRouteList": { + "type": "array", + "description": "Array of network interface routes.", + "items": { + "type": "object", + "description": "A network route definition.", + "required": [ + "name", + "gatewayAddress", + "destination" + ], + "properties": { + "name": { + "type": "string", + "example": "default" + }, + "gatewayAddress": { + "type": "string", + "example": "10.0.0.1" + }, + "destination": { + "type": "string", + "example": "0.0.0.0/0" + } + } + } + }, + "vlanList": { + "type": "array", + "description": "Array of VLAN definitions.", + "items": { + "type": "object", + "description": "A VLAN definition.", + "required": [ + "name", + "nic" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "example": "external" + }, + "nic": { + "type": "string", + "description": "Network interface card identifier (e.g., \"1.1\", \"1.2\").", + "pattern": "^[0-9]+\\.[0-9]+$", + "example": "1.1" + }, + "mtu": { + "type": "integer", + "description": "Maximum transmission unit size in bytes.", + "minimum": 576, + "maximum": 9198, + "example": 1500 + }, + "tag": { + "type": "integer", + "description": "VLAN tag identifier.", + "minimum": 1, + "maximum": 4094, + "example": 100 + } + } + } + }, + "selfIpList": { + "type": "array", + "description": "Array of self-IP definitions for the BIG-IP device.", + "items": { + "type": "object", + "description": "A self-IP definition for the BIG-IP device.\n\nSelf IPs are allocated from an IP pool specified by `ipPoolReference`.\n", + "required": [ + "name", + "vlanName", + "ipPoolReference" + ], + "properties": { + "name": { + "type": "string", + "description": "Self-IP name. Must be unique within the template.", + "example": "external-self" + }, + "ipPoolReference": { + "type": "string", + "format": "uuid", + "description": "UUID referencing an existing IP pool for self-IP allocation.\n", + "example": "c3d4e5f6-a7b8-4890-8bcd-ef1234567892" + }, + "vlanName": { + "type": "string", + "description": "Name of the VLAN this self-IP is associated with.", + "example": "external" + }, + "portLockdown": { + "type": "string", + "description": "Port lockdown mode.", + "enum": [ + "none", + "default", + "all", + "custom", + "custom-default" + ], + "default": "none", + "example": "default" + }, + "allowServices": { + "type": "array", + "description": "Allowed services when portLockdown is custom/custom-default.", + "nullable": true, + "items": { + "type": "string" + }, + "example": null + } + } + } + }, + "bgpConfig": { + "type": "object", + "description": "BGP routing configuration for the BIG-IP device.", + "required": [ + "name", + "localAs", + "routerId", + "routeDomain", + "addressFamilies" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the BGP configuration.", + "example": "my_bgp" + }, + "description": { + "type": "string", + "description": "Optional description of the BGP configuration.", + "nullable": true, + "example": "Example BGP configuration" + }, + "localAs": { + "type": "integer", + "description": "Local AS number.", + "minimum": 1, + "maximum": 4294967295, + "example": 65001 + }, + "routerId": { + "type": "string", + "description": "Router ID reference. Must be the name of a self IP defined in the selfIpList.\nThe actual router ID (IP address) will be resolved from the referenced self IP's address at deployment time.\n", + "example": "external-self" + }, + "routeDomain": { + "type": "string", + "description": "Route domain for the BGP configuration.", + "example": "/Common/0" + }, + "enabled": { + "type": "boolean", + "description": "Whether BGP is enabled.", + "default": true, + "example": true + }, + "defaultLocalPreference": { + "type": "integer", + "description": "Default local preference value.", + "default": 100, + "example": 100 + }, + "holdTime": { + "type": "integer", + "description": "BGP hold time in seconds.", + "default": 90, + "example": 90 + }, + "keepAlive": { + "type": "integer", + "description": "BGP keepalive interval in seconds.", + "default": 30, + "example": 30 + }, + "neighbor": { + "type": "array", + "description": "List of BGP neighbors.", + "items": { + "type": "object", + "description": "A BGP neighbor configuration.", + "required": [ + "name", + "remoteAs" + ], + "properties": { + "name": { + "type": "string", + "description": "IP address of the BGP neighbor.", + "example": "10.0.1.1" + }, + "description": { + "type": "string", + "description": "Optional description of the neighbor.", + "nullable": true, + "example": "Upstream BGP neighbor" + }, + "remoteAs": { + "type": "integer", + "description": "Remote AS number of the neighbor.", + "minimum": 1, + "maximum": 4294967295, + "example": 65002 + }, + "password": { + "type": "string", + "description": "Optional password for BGP authentication.", + "nullable": true, + "minLength": 1, + "maxLength": 255, + "example": "SecureBGPPassword" + }, + "ebgpMultihop": { + "type": "integer", + "description": "Allow EBGP neighbors not on directly connected networks.\nSpecifies the maximum number of hops allowed to reach the neighbor.\n", + "nullable": true, + "minimum": 1, + "maximum": 255, + "default": 1, + "example": 1 + }, + "fallOver": { + "type": "string", + "description": "Fall-over detection method for BGP neighbor.\n- \"bfd\": Bidirectional Forwarding Detection (BFD)\n- \"bfd-multihop\": BFD for multihop neighbors\n- \"none\": No fall-over detection\n", + "enum": [ + "bfd", + "bfd-multihop", + "none" + ], + "default": "none", + "example": "bfd", + "nullable": true + }, + "bfdTimers": { + "description": "BFD timer configuration (required if fallOver is \"bfd\" or \"bfd-multihop\").\n", + "nullable": true, + "type": "object", + "required": [ + "transmitInterval", + "receiveInterval", + "detectionMultiplier" + ], + "properties": { + "transmitInterval": { + "type": "integer", + "description": "BFD transmission interval in milliseconds.\nThe time interval between BFD control packets sent to the peer.\n", + "minimum": 1, + "maximum": 60000, + "example": 300 + }, + "receiveInterval": { + "type": "integer", + "description": "BFD reception interval in milliseconds.\nThe time interval expected between BFD control packets received from the peer.\n", + "minimum": 1, + "maximum": 60000, + "example": 300 + }, + "detectionMultiplier": { + "type": "integer", + "description": "BFD detection multiplier.\nThe number of BFD packets that must be missed to declare the session down.\nDetection time = transmitInterval \u00d7 detectionMultiplier.\n", + "minimum": 1, + "maximum": 50, + "example": 3 + } + } + }, + "enabled": { + "type": "boolean", + "description": "Whether the neighbor is enabled.", + "default": true, + "example": true + } + } + }, + "example": [ + { + "name": "10.0.1.1", + "description": "Upstream BGP neighbor", + "remoteAs": 65002, + "password": "bgpSecretKey123", + "ebgpMultihop": 1, + "fallOver": "bfd", + "bfdTimers": { + "transmitInterval": 300, + "receiveInterval": 300, + "detectionMultiplier": 3 + }, + "enabled": true + } + ] + }, + "addressFamilies": { + "type": "array", + "description": "List of address family configurations for BGP.\nEach entry defines an internet protocol (e.g. `ipv4`) and an optional\nlist of routing protocols to redistribute into BGP.\nIf omitted, a default `ipv4` address family with `kernel` and `connected`\nredistribution is applied automatically.\n", + "items": { + "type": "object", + "description": "An address family configuration for BGP.\nDefines the internet protocol and the list of routing protocols\nto redistribute into BGP for that address family.\nOnly `ipv4` is currently supported for `internetProtocol`.\n", + "required": [ + "internetProtocol", + "redistributionList" + ], + "properties": { + "internetProtocol": { + "type": "string", + "description": "The internet protocol for this address family.\nCurrently only `ipv4` is supported.\n", + "example": "ipv4" + }, + "redistributionList": { + "type": "array", + "description": "List of routing protocols to redistribute into BGP for this address family.\nIf omitted or empty, no redistribution is configured.\n", + "items": { + "type": "object", + "description": "A routing protocol redistribution entry for a BGP address family.", + "required": [ + "routingProtocol" + ], + "properties": { + "routingProtocol": { + "type": "string", + "description": "The routing protocol to redistribute into BGP (e.g. `connected`, `kernel`).\nThe accepted values depend on the BIG-IP version and configuration.\n", + "example": "connected" + } + } + }, + "example": [ + { + "routingProtocol": "connected" + }, + { + "routingProtocol": "kernel" + } + ] + } + } + }, + "example": [ + { + "internetProtocol": "ipv4", + "redistributionList": [ + { + "routingProtocol": "connected" + }, + { + "routingProtocol": "kernel" + } + ] + } + ] + } + } + } + } + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "3bba4c01-0b6a-4065-a1ec-cd4d0100d1dc", + "created": "2026-08-28T15:12:57.690Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 95, + "reference": "b90970ba-c918-4104-88bf-036c1c4d6d40", + "type": "workflow", + "folder": "/Device Templates", + "document": { + "name": "Delete Device Template", + "description": "Delete Device Template", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "DeleteDeviceTemplate", + "canvasName": "DeleteDeviceTemplate", + "summary": "DeleteDeviceTemplate", + "description": "DeleteDeviceTemplate", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "c54a74b0-ceb3-4b34-924f-46fd303907a0", + "created": "2026-08-28T15:12:57.864Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 96, + "reference": "7d4d23e9-4b3f-4f46-94fb-b931f4287076", + "type": "workflow", + "folder": "/Device Templates", + "document": { + "name": "Deploy Device Template", + "description": "Deploy Device Template", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "DeployDeviceTemplate", + "canvasName": "DeployDeviceTemplate", + "summary": "DeployDeviceTemplate", + "description": "DeployDeviceTemplate", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Payload for deploying a device template to a target BIG-IP device.", + "required": [ + "mgmtIp", + "encodedBasicAuth" + ], + "properties": { + "mgmtIp": { + "type": "string", + "format": "ipv4", + "description": "Management IP address of the target BIG-IP device.", + "example": "192.168.1.100" + }, + "username": { + "type": "string", + "description": "Username for the BIG-IP device (optional, for display/logging purposes).", + "minLength": 1, + "maxLength": 255, + "example": "admin" + }, + "encodedBasicAuth": { + "type": "string", + "description": "Base64-encoded basic authentication credentials (username:password).", + "minLength": 1, + "example": "YWRtaW46YWRtaW5QYXNzd29yZDEyMw==" + } + } + } + }, + "required": [ + "id", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Payload for deploying a device template to a target BIG-IP device.", + "required": [ + "mgmtIp", + "encodedBasicAuth" + ], + "properties": { + "mgmtIp": { + "type": "string", + "format": "ipv4", + "description": "Management IP address of the target BIG-IP device.", + "example": "192.168.1.100" + }, + "username": { + "type": "string", + "description": "Username for the BIG-IP device (optional, for display/logging purposes).", + "minLength": 1, + "maxLength": 255, + "example": "admin" + }, + "encodedBasicAuth": { + "type": "string", + "description": "Base64-encoded basic authentication credentials (username:password).", + "minLength": 1, + "example": "YWRtaW46YWRtaW5QYXNzd29yZDEyMw==" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "76c3eb76-f064-4598-8170-e4440f57c65d", + "created": "2026-08-28T15:12:57.924Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 97, + "reference": "5c7e8225-1ef2-4a09-a3f6-5f5a05ecd949", + "type": "workflow", + "folder": "/Device Templates", + "document": { + "name": "Get Device Template", + "description": "Get Device Template", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "GetDeviceTemplate", + "canvasName": "GetDeviceTemplate", + "summary": "GetDeviceTemplate", + "description": "GetDeviceTemplate", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "dfdbd514-eecd-4f7a-902c-8fa106444847", + "created": "2026-08-28T15:12:57.748Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 98, + "reference": "0b270e04-60ec-4c7f-82a8-cd523af871c6", + "type": "workflow", + "folder": "/Device Templates", + "document": { + "name": "Get Device Template Task", + "description": "Get Device Template Task", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "GetDeviceTemplateTask", + "canvasName": "GetDeviceTemplateTask", + "summary": "GetDeviceTemplateTask", + "description": "GetDeviceTemplateTask", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "taskId": "$var.job.taskId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "taskId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "taskId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "taskId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "023866c5-70dd-4c1e-9834-95e57bb34e61", + "created": "2026-08-28T15:12:57.721Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 99, + "reference": "6d29477b-3e3f-495c-8e9b-9bdfbda180b9", + "type": "workflow", + "folder": "/Device Templates", + "document": { + "name": "List Device Templates", + "description": "List Device Templates", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "ListDeviceTemplates", + "canvasName": "ListDeviceTemplates", + "summary": "ListDeviceTemplates", + "description": "ListDeviceTemplates", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "4443260f-fcbe-4616-9784-5ba48ece7d83", + "created": "2026-08-28T15:12:57.647Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 100, + "reference": "c495a326-a0f3-40be-bc92-66ecc8e14bce", + "type": "workflow", + "folder": "/Device Templates", + "document": { + "name": "Lock Device Template", + "description": "Lock Device Template", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "LockDeviceTemplate", + "canvasName": "LockDeviceTemplate", + "summary": "LockDeviceTemplate", + "description": "LockDeviceTemplate", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "7fe8d462-9abb-4f6c-9152-65f0098bc696", + "created": "2026-08-28T15:12:57.954Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 101, + "reference": "a8fe2b55-15bd-4c30-9e9e-e4040d293996", + "type": "workflow", + "folder": "/Device Templates", + "document": { + "name": "Patch Device Template", + "description": "Patch Device Template", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "PatchDeviceTemplate", + "canvasName": "PatchDeviceTemplate", + "summary": "PatchDeviceTemplate", + "description": "PatchDeviceTemplate", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Payload for partially updating a device template (PATCH).\nAll fields are optional \u2014 only provided fields are modified.\nFor `definition`, merge-patch semantics apply.\n", + "properties": { + "name": { + "type": "string", + "description": "Human-readable name. Must be unique.", + "minLength": 1, + "maxLength": 255, + "example": "BIG-IP Standard Template v2" + }, + "provider": { + "type": "string", + "description": "Provider or vendor.", + "minLength": 1, + "maxLength": 255, + "example": "VMware" + }, + "description": { + "type": "string", + "description": "Optional description. Set to `null` to clear.", + "nullable": true, + "maxLength": 1000, + "example": "Updated description" + }, + "draft": { + "type": "boolean", + "description": "Controls DRAFT state on partial update." + }, + "definition": { + "type": "object", + "description": "Partial template definition for merge-patching (used by PATCH).\nAll fields are optional \u2014 only provided fields are updated.\nOmitted fields retain their current values.\nTo explicitly clear a nullable field, set it to `null`.\n", + "properties": { + "rootPassword": { + "type": "string", + "description": "BIG-IP root password.", + "nullable": true, + "minLength": 1, + "example": "s3cur3P@ss!" + }, + "timeZone": { + "type": "string", + "description": "NTP timezone string.", + "nullable": true, + "example": "America/Los_Angeles" + }, + "defaultRoute": { + "type": "string", + "description": "Default network gateway route.", + "nullable": true, + "example": "10.0.0.1" + }, + "managementSslPort": { + "type": "integer", + "description": "BIG-IP management SSL port.", + "nullable": true, + "example": 443 + }, + "managementIp": { + "type": "object", + "description": "Management IP configuration.\n\nThe management IP is configured via DHCP. This field is reserved for future use.\n\nThe field should be omitted or set to `null`.\n", + "properties": {} + }, + "hostnameComponents": { + "type": "array", + "description": "Ordered array of hostname building blocks.", + "items": { + "type": "object", + "description": "A hostname building block.", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "description": "Component type.", + "enum": [ + "STATIC_TEXT", + "SERIAL_NUMBER" + ], + "example": "STATIC_TEXT" + }, + "value": { + "type": "string", + "description": "Value for the component. Required for STATIC_TEXT, null for SERIAL_NUMBER.", + "nullable": true, + "example": "bigip-" + } + } + } + }, + "lookupServerList": { + "type": "array", + "description": "List of DNS lookup server addresses.", + "items": { + "type": "string" + } + }, + "ntpServerList": { + "type": "array", + "description": "List of NTP server addresses.", + "items": { + "type": "string" + } + }, + "userAccountList": { + "type": "array", + "description": "Array of BIG-IP user accounts.", + "items": { + "type": "object", + "description": "A BIG-IP user account definition with required credentials and role assignment.", + "required": [ + "username", + "password", + "role" + ], + "properties": { + "username": { + "type": "string", + "description": "Username for the BIG-IP account. Must start with a letter or underscore,\nand contain only letters, digits, hyphens, dots, or underscores.\n", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z_][-a-zA-Z_.0-9]*$", + "example": "admin" + }, + "password": { + "type": "string", + "description": "Password for the BIG-IP account. Must be at least 8 characters.", + "minLength": 8, + "maxLength": 255, + "example": "adminP@ss!" + }, + "role": { + "type": "string", + "description": "User role on the BIG-IP device. Defines the access level and permissions\nfor the user account. Common roles include 'admin', 'operator', 'guest', etc.\n", + "minLength": 1, + "maxLength": 255, + "example": "admin" + }, + "shell": { + "type": "string", + "description": "Shell access level for the user (e.g., 'bash', 'tmsh', 'none').", + "example": "bash" + } + } + } + }, + "provisionedModuleList": { + "type": "array", + "description": "Array of BIG-IP modules to provision.", + "items": { + "type": "object", + "description": "A BIG-IP module provisioning entry.", + "required": [ + "module", + "level" + ], + "properties": { + "module": { + "type": "string", + "description": "BIG-IP module name.", + "enum": [ + "AFM", + "AM", + "APM", + "ASM", + "AVR", + "DOS", + "FPS", + "GTM", + "ILX", + "LC", + "LTM", + "PEM", + "SWG", + "URLDB" + ], + "example": "LTM" + }, + "level": { + "type": "string", + "description": "Provisioning level.", + "enum": [ + "DEDICATED", + "MINIMUM", + "NOMINAL", + "NONE" + ], + "example": "NOMINAL" + } + } + } + }, + "networkRouteList": { + "type": "array", + "description": "Array of network interface routes.", + "items": { + "type": "object", + "description": "A network route definition.", + "required": [ + "name", + "gatewayAddress", + "destination" + ], + "properties": { + "name": { + "type": "string", + "example": "default" + }, + "gatewayAddress": { + "type": "string", + "example": "10.0.0.1" + }, + "destination": { + "type": "string", + "example": "0.0.0.0/0" + } + } + } + }, + "vlanList": { + "type": "array", + "description": "Array of VLAN definitions.", + "items": { + "type": "object", + "description": "A VLAN definition.", + "required": [ + "name", + "nic" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "example": "external" + }, + "nic": { + "type": "string", + "description": "Network interface card identifier (e.g., \"1.1\", \"1.2\").", + "pattern": "^[0-9]+\\.[0-9]+$", + "example": "1.1" + }, + "mtu": { + "type": "integer", + "description": "Maximum transmission unit size in bytes.", + "minimum": 576, + "maximum": 9198, + "example": 1500 + }, + "tag": { + "type": "integer", + "description": "VLAN tag identifier.", + "minimum": 1, + "maximum": 4094, + "example": 100 + } + } + } + }, + "selfIpList": { + "type": "array", + "description": "Array of self-IP definitions. Replaces the entire selfIpList on PATCH.\n", + "items": { + "type": "object", + "description": "A self-IP definition for the BIG-IP device.\n\nSelf IPs are allocated from an IP pool specified by `ipPoolReference`.\n", + "required": [ + "name", + "vlanName", + "ipPoolReference" + ], + "properties": { + "name": { + "type": "string", + "description": "Self-IP name. Must be unique within the template.", + "example": "external-self" + }, + "ipPoolReference": { + "type": "string", + "format": "uuid", + "description": "UUID referencing an existing IP pool for self-IP allocation.\n", + "example": "c3d4e5f6-a7b8-4890-8bcd-ef1234567892" + }, + "vlanName": { + "type": "string", + "description": "Name of the VLAN this self-IP is associated with.", + "example": "external" + }, + "portLockdown": { + "type": "string", + "description": "Port lockdown mode.", + "enum": [ + "none", + "default", + "all", + "custom", + "custom-default" + ], + "default": "none", + "example": "default" + }, + "allowServices": { + "type": "array", + "description": "Allowed services when portLockdown is custom/custom-default.", + "nullable": true, + "items": { + "type": "string" + }, + "example": null + } + } + } + }, + "bgpConfig": { + "type": "object", + "description": "BGP routing configuration for the BIG-IP device.", + "required": [ + "name", + "localAs", + "routerId", + "routeDomain", + "addressFamilies" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the BGP configuration.", + "example": "my_bgp" + }, + "description": { + "type": "string", + "description": "Optional description of the BGP configuration.", + "nullable": true, + "example": "Example BGP configuration" + }, + "localAs": { + "type": "integer", + "description": "Local AS number.", + "minimum": 1, + "maximum": 4294967295, + "example": 65001 + }, + "routerId": { + "type": "string", + "description": "Router ID reference. Must be the name of a self IP defined in the selfIpList.\nThe actual router ID (IP address) will be resolved from the referenced self IP's address at deployment time.\n", + "example": "external-self" + }, + "routeDomain": { + "type": "string", + "description": "Route domain for the BGP configuration.", + "example": "/Common/0" + }, + "enabled": { + "type": "boolean", + "description": "Whether BGP is enabled.", + "default": true, + "example": true + }, + "defaultLocalPreference": { + "type": "integer", + "description": "Default local preference value.", + "default": 100, + "example": 100 + }, + "holdTime": { + "type": "integer", + "description": "BGP hold time in seconds.", + "default": 90, + "example": 90 + }, + "keepAlive": { + "type": "integer", + "description": "BGP keepalive interval in seconds.", + "default": 30, + "example": 30 + }, + "neighbor": { + "type": "array", + "description": "List of BGP neighbors.", + "items": { + "type": "object", + "description": "A BGP neighbor configuration.", + "required": [ + "name", + "remoteAs" + ], + "properties": { + "name": { + "type": "string", + "description": "IP address of the BGP neighbor.", + "example": "10.0.1.1" + }, + "description": { + "type": "string", + "description": "Optional description of the neighbor.", + "nullable": true, + "example": "Upstream BGP neighbor" + }, + "remoteAs": { + "type": "integer", + "description": "Remote AS number of the neighbor.", + "minimum": 1, + "maximum": 4294967295, + "example": 65002 + }, + "password": { + "type": "string", + "description": "Optional password for BGP authentication.", + "nullable": true, + "minLength": 1, + "maxLength": 255, + "example": "SecureBGPPassword" + }, + "ebgpMultihop": { + "type": "integer", + "description": "Allow EBGP neighbors not on directly connected networks.\nSpecifies the maximum number of hops allowed to reach the neighbor.\n", + "nullable": true, + "minimum": 1, + "maximum": 255, + "default": 1, + "example": 1 + }, + "fallOver": { + "type": "string", + "description": "Fall-over detection method for BGP neighbor.\n- \"bfd\": Bidirectional Forwarding Detection (BFD)\n- \"bfd-multihop\": BFD for multihop neighbors\n- \"none\": No fall-over detection\n", + "enum": [ + "bfd", + "bfd-multihop", + "none" + ], + "default": "none", + "example": "bfd", + "nullable": true + }, + "bfdTimers": { + "description": "BFD timer configuration (required if fallOver is \"bfd\" or \"bfd-multihop\").\n", + "nullable": true, + "type": "object", + "required": [ + "transmitInterval", + "receiveInterval", + "detectionMultiplier" + ], + "properties": { + "transmitInterval": { + "type": "integer", + "description": "BFD transmission interval in milliseconds.\nThe time interval between BFD control packets sent to the peer.\n", + "minimum": 1, + "maximum": 60000, + "example": 300 + }, + "receiveInterval": { + "type": "integer", + "description": "BFD reception interval in milliseconds.\nThe time interval expected between BFD control packets received from the peer.\n", + "minimum": 1, + "maximum": 60000, + "example": 300 + }, + "detectionMultiplier": { + "type": "integer", + "description": "BFD detection multiplier.\nThe number of BFD packets that must be missed to declare the session down.\nDetection time = transmitInterval \u00d7 detectionMultiplier.\n", + "minimum": 1, + "maximum": 50, + "example": 3 + } + } + }, + "enabled": { + "type": "boolean", + "description": "Whether the neighbor is enabled.", + "default": true, + "example": true + } + } + }, + "example": [ + { + "name": "10.0.1.1", + "description": "Upstream BGP neighbor", + "remoteAs": 65002, + "password": "bgpSecretKey123", + "ebgpMultihop": 1, + "fallOver": "bfd", + "bfdTimers": { + "transmitInterval": 300, + "receiveInterval": 300, + "detectionMultiplier": 3 + }, + "enabled": true + } + ] + }, + "addressFamilies": { + "type": "array", + "description": "List of address family configurations for BGP.\nEach entry defines an internet protocol (e.g. `ipv4`) and an optional\nlist of routing protocols to redistribute into BGP.\nIf omitted, a default `ipv4` address family with `kernel` and `connected`\nredistribution is applied automatically.\n", + "items": { + "type": "object", + "description": "An address family configuration for BGP.\nDefines the internet protocol and the list of routing protocols\nto redistribute into BGP for that address family.\nOnly `ipv4` is currently supported for `internetProtocol`.\n", + "required": [ + "internetProtocol", + "redistributionList" + ], + "properties": { + "internetProtocol": { + "type": "string", + "description": "The internet protocol for this address family.\nCurrently only `ipv4` is supported.\n", + "example": "ipv4" + }, + "redistributionList": { + "type": "array", + "description": "List of routing protocols to redistribute into BGP for this address family.\nIf omitted or empty, no redistribution is configured.\n", + "items": { + "type": "object", + "description": "A routing protocol redistribution entry for a BGP address family.", + "required": [ + "routingProtocol" + ], + "properties": { + "routingProtocol": { + "type": "string", + "description": "The routing protocol to redistribute into BGP (e.g. `connected`, `kernel`).\nThe accepted values depend on the BIG-IP version and configuration.\n", + "example": "connected" + } + } + }, + "example": [ + { + "routingProtocol": "connected" + }, + { + "routingProtocol": "kernel" + } + ] + } + } + }, + "example": [ + { + "internetProtocol": "ipv4", + "redistributionList": [ + { + "routingProtocol": "connected" + }, + { + "routingProtocol": "kernel" + } + ] + } + ] + } + } + } + } + } + } + } + }, + "required": [ + "id", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Payload for partially updating a device template (PATCH).\nAll fields are optional \u2014 only provided fields are modified.\nFor `definition`, merge-patch semantics apply.\n", + "properties": { + "name": { + "type": "string", + "description": "Human-readable name. Must be unique.", + "minLength": 1, + "maxLength": 255, + "example": "BIG-IP Standard Template v2" + }, + "provider": { + "type": "string", + "description": "Provider or vendor.", + "minLength": 1, + "maxLength": 255, + "example": "VMware" + }, + "description": { + "type": "string", + "description": "Optional description. Set to `null` to clear.", + "nullable": true, + "maxLength": 1000, + "example": "Updated description" + }, + "draft": { + "type": "boolean", + "description": "Controls DRAFT state on partial update." + }, + "definition": { + "type": "object", + "description": "Partial template definition for merge-patching (used by PATCH).\nAll fields are optional \u2014 only provided fields are updated.\nOmitted fields retain their current values.\nTo explicitly clear a nullable field, set it to `null`.\n", + "properties": { + "rootPassword": { + "type": "string", + "description": "BIG-IP root password.", + "nullable": true, + "minLength": 1, + "example": "s3cur3P@ss!" + }, + "timeZone": { + "type": "string", + "description": "NTP timezone string.", + "nullable": true, + "example": "America/Los_Angeles" + }, + "defaultRoute": { + "type": "string", + "description": "Default network gateway route.", + "nullable": true, + "example": "10.0.0.1" + }, + "managementSslPort": { + "type": "integer", + "description": "BIG-IP management SSL port.", + "nullable": true, + "example": 443 + }, + "managementIp": { + "type": "object", + "description": "Management IP configuration.\n\nThe management IP is configured via DHCP. This field is reserved for future use.\n\nThe field should be omitted or set to `null`.\n", + "properties": {} + }, + "hostnameComponents": { + "type": "array", + "description": "Ordered array of hostname building blocks.", + "items": { + "type": "object", + "description": "A hostname building block.", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "description": "Component type.", + "enum": [ + "STATIC_TEXT", + "SERIAL_NUMBER" + ], + "example": "STATIC_TEXT" + }, + "value": { + "type": "string", + "description": "Value for the component. Required for STATIC_TEXT, null for SERIAL_NUMBER.", + "nullable": true, + "example": "bigip-" + } + } + } + }, + "lookupServerList": { + "type": "array", + "description": "List of DNS lookup server addresses.", + "items": { + "type": "string" + } + }, + "ntpServerList": { + "type": "array", + "description": "List of NTP server addresses.", + "items": { + "type": "string" + } + }, + "userAccountList": { + "type": "array", + "description": "Array of BIG-IP user accounts.", + "items": { + "type": "object", + "description": "A BIG-IP user account definition with required credentials and role assignment.", + "required": [ + "username", + "password", + "role" + ], + "properties": { + "username": { + "type": "string", + "description": "Username for the BIG-IP account. Must start with a letter or underscore,\nand contain only letters, digits, hyphens, dots, or underscores.\n", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z_][-a-zA-Z_.0-9]*$", + "example": "admin" + }, + "password": { + "type": "string", + "description": "Password for the BIG-IP account. Must be at least 8 characters.", + "minLength": 8, + "maxLength": 255, + "example": "adminP@ss!" + }, + "role": { + "type": "string", + "description": "User role on the BIG-IP device. Defines the access level and permissions\nfor the user account. Common roles include 'admin', 'operator', 'guest', etc.\n", + "minLength": 1, + "maxLength": 255, + "example": "admin" + }, + "shell": { + "type": "string", + "description": "Shell access level for the user (e.g., 'bash', 'tmsh', 'none').", + "example": "bash" + } + } + } + }, + "provisionedModuleList": { + "type": "array", + "description": "Array of BIG-IP modules to provision.", + "items": { + "type": "object", + "description": "A BIG-IP module provisioning entry.", + "required": [ + "module", + "level" + ], + "properties": { + "module": { + "type": "string", + "description": "BIG-IP module name.", + "enum": [ + "AFM", + "AM", + "APM", + "ASM", + "AVR", + "DOS", + "FPS", + "GTM", + "ILX", + "LC", + "LTM", + "PEM", + "SWG", + "URLDB" + ], + "example": "LTM" + }, + "level": { + "type": "string", + "description": "Provisioning level.", + "enum": [ + "DEDICATED", + "MINIMUM", + "NOMINAL", + "NONE" + ], + "example": "NOMINAL" + } + } + } + }, + "networkRouteList": { + "type": "array", + "description": "Array of network interface routes.", + "items": { + "type": "object", + "description": "A network route definition.", + "required": [ + "name", + "gatewayAddress", + "destination" + ], + "properties": { + "name": { + "type": "string", + "example": "default" + }, + "gatewayAddress": { + "type": "string", + "example": "10.0.0.1" + }, + "destination": { + "type": "string", + "example": "0.0.0.0/0" + } + } + } + }, + "vlanList": { + "type": "array", + "description": "Array of VLAN definitions.", + "items": { + "type": "object", + "description": "A VLAN definition.", + "required": [ + "name", + "nic" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "example": "external" + }, + "nic": { + "type": "string", + "description": "Network interface card identifier (e.g., \"1.1\", \"1.2\").", + "pattern": "^[0-9]+\\.[0-9]+$", + "example": "1.1" + }, + "mtu": { + "type": "integer", + "description": "Maximum transmission unit size in bytes.", + "minimum": 576, + "maximum": 9198, + "example": 1500 + }, + "tag": { + "type": "integer", + "description": "VLAN tag identifier.", + "minimum": 1, + "maximum": 4094, + "example": 100 + } + } + } + }, + "selfIpList": { + "type": "array", + "description": "Array of self-IP definitions. Replaces the entire selfIpList on PATCH.\n", + "items": { + "type": "object", + "description": "A self-IP definition for the BIG-IP device.\n\nSelf IPs are allocated from an IP pool specified by `ipPoolReference`.\n", + "required": [ + "name", + "vlanName", + "ipPoolReference" + ], + "properties": { + "name": { + "type": "string", + "description": "Self-IP name. Must be unique within the template.", + "example": "external-self" + }, + "ipPoolReference": { + "type": "string", + "format": "uuid", + "description": "UUID referencing an existing IP pool for self-IP allocation.\n", + "example": "c3d4e5f6-a7b8-4890-8bcd-ef1234567892" + }, + "vlanName": { + "type": "string", + "description": "Name of the VLAN this self-IP is associated with.", + "example": "external" + }, + "portLockdown": { + "type": "string", + "description": "Port lockdown mode.", + "enum": [ + "none", + "default", + "all", + "custom", + "custom-default" + ], + "default": "none", + "example": "default" + }, + "allowServices": { + "type": "array", + "description": "Allowed services when portLockdown is custom/custom-default.", + "nullable": true, + "items": { + "type": "string" + }, + "example": null + } + } + } + }, + "bgpConfig": { + "type": "object", + "description": "BGP routing configuration for the BIG-IP device.", + "required": [ + "name", + "localAs", + "routerId", + "routeDomain", + "addressFamilies" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the BGP configuration.", + "example": "my_bgp" + }, + "description": { + "type": "string", + "description": "Optional description of the BGP configuration.", + "nullable": true, + "example": "Example BGP configuration" + }, + "localAs": { + "type": "integer", + "description": "Local AS number.", + "minimum": 1, + "maximum": 4294967295, + "example": 65001 + }, + "routerId": { + "type": "string", + "description": "Router ID reference. Must be the name of a self IP defined in the selfIpList.\nThe actual router ID (IP address) will be resolved from the referenced self IP's address at deployment time.\n", + "example": "external-self" + }, + "routeDomain": { + "type": "string", + "description": "Route domain for the BGP configuration.", + "example": "/Common/0" + }, + "enabled": { + "type": "boolean", + "description": "Whether BGP is enabled.", + "default": true, + "example": true + }, + "defaultLocalPreference": { + "type": "integer", + "description": "Default local preference value.", + "default": 100, + "example": 100 + }, + "holdTime": { + "type": "integer", + "description": "BGP hold time in seconds.", + "default": 90, + "example": 90 + }, + "keepAlive": { + "type": "integer", + "description": "BGP keepalive interval in seconds.", + "default": 30, + "example": 30 + }, + "neighbor": { + "type": "array", + "description": "List of BGP neighbors.", + "items": { + "type": "object", + "description": "A BGP neighbor configuration.", + "required": [ + "name", + "remoteAs" + ], + "properties": { + "name": { + "type": "string", + "description": "IP address of the BGP neighbor.", + "example": "10.0.1.1" + }, + "description": { + "type": "string", + "description": "Optional description of the neighbor.", + "nullable": true, + "example": "Upstream BGP neighbor" + }, + "remoteAs": { + "type": "integer", + "description": "Remote AS number of the neighbor.", + "minimum": 1, + "maximum": 4294967295, + "example": 65002 + }, + "password": { + "type": "string", + "description": "Optional password for BGP authentication.", + "nullable": true, + "minLength": 1, + "maxLength": 255, + "example": "SecureBGPPassword" + }, + "ebgpMultihop": { + "type": "integer", + "description": "Allow EBGP neighbors not on directly connected networks.\nSpecifies the maximum number of hops allowed to reach the neighbor.\n", + "nullable": true, + "minimum": 1, + "maximum": 255, + "default": 1, + "example": 1 + }, + "fallOver": { + "type": "string", + "description": "Fall-over detection method for BGP neighbor.\n- \"bfd\": Bidirectional Forwarding Detection (BFD)\n- \"bfd-multihop\": BFD for multihop neighbors\n- \"none\": No fall-over detection\n", + "enum": [ + "bfd", + "bfd-multihop", + "none" + ], + "default": "none", + "example": "bfd", + "nullable": true + }, + "bfdTimers": { + "description": "BFD timer configuration (required if fallOver is \"bfd\" or \"bfd-multihop\").\n", + "nullable": true, + "type": "object", + "required": [ + "transmitInterval", + "receiveInterval", + "detectionMultiplier" + ], + "properties": { + "transmitInterval": { + "type": "integer", + "description": "BFD transmission interval in milliseconds.\nThe time interval between BFD control packets sent to the peer.\n", + "minimum": 1, + "maximum": 60000, + "example": 300 + }, + "receiveInterval": { + "type": "integer", + "description": "BFD reception interval in milliseconds.\nThe time interval expected between BFD control packets received from the peer.\n", + "minimum": 1, + "maximum": 60000, + "example": 300 + }, + "detectionMultiplier": { + "type": "integer", + "description": "BFD detection multiplier.\nThe number of BFD packets that must be missed to declare the session down.\nDetection time = transmitInterval \u00d7 detectionMultiplier.\n", + "minimum": 1, + "maximum": 50, + "example": 3 + } + } + }, + "enabled": { + "type": "boolean", + "description": "Whether the neighbor is enabled.", + "default": true, + "example": true + } + } + }, + "example": [ + { + "name": "10.0.1.1", + "description": "Upstream BGP neighbor", + "remoteAs": 65002, + "password": "bgpSecretKey123", + "ebgpMultihop": 1, + "fallOver": "bfd", + "bfdTimers": { + "transmitInterval": 300, + "receiveInterval": 300, + "detectionMultiplier": 3 + }, + "enabled": true + } + ] + }, + "addressFamilies": { + "type": "array", + "description": "List of address family configurations for BGP.\nEach entry defines an internet protocol (e.g. `ipv4`) and an optional\nlist of routing protocols to redistribute into BGP.\nIf omitted, a default `ipv4` address family with `kernel` and `connected`\nredistribution is applied automatically.\n", + "items": { + "type": "object", + "description": "An address family configuration for BGP.\nDefines the internet protocol and the list of routing protocols\nto redistribute into BGP for that address family.\nOnly `ipv4` is currently supported for `internetProtocol`.\n", + "required": [ + "internetProtocol", + "redistributionList" + ], + "properties": { + "internetProtocol": { + "type": "string", + "description": "The internet protocol for this address family.\nCurrently only `ipv4` is supported.\n", + "example": "ipv4" + }, + "redistributionList": { + "type": "array", + "description": "List of routing protocols to redistribute into BGP for this address family.\nIf omitted or empty, no redistribution is configured.\n", + "items": { + "type": "object", + "description": "A routing protocol redistribution entry for a BGP address family.", + "required": [ + "routingProtocol" + ], + "properties": { + "routingProtocol": { + "type": "string", + "description": "The routing protocol to redistribute into BGP (e.g. `connected`, `kernel`).\nThe accepted values depend on the BIG-IP version and configuration.\n", + "example": "connected" + } + } + }, + "example": [ + { + "routingProtocol": "connected" + }, + { + "routingProtocol": "kernel" + } + ] + } + } + }, + "example": [ + { + "internetProtocol": "ipv4", + "redistributionList": [ + { + "routingProtocol": "connected" + }, + { + "routingProtocol": "kernel" + } + ] + } + ] + } + } + } + } + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "78ddcd36-d03e-49a8-bcb4-f0f063e660d6", + "created": "2026-08-28T15:12:57.833Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 102, + "reference": "fd834aad-b2ae-4185-8ca4-8a0e28ddffe9", + "type": "workflow", + "folder": "/Device Templates", + "document": { + "name": "Unlock Device Template", + "description": "Unlock Device Template", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "UnlockDeviceTemplate", + "canvasName": "UnlockDeviceTemplate", + "summary": "UnlockDeviceTemplate", + "description": "UnlockDeviceTemplate", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "ac305a82-b1de-407a-b4d6-9853010598b0", + "created": "2026-08-28T15:12:57.992Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 103, + "reference": "6c9fc7da-cfab-466e-a42b-d3a38fd05d79", + "type": "workflow", + "folder": "/Device Templates", + "document": { + "name": "Update Device Template", + "description": "Update Device Template", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "UpdateDeviceTemplate", + "canvasName": "UpdateDeviceTemplate", + "summary": "UpdateDeviceTemplate", + "description": "UpdateDeviceTemplate", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Payload for creating (POST) or fully replacing (PUT) a device template.\n", + "required": [ + "name", + "provider", + "definition" + ], + "properties": { + "name": { + "type": "string", + "description": "Human-readable name for the device template. Must be unique.", + "minLength": 1, + "maxLength": 255, + "example": "BIG-IP Standard Template" + }, + "provider": { + "type": "string", + "description": "Provider or vendor (e.g. VMware, AWS, Azure).", + "minLength": 1, + "maxLength": 255, + "example": "VMware" + }, + "description": { + "type": "string", + "description": "Optional human-readable description.", + "nullable": true, + "maxLength": 1000, + "example": "Standard VMware configuration for production workloads" + }, + "draft": { + "type": "boolean", + "description": "When `true`, the template is created/kept in DRAFT state.\nWhen `false` or omitted, a DRAFT template is promoted to NEW.\n", + "default": false + }, + "definition": { + "type": "object", + "description": "Template definition containing all BIG-IP device configuration parameters.", + "required": [ + "rootPassword" + ], + "properties": { + "rootPassword": { + "type": "string", + "description": "BIG-IP root password. Must be at least 8 characters.", + "minLength": 8, + "example": "s3cur3P@ss!" + }, + "timeZone": { + "type": "string", + "description": "NTP timezone string applied to the BIG-IP device.", + "nullable": true, + "maxLength": 100, + "example": "America/Los_Angeles" + }, + "defaultRoute": { + "type": "string", + "description": "Default network gateway route for the BIG-IP device. Must be a valid IP address without prefix.", + "nullable": true, + "example": "10.0.0.1" + }, + "managementSslPort": { + "type": "integer", + "description": "BIG-IP management SSL port. If omitted, the device default is used.", + "nullable": true, + "minimum": 0, + "maximum": 65535, + "example": 443 + }, + "managementIp": { + "type": "object", + "description": "Management IP configuration.\n\nThe management IP is configured via DHCP. This field is reserved for future use.\n\nThe field should be omitted or set to `null`.\n", + "properties": {} + }, + "hostnameComponents": { + "type": "array", + "description": "Ordered array of hostname building blocks.", + "items": { + "type": "object", + "description": "A hostname building block.", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "description": "Component type.", + "enum": [ + "STATIC_TEXT", + "SERIAL_NUMBER" + ], + "example": "STATIC_TEXT" + }, + "value": { + "type": "string", + "description": "Value for the component. Required for STATIC_TEXT, null for SERIAL_NUMBER.", + "nullable": true, + "example": "bigip-" + } + } + }, + "example": [ + { + "type": "STATIC_TEXT", + "value": "bigip-" + }, + { + "type": "SERIAL_NUMBER", + "value": null + } + ] + }, + "lookupServerList": { + "type": "array", + "description": "List of DNS lookup server addresses.", + "items": { + "type": "string" + }, + "example": [ + "8.8.8.8", + "8.8.4.4" + ] + }, + "ntpServerList": { + "type": "array", + "description": "List of NTP server addresses.", + "items": { + "type": "string" + }, + "example": [ + "0.pool.ntp.org" + ] + }, + "userAccountList": { + "type": "array", + "description": "Array of BIG-IP user accounts to create.", + "items": { + "type": "object", + "description": "A BIG-IP user account definition with required credentials and role assignment.", + "required": [ + "username", + "password", + "role" + ], + "properties": { + "username": { + "type": "string", + "description": "Username for the BIG-IP account. Must start with a letter or underscore,\nand contain only letters, digits, hyphens, dots, or underscores.\n", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z_][-a-zA-Z_.0-9]*$", + "example": "admin" + }, + "password": { + "type": "string", + "description": "Password for the BIG-IP account. Must be at least 8 characters.", + "minLength": 8, + "maxLength": 255, + "example": "adminP@ss!" + }, + "role": { + "type": "string", + "description": "User role on the BIG-IP device. Defines the access level and permissions\nfor the user account. Common roles include 'admin', 'operator', 'guest', etc.\n", + "minLength": 1, + "maxLength": 255, + "example": "admin" + }, + "shell": { + "type": "string", + "description": "Shell access level for the user (e.g., 'bash', 'tmsh', 'none').", + "example": "bash" + } + } + } + }, + "provisionedModuleList": { + "type": "array", + "description": "Array of BIG-IP modules to provision.", + "items": { + "type": "object", + "description": "A BIG-IP module provisioning entry.", + "required": [ + "module", + "level" + ], + "properties": { + "module": { + "type": "string", + "description": "BIG-IP module name.", + "enum": [ + "AFM", + "AM", + "APM", + "ASM", + "AVR", + "DOS", + "FPS", + "GTM", + "ILX", + "LC", + "LTM", + "PEM", + "SWG", + "URLDB" + ], + "example": "LTM" + }, + "level": { + "type": "string", + "description": "Provisioning level.", + "enum": [ + "DEDICATED", + "MINIMUM", + "NOMINAL", + "NONE" + ], + "example": "NOMINAL" + } + } + } + }, + "networkRouteList": { + "type": "array", + "description": "Array of network interface routes.", + "items": { + "type": "object", + "description": "A network route definition.", + "required": [ + "name", + "gatewayAddress", + "destination" + ], + "properties": { + "name": { + "type": "string", + "example": "default" + }, + "gatewayAddress": { + "type": "string", + "example": "10.0.0.1" + }, + "destination": { + "type": "string", + "example": "0.0.0.0/0" + } + } + } + }, + "vlanList": { + "type": "array", + "description": "Array of VLAN definitions.", + "items": { + "type": "object", + "description": "A VLAN definition.", + "required": [ + "name", + "nic" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "example": "external" + }, + "nic": { + "type": "string", + "description": "Network interface card identifier (e.g., \"1.1\", \"1.2\").", + "pattern": "^[0-9]+\\.[0-9]+$", + "example": "1.1" + }, + "mtu": { + "type": "integer", + "description": "Maximum transmission unit size in bytes.", + "minimum": 576, + "maximum": 9198, + "example": 1500 + }, + "tag": { + "type": "integer", + "description": "VLAN tag identifier.", + "minimum": 1, + "maximum": 4094, + "example": 100 + } + } + } + }, + "selfIpList": { + "type": "array", + "description": "Array of self-IP definitions for the BIG-IP device.", + "items": { + "type": "object", + "description": "A self-IP definition for the BIG-IP device.\n\nSelf IPs are allocated from an IP pool specified by `ipPoolReference`.\n", + "required": [ + "name", + "vlanName", + "ipPoolReference" + ], + "properties": { + "name": { + "type": "string", + "description": "Self-IP name. Must be unique within the template.", + "example": "external-self" + }, + "ipPoolReference": { + "type": "string", + "format": "uuid", + "description": "UUID referencing an existing IP pool for self-IP allocation.\n", + "example": "c3d4e5f6-a7b8-4890-8bcd-ef1234567892" + }, + "vlanName": { + "type": "string", + "description": "Name of the VLAN this self-IP is associated with.", + "example": "external" + }, + "portLockdown": { + "type": "string", + "description": "Port lockdown mode.", + "enum": [ + "none", + "default", + "all", + "custom", + "custom-default" + ], + "default": "none", + "example": "default" + }, + "allowServices": { + "type": "array", + "description": "Allowed services when portLockdown is custom/custom-default.", + "nullable": true, + "items": { + "type": "string" + }, + "example": null + } + } + } + }, + "bgpConfig": { + "type": "object", + "description": "BGP routing configuration for the BIG-IP device.", + "required": [ + "name", + "localAs", + "routerId", + "routeDomain", + "addressFamilies" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the BGP configuration.", + "example": "my_bgp" + }, + "description": { + "type": "string", + "description": "Optional description of the BGP configuration.", + "nullable": true, + "example": "Example BGP configuration" + }, + "localAs": { + "type": "integer", + "description": "Local AS number.", + "minimum": 1, + "maximum": 4294967295, + "example": 65001 + }, + "routerId": { + "type": "string", + "description": "Router ID reference. Must be the name of a self IP defined in the selfIpList.\nThe actual router ID (IP address) will be resolved from the referenced self IP's address at deployment time.\n", + "example": "external-self" + }, + "routeDomain": { + "type": "string", + "description": "Route domain for the BGP configuration.", + "example": "/Common/0" + }, + "enabled": { + "type": "boolean", + "description": "Whether BGP is enabled.", + "default": true, + "example": true + }, + "defaultLocalPreference": { + "type": "integer", + "description": "Default local preference value.", + "default": 100, + "example": 100 + }, + "holdTime": { + "type": "integer", + "description": "BGP hold time in seconds.", + "default": 90, + "example": 90 + }, + "keepAlive": { + "type": "integer", + "description": "BGP keepalive interval in seconds.", + "default": 30, + "example": 30 + }, + "neighbor": { + "type": "array", + "description": "List of BGP neighbors.", + "items": { + "type": "object", + "description": "A BGP neighbor configuration.", + "required": [ + "name", + "remoteAs" + ], + "properties": { + "name": { + "type": "string", + "description": "IP address of the BGP neighbor.", + "example": "10.0.1.1" + }, + "description": { + "type": "string", + "description": "Optional description of the neighbor.", + "nullable": true, + "example": "Upstream BGP neighbor" + }, + "remoteAs": { + "type": "integer", + "description": "Remote AS number of the neighbor.", + "minimum": 1, + "maximum": 4294967295, + "example": 65002 + }, + "password": { + "type": "string", + "description": "Optional password for BGP authentication.", + "nullable": true, + "minLength": 1, + "maxLength": 255, + "example": "SecureBGPPassword" + }, + "ebgpMultihop": { + "type": "integer", + "description": "Allow EBGP neighbors not on directly connected networks.\nSpecifies the maximum number of hops allowed to reach the neighbor.\n", + "nullable": true, + "minimum": 1, + "maximum": 255, + "default": 1, + "example": 1 + }, + "fallOver": { + "type": "string", + "description": "Fall-over detection method for BGP neighbor.\n- \"bfd\": Bidirectional Forwarding Detection (BFD)\n- \"bfd-multihop\": BFD for multihop neighbors\n- \"none\": No fall-over detection\n", + "enum": [ + "bfd", + "bfd-multihop", + "none" + ], + "default": "none", + "example": "bfd", + "nullable": true + }, + "bfdTimers": { + "description": "BFD timer configuration (required if fallOver is \"bfd\" or \"bfd-multihop\").\n", + "nullable": true, + "type": "object", + "required": [ + "transmitInterval", + "receiveInterval", + "detectionMultiplier" + ], + "properties": { + "transmitInterval": { + "type": "integer", + "description": "BFD transmission interval in milliseconds.\nThe time interval between BFD control packets sent to the peer.\n", + "minimum": 1, + "maximum": 60000, + "example": 300 + }, + "receiveInterval": { + "type": "integer", + "description": "BFD reception interval in milliseconds.\nThe time interval expected between BFD control packets received from the peer.\n", + "minimum": 1, + "maximum": 60000, + "example": 300 + }, + "detectionMultiplier": { + "type": "integer", + "description": "BFD detection multiplier.\nThe number of BFD packets that must be missed to declare the session down.\nDetection time = transmitInterval \u00d7 detectionMultiplier.\n", + "minimum": 1, + "maximum": 50, + "example": 3 + } + } + }, + "enabled": { + "type": "boolean", + "description": "Whether the neighbor is enabled.", + "default": true, + "example": true + } + } + }, + "example": [ + { + "name": "10.0.1.1", + "description": "Upstream BGP neighbor", + "remoteAs": 65002, + "password": "bgpSecretKey123", + "ebgpMultihop": 1, + "fallOver": "bfd", + "bfdTimers": { + "transmitInterval": 300, + "receiveInterval": 300, + "detectionMultiplier": 3 + }, + "enabled": true + } + ] + }, + "addressFamilies": { + "type": "array", + "description": "List of address family configurations for BGP.\nEach entry defines an internet protocol (e.g. `ipv4`) and an optional\nlist of routing protocols to redistribute into BGP.\nIf omitted, a default `ipv4` address family with `kernel` and `connected`\nredistribution is applied automatically.\n", + "items": { + "type": "object", + "description": "An address family configuration for BGP.\nDefines the internet protocol and the list of routing protocols\nto redistribute into BGP for that address family.\nOnly `ipv4` is currently supported for `internetProtocol`.\n", + "required": [ + "internetProtocol", + "redistributionList" + ], + "properties": { + "internetProtocol": { + "type": "string", + "description": "The internet protocol for this address family.\nCurrently only `ipv4` is supported.\n", + "example": "ipv4" + }, + "redistributionList": { + "type": "array", + "description": "List of routing protocols to redistribute into BGP for this address family.\nIf omitted or empty, no redistribution is configured.\n", + "items": { + "type": "object", + "description": "A routing protocol redistribution entry for a BGP address family.", + "required": [ + "routingProtocol" + ], + "properties": { + "routingProtocol": { + "type": "string", + "description": "The routing protocol to redistribute into BGP (e.g. `connected`, `kernel`).\nThe accepted values depend on the BIG-IP version and configuration.\n", + "example": "connected" + } + } + }, + "example": [ + { + "routingProtocol": "connected" + }, + { + "routingProtocol": "kernel" + } + ] + } + } + }, + "example": [ + { + "internetProtocol": "ipv4", + "redistributionList": [ + { + "routingProtocol": "connected" + }, + { + "routingProtocol": "kernel" + } + ] + } + ] + } + } + } + } + } + } + } + }, + "required": [ + "id", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Payload for creating (POST) or fully replacing (PUT) a device template.\n", + "required": [ + "name", + "provider", + "definition" + ], + "properties": { + "name": { + "type": "string", + "description": "Human-readable name for the device template. Must be unique.", + "minLength": 1, + "maxLength": 255, + "example": "BIG-IP Standard Template" + }, + "provider": { + "type": "string", + "description": "Provider or vendor (e.g. VMware, AWS, Azure).", + "minLength": 1, + "maxLength": 255, + "example": "VMware" + }, + "description": { + "type": "string", + "description": "Optional human-readable description.", + "nullable": true, + "maxLength": 1000, + "example": "Standard VMware configuration for production workloads" + }, + "draft": { + "type": "boolean", + "description": "When `true`, the template is created/kept in DRAFT state.\nWhen `false` or omitted, a DRAFT template is promoted to NEW.\n", + "default": false + }, + "definition": { + "type": "object", + "description": "Template definition containing all BIG-IP device configuration parameters.", + "required": [ + "rootPassword" + ], + "properties": { + "rootPassword": { + "type": "string", + "description": "BIG-IP root password. Must be at least 8 characters.", + "minLength": 8, + "example": "s3cur3P@ss!" + }, + "timeZone": { + "type": "string", + "description": "NTP timezone string applied to the BIG-IP device.", + "nullable": true, + "maxLength": 100, + "example": "America/Los_Angeles" + }, + "defaultRoute": { + "type": "string", + "description": "Default network gateway route for the BIG-IP device. Must be a valid IP address without prefix.", + "nullable": true, + "example": "10.0.0.1" + }, + "managementSslPort": { + "type": "integer", + "description": "BIG-IP management SSL port. If omitted, the device default is used.", + "nullable": true, + "minimum": 0, + "maximum": 65535, + "example": 443 + }, + "managementIp": { + "type": "object", + "description": "Management IP configuration.\n\nThe management IP is configured via DHCP. This field is reserved for future use.\n\nThe field should be omitted or set to `null`.\n", + "properties": {} + }, + "hostnameComponents": { + "type": "array", + "description": "Ordered array of hostname building blocks.", + "items": { + "type": "object", + "description": "A hostname building block.", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "description": "Component type.", + "enum": [ + "STATIC_TEXT", + "SERIAL_NUMBER" + ], + "example": "STATIC_TEXT" + }, + "value": { + "type": "string", + "description": "Value for the component. Required for STATIC_TEXT, null for SERIAL_NUMBER.", + "nullable": true, + "example": "bigip-" + } + } + }, + "example": [ + { + "type": "STATIC_TEXT", + "value": "bigip-" + }, + { + "type": "SERIAL_NUMBER", + "value": null + } + ] + }, + "lookupServerList": { + "type": "array", + "description": "List of DNS lookup server addresses.", + "items": { + "type": "string" + }, + "example": [ + "8.8.8.8", + "8.8.4.4" + ] + }, + "ntpServerList": { + "type": "array", + "description": "List of NTP server addresses.", + "items": { + "type": "string" + }, + "example": [ + "0.pool.ntp.org" + ] + }, + "userAccountList": { + "type": "array", + "description": "Array of BIG-IP user accounts to create.", + "items": { + "type": "object", + "description": "A BIG-IP user account definition with required credentials and role assignment.", + "required": [ + "username", + "password", + "role" + ], + "properties": { + "username": { + "type": "string", + "description": "Username for the BIG-IP account. Must start with a letter or underscore,\nand contain only letters, digits, hyphens, dots, or underscores.\n", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z_][-a-zA-Z_.0-9]*$", + "example": "admin" + }, + "password": { + "type": "string", + "description": "Password for the BIG-IP account. Must be at least 8 characters.", + "minLength": 8, + "maxLength": 255, + "example": "adminP@ss!" + }, + "role": { + "type": "string", + "description": "User role on the BIG-IP device. Defines the access level and permissions\nfor the user account. Common roles include 'admin', 'operator', 'guest', etc.\n", + "minLength": 1, + "maxLength": 255, + "example": "admin" + }, + "shell": { + "type": "string", + "description": "Shell access level for the user (e.g., 'bash', 'tmsh', 'none').", + "example": "bash" + } + } + } + }, + "provisionedModuleList": { + "type": "array", + "description": "Array of BIG-IP modules to provision.", + "items": { + "type": "object", + "description": "A BIG-IP module provisioning entry.", + "required": [ + "module", + "level" + ], + "properties": { + "module": { + "type": "string", + "description": "BIG-IP module name.", + "enum": [ + "AFM", + "AM", + "APM", + "ASM", + "AVR", + "DOS", + "FPS", + "GTM", + "ILX", + "LC", + "LTM", + "PEM", + "SWG", + "URLDB" + ], + "example": "LTM" + }, + "level": { + "type": "string", + "description": "Provisioning level.", + "enum": [ + "DEDICATED", + "MINIMUM", + "NOMINAL", + "NONE" + ], + "example": "NOMINAL" + } + } + } + }, + "networkRouteList": { + "type": "array", + "description": "Array of network interface routes.", + "items": { + "type": "object", + "description": "A network route definition.", + "required": [ + "name", + "gatewayAddress", + "destination" + ], + "properties": { + "name": { + "type": "string", + "example": "default" + }, + "gatewayAddress": { + "type": "string", + "example": "10.0.0.1" + }, + "destination": { + "type": "string", + "example": "0.0.0.0/0" + } + } + } + }, + "vlanList": { + "type": "array", + "description": "Array of VLAN definitions.", + "items": { + "type": "object", + "description": "A VLAN definition.", + "required": [ + "name", + "nic" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "example": "external" + }, + "nic": { + "type": "string", + "description": "Network interface card identifier (e.g., \"1.1\", \"1.2\").", + "pattern": "^[0-9]+\\.[0-9]+$", + "example": "1.1" + }, + "mtu": { + "type": "integer", + "description": "Maximum transmission unit size in bytes.", + "minimum": 576, + "maximum": 9198, + "example": 1500 + }, + "tag": { + "type": "integer", + "description": "VLAN tag identifier.", + "minimum": 1, + "maximum": 4094, + "example": 100 + } + } + } + }, + "selfIpList": { + "type": "array", + "description": "Array of self-IP definitions for the BIG-IP device.", + "items": { + "type": "object", + "description": "A self-IP definition for the BIG-IP device.\n\nSelf IPs are allocated from an IP pool specified by `ipPoolReference`.\n", + "required": [ + "name", + "vlanName", + "ipPoolReference" + ], + "properties": { + "name": { + "type": "string", + "description": "Self-IP name. Must be unique within the template.", + "example": "external-self" + }, + "ipPoolReference": { + "type": "string", + "format": "uuid", + "description": "UUID referencing an existing IP pool for self-IP allocation.\n", + "example": "c3d4e5f6-a7b8-4890-8bcd-ef1234567892" + }, + "vlanName": { + "type": "string", + "description": "Name of the VLAN this self-IP is associated with.", + "example": "external" + }, + "portLockdown": { + "type": "string", + "description": "Port lockdown mode.", + "enum": [ + "none", + "default", + "all", + "custom", + "custom-default" + ], + "default": "none", + "example": "default" + }, + "allowServices": { + "type": "array", + "description": "Allowed services when portLockdown is custom/custom-default.", + "nullable": true, + "items": { + "type": "string" + }, + "example": null + } + } + } + }, + "bgpConfig": { + "type": "object", + "description": "BGP routing configuration for the BIG-IP device.", + "required": [ + "name", + "localAs", + "routerId", + "routeDomain", + "addressFamilies" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the BGP configuration.", + "example": "my_bgp" + }, + "description": { + "type": "string", + "description": "Optional description of the BGP configuration.", + "nullable": true, + "example": "Example BGP configuration" + }, + "localAs": { + "type": "integer", + "description": "Local AS number.", + "minimum": 1, + "maximum": 4294967295, + "example": 65001 + }, + "routerId": { + "type": "string", + "description": "Router ID reference. Must be the name of a self IP defined in the selfIpList.\nThe actual router ID (IP address) will be resolved from the referenced self IP's address at deployment time.\n", + "example": "external-self" + }, + "routeDomain": { + "type": "string", + "description": "Route domain for the BGP configuration.", + "example": "/Common/0" + }, + "enabled": { + "type": "boolean", + "description": "Whether BGP is enabled.", + "default": true, + "example": true + }, + "defaultLocalPreference": { + "type": "integer", + "description": "Default local preference value.", + "default": 100, + "example": 100 + }, + "holdTime": { + "type": "integer", + "description": "BGP hold time in seconds.", + "default": 90, + "example": 90 + }, + "keepAlive": { + "type": "integer", + "description": "BGP keepalive interval in seconds.", + "default": 30, + "example": 30 + }, + "neighbor": { + "type": "array", + "description": "List of BGP neighbors.", + "items": { + "type": "object", + "description": "A BGP neighbor configuration.", + "required": [ + "name", + "remoteAs" + ], + "properties": { + "name": { + "type": "string", + "description": "IP address of the BGP neighbor.", + "example": "10.0.1.1" + }, + "description": { + "type": "string", + "description": "Optional description of the neighbor.", + "nullable": true, + "example": "Upstream BGP neighbor" + }, + "remoteAs": { + "type": "integer", + "description": "Remote AS number of the neighbor.", + "minimum": 1, + "maximum": 4294967295, + "example": 65002 + }, + "password": { + "type": "string", + "description": "Optional password for BGP authentication.", + "nullable": true, + "minLength": 1, + "maxLength": 255, + "example": "SecureBGPPassword" + }, + "ebgpMultihop": { + "type": "integer", + "description": "Allow EBGP neighbors not on directly connected networks.\nSpecifies the maximum number of hops allowed to reach the neighbor.\n", + "nullable": true, + "minimum": 1, + "maximum": 255, + "default": 1, + "example": 1 + }, + "fallOver": { + "type": "string", + "description": "Fall-over detection method for BGP neighbor.\n- \"bfd\": Bidirectional Forwarding Detection (BFD)\n- \"bfd-multihop\": BFD for multihop neighbors\n- \"none\": No fall-over detection\n", + "enum": [ + "bfd", + "bfd-multihop", + "none" + ], + "default": "none", + "example": "bfd", + "nullable": true + }, + "bfdTimers": { + "description": "BFD timer configuration (required if fallOver is \"bfd\" or \"bfd-multihop\").\n", + "nullable": true, + "type": "object", + "required": [ + "transmitInterval", + "receiveInterval", + "detectionMultiplier" + ], + "properties": { + "transmitInterval": { + "type": "integer", + "description": "BFD transmission interval in milliseconds.\nThe time interval between BFD control packets sent to the peer.\n", + "minimum": 1, + "maximum": 60000, + "example": 300 + }, + "receiveInterval": { + "type": "integer", + "description": "BFD reception interval in milliseconds.\nThe time interval expected between BFD control packets received from the peer.\n", + "minimum": 1, + "maximum": 60000, + "example": 300 + }, + "detectionMultiplier": { + "type": "integer", + "description": "BFD detection multiplier.\nThe number of BFD packets that must be missed to declare the session down.\nDetection time = transmitInterval \u00d7 detectionMultiplier.\n", + "minimum": 1, + "maximum": 50, + "example": 3 + } + } + }, + "enabled": { + "type": "boolean", + "description": "Whether the neighbor is enabled.", + "default": true, + "example": true + } + } + }, + "example": [ + { + "name": "10.0.1.1", + "description": "Upstream BGP neighbor", + "remoteAs": 65002, + "password": "bgpSecretKey123", + "ebgpMultihop": 1, + "fallOver": "bfd", + "bfdTimers": { + "transmitInterval": 300, + "receiveInterval": 300, + "detectionMultiplier": 3 + }, + "enabled": true + } + ] + }, + "addressFamilies": { + "type": "array", + "description": "List of address family configurations for BGP.\nEach entry defines an internet protocol (e.g. `ipv4`) and an optional\nlist of routing protocols to redistribute into BGP.\nIf omitted, a default `ipv4` address family with `kernel` and `connected`\nredistribution is applied automatically.\n", + "items": { + "type": "object", + "description": "An address family configuration for BGP.\nDefines the internet protocol and the list of routing protocols\nto redistribute into BGP for that address family.\nOnly `ipv4` is currently supported for `internetProtocol`.\n", + "required": [ + "internetProtocol", + "redistributionList" + ], + "properties": { + "internetProtocol": { + "type": "string", + "description": "The internet protocol for this address family.\nCurrently only `ipv4` is supported.\n", + "example": "ipv4" + }, + "redistributionList": { + "type": "array", + "description": "List of routing protocols to redistribute into BGP for this address family.\nIf omitted or empty, no redistribution is configured.\n", + "items": { + "type": "object", + "description": "A routing protocol redistribution entry for a BGP address family.", + "required": [ + "routingProtocol" + ], + "properties": { + "routingProtocol": { + "type": "string", + "description": "The routing protocol to redistribute into BGP (e.g. `connected`, `kernel`).\nThe accepted values depend on the BIG-IP version and configuration.\n", + "example": "connected" + } + } + }, + "example": [ + { + "routingProtocol": "connected" + }, + { + "routingProtocol": "kernel" + } + ] + } + } + }, + "example": [ + { + "internetProtocol": "ipv4", + "redistributionList": [ + { + "routingProtocol": "connected" + }, + { + "routingProtocol": "kernel" + } + ] + } + ] + } + } + } + } + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e151cd62-9125-4a51-8a51-2c096b470c86", + "created": "2026-08-28T15:12:57.790Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 104, + "reference": "53605eef-afa9-426a-9e7c-9eef270baab0", + "type": "workflow", + "folder": "/Device Templates", + "document": { + "name": "Validate Device Template", + "description": "Validate Device Template", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "ValidateDeviceTemplate", + "canvasName": "ValidateDeviceTemplate", + "summary": "ValidateDeviceTemplate", + "description": "ValidateDeviceTemplate", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "9ed0bc05-bcff-44db-afaa-2360601046f2", + "created": "2026-08-28T15:12:58.032Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 105, + "reference": "044298b2-19db-47b3-bbac-7e4dc790f2be", + "type": "workflow", + "folder": "/Observability", + "document": { + "name": "Get Execution", + "description": "Get Execution", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getExecution", + "canvasName": "getExecution", + "summary": "getExecution", + "description": "getExecution", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "workflowId": "$var.job.workflowId", + "jobId": "$var.job.jobId", + "executionId": "$var.job.executionId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "executionId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "workflowId", + "jobId", + "executionId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "executionId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "3859e708-3d64-45d2-adb3-ecee101ddda4", + "created": "2026-08-28T15:12:59.376Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 106, + "reference": "88874cf0-64ab-4009-98cb-56fbad71f24c", + "type": "workflow", + "folder": "/Observability", + "document": { + "name": "Get Execution Activity", + "description": "Get Execution Activity", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getExecutionActivity", + "canvasName": "getExecutionActivity", + "summary": "getExecutionActivity", + "description": "getExecutionActivity", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "workflowId": "$var.job.workflowId", + "jobId": "$var.job.jobId", + "executionId": "$var.job.executionId", + "activityId": "$var.job.activityId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "executionId": { + "type": "string", + "format": "uuid" + }, + "activityId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "workflowId", + "jobId", + "executionId", + "activityId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "executionId": { + "type": "string", + "format": "uuid" + }, + "activityId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "084bac8a-9861-4247-ab13-11dc03c19c37", + "created": "2026-08-28T15:12:59.435Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 107, + "reference": "5bfd3bf1-fd21-4d71-858c-60488fd9d8ef", + "type": "workflow", + "folder": "/Observability", + "document": { + "name": "List All Executions", + "description": "List All Executions", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listAllExecutions", + "canvasName": "listAllExecutions", + "summary": "listAllExecutions", + "description": "listAllExecutions", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "page": "$var.job.page", + "limit": "$var.job.limit", + "workflowId": "$var.job.workflowId", + "jobId": "$var.job.jobId", + "type": "$var.job.type", + "executionMode": "$var.job.executionMode", + "status": "$var.job.status", + "trigger": "$var.job.trigger", + "since": "$var.job.since", + "until": "$var.job.until" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + }, + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "executionMode": { + "type": "string", + "enum": [ + "CONTINUOUS", + "ON_DEMAND" + ] + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED", + "CANCELLED", + "TIMEOUT" + ] + }, + "trigger": { + "type": "string", + "enum": [ + "USER", + "ALERT", + "SYSTEM", + "SCHEDULE" + ] + }, + "since": { + "type": "string", + "format": "date-time" + }, + "until": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "page", + "limit", + "workflowId", + "jobId", + "type", + "executionMode", + "status", + "trigger", + "since", + "until" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + }, + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "executionMode": { + "type": "string", + "enum": [ + "CONTINUOUS", + "ON_DEMAND" + ] + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED", + "CANCELLED", + "TIMEOUT" + ] + }, + "trigger": { + "type": "string", + "enum": [ + "USER", + "ALERT", + "SYSTEM", + "SCHEDULE" + ] + }, + "since": { + "type": "string", + "format": "date-time" + }, + "until": { + "type": "string", + "format": "date-time" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "dd21533d-4517-40df-a9de-6e3e6ac3a16b", + "created": "2026-08-28T15:12:58.063Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 108, + "reference": "2b27a03d-4198-4e49-b0d4-1122a460f79f", + "type": "workflow", + "folder": "/Observability", + "document": { + "name": "List All Jobs", + "description": "List All Jobs", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listAllJobs", + "canvasName": "listAllJobs", + "summary": "listAllJobs", + "description": "listAllJobs", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "page": "$var.job.page", + "limit": "$var.job.limit", + "workflowId": "$var.job.workflowId", + "type": "$var.job.type", + "executionMode": "$var.job.executionMode", + "status": "$var.job.status" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + }, + "workflowId": { + "type": "string", + "format": "uuid" + }, + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "executionMode": { + "type": "string", + "enum": [ + "CONTINUOUS", + "ON_DEMAND" + ] + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSED", + "INACTIVE", + "ERROR", + "DELETING" + ] + } + }, + "required": [ + "page", + "limit", + "workflowId", + "type", + "executionMode", + "status" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + }, + "workflowId": { + "type": "string", + "format": "uuid" + }, + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "executionMode": { + "type": "string", + "enum": [ + "CONTINUOUS", + "ON_DEMAND" + ] + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSED", + "INACTIVE", + "ERROR", + "DELETING" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "d11c1429-191d-41de-ac6b-22ac002669be", + "created": "2026-08-28T15:12:58.435Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 109, + "reference": "90e0b57a-3087-4836-a38f-8f6a7b9d25e3", + "type": "workflow", + "folder": "/Observability", + "document": { + "name": "List Events", + "description": "List Events", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listEvents", + "canvasName": "listEvents", + "summary": "listEvents", + "description": "listEvents", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "workflowId": "$var.job.workflowId", + "jobId": "$var.job.jobId", + "page": "$var.job.page", + "limit": "$var.job.limit", + "source": "$var.job.source", + "eventType": "$var.job.eventType", + "correlationId": "$var.job.correlationId", + "since": "$var.job.since" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + }, + "source": { + "type": "string" + }, + "eventType": { + "type": "string" + }, + "correlationId": { + "type": "string", + "format": "uuid" + }, + "since": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "workflowId", + "jobId", + "page", + "limit", + "source", + "eventType", + "correlationId", + "since" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + }, + "source": { + "type": "string" + }, + "eventType": { + "type": "string" + }, + "correlationId": { + "type": "string", + "format": "uuid" + }, + "since": { + "type": "string", + "format": "date-time" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "800929ee-87a6-4abb-b3e2-e7ba0671d980", + "created": "2026-08-28T15:12:59.312Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 110, + "reference": "f486d71a-cdf5-4b23-b620-a17cbc62a57a", + "type": "workflow", + "folder": "/Observability", + "document": { + "name": "List Execution Activities", + "description": "List Execution Activities", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listExecutionActivities", + "canvasName": "listExecutionActivities", + "summary": "listExecutionActivities", + "description": "listExecutionActivities", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "workflowId": "$var.job.workflowId", + "jobId": "$var.job.jobId", + "executionId": "$var.job.executionId", + "page": "$var.job.page", + "limit": "$var.job.limit", + "activityType": "$var.job.activityType", + "status": "$var.job.status", + "since": "$var.job.since" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "executionId": { + "type": "string", + "format": "uuid" + }, + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + }, + "activityType": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "COMPLETED", + "FAILED", + "SKIPPED", + "CANCELLED" + ] + }, + "since": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "workflowId", + "jobId", + "executionId", + "page", + "limit", + "activityType", + "status", + "since" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "executionId": { + "type": "string", + "format": "uuid" + }, + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + }, + "activityType": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "COMPLETED", + "FAILED", + "SKIPPED", + "CANCELLED" + ] + }, + "since": { + "type": "string", + "format": "date-time" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "a62644fd-602b-40ce-88cb-0f52848f618a", + "created": "2026-08-28T15:12:59.405Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 111, + "reference": "532c84bc-286b-47d0-ae2a-7b107fb1f04e", + "type": "workflow", + "folder": "/Observability", + "document": { + "name": "List Executions", + "description": "List Executions", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listExecutions", + "canvasName": "listExecutions", + "summary": "listExecutions", + "description": "listExecutions", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "workflowId": "$var.job.workflowId", + "jobId": "$var.job.jobId", + "page": "$var.job.page", + "limit": "$var.job.limit", + "status": "$var.job.status", + "trigger": "$var.job.trigger", + "since": "$var.job.since", + "until": "$var.job.until" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED", + "CANCELLED", + "TIMEOUT" + ] + }, + "trigger": { + "type": "string", + "enum": [ + "USER", + "ALERT", + "SYSTEM", + "SCHEDULE" + ] + }, + "since": { + "type": "string", + "format": "date-time" + }, + "until": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "workflowId", + "jobId", + "page", + "limit", + "status", + "trigger", + "since", + "until" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + }, + "status": { + "type": "string", + "enum": [ + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED", + "CANCELLED", + "TIMEOUT" + ] + }, + "trigger": { + "type": "string", + "enum": [ + "USER", + "ALERT", + "SYSTEM", + "SCHEDULE" + ] + }, + "since": { + "type": "string", + "format": "date-time" + }, + "until": { + "type": "string", + "format": "date-time" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "82ea53b0-9396-439b-b444-63ed4d4e989b", + "created": "2026-08-28T15:12:59.342Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 112, + "reference": "beb7fdd3-bda3-41e4-96d3-8b3ff26c696b", + "type": "workflow", + "folder": "/Jobs", + "document": { + "name": "Bulk Delete Jobs", + "description": "Bulk Delete Jobs", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "bulkDeleteJobs", + "canvasName": "bulkDeleteJobs", + "summary": "bulkDeleteJobs", + "description": "bulkDeleteJobs", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "job_ids" + ], + "properties": { + "job_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + }, + "minItems": 1, + "maxItems": 100, + "description": "List of job IDs to delete (1\u2013100 items)" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "job_ids" + ], + "properties": { + "job_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + }, + "minItems": 1, + "maxItems": 100, + "description": "List of job IDs to delete (1\u2013100 items)" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e6354c32-a886-4d7a-9b69-75cc62db6c24", + "created": "2026-08-28T15:12:58.464Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 113, + "reference": "b7985abe-106b-4a90-ab82-429d82f44e21", + "type": "workflow", + "folder": "/Jobs", + "document": { + "name": "Create Job", + "description": "Create Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "createJob", + "canvasName": "createJob", + "summary": "createJob", + "description": "createJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "workflowId": "$var.job.workflowId", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "required": [ + "name", + "type", + "config" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "name": { + "type": "string" + }, + "description": { + "type": "string", + "description": "Optional human-readable job description" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "INACTIVE", + "ERROR", + "COMPLETED", + "FAILED", + "CANCELLED", + "DELETING" + ] + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether the job can be activated, paused, or resumed. Defaults to true when omitted." + }, + "config": { + "type": "object", + "description": "Job configuration (discriminated by workflow type - use AutoScaleConfig, UpgradeConfig, or BackupConfig)", + "discriminator": { + "propertyName": "configType", + "mapping": { + "AUTO_SCALE": "#/components/schemas/AutoScaleConfig", + "SOFTWARE_INSTALLATION": "#/components/schemas/SoftwareInstallationConfig", + "SOFTWARE_DISTRIBUTION": "#/components/schemas/SoftwareDistributionConfig", + "BACKUP": "#/components/schemas/BackupConfig" + } + }, + "properties": { + "configType": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_INSTALLATION", + "SOFTWARE_DISTRIBUTION", + "BACKUP" + ], + "description": "Configuration type that determines which config object to use" + }, + "environmentReference": { + "type": "string", + "description": "[AUTO_SCALE] Reference to managed environment (UUID or alias string)" + }, + "templateReference": { + "type": "string", + "description": "[AUTO_SCALE] Template for new instances (UUID or alias string)" + }, + "licensePoolReference": { + "type": "string", + "description": "[AUTO_SCALE] License pool for allocation (UUID or alias string)" + }, + "providerType": { + "type": "string", + "description": "[AUTO_SCALE] Cloud provider type" + }, + "minSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Minimum pool size" + }, + "maxSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Maximum pool size" + }, + "desiredSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Current/target pool size" + }, + "evaluationPeriod": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Seconds between policy evaluations" + }, + "scaleInMethod": { + "type": "string", + "enum": [ + "NEWEST_FIRST", + "OLDEST_FIRST", + "RANDOM" + ], + "description": "[AUTO_SCALE] Strategy for scaling in" + }, + "scaleOutCooldownSeconds": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Cooldown after scale-out" + }, + "scaleInCooldownSeconds": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Cooldown after scale-in" + }, + "scalingPolicies": { + "type": "array", + "items": { + "type": "object", + "required": [ + "name", + "direction", + "metricName", + "threshold", + "operator", + "scalingStep" + ], + "properties": { + "name": { + "type": "string", + "description": "Unique policy identifier" + }, + "direction": { + "type": "string", + "enum": [ + "SCALE_OUT", + "SCALE_IN" + ], + "description": "Scaling direction triggered by this policy" + }, + "metricName": { + "type": "string", + "description": "Metric name to evaluate (e.g. cpu_utilization, memory_usage, connections)" + }, + "threshold": { + "type": "number", + "description": "Threshold value for metric comparison" + }, + "operator": { + "type": "string", + "enum": [ + "GREATER_THAN", + "LESS_THAN", + "GREATER_THAN_OR_EQUAL", + "LESS_THAN_OR_EQUAL", + "EQUAL" + ], + "description": "Comparison operator to evaluate against threshold" + }, + "scalingStep": { + "type": "integer", + "minimum": 1, + "description": "Number of instances to scale in/out" + } + }, + "examples": [ + { + "name": "example-scale-out", + "value": { + "name": "scale-out-high-cpu", + "direction": "SCALE_OUT", + "metricName": "cpu_utilization", + "threshold": 80, + "operator": "GREATER_THAN", + "scalingStep": 1 + } + }, + { + "name": "example-scale-in", + "value": { + "name": "scale-in-low-memory", + "direction": "SCALE_IN", + "metricName": "memory_usage", + "threshold": 30, + "operator": "LESS_THAN", + "scalingStep": 2 + } + } + ] + }, + "description": "[AUTO_SCALE] Scaling policies" + } + } + }, + "schedule": { + "type": "object", + "properties": { + "cron": { + "type": "string", + "description": "Unix cron expression (e.g. \"0 2 * * *\" for 2 AM daily, \"0 2 * * 0\" for Sundays at 2 AM)", + "example": "0 2 * * *" + }, + "timezone": { + "type": "string", + "default": "UTC", + "description": "IANA timezone for cron evaluation (e.g. America/New_York, Europe/London)", + "example": "America/New_York" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether the schedule is active" + } + }, + "example": { + "cron": "0 2 * * 0", + "timezone": "America/New_York", + "enabled": true + } + } + } + } + }, + "required": [ + "workflowId", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "required": [ + "name", + "type", + "config" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "name": { + "type": "string" + }, + "description": { + "type": "string", + "description": "Optional human-readable job description" + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "INACTIVE", + "ERROR", + "COMPLETED", + "FAILED", + "CANCELLED", + "DELETING" + ] + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether the job can be activated, paused, or resumed. Defaults to true when omitted." + }, + "config": { + "type": "object", + "description": "Job configuration (discriminated by workflow type - use AutoScaleConfig, UpgradeConfig, or BackupConfig)", + "discriminator": { + "propertyName": "configType", + "mapping": { + "AUTO_SCALE": "#/components/schemas/AutoScaleConfig", + "SOFTWARE_INSTALLATION": "#/components/schemas/SoftwareInstallationConfig", + "SOFTWARE_DISTRIBUTION": "#/components/schemas/SoftwareDistributionConfig", + "BACKUP": "#/components/schemas/BackupConfig" + } + }, + "properties": { + "configType": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_INSTALLATION", + "SOFTWARE_DISTRIBUTION", + "BACKUP" + ], + "description": "Configuration type that determines which config object to use" + }, + "environmentReference": { + "type": "string", + "description": "[AUTO_SCALE] Reference to managed environment (UUID or alias string)" + }, + "templateReference": { + "type": "string", + "description": "[AUTO_SCALE] Template for new instances (UUID or alias string)" + }, + "licensePoolReference": { + "type": "string", + "description": "[AUTO_SCALE] License pool for allocation (UUID or alias string)" + }, + "providerType": { + "type": "string", + "description": "[AUTO_SCALE] Cloud provider type" + }, + "minSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Minimum pool size" + }, + "maxSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Maximum pool size" + }, + "desiredSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Current/target pool size" + }, + "evaluationPeriod": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Seconds between policy evaluations" + }, + "scaleInMethod": { + "type": "string", + "enum": [ + "NEWEST_FIRST", + "OLDEST_FIRST", + "RANDOM" + ], + "description": "[AUTO_SCALE] Strategy for scaling in" + }, + "scaleOutCooldownSeconds": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Cooldown after scale-out" + }, + "scaleInCooldownSeconds": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Cooldown after scale-in" + }, + "scalingPolicies": { + "type": "array", + "items": { + "type": "object", + "required": [ + "name", + "direction", + "metricName", + "threshold", + "operator", + "scalingStep" + ], + "properties": { + "name": { + "type": "string", + "description": "Unique policy identifier" + }, + "direction": { + "type": "string", + "enum": [ + "SCALE_OUT", + "SCALE_IN" + ], + "description": "Scaling direction triggered by this policy" + }, + "metricName": { + "type": "string", + "description": "Metric name to evaluate (e.g. cpu_utilization, memory_usage, connections)" + }, + "threshold": { + "type": "number", + "description": "Threshold value for metric comparison" + }, + "operator": { + "type": "string", + "enum": [ + "GREATER_THAN", + "LESS_THAN", + "GREATER_THAN_OR_EQUAL", + "LESS_THAN_OR_EQUAL", + "EQUAL" + ], + "description": "Comparison operator to evaluate against threshold" + }, + "scalingStep": { + "type": "integer", + "minimum": 1, + "description": "Number of instances to scale in/out" + } + }, + "examples": [ + { + "name": "example-scale-out", + "value": { + "name": "scale-out-high-cpu", + "direction": "SCALE_OUT", + "metricName": "cpu_utilization", + "threshold": 80, + "operator": "GREATER_THAN", + "scalingStep": 1 + } + }, + { + "name": "example-scale-in", + "value": { + "name": "scale-in-low-memory", + "direction": "SCALE_IN", + "metricName": "memory_usage", + "threshold": 30, + "operator": "LESS_THAN", + "scalingStep": 2 + } + } + ] + }, + "description": "[AUTO_SCALE] Scaling policies" + } + } + }, + "schedule": { + "type": "object", + "properties": { + "cron": { + "type": "string", + "description": "Unix cron expression (e.g. \"0 2 * * *\" for 2 AM daily, \"0 2 * * 0\" for Sundays at 2 AM)", + "example": "0 2 * * *" + }, + "timezone": { + "type": "string", + "default": "UTC", + "description": "IANA timezone for cron evaluation (e.g. America/New_York, Europe/London)", + "example": "America/New_York" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether the schedule is active" + } + }, + "example": { + "cron": "0 2 * * 0", + "timezone": "America/New_York", + "enabled": true + } + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "d5c81eb9-c2c8-4992-a4ef-bdc19de4c92a", + "created": "2026-08-28T15:12:59.108Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 114, + "reference": "6af1ecd4-6bb7-435b-a078-b322f0a11ea8", + "type": "workflow", + "folder": "/Jobs", + "document": { + "name": "Delete Job", + "description": "Delete Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteJob", + "canvasName": "deleteJob", + "summary": "deleteJob", + "description": "deleteJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "workflowId": "$var.job.workflowId", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "workflowId", + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "714b8dda-8f27-4756-8131-5305e285529c", + "created": "2026-08-28T15:12:59.218Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 115, + "reference": "bca35fd6-6181-4781-9872-f8d42b3eeaf1", + "type": "workflow", + "folder": "/Jobs", + "document": { + "name": "F5 Insight Get Job", + "description": "F5 Insight Get Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getJob", + "canvasName": "getJob", + "summary": "getJob", + "description": "getJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "workflowId": "$var.job.workflowId", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "workflowId", + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "3686b2af-0fe0-4047-bee8-1d22b9df1150", + "created": "2026-08-28T15:12:59.152Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 116, + "reference": "8f8ad249-79c1-4483-87fa-c2d12cae1540", + "type": "workflow", + "folder": "/Jobs", + "document": { + "name": "F5 Insight List Devices", + "description": "F5 Insight List Devices", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listDevices", + "canvasName": "listDevices", + "summary": "listDevices", + "description": "listDevices", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "workflowId": "$var.job.workflowId", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "workflowId", + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e5588784-e309-48ce-bdf5-d9185e57c20f", + "created": "2026-08-28T15:12:59.282Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 117, + "reference": "495be2d3-2144-4363-97c0-5b882c8df9cf", + "type": "workflow", + "folder": "/Jobs", + "document": { + "name": "F5 Insight List Jobs", + "description": "F5 Insight List Jobs", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listJobs", + "canvasName": "listJobs", + "summary": "listJobs", + "description": "listJobs", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "workflowId": "$var.job.workflowId", + "page": "$var.job.page", + "limit": "$var.job.limit", + "status": "$var.job.status" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSED", + "INACTIVE", + "ERROR", + "DELETING" + ] + } + }, + "required": [ + "workflowId", + "page", + "limit", + "status" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSED", + "INACTIVE", + "ERROR", + "DELETING" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e7036070-62ae-4b04-bf5c-aca2c5a1b2e7", + "created": "2026-08-28T15:12:59.065Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 118, + "reference": "9bb82203-4a21-4df1-b591-55a4cbbb8c18", + "type": "workflow", + "folder": "/Jobs", + "document": { + "name": "Patch Job", + "description": "Patch Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "patchJob", + "canvasName": "patchJob", + "summary": "patchJob", + "description": "patchJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "workflowId": "$var.job.workflowId", + "jobId": "$var.job.jobId", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "name": { + "type": "string" + }, + "description": { + "type": "string", + "description": "Optional human-readable job description. Set to empty string to clear." + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "INACTIVE", + "ERROR", + "COMPLETED", + "FAILED", + "CANCELLED", + "DELETING" + ] + }, + "enabled": { + "type": "boolean", + "description": "Whether the job can be activated, paused, or resumed." + }, + "config": { + "type": "object", + "description": "Job configuration (discriminated by workflow type - use AutoScaleConfig, UpgradeConfig, or BackupConfig)", + "discriminator": { + "propertyName": "configType", + "mapping": { + "AUTO_SCALE": "#/components/schemas/AutoScaleConfig", + "SOFTWARE_INSTALLATION": "#/components/schemas/SoftwareInstallationConfig", + "SOFTWARE_DISTRIBUTION": "#/components/schemas/SoftwareDistributionConfig", + "BACKUP": "#/components/schemas/BackupConfig" + } + }, + "properties": { + "configType": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_INSTALLATION", + "SOFTWARE_DISTRIBUTION", + "BACKUP" + ], + "description": "Configuration type that determines which config object to use" + }, + "environmentReference": { + "type": "string", + "description": "[AUTO_SCALE] Reference to managed environment (UUID or alias string)" + }, + "templateReference": { + "type": "string", + "description": "[AUTO_SCALE] Template for new instances (UUID or alias string)" + }, + "licensePoolReference": { + "type": "string", + "description": "[AUTO_SCALE] License pool for allocation (UUID or alias string)" + }, + "providerType": { + "type": "string", + "description": "[AUTO_SCALE] Cloud provider type" + }, + "minSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Minimum pool size" + }, + "maxSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Maximum pool size" + }, + "desiredSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Current/target pool size" + }, + "evaluationPeriod": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Seconds between policy evaluations" + }, + "scaleInMethod": { + "type": "string", + "enum": [ + "NEWEST_FIRST", + "OLDEST_FIRST", + "RANDOM" + ], + "description": "[AUTO_SCALE] Strategy for scaling in" + }, + "scaleOutCooldownSeconds": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Cooldown after scale-out" + }, + "scaleInCooldownSeconds": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Cooldown after scale-in" + }, + "scalingPolicies": { + "type": "array", + "items": { + "type": "object", + "required": [ + "name", + "direction", + "metricName", + "threshold", + "operator", + "scalingStep" + ], + "properties": { + "name": { + "type": "string", + "description": "Unique policy identifier" + }, + "direction": { + "type": "string", + "enum": [ + "SCALE_OUT", + "SCALE_IN" + ], + "description": "Scaling direction triggered by this policy" + }, + "metricName": { + "type": "string", + "description": "Metric name to evaluate (e.g. cpu_utilization, memory_usage, connections)" + }, + "threshold": { + "type": "number", + "description": "Threshold value for metric comparison" + }, + "operator": { + "type": "string", + "enum": [ + "GREATER_THAN", + "LESS_THAN", + "GREATER_THAN_OR_EQUAL", + "LESS_THAN_OR_EQUAL", + "EQUAL" + ], + "description": "Comparison operator to evaluate against threshold" + }, + "scalingStep": { + "type": "integer", + "minimum": 1, + "description": "Number of instances to scale in/out" + } + }, + "examples": [ + { + "name": "example-scale-out", + "value": { + "name": "scale-out-high-cpu", + "direction": "SCALE_OUT", + "metricName": "cpu_utilization", + "threshold": 80, + "operator": "GREATER_THAN", + "scalingStep": 1 + } + }, + { + "name": "example-scale-in", + "value": { + "name": "scale-in-low-memory", + "direction": "SCALE_IN", + "metricName": "memory_usage", + "threshold": 30, + "operator": "LESS_THAN", + "scalingStep": 2 + } + } + ] + }, + "description": "[AUTO_SCALE] Scaling policies" + } + } + }, + "schedule": { + "type": "object", + "properties": { + "cron": { + "type": "string", + "description": "Unix cron expression (e.g. \"0 2 * * *\" for 2 AM daily, \"0 2 * * 0\" for Sundays at 2 AM)", + "example": "0 2 * * *" + }, + "timezone": { + "type": "string", + "default": "UTC", + "description": "IANA timezone for cron evaluation (e.g. America/New_York, Europe/London)", + "example": "America/New_York" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether the schedule is active" + } + }, + "example": { + "cron": "0 2 * * 0", + "timezone": "America/New_York", + "enabled": true + } + } + } + } + }, + "required": [ + "workflowId", + "jobId", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "name": { + "type": "string" + }, + "description": { + "type": "string", + "description": "Optional human-readable job description. Set to empty string to clear." + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "READY", + "ACTIVE", + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "INACTIVE", + "ERROR", + "COMPLETED", + "FAILED", + "CANCELLED", + "DELETING" + ] + }, + "enabled": { + "type": "boolean", + "description": "Whether the job can be activated, paused, or resumed." + }, + "config": { + "type": "object", + "description": "Job configuration (discriminated by workflow type - use AutoScaleConfig, UpgradeConfig, or BackupConfig)", + "discriminator": { + "propertyName": "configType", + "mapping": { + "AUTO_SCALE": "#/components/schemas/AutoScaleConfig", + "SOFTWARE_INSTALLATION": "#/components/schemas/SoftwareInstallationConfig", + "SOFTWARE_DISTRIBUTION": "#/components/schemas/SoftwareDistributionConfig", + "BACKUP": "#/components/schemas/BackupConfig" + } + }, + "properties": { + "configType": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_INSTALLATION", + "SOFTWARE_DISTRIBUTION", + "BACKUP" + ], + "description": "Configuration type that determines which config object to use" + }, + "environmentReference": { + "type": "string", + "description": "[AUTO_SCALE] Reference to managed environment (UUID or alias string)" + }, + "templateReference": { + "type": "string", + "description": "[AUTO_SCALE] Template for new instances (UUID or alias string)" + }, + "licensePoolReference": { + "type": "string", + "description": "[AUTO_SCALE] License pool for allocation (UUID or alias string)" + }, + "providerType": { + "type": "string", + "description": "[AUTO_SCALE] Cloud provider type" + }, + "minSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Minimum pool size" + }, + "maxSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Maximum pool size" + }, + "desiredSize": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Current/target pool size" + }, + "evaluationPeriod": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Seconds between policy evaluations" + }, + "scaleInMethod": { + "type": "string", + "enum": [ + "NEWEST_FIRST", + "OLDEST_FIRST", + "RANDOM" + ], + "description": "[AUTO_SCALE] Strategy for scaling in" + }, + "scaleOutCooldownSeconds": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Cooldown after scale-out" + }, + "scaleInCooldownSeconds": { + "type": "integer", + "minimum": 0, + "description": "[AUTO_SCALE] Cooldown after scale-in" + }, + "scalingPolicies": { + "type": "array", + "items": { + "type": "object", + "required": [ + "name", + "direction", + "metricName", + "threshold", + "operator", + "scalingStep" + ], + "properties": { + "name": { + "type": "string", + "description": "Unique policy identifier" + }, + "direction": { + "type": "string", + "enum": [ + "SCALE_OUT", + "SCALE_IN" + ], + "description": "Scaling direction triggered by this policy" + }, + "metricName": { + "type": "string", + "description": "Metric name to evaluate (e.g. cpu_utilization, memory_usage, connections)" + }, + "threshold": { + "type": "number", + "description": "Threshold value for metric comparison" + }, + "operator": { + "type": "string", + "enum": [ + "GREATER_THAN", + "LESS_THAN", + "GREATER_THAN_OR_EQUAL", + "LESS_THAN_OR_EQUAL", + "EQUAL" + ], + "description": "Comparison operator to evaluate against threshold" + }, + "scalingStep": { + "type": "integer", + "minimum": 1, + "description": "Number of instances to scale in/out" + } + }, + "examples": [ + { + "name": "example-scale-out", + "value": { + "name": "scale-out-high-cpu", + "direction": "SCALE_OUT", + "metricName": "cpu_utilization", + "threshold": 80, + "operator": "GREATER_THAN", + "scalingStep": 1 + } + }, + { + "name": "example-scale-in", + "value": { + "name": "scale-in-low-memory", + "direction": "SCALE_IN", + "metricName": "memory_usage", + "threshold": 30, + "operator": "LESS_THAN", + "scalingStep": 2 + } + } + ] + }, + "description": "[AUTO_SCALE] Scaling policies" + } + } + }, + "schedule": { + "type": "object", + "properties": { + "cron": { + "type": "string", + "description": "Unix cron expression (e.g. \"0 2 * * *\" for 2 AM daily, \"0 2 * * 0\" for Sundays at 2 AM)", + "example": "0 2 * * *" + }, + "timezone": { + "type": "string", + "default": "UTC", + "description": "IANA timezone for cron evaluation (e.g. America/New_York, Europe/London)", + "example": "America/New_York" + }, + "enabled": { + "type": "boolean", + "default": true, + "description": "Whether the schedule is active" + } + }, + "example": { + "cron": "0 2 * * 0", + "timezone": "America/New_York", + "enabled": true + } + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "42a7ca88-00f4-4338-ac77-480e99c62507", + "created": "2026-08-28T15:12:59.186Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 119, + "reference": "e3147075-2edb-48f6-a0a4-1ad08b3322cb", + "type": "workflow", + "folder": "/Tasks", + "document": { + "name": "Get Task Status", + "description": "Get Task Status", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getTaskStatus", + "canvasName": "getTaskStatus", + "summary": "getTaskStatus", + "description": "getTaskStatus", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "taskId": "$var.job.taskId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "taskId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "taskId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "taskId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "cc162357-b85f-4893-b23b-c3f4ee9ab47d", + "created": "2026-08-28T15:12:58.974Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 120, + "reference": "cb01b9b0-beb7-4cc7-9fe2-e804ef841993", + "type": "workflow", + "folder": "/Tasks", + "document": { + "name": "List Tasks", + "description": "List Tasks", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listTasks", + "canvasName": "listTasks", + "summary": "listTasks", + "description": "listTasks", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "status": "$var.job.status", + "type": "$var.job.type", + "resourceType": "$var.job.resourceType", + "resourceId": "$var.job.resourceId", + "page": "$var.job.page", + "size": "$var.job.size", + "sort": "$var.job.sort" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "PENDING", + "IN_PROGRESS", + "COMPLETED", + "FAILED" + ] + }, + "type": { + "type": "string", + "enum": [ + "ADD_OFFERING", + "REACTIVATE_OFFERING", + "ASSIGN_LICENSE", + "REVOKE_LICENSE" + ] + }, + "resourceType": { + "type": "string", + "enum": [ + "LicenseOffering", + "LicenseMember" + ] + }, + "resourceId": { + "type": "string", + "format": "uuid" + }, + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "size": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 20 + }, + "sort": { + "type": "string", + "default": "createdAt:desc" + } + }, + "required": [ + "status", + "type", + "resourceType", + "resourceId", + "page", + "size", + "sort" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "PENDING", + "IN_PROGRESS", + "COMPLETED", + "FAILED" + ] + }, + "type": { + "type": "string", + "enum": [ + "ADD_OFFERING", + "REACTIVATE_OFFERING", + "ASSIGN_LICENSE", + "REVOKE_LICENSE" + ] + }, + "resourceType": { + "type": "string", + "enum": [ + "LicenseOffering", + "LicenseMember" + ] + }, + "resourceId": { + "type": "string", + "format": "uuid" + }, + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "size": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 20 + }, + "sort": { + "type": "string", + "default": "createdAt:desc" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e3e4bb71-e8e5-48e8-a648-1900ad693418", + "created": "2026-08-28T15:12:58.942Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 121, + "reference": "2b2c7933-e418-4ef7-8ca8-24d38cbd78f3", + "type": "workflow", + "folder": "/Workflows", + "document": { + "name": "F5 Insight Get Workflow", + "description": "F5 Insight Get Workflow", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getWorkflow", + "canvasName": "getWorkflow", + "summary": "getWorkflow", + "description": "getWorkflow", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "workflowId": "$var.job.workflowId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "workflowId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "163df903-e8e4-43bc-90cd-6d08d8c806f1", + "created": "2026-08-28T15:12:59.035Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 122, + "reference": "b3de57c4-7f37-4be4-bf59-217d528c4e10", + "type": "workflow", + "folder": "/Workflows", + "document": { + "name": "F5 Insight List Workflows", + "description": "F5 Insight List Workflows", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listWorkflows", + "canvasName": "listWorkflows", + "summary": "listWorkflows", + "description": "listWorkflows", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "page": "$var.job.page", + "limit": "$var.job.limit", + "type": "$var.job.type", + "executionMode": "$var.job.executionMode", + "status": "$var.job.status" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + }, + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "executionMode": { + "type": "string", + "enum": [ + "CONTINUOUS", + "ON_DEMAND" + ] + }, + "status": { + "type": "string", + "enum": [ + "DRAFT", + "ACTIVE", + "DEPRECATED" + ] + } + }, + "required": [ + "page", + "limit", + "type", + "executionMode", + "status" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + }, + "type": { + "type": "string", + "enum": [ + "AUTO_SCALE", + "SOFTWARE_DISTRIBUTION", + "SOFTWARE_INSTALLATION", + "BACKUP" + ] + }, + "executionMode": { + "type": "string", + "enum": [ + "CONTINUOUS", + "ON_DEMAND" + ] + }, + "status": { + "type": "string", + "enum": [ + "DRAFT", + "ACTIVE", + "DEPRECATED" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "f88e9186-f8d8-4738-ace8-74ee2170dd9a", + "created": "2026-08-28T15:12:59.007Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 123, + "reference": "90eadee9-4fd1-426c-b3ef-bce7acf47e64", + "type": "workflow", + "folder": "/Lifecycle", + "document": { + "name": "Activate Job", + "description": "Activate Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "activateJob", + "canvasName": "activateJob", + "summary": "activateJob", + "description": "activateJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "workflowId": "$var.job.workflowId", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "workflowId", + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "47404cfc-b5d0-4419-8503-0a95108106d0", + "created": "2026-08-28T15:12:59.248Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 124, + "reference": "1226fc0e-9269-43c8-bcb6-749b06013123", + "type": "workflow", + "folder": "/Lifecycle", + "document": { + "name": "Pause Job", + "description": "Pause Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "pauseJob", + "canvasName": "pauseJob", + "summary": "pauseJob", + "description": "pauseJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "workflowId": "$var.job.workflowId", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "workflowId", + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "48c70e0c-c1db-4f03-bbb0-7615b951bea6", + "created": "2026-08-28T15:12:59.469Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 125, + "reference": "aacb30eb-f3ec-494d-aaf8-a7d6f6fd016e", + "type": "workflow", + "folder": "/Lifecycle", + "document": { + "name": "Resume Job", + "description": "Resume Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "resumeJob", + "canvasName": "resumeJob", + "summary": "resumeJob", + "description": "resumeJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "workflowId": "$var.job.workflowId", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "workflowId", + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "format": "uuid" + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "0eb72830-623f-43a2-b352-2a4a10b18c08", + "created": "2026-08-28T15:12:59.500Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 126, + "reference": "f5754f9f-5e97-4e03-9c63-78260c39b936", + "type": "workflow", + "folder": "/Storage", + "document": { + "name": "Create Storage Target", + "description": "Create Storage Target", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "createStorageTarget", + "canvasName": "createStorageTarget", + "summary": "createStorageTarget", + "description": "createStorageTarget", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "name", + "storage_type" + ], + "properties": { + "name": { + "type": "string" + }, + "storage_type": { + "type": "string", + "enum": [ + "nfs", + "smb" + ] + }, + "server": { + "type": "string" + }, + "share_path": { + "type": "string" + }, + "mount_options": { + "type": "string" + }, + "username": { + "type": "string" + }, + "password": { + "type": "string", + "description": "SMB password (stored securely in Vault, never in DB)" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "name", + "storage_type" + ], + "properties": { + "name": { + "type": "string" + }, + "storage_type": { + "type": "string", + "enum": [ + "nfs", + "smb" + ] + }, + "server": { + "type": "string" + }, + "share_path": { + "type": "string" + }, + "mount_options": { + "type": "string" + }, + "username": { + "type": "string" + }, + "password": { + "type": "string", + "description": "SMB password (stored securely in Vault, never in DB)" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "d6c933ff-9d10-4caf-9c1e-b86eeed231aa", + "created": "2026-08-28T15:13:00.116Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 127, + "reference": "875a89fd-5c36-421f-a860-246307eef6c5", + "type": "workflow", + "folder": "/Storage", + "document": { + "name": "Delete Storage Target", + "description": "Delete Storage Target", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteStorageTarget", + "canvasName": "deleteStorageTarget", + "summary": "deleteStorageTarget", + "description": "deleteStorageTarget", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "143eb5ee-0c2f-44ce-a3e3-6385d3dda5f3", + "created": "2026-08-28T15:13:00.242Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 128, + "reference": "d2af280b-ac3f-484d-9cf7-2be3aa46ea8a", + "type": "workflow", + "folder": "/Storage", + "document": { + "name": "Get Storage Config", + "description": "Get Storage Config", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getStorageConfig", + "canvasName": "getStorageConfig", + "summary": "getStorageConfig", + "description": "getStorageConfig", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "067e2955-d79e-4945-b31a-b058a2152f40", + "created": "2026-08-28T15:12:59.532Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 129, + "reference": "9d4ee77f-ef34-40e1-8089-467cc3592a8b", + "type": "workflow", + "folder": "/Storage", + "document": { + "name": "Get Storage Target", + "description": "Get Storage Target", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getStorageTarget", + "canvasName": "getStorageTarget", + "summary": "getStorageTarget", + "description": "getStorageTarget", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e255a014-16d5-4697-b90c-939eb879b285", + "created": "2026-08-28T15:13:00.178Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 130, + "reference": "46402a68-5dea-4baf-8157-4781c4fdc666", + "type": "workflow", + "folder": "/Storage", + "document": { + "name": "List Storage Targets", + "description": "List Storage Targets", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listStorageTargets", + "canvasName": "listStorageTargets", + "summary": "listStorageTargets", + "description": "listStorageTargets", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "25f661af-d5eb-40ec-8561-d20fe443cdb6", + "created": "2026-08-28T15:13:00.087Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 131, + "reference": "7a3e4576-57d1-4b6c-bd22-04408885c0ea", + "type": "workflow", + "folder": "/Storage", + "document": { + "name": "Test Storage Connectivity", + "description": "Test Storage Connectivity", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "testStorageConnectivity", + "canvasName": "testStorageConnectivity", + "summary": "testStorageConnectivity", + "description": "testStorageConnectivity", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Ad-hoc connectivity test for a storage target that has not been saved.\nNo name is required because nothing is persisted.\n", + "required": [ + "storage_type" + ], + "properties": { + "storage_type": { + "type": "string", + "enum": [ + "local", + "nfs", + "smb" + ] + }, + "server": { + "type": "string" + }, + "share_path": { + "type": "string" + }, + "mount_options": { + "type": "string" + }, + "username": { + "type": "string" + }, + "password": { + "type": "string", + "description": "SMB password (used only for the test, never persisted)" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Ad-hoc connectivity test for a storage target that has not been saved.\nNo name is required because nothing is persisted.\n", + "required": [ + "storage_type" + ], + "properties": { + "storage_type": { + "type": "string", + "enum": [ + "local", + "nfs", + "smb" + ] + }, + "server": { + "type": "string" + }, + "share_path": { + "type": "string" + }, + "mount_options": { + "type": "string" + }, + "username": { + "type": "string" + }, + "password": { + "type": "string", + "description": "SMB password (used only for the test, never persisted)" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "946e4e83-4283-4329-980d-53f7606709aa", + "created": "2026-08-28T15:13:00.149Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 132, + "reference": "138c53b9-06ab-4e83-bd15-6f0daf38965a", + "type": "workflow", + "folder": "/Storage", + "document": { + "name": "Test Storage Target", + "description": "Test Storage Target", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "testStorageTarget", + "canvasName": "testStorageTarget", + "summary": "testStorageTarget", + "description": "testStorageTarget", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "1fc57cd5-ab4e-455e-af8b-3c41393ecf12", + "created": "2026-08-28T15:13:00.273Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 133, + "reference": "2b64108c-3ce6-4c4b-a82c-caf97e6c97c9", + "type": "workflow", + "folder": "/Storage", + "document": { + "name": "Update Storage Config", + "description": "Update Storage Config", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "updateStorageConfig", + "canvasName": "updateStorageConfig", + "summary": "updateStorageConfig", + "description": "updateStorageConfig", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "clickhouse_allocation_percent", + "victoriametrics_allocation_percent" + ], + "description": "Request body for updating storage allocation config. Only accepts 4 fields - allocation percentages (mandatory) and cleanup percentages (optional). All percentages support up to 2 decimal places (e.g., 70.50).", + "properties": { + "clickhouse_allocation_percent": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 100, + "description": "Percentage of total storage allocated to ClickHouse (mandatory, must sum to 100 with victoriametrics_allocation_percent). Supports up to 2 decimal places.", + "example": 70.5 + }, + "victoriametrics_allocation_percent": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 100, + "description": "Percentage of total storage allocated to VictoriaMetrics (mandatory, must sum to 100 with clickhouse_allocation_percent). Supports up to 2 decimal places.", + "example": 29.5 + }, + "cleanup_threshold_percent": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 100, + "description": "Threshold percentage at which cleanup is triggered (optional). Supports up to 2 decimal places.", + "example": 80 + }, + "cleanup_data_percent": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 100, + "description": "Percentage of data to delete during cleanup (optional). Supports up to 2 decimal places.", + "example": 70 + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "clickhouse_allocation_percent", + "victoriametrics_allocation_percent" + ], + "description": "Request body for updating storage allocation config. Only accepts 4 fields - allocation percentages (mandatory) and cleanup percentages (optional). All percentages support up to 2 decimal places (e.g., 70.50).", + "properties": { + "clickhouse_allocation_percent": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 100, + "description": "Percentage of total storage allocated to ClickHouse (mandatory, must sum to 100 with victoriametrics_allocation_percent). Supports up to 2 decimal places.", + "example": 70.5 + }, + "victoriametrics_allocation_percent": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 100, + "description": "Percentage of total storage allocated to VictoriaMetrics (mandatory, must sum to 100 with clickhouse_allocation_percent). Supports up to 2 decimal places.", + "example": 29.5 + }, + "cleanup_threshold_percent": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 100, + "description": "Threshold percentage at which cleanup is triggered (optional). Supports up to 2 decimal places.", + "example": 80 + }, + "cleanup_data_percent": { + "type": "number", + "format": "double", + "minimum": 0, + "maximum": 100, + "description": "Percentage of data to delete during cleanup (optional). Supports up to 2 decimal places.", + "example": 70 + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "341168b1-3980-4184-8696-65674ea5721d", + "created": "2026-08-28T15:12:59.567Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 134, + "reference": "97884ea6-fea7-4c64-b6b9-1cf6d59a570e", + "type": "workflow", + "folder": "/Storage", + "document": { + "name": "Update Storage Target", + "description": "Update Storage Target", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "updateStorageTarget", + "canvasName": "updateStorageTarget", + "summary": "updateStorageTarget", + "description": "updateStorageTarget", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Partial update of a storage target. All fields are optional. Only the\nlisted fields are accepted; any other keys are ignored server-side.\nSensitive/internal fields (id, credentials_ref, status, last_checked_at,\nlatency, created_at, last_modified) cannot be set by clients.\n", + "properties": { + "name": { + "type": "string" + }, + "storage_type": { + "type": "string", + "enum": [ + "nfs", + "smb" + ] + }, + "server": { + "type": "string" + }, + "share_path": { + "type": "string" + }, + "mount_options": { + "type": "string" + }, + "username": { + "type": "string" + }, + "password": { + "type": "string", + "description": "SMB password (stored securely in Vault, never in DB)" + }, + "is_default": { + "type": "boolean", + "description": "When true, marks this target as the default for new backups." + } + } + } + }, + "required": [ + "id", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Partial update of a storage target. All fields are optional. Only the\nlisted fields are accepted; any other keys are ignored server-side.\nSensitive/internal fields (id, credentials_ref, status, last_checked_at,\nlatency, created_at, last_modified) cannot be set by clients.\n", + "properties": { + "name": { + "type": "string" + }, + "storage_type": { + "type": "string", + "enum": [ + "nfs", + "smb" + ] + }, + "server": { + "type": "string" + }, + "share_path": { + "type": "string" + }, + "mount_options": { + "type": "string" + }, + "username": { + "type": "string" + }, + "password": { + "type": "string", + "description": "SMB password (stored securely in Vault, never in DB)" + }, + "is_default": { + "type": "boolean", + "description": "When true, marks this target as the default for new backups." + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "3e035372-c2cf-494f-9b4c-11a0283c2afe", + "created": "2026-08-28T15:13:00.209Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 135, + "reference": "6399722c-bb2b-468e-92cf-1986c46bde60", + "type": "workflow", + "folder": "/Schedule", + "document": { + "name": "Create Backup Schedule", + "description": "Create Backup Schedule", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "createBackupSchedule", + "canvasName": "createBackupSchedule", + "summary": "createBackupSchedule", + "description": "createBackupSchedule", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "name", + "cron", + "passphrase" + ], + "properties": { + "name": { + "type": "string", + "description": "Schedule name (e.g., \"daily-config\", \"weekly-full\")" + }, + "cron": { + "type": "string", + "description": "Standard 5-field cron expression", + "example": "0 2 * * *" + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ], + "default": "full" + }, + "storage_target": { + "type": "string" + }, + "passphrase": { + "type": "string", + "minLength": 12, + "description": "Encryption passphrase (stored in Vault). Must be at least 12 characters with uppercase, lowercase, digit, and special character. Max 2 consecutive identical characters." + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "name", + "cron", + "passphrase" + ], + "properties": { + "name": { + "type": "string", + "description": "Schedule name (e.g., \"daily-config\", \"weekly-full\")" + }, + "cron": { + "type": "string", + "description": "Standard 5-field cron expression", + "example": "0 2 * * *" + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ], + "default": "full" + }, + "storage_target": { + "type": "string" + }, + "passphrase": { + "type": "string", + "minLength": 12, + "description": "Encryption passphrase (stored in Vault). Must be at least 12 characters with uppercase, lowercase, digit, and special character. Max 2 consecutive identical characters." + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e68ffe90-e121-4a0d-aa84-bfc1034d8a23", + "created": "2026-08-28T15:12:59.627Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 136, + "reference": "a18c8086-b62d-45f5-a3f5-8d94f99eca1b", + "type": "workflow", + "folder": "/Schedule", + "document": { + "name": "Delete Backup Schedule", + "description": "Delete Backup Schedule", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteBackupSchedule", + "canvasName": "deleteBackupSchedule", + "summary": "deleteBackupSchedule", + "description": "deleteBackupSchedule", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "2749046e-09de-45b6-a85c-b77f61c52233", + "created": "2026-08-28T15:12:59.718Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 137, + "reference": "197dddf7-28ba-47c7-a8dd-e51f39b8a520", + "type": "workflow", + "folder": "/Schedule", + "document": { + "name": "Get Backup Schedule", + "description": "Get Backup Schedule", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getBackupSchedule", + "canvasName": "getBackupSchedule", + "summary": "getBackupSchedule", + "description": "getBackupSchedule", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "08a20791-0781-40dd-bffd-95a482e89fa1", + "created": "2026-08-28T15:12:59.596Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 138, + "reference": "dc85a5b3-68f7-4697-887b-b44b14128f85", + "type": "workflow", + "folder": "/Schedule", + "document": { + "name": "Get Backup Schedule By ID", + "description": "Get Backup Schedule By ID", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getBackupScheduleById", + "canvasName": "getBackupScheduleById", + "summary": "getBackupScheduleById", + "description": "getBackupScheduleById", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "f08b316f-721c-4fce-ab59-357f6372ff56", + "created": "2026-08-28T15:12:59.657Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 139, + "reference": "94b48d83-c183-4e23-bf53-0b3f189e5e5f", + "type": "workflow", + "folder": "/Schedule", + "document": { + "name": "Update Backup Schedule", + "description": "Update Backup Schedule", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "updateBackupSchedule", + "canvasName": "updateBackupSchedule", + "summary": "updateBackupSchedule", + "description": "updateBackupSchedule", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object" + } + }, + "required": [ + "id", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "5f926957-1ded-4c1d-a31f-6ecbe3d5460b", + "created": "2026-08-28T15:12:59.690Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 140, + "reference": "ecdf1e7a-60eb-4541-b52d-447dfc5f2a3f", + "type": "workflow", + "folder": "/Backup", + "document": { + "name": "Create Backup", + "description": "Create Backup", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "createBackup", + "canvasName": "createBackup", + "summary": "createBackup", + "description": "createBackup", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "passphrase" + ], + "properties": { + "name": { + "type": "string", + "description": "Optional backup name. If omitted, auto-generated as backup-YYYYMMDD-HHMMSS." + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ], + "default": "full", + "description": "Type of backup to create. Full backups require a remote storage target and are not supported on local storage; config backups may be stored locally." + }, + "passphrase": { + "type": "string", + "minLength": 12, + "description": "Encryption passphrase. Must be at least 12 characters with uppercase, lowercase, digit, and special character. Max 2 consecutive identical characters." + }, + "storage_target": { + "type": "string", + "description": "Name of the storage target to associate with this backup. Required for full backups (must be a remote target). If omitted, a config backup is stored locally." + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "passphrase" + ], + "properties": { + "name": { + "type": "string", + "description": "Optional backup name. If omitted, auto-generated as backup-YYYYMMDD-HHMMSS." + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ], + "default": "full", + "description": "Type of backup to create. Full backups require a remote storage target and are not supported on local storage; config backups may be stored locally." + }, + "passphrase": { + "type": "string", + "minLength": 12, + "description": "Encryption passphrase. Must be at least 12 characters with uppercase, lowercase, digit, and special character. Max 2 consecutive identical characters." + }, + "storage_target": { + "type": "string", + "description": "Name of the storage target to associate with this backup. Required for full backups (must be a remote target). If omitted, a config backup is stored locally." + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "f8a4dbbc-e96b-44d1-8f68-2a3b0388010d", + "created": "2026-08-28T15:12:59.778Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 141, + "reference": "35f6ad09-6e1b-40ce-b16d-40b6dceafa2c", + "type": "workflow", + "folder": "/Backup", + "document": { + "name": "Create Restore", + "description": "Create Restore", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "createRestore", + "canvasName": "createRestore", + "summary": "createRestore", + "description": "createRestore", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "required": [ + "passphrase" + ], + "properties": { + "passphrase": { + "type": "string", + "description": "Encryption passphrase used when backup was created" + }, + "components": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "data", + "config", + "network", + "dns", + "hostname", + "ntp", + "proxy", + "ssh" + ] + }, + "description": "Components to restore. Valid values data, config, network, dns, hostname, ntp, proxy, ssh. 'data' covers databases, 'config' covers configuration; system settings (dns, ntp, proxy, ssh, network, hostname) must be selected individually." + }, + "force": { + "type": "boolean", + "description": "Skip pre-restore state preservation (no rollback possible)" + } + } + } + }, + "required": [ + "id", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "required": [ + "passphrase" + ], + "properties": { + "passphrase": { + "type": "string", + "description": "Encryption passphrase used when backup was created" + }, + "components": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "data", + "config", + "network", + "dns", + "hostname", + "ntp", + "proxy", + "ssh" + ] + }, + "description": "Components to restore. Valid values data, config, network, dns, hostname, ntp, proxy, ssh. 'data' covers databases, 'config' covers configuration; system settings (dns, ntp, proxy, ssh, network, hostname) must be selected individually." + }, + "force": { + "type": "boolean", + "description": "Skip pre-restore state preservation (no rollback possible)" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "ceb1cefb-e4f8-4213-a6ed-a287d20512b0", + "created": "2026-08-28T15:12:59.963Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 142, + "reference": "c2373f3e-0e59-4a19-9ffa-816e026d8d8e", + "type": "workflow", + "folder": "/Backup", + "document": { + "name": "Delete Backup", + "description": "Delete Backup", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteBackup", + "canvasName": "deleteBackup", + "summary": "deleteBackup", + "description": "deleteBackup", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e39c212f-813d-4569-91f9-53b3a5241696", + "created": "2026-08-28T15:12:59.899Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 143, + "reference": "c08ff74b-cee8-4f78-8087-a8dc26a3ebad", + "type": "workflow", + "folder": "/Backup", + "document": { + "name": "Download Backup", + "description": "Download Backup", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "downloadBackup", + "canvasName": "downloadBackup", + "summary": "downloadBackup", + "description": "downloadBackup", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "8893a5b2-fada-4aeb-9785-17c7d7b90f08", + "created": "2026-08-28T15:12:59.930Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 144, + "reference": "25c38e01-cc6f-4181-a981-5206bfbc50b7", + "type": "workflow", + "folder": "/Backup", + "document": { + "name": "Get Backup", + "description": "Get Backup", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getBackup", + "canvasName": "getBackup", + "summary": "getBackup", + "description": "getBackup", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "id": "$var.job.id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "b6b69a4d-0176-4ddd-9ac4-a2984238443d", + "created": "2026-08-28T15:12:59.868Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 145, + "reference": "aa43aeee-c9f9-439f-89ba-41de6d49e299", + "type": "workflow", + "folder": "/Backup", + "document": { + "name": "Get Backups Analysis", + "description": "Get Backups Analysis", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getBackupsAnalysis", + "canvasName": "getBackupsAnalysis", + "summary": "getBackupsAnalysis", + "description": "getBackupsAnalysis", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "d60a3216-2998-4625-a772-9cc307ebf498", + "created": "2026-08-28T15:12:59.806Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 146, + "reference": "cbaf2a18-5eaf-4024-83a9-b3e39d076be5", + "type": "workflow", + "folder": "/Backup", + "document": { + "name": "Import Backup", + "description": "Import Backup", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "importBackup", + "canvasName": "importBackup", + "summary": "importBackup", + "description": "importBackup", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "file_path" + ], + "properties": { + "storage_target": { + "type": "string", + "description": "Name of the storage target where the file resides. If omitted, looks in local backup directory." + }, + "file_path": { + "type": "string", + "description": "Filename on the remote share, or filename in local backup directory." + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "file_path" + ], + "properties": { + "storage_target": { + "type": "string", + "description": "Name of the storage target where the file resides. If omitted, looks in local backup directory." + }, + "file_path": { + "type": "string", + "description": "Filename on the remote share, or filename in local backup directory." + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "4bf2a783-972a-44e0-a67c-a5e4d466b016", + "created": "2026-08-28T15:12:59.834Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 147, + "reference": "cc36920e-4c0f-4778-a5c4-7e7a82a117b8", + "type": "workflow", + "folder": "/Backup", + "document": { + "name": "List Backups", + "description": "List Backups", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listBackups", + "canvasName": "listBackups", + "summary": "listBackups", + "description": "listBackups", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "478da163-6d6c-46ed-807a-26da08b39fe1", + "created": "2026-08-28T15:12:59.747Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 148, + "reference": "f3a64523-7c6c-4b37-ae81-d33f4d8d3427", + "type": "workflow", + "folder": "/FQDN Configuration", + "document": { + "name": "Configure FQDN", + "description": "Configure FQDN", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "configureFqdn", + "canvasName": "configureFqdn", + "summary": "configureFqdn", + "description": "configureFqdn", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "target" + ], + "properties": { + "target": { + "type": "string", + "description": "External FQDN target. May include https scheme and port.", + "example": "f5insights.example.com" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "target" + ], + "properties": { + "target": { + "type": "string", + "description": "External FQDN target. May include https scheme and port.", + "example": "f5insights.example.com" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "bf145012-9e3b-48bc-9b99-31d1985d6057", + "created": "2026-08-28T15:12:59.992Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 149, + "reference": "056c5ace-e7e1-4724-a605-04dc05b411b4", + "type": "workflow", + "folder": "/FQDN Configuration", + "document": { + "name": "Get FQDN Status", + "description": "Get FQDN Status", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getFqdnStatus", + "canvasName": "getFqdnStatus", + "summary": "getFqdnStatus", + "description": "getFqdnStatus", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "task_id": "$var.job.task_id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "example": "123e4567-e89b-12d3-a456-426614174000" + } + }, + "required": [ + "task_id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "format": "uuid", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "93cdcc62-201a-4840-ba75-bca879a327d5", + "created": "2026-08-28T15:13:00.024Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 150, + "reference": "815d46a5-7435-4eee-8fdf-322a3649252d", + "type": "workflow", + "folder": "/Health and Readiness", + "document": { + "name": "Get Health", + "description": "Get Health", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getHealth", + "canvasName": "getHealth", + "summary": "getHealth", + "description": "getHealth", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "cde89903-1192-4b9c-81d7-792d55c0a9e3", + "created": "2026-08-28T15:13:00.057Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 151, + "reference": "eb862afa-0916-478c-9e71-77bda17a5a73", + "type": "workflow", + "folder": "/Health and Readiness", + "document": { + "name": "Get Readiness Results", + "description": "Get Readiness Results", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getReadinessResults", + "canvasName": "getReadinessResults", + "summary": "getReadinessResults", + "description": "getReadinessResults", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "runId": "$var.job.runId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "runId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "runId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "runId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "769820dc-e31d-4b39-bd52-d736e778ee61", + "created": "2026-08-28T15:13:02.386Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 152, + "reference": "619102b3-3e3f-4109-b0b1-fcd278a85603", + "type": "workflow", + "folder": "/Health and Readiness", + "document": { + "name": "Get Version", + "description": "Get Version", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getVersion", + "canvasName": "getVersion", + "summary": "getVersion", + "description": "getVersion", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "f032b94d-c139-4ae1-8d8c-6bbde8df7f93", + "created": "2026-08-28T15:13:00.983Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 153, + "reference": "330c8358-80a5-4f0e-9609-d073540cd104", + "type": "workflow", + "folder": "/Health and Readiness", + "document": { + "name": "List Readiness Runs", + "description": "List Readiness Runs", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listReadinessRuns", + "canvasName": "listReadinessRuns", + "summary": "listReadinessRuns", + "description": "listReadinessRuns", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "page": "$var.job.page", + "page_size": "$var.job.page_size", + "status": "$var.job.status" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "page_size": { + "type": "integer", + "default": 20, + "minimum": 1, + "maximum": 500 + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "PASSED", + "WARNING", + "FAILED", + "ERROR" + ] + } + }, + "required": [ + "page", + "page_size", + "status" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "page_size": { + "type": "integer", + "default": 20, + "minimum": 1, + "maximum": 500 + }, + "status": { + "type": "string", + "enum": [ + "PENDING", + "RUNNING", + "PASSED", + "WARNING", + "FAILED", + "ERROR" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e31db154-8f45-42ee-9bec-a899a4be4bca", + "created": "2026-08-28T15:13:02.326Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 154, + "reference": "ca7899c4-dc8d-41b2-bc7f-793c310fbe65", + "type": "workflow", + "folder": "/Health and Readiness", + "document": { + "name": "Trigger Readiness Checks", + "description": "Trigger Readiness Checks", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "triggerReadinessChecks", + "canvasName": "triggerReadinessChecks", + "summary": "triggerReadinessChecks", + "description": "triggerReadinessChecks", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Request body for POST /readiness.\nThe `context` object holds shared parameters (device targets and image IDs)\napplied to all checks. The `checks` array specifies which readiness check\ntypes to run.\n", + "required": [ + "context", + "checks" + ], + "properties": { + "context": { + "type": "object", + "description": "Shared context for all readiness checks in a single run.", + "required": [ + "device_targets", + "image_ids" + ], + "properties": { + "device_targets": { + "type": "array", + "description": "Target devices to run readiness checks against.", + "minItems": 1, + "items": { + "type": "object", + "description": "A single device target for readiness checks.", + "required": [ + "device_id" + ], + "properties": { + "device_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the device to check." + } + } + } + }, + "image_ids": { + "type": "array", + "description": "UUIDs of the software images being distributed. Used by all checks to resolve image metadata.", + "minItems": 1, + "items": { + "type": "string", + "format": "uuid" + } + } + } + }, + "checks": { + "type": "array", + "description": "List of readiness check types to run.", + "minItems": 1, + "items": { + "type": "object", + "description": "A single readiness check to run. The `type` field selects the check\nimplementation.\n", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "description": "The readiness check type. Supported values:\n- `base_image_presence` \u2014 verifies required base OS image is on the device\n- `disk_space` \u2014 verifies sufficient free space for the image distribution\n- `image_compatibility` \u2014 verifies image product family is compatible with the target device type\n", + "enum": [ + "base_image_presence", + "disk_space", + "image_compatibility" + ] + } + } + } + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Request body for POST /readiness.\nThe `context` object holds shared parameters (device targets and image IDs)\napplied to all checks. The `checks` array specifies which readiness check\ntypes to run.\n", + "required": [ + "context", + "checks" + ], + "properties": { + "context": { + "type": "object", + "description": "Shared context for all readiness checks in a single run.", + "required": [ + "device_targets", + "image_ids" + ], + "properties": { + "device_targets": { + "type": "array", + "description": "Target devices to run readiness checks against.", + "minItems": 1, + "items": { + "type": "object", + "description": "A single device target for readiness checks.", + "required": [ + "device_id" + ], + "properties": { + "device_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the device to check." + } + } + } + }, + "image_ids": { + "type": "array", + "description": "UUIDs of the software images being distributed. Used by all checks to resolve image metadata.", + "minItems": 1, + "items": { + "type": "string", + "format": "uuid" + } + } + } + }, + "checks": { + "type": "array", + "description": "List of readiness check types to run.", + "minItems": 1, + "items": { + "type": "object", + "description": "A single readiness check to run. The `type` field selects the check\nimplementation.\n", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "description": "The readiness check type. Supported values:\n- `base_image_presence` \u2014 verifies required base OS image is on the device\n- `disk_space` \u2014 verifies sufficient free space for the image distribution\n- `image_compatibility` \u2014 verifies image product family is compatible with the target device type\n", + "enum": [ + "base_image_presence", + "disk_space", + "image_compatibility" + ] + } + } + } + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "0015044e-7033-4534-9e37-3e7485b7921c", + "created": "2026-08-28T15:13:02.355Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 155, + "reference": "f22b4c4e-1ea9-4a04-80fe-26cefbd050e4", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Delete Upgrade Scheduled", + "description": "Delete Upgrade Scheduled", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteUpgradeScheduled", + "canvasName": "deleteUpgradeScheduled", + "summary": "deleteUpgradeScheduled", + "description": "deleteUpgradeScheduled", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "sched_id": "$var.job.sched_id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "sched_id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "sched_id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "sched_id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "9d30a825-cb4a-4dcc-a6dc-4cd72941a3d7", + "created": "2026-08-28T15:13:00.837Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 156, + "reference": "ad5adb9c-83e8-4a51-952c-3f0269d6b4fa", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Delete Uploaded Bundle", + "description": "Delete Uploaded Bundle", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteUploadedBundle", + "canvasName": "deleteUploadedBundle", + "summary": "deleteUploadedBundle", + "description": "deleteUploadedBundle", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "version": "$var.job.version", + "kind": "$var.job.kind" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "version": { + "type": "string", + "example": "1.2.1-3" + }, + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "example": "patch" + } + }, + "required": [ + "version", + "kind" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "version": { + "type": "string", + "example": "1.2.1-3" + }, + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "example": "patch" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "bae6adff-1f96-4ec7-a942-34ecf21f49eb", + "created": "2026-08-28T15:13:00.954Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 157, + "reference": "107b810d-ed9f-42c5-8a84-c17e9db78a7c", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Get Upgrade Active Job", + "description": "Get Upgrade Active Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getUpgradeActiveJob", + "canvasName": "getUpgradeActiveJob", + "summary": "getUpgradeActiveJob", + "description": "getUpgradeActiveJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "4680a599-0bc2-4c8f-8cbe-ab7a73063931", + "created": "2026-08-28T15:13:00.300Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 158, + "reference": "5f8055ed-ae71-402d-ac18-1cc8499442c3", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Get Upgrade Catalog", + "description": "Get Upgrade Catalog", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getUpgradeCatalog", + "canvasName": "getUpgradeCatalog", + "summary": "getUpgradeCatalog", + "description": "getUpgradeCatalog", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "mode": "$var.job.mode" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "mode": { + "type": "string", + "enum": [ + "online", + "offline" + ] + } + }, + "required": [ + "mode" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "mode": { + "type": "string", + "enum": [ + "online", + "offline" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "f69395ad-f01f-46a8-a19e-face09953ccf", + "created": "2026-08-28T15:13:00.358Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 159, + "reference": "3cecf530-d80a-44a1-bc5c-9d77ffde5956", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Get Upgrade Current", + "description": "Get Upgrade Current", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getUpgradeCurrent", + "canvasName": "getUpgradeCurrent", + "summary": "getUpgradeCurrent", + "description": "getUpgradeCurrent", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "6aa0b913-e2ee-4c87-bafa-1ede9cd694db", + "created": "2026-08-28T15:13:00.386Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 160, + "reference": "178093dc-246c-43ff-87e7-1e719f4ec095", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Get Upgrade History", + "description": "Get Upgrade History", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getUpgradeHistory", + "canvasName": "getUpgradeHistory", + "summary": "getUpgradeHistory", + "description": "getUpgradeHistory", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "a97292d9-fb78-4e2d-a530-c01b26ee1648", + "created": "2026-08-28T15:13:00.415Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 161, + "reference": "4238e8e4-7a71-4b62-b247-32e3ce8e423e", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Get Upgrade History Stats", + "description": "Get Upgrade History Stats", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getUpgradeHistoryStats", + "canvasName": "getUpgradeHistoryStats", + "summary": "getUpgradeHistoryStats", + "description": "getUpgradeHistoryStats", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "abab12d0-2fe9-444c-9000-0bb259f85196", + "created": "2026-08-28T15:13:00.454Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 162, + "reference": "363ace11-af5c-469a-a3da-ed13e80d461a", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Get Upgrade Job", + "description": "Get Upgrade Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getUpgradeJob", + "canvasName": "getUpgradeJob", + "summary": "getUpgradeJob", + "description": "getUpgradeJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "job_id": "$var.job.job_id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "job_id": { + "type": "string", + "format": "uuid", + "example": "550e8400-e29b-41d4-a716-446655440000" + } + }, + "required": [ + "job_id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "job_id": { + "type": "string", + "format": "uuid", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "6786d3e3-d205-48f8-9b90-f2a30444fd51", + "created": "2026-08-28T15:13:00.486Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 163, + "reference": "9036432b-15be-4d40-b59b-e06a10c516a6", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Get Upgrade Job Postflight", + "description": "Get Upgrade Job Postflight", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getUpgradeJobPostflight", + "canvasName": "getUpgradeJobPostflight", + "summary": "getUpgradeJobPostflight", + "description": "getUpgradeJobPostflight", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "job_id": "$var.job.job_id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "job_id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "job_id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "job_id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "a28c74f0-8c1b-49f4-8337-acc435126bf0", + "created": "2026-08-28T15:13:00.574Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 164, + "reference": "08447f10-d7ff-4fa5-948e-0d2d7bf33c38", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Get Upgrade Job Rollback State", + "description": "Get Upgrade Job Rollback State", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getUpgradeJobRollbackState", + "canvasName": "getUpgradeJobRollbackState", + "summary": "getUpgradeJobRollbackState", + "description": "getUpgradeJobRollbackState", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "job_id": "$var.job.job_id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "job_id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "job_id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "job_id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "325001ec-fbe9-464b-adf9-b37c54d24f06", + "created": "2026-08-28T15:13:00.634Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 165, + "reference": "bdd7a502-9c7d-479d-90d5-5253640c17c3", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Get Upgrade Preflight", + "description": "Get Upgrade Preflight", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getUpgradePreflight", + "canvasName": "getUpgradePreflight", + "summary": "getUpgradePreflight", + "description": "getUpgradePreflight", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "kind": "$var.job.kind", + "version": "$var.job.version" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "example": "patch" + }, + "version": { + "type": "string", + "example": "f5-insight-patch-1.2.3" + } + }, + "required": [ + "kind", + "version" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "example": "patch" + }, + "version": { + "type": "string", + "example": "f5-insight-patch-1.2.3" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "c8682c7a-9b45-4a2d-bdb8-e65e579fa8c4", + "created": "2026-08-28T15:13:00.664Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 166, + "reference": "5c0ac212-fa5e-4597-9c21-722ae7950d35", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Get Upgrade Rollback", + "description": "Get Upgrade Rollback", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getUpgradeRollback", + "canvasName": "getUpgradeRollback", + "summary": "getUpgradeRollback", + "description": "getUpgradeRollback", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "rollback_id": "$var.job.rollback_id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "rollback_id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "rollback_id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "rollback_id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "93011d9f-fd41-4e09-9ec7-3206445e4f94", + "created": "2026-08-28T15:13:00.694Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 167, + "reference": "e85e8b18-2552-4b08-adfb-f5a2c6568777", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Get Upgrade Schedule Recommendation", + "description": "Get Upgrade Schedule Recommendation", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getUpgradeScheduleRecommendation", + "canvasName": "getUpgradeScheduleRecommendation", + "summary": "getUpgradeScheduleRecommendation", + "description": "getUpgradeScheduleRecommendation", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "53338303-dc4d-4185-932e-0ad0d49f62be", + "created": "2026-08-28T15:13:00.752Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 168, + "reference": "340151f6-6b3f-4489-9908-b12bebb97214", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Get Upgrade Scheduled", + "description": "Get Upgrade Scheduled", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getUpgradeScheduled", + "canvasName": "getUpgradeScheduled", + "summary": "getUpgradeScheduled", + "description": "getUpgradeScheduled", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "296ac8e5-7419-4bcc-88d4-9c42e391ce08", + "created": "2026-08-28T15:13:00.783Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 169, + "reference": "5378708c-d2fc-4d42-a902-b382272933ae", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Get Upgrade Scheduled History", + "description": "Get Upgrade Scheduled History", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getUpgradeScheduledHistory", + "canvasName": "getUpgradeScheduledHistory", + "summary": "getUpgradeScheduledHistory", + "description": "getUpgradeScheduledHistory", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "8e27ea6b-e001-4613-8247-0cc45de64e73", + "created": "2026-08-28T15:13:00.809Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 170, + "reference": "4cb0e608-15cd-496d-bad3-1cc249f2d561", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Get Upgrade Status", + "description": "Get Upgrade Status", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getUpgradeStatus", + "canvasName": "getUpgradeStatus", + "summary": "getUpgradeStatus", + "description": "getUpgradeStatus", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "dfd4ee35-6e88-4d02-ad34-57250218dab4", + "created": "2026-08-28T15:13:00.894Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 171, + "reference": "de422b0d-a501-4928-975e-33d667546b44", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Get Uploaded Bundle", + "description": "Get Uploaded Bundle", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getUploadedBundle", + "canvasName": "getUploadedBundle", + "summary": "getUploadedBundle", + "description": "getUploadedBundle", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "bdad8284-8779-46c0-96fa-cc259915c7fc", + "created": "2026-08-28T15:13:00.922Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 172, + "reference": "1d7eb2c2-da3b-448a-8b83-79ca9409c8eb", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Post Upgrade Apply", + "description": "Post Upgrade Apply", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "postUpgradeApply", + "canvasName": "postUpgradeApply", + "summary": "postUpgradeApply", + "description": "postUpgradeApply", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "version", + "kind" + ], + "properties": { + "version": { + "type": "string", + "description": "Target version to upgrade to", + "example": "3.2.1" + }, + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "description": "Upgrade kind to apply", + "example": "patch" + }, + "skip_backup": { + "type": "boolean", + "default": false, + "example": false + }, + "backup_passphrase": { + "type": "string", + "format": "password", + "description": "Required when skip_backup is false. Used only to create the pre-upgrade backup and never persisted in plaintext.", + "example": "MyStr0ng!Pass" + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ], + "description": "Required when skip_backup is false. Determines whether the pre-upgrade backup captures all components or config-only.", + "example": "full" + }, + "storage_target": { + "type": "string", + "description": "Required when skip_backup is false. Use \"local\" for local appliance storage or a configured storage target name.", + "example": "local" + }, + "bypass_preflight_checks": { + "type": "boolean", + "default": false, + "description": "Explicit user override for failed preflight checks that have bypass_allowed=true. no_active_job, disk_space, and version_compatibility failures always block apply.", + "example": false + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "version", + "kind" + ], + "properties": { + "version": { + "type": "string", + "description": "Target version to upgrade to", + "example": "3.2.1" + }, + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "description": "Upgrade kind to apply", + "example": "patch" + }, + "skip_backup": { + "type": "boolean", + "default": false, + "example": false + }, + "backup_passphrase": { + "type": "string", + "format": "password", + "description": "Required when skip_backup is false. Used only to create the pre-upgrade backup and never persisted in plaintext.", + "example": "MyStr0ng!Pass" + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ], + "description": "Required when skip_backup is false. Determines whether the pre-upgrade backup captures all components or config-only.", + "example": "full" + }, + "storage_target": { + "type": "string", + "description": "Required when skip_backup is false. Use \"local\" for local appliance storage or a configured storage target name.", + "example": "local" + }, + "bypass_preflight_checks": { + "type": "boolean", + "default": false, + "description": "Explicit user override for failed preflight checks that have bypass_allowed=true. no_active_job, disk_space, and version_compatibility failures always block apply.", + "example": false + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "8e497720-1fe2-4194-9535-c5b69e520862", + "created": "2026-08-28T15:13:00.331Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 173, + "reference": "fb9fa7fb-da1d-493a-a8cb-0346b20b3ca1", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Post Upgrade Job Cancel", + "description": "Post Upgrade Job Cancel", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "postUpgradeJobCancel", + "canvasName": "postUpgradeJobCancel", + "summary": "postUpgradeJobCancel", + "description": "postUpgradeJobCancel", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "job_id": "$var.job.job_id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "job_id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "job_id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "job_id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "327d1d0e-2e7a-4d06-a7bb-a60c4c4bdddb", + "created": "2026-08-28T15:13:00.517Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 174, + "reference": "6310c04d-224e-47ab-bd3f-7e43e0e23697", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Post Upgrade Job Confirm Clean", + "description": "Post Upgrade Job Confirm Clean", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "postUpgradeJobConfirmClean", + "canvasName": "postUpgradeJobConfirmClean", + "summary": "postUpgradeJobConfirmClean", + "description": "postUpgradeJobConfirmClean", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "job_id": "$var.job.job_id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "job_id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "job_id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "job_id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "6beaf0e0-96ef-4980-8eca-a717b9a55604", + "created": "2026-08-28T15:13:00.545Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 175, + "reference": "146eae54-b52c-47f5-8835-7a09fb7a3433", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Post Upgrade Job Rollback", + "description": "Post Upgrade Job Rollback", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "postUpgradeJobRollback", + "canvasName": "postUpgradeJobRollback", + "summary": "postUpgradeJobRollback", + "description": "postUpgradeJobRollback", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "job_id": "$var.job.job_id" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "job_id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "job_id" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "job_id": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "a6aadf54-635d-4861-b478-446618968dd6", + "created": "2026-08-28T15:13:00.607Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 176, + "reference": "f5abe685-cf66-46dd-9835-0d7afb6d520c", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Post Upgrade Schedule", + "description": "Post Upgrade Schedule", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "postUpgradeSchedule", + "canvasName": "postUpgradeSchedule", + "summary": "postUpgradeSchedule", + "description": "postUpgradeSchedule", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "kind", + "version", + "scheduled_at" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "example": "patch" + }, + "version": { + "type": "string", + "example": "f5-insight-patch-3.20" + }, + "scheduled_at": { + "type": "string", + "format": "date-time", + "description": "Future UTC timestamp when the upgrade should run", + "example": "2026-05-12T02:00:00Z" + }, + "skip_backup": { + "type": "boolean", + "default": false, + "example": false + }, + "backup_passphrase": { + "type": "string", + "format": "password", + "description": "Required when skip_backup is false. Stored securely and used when the scheduled upgrade creates its pre-upgrade backup.", + "example": "MyStr0ng!Pass" + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ], + "description": "Required when skip_backup is false. Determines whether the scheduled pre-upgrade backup captures all components or config-only.", + "example": "full" + }, + "storage_target": { + "type": "string", + "description": "Required when skip_backup is false. Use \"local\" for local appliance storage or a configured storage target name.", + "example": "local" + }, + "bypass_preflight_checks": { + "type": "boolean", + "default": false, + "description": "Explicit user override for failed preflight checks that have bypass_allowed=true. no_active_job, disk_space, and version_compatibility failures always block scheduled apply." + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "kind", + "version", + "scheduled_at" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "patch", + "full_upgrade" + ], + "example": "patch" + }, + "version": { + "type": "string", + "example": "f5-insight-patch-3.20" + }, + "scheduled_at": { + "type": "string", + "format": "date-time", + "description": "Future UTC timestamp when the upgrade should run", + "example": "2026-05-12T02:00:00Z" + }, + "skip_backup": { + "type": "boolean", + "default": false, + "example": false + }, + "backup_passphrase": { + "type": "string", + "format": "password", + "description": "Required when skip_backup is false. Stored securely and used when the scheduled upgrade creates its pre-upgrade backup.", + "example": "MyStr0ng!Pass" + }, + "backup_type": { + "type": "string", + "enum": [ + "full", + "config" + ], + "description": "Required when skip_backup is false. Determines whether the scheduled pre-upgrade backup captures all components or config-only.", + "example": "full" + }, + "storage_target": { + "type": "string", + "description": "Required when skip_backup is false. Use \"local\" for local appliance storage or a configured storage target name.", + "example": "local" + }, + "bypass_preflight_checks": { + "type": "boolean", + "default": false, + "description": "Explicit user override for failed preflight checks that have bypass_allowed=true. no_active_job, disk_space, and version_compatibility failures always block scheduled apply." + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "4e9973a0-dffb-46f2-ab2c-d10095c49f02", + "created": "2026-08-28T15:13:00.724Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 177, + "reference": "5b119a8d-b039-4c07-811c-523d185d9395", + "type": "workflow", + "folder": "/Upgrade", + "document": { + "name": "Start Upgrade", + "description": "Start Upgrade", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "startUpgrade", + "canvasName": "startUpgrade", + "summary": "startUpgrade", + "description": "startUpgrade", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "d7157097-b9a0-4f35-9db7-a6ae39747148", + "created": "2026-08-28T15:13:00.867Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 178, + "reference": "a43a5496-47c9-43a8-aa5d-a79143950025", + "type": "workflow", + "folder": "/Telemetry Configuration", + "document": { + "name": "Get Telemetry Type", + "description": "Get Telemetry Type", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getTelemetryType", + "canvasName": "getTelemetryType", + "summary": "getTelemetryType", + "description": "getTelemetryType", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "type": "$var.job.type" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "API_Discovery", + "Application_Telemetry" + ] + } + }, + "required": [ + "type" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "API_Discovery", + "Application_Telemetry" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "4e5a6a0c-040b-4bf4-855d-342867f67e5f", + "created": "2026-08-28T15:13:01.068Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 179, + "reference": "65984d23-5a95-4761-9913-064d4f4c9805", + "type": "workflow", + "folder": "/Telemetry Configuration", + "document": { + "name": "Get Telemetry Types", + "description": "Get Telemetry Types", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getTelemetryTypes", + "canvasName": "getTelemetryTypes", + "summary": "getTelemetryTypes", + "description": "getTelemetryTypes", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "7ae0d25d-de86-40ae-a3f2-9eea5c42a54f", + "created": "2026-08-28T15:13:01.009Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 180, + "reference": "a32a7359-8de1-4870-b3d1-1f471e533fa3", + "type": "workflow", + "folder": "/Telemetry Configuration", + "document": { + "name": "Update Telemetry Types", + "description": "Update Telemetry Types", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "updateTelemetryTypes", + "canvasName": "updateTelemetryTypes", + "summary": "updateTelemetryTypes", + "description": "updateTelemetryTypes", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "enabled_types" + ], + "properties": { + "enabled_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "API_Discovery", + "Application_Telemetry" + ] + }, + "description": "List of telemetry types to enable (all others will be disabled)", + "example": [ + "API_Discovery", + "Application_Telemetry" + ], + "minItems": 0 + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "enabled_types" + ], + "properties": { + "enabled_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "API_Discovery", + "Application_Telemetry" + ] + }, + "description": "List of telemetry types to enable (all others will be disabled)", + "example": [ + "API_Discovery", + "Application_Telemetry" + ], + "minItems": 0 + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "aa069800-834d-4cd8-bf21-6862970cd930", + "created": "2026-08-28T15:13:01.040Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 181, + "reference": "5948663b-bd50-4af0-826c-f67812bf94fd", + "type": "workflow", + "folder": "/Compatibility Matrix", + "document": { + "name": "Delete Compat Upgrade Path", + "description": "Delete Compat Upgrade Path", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteCompatUpgradePath", + "canvasName": "deleteCompatUpgradePath", + "summary": "deleteCompatUpgradePath", + "description": "deleteCompatUpgradePath", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "compatId": "$var.job.compatId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "compatId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "compatId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "compatId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "88962aa6-f720-4177-bcfa-eba1d759e2c7", + "created": "2026-08-28T15:13:01.183Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 182, + "reference": "fec6c68a-ab3b-4fab-944f-4f13f1f96e87", + "type": "workflow", + "folder": "/Compatibility Matrix", + "document": { + "name": "Get Compat Upgrade Path", + "description": "Get Compat Upgrade Path", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getCompatUpgradePath", + "canvasName": "getCompatUpgradePath", + "summary": "getCompatUpgradePath", + "description": "getCompatUpgradePath", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "compatId": "$var.job.compatId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "compatId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "compatId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "compatId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "724e6c52-40c6-4a86-8dd9-f22312778aee", + "created": "2026-08-28T15:13:01.156Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 183, + "reference": "f57541f0-2c00-4163-a98e-3b75a12719ef", + "type": "workflow", + "folder": "/Compatibility Matrix", + "document": { + "name": "List Compat Upgrade Paths", + "description": "List Compat Upgrade Paths", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listCompatUpgradePaths", + "canvasName": "listCompatUpgradePaths", + "summary": "listCompatUpgradePaths", + "description": "listCompatUpgradePaths", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "4ec09ebd-d12c-4204-bacd-070f67183fce", + "created": "2026-08-28T15:13:01.097Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 184, + "reference": "4ac857b4-2fd6-4d8c-880a-b9b38560e6be", + "type": "workflow", + "folder": "/Compatibility Matrix", + "document": { + "name": "Upsert Compat Upgrade Path", + "description": "Upsert Compat Upgrade Path", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "upsertCompatUpgradePath", + "canvasName": "upsertCompatUpgradePath", + "summary": "upsertCompatUpgradePath", + "description": "upsertCompatUpgradePath", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Request body for POST /compat/upgrade-paths.", + "required": [ + "target_major_version", + "min_source_version" + ], + "properties": { + "target_major_version": { + "type": "string", + "description": "Target BIG-IP major version, e.g. \"17\" or \"21\".", + "minLength": 1, + "example": "21" + }, + "min_source_version": { + "type": "string", + "description": "Minimum source version required (inclusive), e.g. \"17.1.0\".", + "minLength": 1, + "example": "14.0.0" + }, + "max_source_version": { + "type": "string", + "nullable": true, + "description": "Maximum source version (inclusive). Omit or null for no upper bound." + }, + "notes": { + "type": "string", + "nullable": true, + "description": "Optional human-readable note." + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Request body for POST /compat/upgrade-paths.", + "required": [ + "target_major_version", + "min_source_version" + ], + "properties": { + "target_major_version": { + "type": "string", + "description": "Target BIG-IP major version, e.g. \"17\" or \"21\".", + "minLength": 1, + "example": "21" + }, + "min_source_version": { + "type": "string", + "description": "Minimum source version required (inclusive), e.g. \"17.1.0\".", + "minLength": 1, + "example": "14.0.0" + }, + "max_source_version": { + "type": "string", + "nullable": true, + "description": "Maximum source version (inclusive). Omit or null for no upper bound." + }, + "notes": { + "type": "string", + "nullable": true, + "description": "Optional human-readable note." + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "345c25a2-c51d-4b00-be02-3dfd3b8ad542", + "created": "2026-08-28T15:13:01.128Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 185, + "reference": "c2368b9c-6f18-4f91-b9d0-de97c22f4b7c", + "type": "workflow", + "folder": "/Inventory", + "document": { + "name": "Create Devices Disk Analysis Task", + "description": "Create Devices Disk Analysis Task", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "createDevicesDiskAnalysisTask", + "canvasName": "createDevicesDiskAnalysisTask", + "summary": "createDevicesDiskAnalysisTask", + "description": "createDevicesDiskAnalysisTask", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "required_size_bytes", + "devices" + ], + "properties": { + "required_size_bytes": { + "type": "integer", + "format": "int64", + "minimum": 1, + "description": "Required disk size per device, in bytes" + }, + "devices": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": [ + "device_id" + ], + "properties": { + "device_id": { + "type": "string", + "format": "uuid" + } + } + } + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "required_size_bytes", + "devices" + ], + "properties": { + "required_size_bytes": { + "type": "integer", + "format": "int64", + "minimum": 1, + "description": "Required disk size per device, in bytes" + }, + "devices": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": [ + "device_id" + ], + "properties": { + "device_id": { + "type": "string", + "format": "uuid" + } + } + } + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "14d281da-bd59-4f54-a926-3138fc0a49f2", + "created": "2026-08-28T15:13:01.244Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 186, + "reference": "7adbca84-1032-4130-b148-a38213959479", + "type": "workflow", + "folder": "/Inventory", + "document": { + "name": "Get Devices Disk Analysis Task", + "description": "Get Devices Disk Analysis Task", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getDevicesDiskAnalysisTask", + "canvasName": "getDevicesDiskAnalysisTask", + "summary": "getDevicesDiskAnalysisTask", + "description": "getDevicesDiskAnalysisTask", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "taskId": "$var.job.taskId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "taskId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "taskId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "taskId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "0f4536b9-2e13-4173-a996-c24c5a9de21b", + "created": "2026-08-28T15:13:01.272Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 187, + "reference": "6765e5a4-08c5-4f6b-a779-fb17a5c602d8", + "type": "workflow", + "folder": "/Inventory", + "document": { + "name": "Get Fleet Device", + "description": "Get Fleet Device", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getFleetDevice", + "canvasName": "getFleetDevice", + "summary": "getFleetDevice", + "description": "getFleetDevice", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "deviceId": "$var.job.deviceId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "deviceId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "deviceId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "deviceId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "9f6aaec4-4a62-4bc2-80cc-6e81e63f497d", + "created": "2026-08-28T15:13:01.305Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 188, + "reference": "02ed370c-9115-4e55-a25b-3d91fbd62898", + "type": "workflow", + "folder": "/Inventory", + "document": { + "name": "Get Fleet Summary", + "description": "Get Fleet Summary", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getFleetSummary", + "canvasName": "getFleetSummary", + "summary": "getFleetSummary", + "description": "getFleetSummary", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "type": "object", + "properties": { + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "ecd3cbe0-a8b1-4c19-b72e-22b3998a17fd", + "created": "2026-08-28T15:13:02.412Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 189, + "reference": "cbe80736-ea19-4b1f-ae8b-42199ccbc748", + "type": "workflow", + "folder": "/Inventory", + "document": { + "name": "List Fleet Devices", + "description": "List Fleet Devices", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listFleetDevices", + "canvasName": "listFleetDevices", + "summary": "listFleetDevices", + "description": "listFleetDevices", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "page": "$var.job.page", + "page_size": "$var.job.page_size", + "type": "$var.job.type", + "search": "$var.job.search", + "$filter": "$var.job.$filter", + "$orderby": "$var.job.$orderby" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "page_size": { + "type": "integer", + "default": 20, + "minimum": 1, + "maximum": 500 + }, + "type": { + "type": "string", + "enum": [ + "BIGIP", + "RSERIES", + "VELOS" + ] + }, + "search": { + "type": "string" + }, + "": { + "type": [ + "array", + "boolean", + "null", + "number", + "object", + "string" + ] + } + }, + "required": [ + "page", + "page_size", + "type", + "search", + "" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "page_size": { + "type": "integer", + "default": 20, + "minimum": 1, + "maximum": 500 + }, + "type": { + "type": "string", + "enum": [ + "BIGIP", + "RSERIES", + "VELOS" + ] + }, + "search": { + "type": "string" + }, + "": { + "type": [ + "array", + "boolean", + "null", + "number", + "object", + "string" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "6c8ca150-e99b-405e-92c3-03802c7aac6a", + "created": "2026-08-28T15:13:01.216Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 190, + "reference": "f093b370-4a5f-41c0-aa2b-7cec373518e9", + "type": "workflow", + "folder": "/Inventory", + "document": { + "name": "Refresh Fleet Device", + "description": "Refresh Fleet Device", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "refreshFleetDevice", + "canvasName": "refreshFleetDevice", + "summary": "refreshFleetDevice", + "description": "refreshFleetDevice", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "deviceId": "$var.job.deviceId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "deviceId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "deviceId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "deviceId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "bb6a1a9b-1ea9-446c-815f-e05ffee7da4a", + "created": "2026-08-28T15:13:01.330Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 191, + "reference": "9d9a7b2e-caff-42c3-941b-4ef3ef0c7bb3", + "type": "workflow", + "folder": "/Flight Checks", + "document": { + "name": "Get Flight Diff", + "description": "Get Flight Diff", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getFlightDiff", + "canvasName": "getFlightDiff", + "summary": "getFlightDiff", + "description": "getFlightDiff", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "diffId": "$var.job.diffId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "diffId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "diffId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "diffId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "61dfa36b-db75-42bc-9eb0-8fcf6443ab5c", + "created": "2026-08-28T15:13:01.388Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 192, + "reference": "1db84c40-788c-43af-80af-5b575020aeb3", + "type": "workflow", + "folder": "/Flight Checks", + "document": { + "name": "Get Flight Snapshot", + "description": "Get Flight Snapshot", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getFlightSnapshot", + "canvasName": "getFlightSnapshot", + "summary": "getFlightSnapshot", + "description": "getFlightSnapshot", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "snapshotId": "$var.job.snapshotId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "snapshotId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "snapshotId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "snapshotId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "265904d5-179d-4300-a9d6-8e4ac5aa0e7b", + "created": "2026-08-28T15:13:01.442Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 193, + "reference": "7181b949-740b-473a-be70-187615dad45e", + "type": "workflow", + "folder": "/Flight Checks", + "document": { + "name": "List Flight Diffs", + "description": "List Flight Diffs", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listFlightDiffs", + "canvasName": "listFlightDiffs", + "summary": "listFlightDiffs", + "description": "listFlightDiffs", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "page": "$var.job.page", + "page_size": "$var.job.page_size", + "jobId": "$var.job.jobId", + "deviceId": "$var.job.deviceId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "page_size": { + "type": "integer", + "default": 20, + "minimum": 1, + "maximum": 500 + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "deviceId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "page", + "page_size", + "jobId", + "deviceId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "page_size": { + "type": "integer", + "default": 20, + "minimum": 1, + "maximum": 500 + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "deviceId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "ddca8e69-8e33-4431-bde2-c3a0720e3267", + "created": "2026-08-28T15:13:01.357Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 194, + "reference": "62fb3b97-8238-4547-8c02-68695be932d4", + "type": "workflow", + "folder": "/Flight Checks", + "document": { + "name": "List Flight Snapshots", + "description": "List Flight Snapshots", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listFlightSnapshots", + "canvasName": "listFlightSnapshots", + "summary": "listFlightSnapshots", + "description": "listFlightSnapshots", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "page": "$var.job.page", + "page_size": "$var.job.page_size", + "jobId": "$var.job.jobId", + "deviceId": "$var.job.deviceId", + "phase": "$var.job.phase" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "page_size": { + "type": "integer", + "default": 20, + "minimum": 1, + "maximum": 500 + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "deviceId": { + "type": "string", + "format": "uuid" + }, + "phase": { + "type": "string", + "enum": [ + "PRE", + "POST" + ] + } + }, + "required": [ + "page", + "page_size", + "jobId", + "deviceId", + "phase" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "page_size": { + "type": "integer", + "default": 20, + "minimum": 1, + "maximum": 500 + }, + "jobId": { + "type": "string", + "format": "uuid" + }, + "deviceId": { + "type": "string", + "format": "uuid" + }, + "phase": { + "type": "string", + "enum": [ + "PRE", + "POST" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "2fef8710-4a6e-422c-8db6-8a3931b7023e", + "created": "2026-08-28T15:13:01.414Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 195, + "reference": "82a8d3fb-7633-4845-890d-e6620e2fef04", + "type": "workflow", + "folder": "/Images", + "document": { + "name": "Bulk Delete Images", + "description": "Bulk Delete Images", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "bulkDeleteImages", + "canvasName": "bulkDeleteImages", + "summary": "bulkDeleteImages", + "description": "bulkDeleteImages", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "image_ids" + ], + "properties": { + "image_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + }, + "minItems": 1, + "maxItems": 100 + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "image_ids" + ], + "properties": { + "image_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + }, + "minItems": 1, + "maxItems": 100 + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "7d690595-81a9-41fe-aaf4-8169d0b7d30b", + "created": "2026-08-28T15:13:01.507Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 196, + "reference": "f9d6a780-2005-4689-a8fb-bc57798d3a2a", + "type": "workflow", + "folder": "/Images", + "document": { + "name": "Delete Image", + "description": "Delete Image", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteImage", + "canvasName": "deleteImage", + "summary": "deleteImage", + "description": "deleteImage", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "imageId": "$var.job.imageId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "imageId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "imageId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "imageId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "b9a72bca-bee0-4511-9c68-cc395607cb7b", + "created": "2026-08-28T15:13:01.576Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 197, + "reference": "387acbfd-11ad-434e-b36c-d201a5950edc", + "type": "workflow", + "folder": "/Images", + "document": { + "name": "Get Image", + "description": "Get Image", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getImage", + "canvasName": "getImage", + "summary": "getImage", + "description": "getImage", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "imageId": "$var.job.imageId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "imageId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "imageId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "imageId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "1c7fbd50-7435-4f1b-a3e8-f58ebf13ae23", + "created": "2026-08-28T15:13:01.538Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 198, + "reference": "d24a31bd-7a49-47de-a9b0-5c411b12e756", + "type": "workflow", + "folder": "/Images", + "document": { + "name": "List Images", + "description": "List Images", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listImages", + "canvasName": "listImages", + "summary": "listImages", + "description": "listImages", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "page": "$var.job.page", + "page_size": "$var.job.page_size", + "product_family": "$var.job.product_family", + "sort_by": "$var.job.sort_by", + "sort_order": "$var.job.sort_order" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "page_size": { + "type": "integer", + "default": 20, + "minimum": 1, + "maximum": 500 + }, + "product_family": { + "type": "string", + "enum": [ + "BIG-IP", + "F5OS-C", + "F5OS-A" + ] + }, + "sort_by": { + "type": "string", + "enum": [ + "version" + ], + "description": "Field to sort images by" + }, + "sort_order": { + "type": "string", + "enum": [ + "asc", + "desc" + ], + "description": "Sort direction (shared schema, reusable across endpoints)" + } + }, + "required": [ + "page", + "page_size", + "product_family", + "sort_by", + "sort_order" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "page_size": { + "type": "integer", + "default": 20, + "minimum": 1, + "maximum": 500 + }, + "product_family": { + "type": "string", + "enum": [ + "BIG-IP", + "F5OS-C", + "F5OS-A" + ] + }, + "sort_by": { + "type": "string", + "enum": [ + "version" + ], + "description": "Field to sort images by" + }, + "sort_order": { + "type": "string", + "enum": [ + "asc", + "desc" + ], + "description": "Sort direction (shared schema, reusable across endpoints)" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "a879dfa7-c5f9-4ef7-8a6f-5f7a50dcc582", + "created": "2026-08-28T15:13:01.474Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 199, + "reference": "a7c97d07-8aa1-4e30-bd2c-89ac0ce9f70d", + "type": "workflow", + "folder": "/Software Distribution", + "document": { + "name": "Activate Software Distribution Job", + "description": "Activate Software Distribution Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "activateSoftwareDistributionJob", + "canvasName": "activateSoftwareDistributionJob", + "summary": "activateSoftwareDistributionJob", + "description": "activateSoftwareDistributionJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Optional request body for POST /jobs/software-distribution/{jobId}/activate.\nAll fields are optional; the endpoint may be called with no body at all.\n", + "properties": { + "changeRequest": { + "type": "string", + "nullable": true, + "maxLength": 255, + "description": "Optional change-request identifier (e.g. \"CHG0012345\") associated with\nthis specific activation/run. Persisted on the execution record so the\nUI can display it in the execution drawer. Each activation of the same\njob may carry a different change request.\n" + } + } + } + }, + "required": [ + "jobId", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Optional request body for POST /jobs/software-distribution/{jobId}/activate.\nAll fields are optional; the endpoint may be called with no body at all.\n", + "properties": { + "changeRequest": { + "type": "string", + "nullable": true, + "maxLength": 255, + "description": "Optional change-request identifier (e.g. \"CHG0012345\") associated with\nthis specific activation/run. Persisted on the execution record so the\nUI can display it in the execution drawer. Each activation of the same\njob may carry a different change request.\n" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "4710ac5d-073d-4d90-8534-b5cb54c87724", + "created": "2026-08-28T15:13:01.778Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 200, + "reference": "e1335811-1ca7-4dd6-9690-868373c3566a", + "type": "workflow", + "folder": "/Software Distribution", + "document": { + "name": "Cancel Software Distribution Job", + "description": "Cancel Software Distribution Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "cancelSoftwareDistributionJob", + "canvasName": "cancelSoftwareDistributionJob", + "summary": "cancelSoftwareDistributionJob", + "description": "cancelSoftwareDistributionJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "1f49c0a5-4ca3-478f-a33f-ea73f65d970a", + "created": "2026-08-28T15:13:01.804Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 201, + "reference": "1f9205f3-15ef-467a-8a74-d2f8565964a2", + "type": "workflow", + "folder": "/Software Distribution", + "document": { + "name": "Cancel Software Distribution Target", + "description": "Cancel Software Distribution Target", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "cancelSoftwareDistributionTarget", + "canvasName": "cancelSoftwareDistributionTarget", + "summary": "cancelSoftwareDistributionTarget", + "description": "cancelSoftwareDistributionTarget", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId", + "deviceId": "$var.job.deviceId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "deviceId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "jobId", + "deviceId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "deviceId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "31fd4639-92c7-431e-86b5-0bdebd4fd049", + "created": "2026-08-28T15:13:01.974Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 202, + "reference": "93f5fca9-2a8b-4dae-a705-5d2f0e6afee7", + "type": "workflow", + "folder": "/Software Distribution", + "document": { + "name": "Create Software Distribution Job", + "description": "Create Software Distribution Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "createSoftwareDistributionJob", + "canvasName": "createSoftwareDistributionJob", + "summary": "createSoftwareDistributionJob", + "description": "createSoftwareDistributionJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Request body for creating a new software distribution job. Name is required.", + "properties": { + "name": { + "type": "string", + "description": "Unique name for this distribution job.", + "minLength": 1, + "maxLength": 255 + }, + "description": { + "type": "string", + "description": "Optional human-readable description." + }, + "enabled": { + "type": "boolean", + "description": "Whether this job is enabled. Set to false to disable the job.\nA disabled job cannot be activated, paused, or resumed.\nOmit on create to default to true.\n" + }, + "config": { + "type": "object", + "required": [ + "configType" + ], + "properties": { + "configType": { + "type": "string", + "enum": [ + "SOFTWARE_DISTRIBUTION" + ], + "description": "Config type discriminator" + } + } + } + }, + "required": [ + "name" + ] + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Request body for creating a new software distribution job. Name is required.", + "properties": { + "name": { + "type": "string", + "description": "Unique name for this distribution job.", + "minLength": 1, + "maxLength": 255 + }, + "description": { + "type": "string", + "description": "Optional human-readable description." + }, + "enabled": { + "type": "boolean", + "description": "Whether this job is enabled. Set to false to disable the job.\nA disabled job cannot be activated, paused, or resumed.\nOmit on create to default to true.\n" + }, + "config": { + "type": "object", + "required": [ + "configType" + ], + "properties": { + "configType": { + "type": "string", + "enum": [ + "SOFTWARE_DISTRIBUTION" + ], + "description": "Config type discriminator" + } + } + } + }, + "required": [ + "name" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "6cda600e-f7c6-46f1-8e73-e7ab6396361c", + "created": "2026-08-28T15:13:01.648Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 203, + "reference": "2c0e5322-7d9d-4799-a394-ca60e6e83012", + "type": "workflow", + "folder": "/Software Distribution", + "document": { + "name": "Delete Software Distribution Job", + "description": "Delete Software Distribution Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteSoftwareDistributionJob", + "canvasName": "deleteSoftwareDistributionJob", + "summary": "deleteSoftwareDistributionJob", + "description": "deleteSoftwareDistributionJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "10a6c049-9f72-41f6-b415-7127480aa68d", + "created": "2026-08-28T15:13:01.747Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 204, + "reference": "7f066f12-5d0c-4035-81b5-5d72f9fa95f9", + "type": "workflow", + "folder": "/Software Distribution", + "document": { + "name": "Get Software Distribution Job", + "description": "Get Software Distribution Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getSoftwareDistributionJob", + "canvasName": "getSoftwareDistributionJob", + "summary": "getSoftwareDistributionJob", + "description": "getSoftwareDistributionJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "12989f71-e1d1-42f9-9ec0-3f712bcbbffe", + "created": "2026-08-28T15:13:01.685Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 205, + "reference": "e285d30e-b3fa-4231-ab8b-b64cfcb6ff8c", + "type": "workflow", + "folder": "/Software Distribution", + "document": { + "name": "Get Software Distribution Job Execution", + "description": "Get Software Distribution Job Execution", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getSoftwareDistributionJobExecution", + "canvasName": "getSoftwareDistributionJobExecution", + "summary": "getSoftwareDistributionJobExecution", + "description": "getSoftwareDistributionJobExecution", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId", + "executionId": "$var.job.executionId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "executionId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "jobId", + "executionId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "executionId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e5d798dc-2467-445c-bd4f-5bfd2831f774", + "created": "2026-08-28T15:13:01.861Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 206, + "reference": "0c6ad7f6-67e3-4e78-a13b-ed4e93edb6b6", + "type": "workflow", + "folder": "/Software Distribution", + "document": { + "name": "Get Software Distribution Job Status", + "description": "Get Software Distribution Job Status", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getSoftwareDistributionJobStatus", + "canvasName": "getSoftwareDistributionJobStatus", + "summary": "getSoftwareDistributionJobStatus", + "description": "getSoftwareDistributionJobStatus", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "2dc4795c-173d-49a9-ac74-81a1588521ab", + "created": "2026-08-28T15:13:01.946Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 207, + "reference": "c62e21a4-0697-4e4a-b4f8-bc90bc3a634d", + "type": "workflow", + "folder": "/Software Distribution", + "document": { + "name": "List Software Distribution Job Executions", + "description": "List Software Distribution Job Executions", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listSoftwareDistributionJobExecutions", + "canvasName": "listSoftwareDistributionJobExecutions", + "summary": "listSoftwareDistributionJobExecutions", + "description": "listSoftwareDistributionJobExecutions", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "1f800c5d-8569-4402-9c20-d92a71cd3d5b", + "created": "2026-08-28T15:13:01.831Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 208, + "reference": "14950562-03c8-4563-97d8-f5335583c4d1", + "type": "workflow", + "folder": "/Software Distribution", + "document": { + "name": "List Software Distribution Jobs", + "description": "List Software Distribution Jobs", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listSoftwareDistributionJobs", + "canvasName": "listSoftwareDistributionJobs", + "summary": "listSoftwareDistributionJobs", + "description": "listSoftwareDistributionJobs", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "page": "$var.job.page", + "page_size": "$var.job.page_size", + "status": "$var.job.status" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "page_size": { + "type": "integer", + "default": 20, + "minimum": 1, + "maximum": 500 + }, + "status": { + "type": "string", + "description": "Lifecycle status of an upgrade job. The job is a long-lived\nre-activatable definition; per-run outcomes (success/fail/abort)\nare recorded on the execution row, NOT here. Operator-driven\ncancel converges back to READY at the job level; CANCELLED is\nrecorded on the execution row only.\n", + "enum": [ + "DRAFT", + "READY", + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED" + ] + } + }, + "required": [ + "page", + "page_size", + "status" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "page_size": { + "type": "integer", + "default": 20, + "minimum": 1, + "maximum": 500 + }, + "status": { + "type": "string", + "description": "Lifecycle status of an upgrade job. The job is a long-lived\nre-activatable definition; per-run outcomes (success/fail/abort)\nare recorded on the execution row, NOT here. Operator-driven\ncancel converges back to READY at the job level; CANCELLED is\nrecorded on the execution row only.\n", + "enum": [ + "DRAFT", + "READY", + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "bfadecde-ed03-43c0-bf74-4962ea45565f", + "created": "2026-08-28T15:13:01.614Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 209, + "reference": "b65bb8f0-5e36-4b9e-a0b0-a317239593c1", + "type": "workflow", + "folder": "/Software Distribution", + "document": { + "name": "Pause Software Distribution Job", + "description": "Pause Software Distribution Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "pauseSoftwareDistributionJob", + "canvasName": "pauseSoftwareDistributionJob", + "summary": "pauseSoftwareDistributionJob", + "description": "pauseSoftwareDistributionJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "9484e4ee-6164-459b-a62b-473c00f1433a", + "created": "2026-08-28T15:13:01.888Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 210, + "reference": "69e2b51a-c320-4ae8-a461-81ed050854d4", + "type": "workflow", + "folder": "/Software Distribution", + "document": { + "name": "Resume Software Distribution Job", + "description": "Resume Software Distribution Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "resumeSoftwareDistributionJob", + "canvasName": "resumeSoftwareDistributionJob", + "summary": "resumeSoftwareDistributionJob", + "description": "resumeSoftwareDistributionJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "017eb16a-bf94-4b3b-8dab-516b6d3b2c87", + "created": "2026-08-28T15:13:01.915Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 211, + "reference": "39bec109-c932-4ab9-8489-b315fbb24111", + "type": "workflow", + "folder": "/Software Distribution", + "document": { + "name": "Update Software Distribution Job", + "description": "Update Software Distribution Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "updateSoftwareDistributionJob", + "canvasName": "updateSoftwareDistributionJob", + "summary": "updateSoftwareDistributionJob", + "description": "updateSoftwareDistributionJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Replaces the mutable fields of a software distribution job.\nOnly allowed when the job is in DRAFT or READY state.\nAll fields are optional \u2014 only the provided fields will be updated.\n", + "properties": { + "name": { + "type": "string", + "description": "Unique name for this distribution job.", + "minLength": 1, + "maxLength": 255 + }, + "description": { + "type": "string", + "description": "Optional human-readable description." + }, + "enabled": { + "type": "boolean", + "description": "Whether this job is enabled. Set to false to disable the job.\nA disabled job cannot be activated, paused, or resumed.\nOmit on create to default to true.\n" + }, + "config": { + "type": "object", + "required": [ + "configType" + ], + "properties": { + "configType": { + "type": "string", + "enum": [ + "SOFTWARE_DISTRIBUTION" + ], + "description": "Config type discriminator" + } + } + } + } + } + }, + "required": [ + "jobId", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Replaces the mutable fields of a software distribution job.\nOnly allowed when the job is in DRAFT or READY state.\nAll fields are optional \u2014 only the provided fields will be updated.\n", + "properties": { + "name": { + "type": "string", + "description": "Unique name for this distribution job.", + "minLength": 1, + "maxLength": 255 + }, + "description": { + "type": "string", + "description": "Optional human-readable description." + }, + "enabled": { + "type": "boolean", + "description": "Whether this job is enabled. Set to false to disable the job.\nA disabled job cannot be activated, paused, or resumed.\nOmit on create to default to true.\n" + }, + "config": { + "type": "object", + "required": [ + "configType" + ], + "properties": { + "configType": { + "type": "string", + "enum": [ + "SOFTWARE_DISTRIBUTION" + ], + "description": "Config type discriminator" + } + } + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "c7ba7954-953c-43bc-95de-ed4ffded799e", + "created": "2026-08-28T15:13:01.718Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 212, + "reference": "f5f4340b-22ae-4911-a961-eef6a81abfed", + "type": "workflow", + "folder": "/Software Installation", + "document": { + "name": "Activate Software Installation Job", + "description": "Activate Software Installation Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "activateSoftwareInstallationJob", + "canvasName": "activateSoftwareInstallationJob", + "summary": "activateSoftwareInstallationJob", + "description": "activateSoftwareInstallationJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Optional request body for POST /jobs/software-installation/{jobId}/activate.\nAll fields are optional; the endpoint may be called with no body at all.\n", + "properties": { + "changeRequest": { + "type": "string", + "nullable": true, + "maxLength": 255, + "description": "Optional change-request identifier (e.g. \"CHG0012345\") associated with\nthis specific activation/run. Persisted on the execution record so the\nUI can display it in the execution drawer. Each activation of the same\njob may carry a different change request.\n" + } + } + } + }, + "required": [ + "jobId", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Optional request body for POST /jobs/software-installation/{jobId}/activate.\nAll fields are optional; the endpoint may be called with no body at all.\n", + "properties": { + "changeRequest": { + "type": "string", + "nullable": true, + "maxLength": 255, + "description": "Optional change-request identifier (e.g. \"CHG0012345\") associated with\nthis specific activation/run. Persisted on the execution record so the\nUI can display it in the execution drawer. Each activation of the same\njob may carry a different change request.\n" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "5d2d868c-f13b-458e-90b1-0f9062a798e8", + "created": "2026-08-28T15:13:02.152Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 213, + "reference": "03a65a49-009e-40f3-a57e-2e8c0b6fe880", + "type": "workflow", + "folder": "/Software Installation", + "document": { + "name": "Cancel Software Installation Job", + "description": "Cancel Software Installation Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "cancelSoftwareInstallationJob", + "canvasName": "cancelSoftwareInstallationJob", + "summary": "cancelSoftwareInstallationJob", + "description": "cancelSoftwareInstallationJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "d44475a5-ffe5-45ba-aa96-6bd0bff92191", + "created": "2026-08-28T15:13:02.181Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 214, + "reference": "d4421c07-48b6-4a65-87b1-879bc972f1c9", + "type": "workflow", + "folder": "/Software Installation", + "document": { + "name": "Create Software Installation Job", + "description": "Create Software Installation Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "createSoftwareInstallationJob", + "canvasName": "createSoftwareInstallationJob", + "summary": "createSoftwareInstallationJob", + "description": "createSoftwareInstallationJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Request body for creating a new software installation job. Name is required.", + "properties": { + "name": { + "type": "string", + "description": "Unique name for this installation job.", + "minLength": 1, + "maxLength": 255 + }, + "description": { + "type": "string", + "description": "Optional human-readable description." + }, + "enabled": { + "type": "boolean", + "description": "Whether this job is enabled. Set to false to disable the job.\nA disabled job cannot be activated, paused, or resumed.\nOmit on create to default to true.\n" + }, + "config": { + "type": "object", + "required": [ + "configType" + ], + "properties": { + "configType": { + "type": "string", + "enum": [ + "SOFTWARE_INSTALLATION" + ], + "description": "Config type discriminator" + } + } + } + }, + "required": [ + "name" + ] + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Request body for creating a new software installation job. Name is required.", + "properties": { + "name": { + "type": "string", + "description": "Unique name for this installation job.", + "minLength": 1, + "maxLength": 255 + }, + "description": { + "type": "string", + "description": "Optional human-readable description." + }, + "enabled": { + "type": "boolean", + "description": "Whether this job is enabled. Set to false to disable the job.\nA disabled job cannot be activated, paused, or resumed.\nOmit on create to default to true.\n" + }, + "config": { + "type": "object", + "required": [ + "configType" + ], + "properties": { + "configType": { + "type": "string", + "enum": [ + "SOFTWARE_INSTALLATION" + ], + "description": "Config type discriminator" + } + } + } + }, + "required": [ + "name" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "b0adea96-5396-489c-acde-2db09119b029", + "created": "2026-08-28T15:13:02.034Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 215, + "reference": "e2862d82-032f-456b-b765-ac90f6929cf3", + "type": "workflow", + "folder": "/Software Installation", + "document": { + "name": "Delete Software Installation Job", + "description": "Delete Software Installation Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "deleteSoftwareInstallationJob", + "canvasName": "deleteSoftwareInstallationJob", + "summary": "deleteSoftwareInstallationJob", + "description": "deleteSoftwareInstallationJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "c659f0aa-1c27-4b84-8629-5756fe6ae50a", + "created": "2026-08-28T15:13:02.123Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 216, + "reference": "328e51e2-1d1c-4a54-9a3e-cd2d66b4dd15", + "type": "workflow", + "folder": "/Software Installation", + "document": { + "name": "Get Software Installation Job", + "description": "Get Software Installation Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getSoftwareInstallationJob", + "canvasName": "getSoftwareInstallationJob", + "summary": "getSoftwareInstallationJob", + "description": "getSoftwareInstallationJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "9af42ce0-483f-44b8-ae34-699afc115217", + "created": "2026-08-28T15:13:02.063Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 217, + "reference": "2d9fe704-ca7f-4391-a707-4f34dd8bd25a", + "type": "workflow", + "folder": "/Software Installation", + "document": { + "name": "Get Software Installation Job Execution", + "description": "Get Software Installation Job Execution", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getSoftwareInstallationJobExecution", + "canvasName": "getSoftwareInstallationJobExecution", + "summary": "getSoftwareInstallationJobExecution", + "description": "getSoftwareInstallationJobExecution", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId", + "executionId": "$var.job.executionId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "executionId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "jobId", + "executionId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "executionId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "150a1450-13ad-4f2d-8aa3-79662598ad1c", + "created": "2026-08-28T15:13:02.239Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 218, + "reference": "5d233bd8-2006-47ae-98db-e087bc44233f", + "type": "workflow", + "folder": "/Software Installation", + "document": { + "name": "List Software Installation Job Executions", + "description": "List Software Installation Job Executions", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listSoftwareInstallationJobExecutions", + "canvasName": "listSoftwareInstallationJobExecutions", + "summary": "listSoftwareInstallationJobExecutions", + "description": "listSoftwareInstallationJobExecutions", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "a1457c4a-8910-48ea-9846-fbdd7a478d00", + "created": "2026-08-28T15:13:02.213Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 219, + "reference": "e8af11e7-6c84-4fcc-a5eb-ec581a1a8cd6", + "type": "workflow", + "folder": "/Software Installation", + "document": { + "name": "List Software Installation Jobs", + "description": "List Software Installation Jobs", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "listSoftwareInstallationJobs", + "canvasName": "listSoftwareInstallationJobs", + "summary": "listSoftwareInstallationJobs", + "description": "listSoftwareInstallationJobs", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "page": "$var.job.page", + "page_size": "$var.job.page_size", + "status": "$var.job.status", + "installationType": "$var.job.installationType" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "page_size": { + "type": "integer", + "default": 20, + "minimum": 1, + "maximum": 500 + }, + "status": { + "type": "string", + "description": "Lifecycle status of an upgrade job. The job is a long-lived\nre-activatable definition; per-run outcomes (success/fail/abort)\nare recorded on the execution row, NOT here. Operator-driven\ncancel converges back to READY at the job level; CANCELLED is\nrecorded on the execution row only.\n", + "enum": [ + "DRAFT", + "READY", + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED" + ] + }, + "installationType": { + "type": "string", + "description": "Controls which devices are targeted and how they are treated during upgrade.\nSerial (batchSize=1) or batch (batchSize>1) execution is determined by the batchSize field,\nnot by this enum.\n- STANDALONE: upgrade independent BIG-IP or F5OS devices\n- HA: upgrade HA pairs, maintaining HA continuity during the upgrade [E7 scope]\n", + "enum": [ + "STANDALONE", + "HA" + ] + } + }, + "required": [ + "page", + "page_size", + "status", + "installationType" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "page_size": { + "type": "integer", + "default": 20, + "minimum": 1, + "maximum": 500 + }, + "status": { + "type": "string", + "description": "Lifecycle status of an upgrade job. The job is a long-lived\nre-activatable definition; per-run outcomes (success/fail/abort)\nare recorded on the execution row, NOT here. Operator-driven\ncancel converges back to READY at the job level; CANCELLED is\nrecorded on the execution row only.\n", + "enum": [ + "DRAFT", + "READY", + "RUNNING", + "PAUSING", + "PAUSED", + "CANCELLING", + "COMPLETED", + "FAILED" + ] + }, + "installationType": { + "type": "string", + "description": "Controls which devices are targeted and how they are treated during upgrade.\nSerial (batchSize=1) or batch (batchSize>1) execution is determined by the batchSize field,\nnot by this enum.\n- STANDALONE: upgrade independent BIG-IP or F5OS devices\n- HA: upgrade HA pairs, maintaining HA continuity during the upgrade [E7 scope]\n", + "enum": [ + "STANDALONE", + "HA" + ] + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "d0fd7ddc-1f9b-488c-bc34-131d4f7b6b4a", + "created": "2026-08-28T15:13:02.002Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 220, + "reference": "48938086-80dd-486d-9df3-7f34653db3f1", + "type": "workflow", + "folder": "/Software Installation", + "document": { + "name": "Pause Software Installation Job", + "description": "Pause Software Installation Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "pauseSoftwareInstallationJob", + "canvasName": "pauseSoftwareInstallationJob", + "summary": "pauseSoftwareInstallationJob", + "description": "pauseSoftwareInstallationJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "b4229f5b-cc4c-4bb4-b9f0-db031c52ee78", + "created": "2026-08-28T15:13:02.267Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 221, + "reference": "5f47b807-7a7f-4cc8-9902-0e7c9ec1021a", + "type": "workflow", + "folder": "/Software Installation", + "document": { + "name": "Resume Software Installation Job", + "description": "Resume Software Installation Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "resumeSoftwareInstallationJob", + "canvasName": "resumeSoftwareInstallationJob", + "summary": "resumeSoftwareInstallationJob", + "description": "resumeSoftwareInstallationJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "jobId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "297b5dc0-2271-43f1-9fd0-092bdb19dd04", + "created": "2026-08-28T15:13:02.299Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 222, + "reference": "4256b2d5-ca87-42c5-82f7-192b62d5c02b", + "type": "workflow", + "folder": "/Software Installation", + "document": { + "name": "Update Software Installation Job", + "description": "Update Software Installation Job", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "updateSoftwareInstallationJob", + "canvasName": "updateSoftwareInstallationJob", + "summary": "updateSoftwareInstallationJob", + "description": "updateSoftwareInstallationJob", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "jobId": "$var.job.jobId", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Replaces the mutable fields of a software installation job.\nOnly allowed when the job is in DRAFT or READY state.\nAll fields are optional \u2014 only the provided fields will be updated.\n", + "properties": { + "name": { + "type": "string", + "description": "Unique name for this installation job.", + "minLength": 1, + "maxLength": 255 + }, + "description": { + "type": "string", + "description": "Optional human-readable description." + }, + "enabled": { + "type": "boolean", + "description": "Whether this job is enabled. Set to false to disable the job.\nA disabled job cannot be activated, paused, or resumed.\nOmit on create to default to true.\n" + }, + "config": { + "type": "object", + "required": [ + "configType" + ], + "properties": { + "configType": { + "type": "string", + "enum": [ + "SOFTWARE_INSTALLATION" + ], + "description": "Config type discriminator" + } + } + } + } + } + }, + "required": [ + "jobId", + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "jobId": { + "type": "string", + "format": "uuid" + }, + "spec": { + "type": "object", + "description": "Replaces the mutable fields of a software installation job.\nOnly allowed when the job is in DRAFT or READY state.\nAll fields are optional \u2014 only the provided fields will be updated.\n", + "properties": { + "name": { + "type": "string", + "description": "Unique name for this installation job.", + "minLength": 1, + "maxLength": 255 + }, + "description": { + "type": "string", + "description": "Optional human-readable description." + }, + "enabled": { + "type": "boolean", + "description": "Whether this job is enabled. Set to false to disable the job.\nA disabled job cannot be activated, paused, or resumed.\nOmit on create to default to true.\n" + }, + "config": { + "type": "object", + "required": [ + "configType" + ], + "properties": { + "configType": { + "type": "string", + "enum": [ + "SOFTWARE_INSTALLATION" + ], + "description": "Config type discriminator" + } + } + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "7e641ada-15aa-4c1a-a3a8-14e952bf9732", + "created": "2026-08-28T15:13:02.090Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 223, + "reference": "ecdb8012-0e05-48db-b223-129d1785e48b", + "type": "workflow", + "folder": "/Validation", + "document": { + "name": "Get Validation Results", + "description": "Get Validation Results", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "getValidationResults", + "canvasName": "getValidationResults", + "summary": "getValidationResults", + "description": "getValidationResults", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "validationRunId": "$var.job.validationRunId" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "validationRunId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "validationRunId" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "validationRunId": { + "type": "string", + "format": "uuid" + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "0a38e0e5-a962-444b-ac7a-7cc063aa7244", + "created": "2026-08-28T15:13:02.474Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 224, + "reference": "76d68821-204b-43fd-8f66-d8765d3e9794", + "type": "workflow", + "folder": "/Validation", + "document": { + "name": "Trigger Validation", + "description": "Trigger Validation", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "triggerValidation", + "canvasName": "triggerValidation", + "summary": "triggerValidation", + "description": "triggerValidation", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Request body for POST /validate.\nThe caller provides the list of device targets to validate and the target image UUID.\nNo job needs to exist \u2014 this is a pre-job eligibility check.\n", + "required": [ + "device_targets", + "image_id" + ], + "properties": { + "device_targets": { + "type": "array", + "description": "List of device targets (with optional per-device volume_override) to validate against the target image.", + "minItems": 1, + "items": { + "type": "object", + "description": "A single device target for the POST /validate request.", + "required": [ + "device_id" + ], + "properties": { + "device_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the device to validate." + }, + "volume_override": { + "type": "string", + "description": "Optional explicit volume name for this device (e.g. \"HD1.2\"). When set, pins this device to that specific volume slot and applies the existing-slot disk-space threshold (2 GB soft) rather than the new-slot threshold (15 GB soft). Mirrors SoftwareInstallationDeviceTarget.volumeOverride so callers can use the same configuration for both validation and job creation. Takes precedence over the top-level volume_strategy on the request for this device.\n" + } + } + } + }, + "image_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the target software image to validate against." + }, + "volume_strategy": { + "description": "Volume selection strategy applied to all devices in this validation request.\nA per-device volume_override (explicit slot name, e.g. \"HD1.2\") takes precedence\nover this field for that device. Defaults to NEXT_SEQUENTIAL_NEW when omitted.\n", + "type": "string", + "enum": [ + "NEXT_INACTIVE", + "LAST_INACTIVE", + "NEXT_SEQUENTIAL_NEW" + ] + }, + "install_config": { + "type": "boolean", + "default": true, + "description": "Controls config carry-forward (BIG-IP cpcfg) for all devices in this\nvalidation request. Mirrors SoftwareInstallationConfig.installConfig.\nWhen true (or omitted), the install_config readiness check warns if the\ntarget version is older than the active version (a downgrade causes cpcfg\nto skip config copy). When false, the install_config check is skipped.\n" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Request body for POST /validate.\nThe caller provides the list of device targets to validate and the target image UUID.\nNo job needs to exist \u2014 this is a pre-job eligibility check.\n", + "required": [ + "device_targets", + "image_id" + ], + "properties": { + "device_targets": { + "type": "array", + "description": "List of device targets (with optional per-device volume_override) to validate against the target image.", + "minItems": 1, + "items": { + "type": "object", + "description": "A single device target for the POST /validate request.", + "required": [ + "device_id" + ], + "properties": { + "device_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the device to validate." + }, + "volume_override": { + "type": "string", + "description": "Optional explicit volume name for this device (e.g. \"HD1.2\"). When set, pins this device to that specific volume slot and applies the existing-slot disk-space threshold (2 GB soft) rather than the new-slot threshold (15 GB soft). Mirrors SoftwareInstallationDeviceTarget.volumeOverride so callers can use the same configuration for both validation and job creation. Takes precedence over the top-level volume_strategy on the request for this device.\n" + } + } + } + }, + "image_id": { + "type": "string", + "format": "uuid", + "description": "UUID of the target software image to validate against." + }, + "volume_strategy": { + "description": "Volume selection strategy applied to all devices in this validation request.\nA per-device volume_override (explicit slot name, e.g. \"HD1.2\") takes precedence\nover this field for that device. Defaults to NEXT_SEQUENTIAL_NEW when omitted.\n", + "type": "string", + "enum": [ + "NEXT_INACTIVE", + "LAST_INACTIVE", + "NEXT_SEQUENTIAL_NEW" + ] + }, + "install_config": { + "type": "boolean", + "default": true, + "description": "Controls config carry-forward (BIG-IP cpcfg) for all devices in this\nvalidation request. Mirrors SoftwareInstallationConfig.installConfig.\nWhen true (or omitted), the install_config readiness check warns if the\ntarget version is older than the active version (a downgrade causes cpcfg\nto skip config copy). When false, the install_config check is skipped.\n" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "47fd1f2e-46ee-47a7-92e3-f5c88f45399a", + "created": "2026-08-28T15:13:02.441Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 225, + "reference": "ae259450-1c53-4277-bc58-272d0da5db27", + "type": "workflow", + "folder": "/Validation", + "document": { + "name": "Validate AI Provider", + "description": "Validate AI Provider", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "validateAIProvider", + "canvasName": "validateAIProvider", + "summary": "validateAIProvider", + "description": "validateAIProvider", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "provider_name" + ], + "properties": { + "provider_name": { + "type": "string", + "description": "AI provider name (e.g., openai, claude, local)" + }, + "api_token": { + "type": "string", + "description": "API token for the provider. Required for 'openai' and 'claude' providers, optional for 'local' provider." + }, + "base_url": { + "type": "string", + "description": "Base URL for the provider. Required for 'local' provider, optional for 'openai' and 'claude'." + }, + "model": { + "type": "string", + "description": "Model name to use. Required for 'local' provider, optional for others." + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "Optional CA certificate UUID from trust store" + }, + "skip_tls_verify": { + "type": "boolean", + "description": "Indicates if TLS verification should be skipped for this provider" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "provider_name" + ], + "properties": { + "provider_name": { + "type": "string", + "description": "AI provider name (e.g., openai, claude, local)" + }, + "api_token": { + "type": "string", + "description": "API token for the provider. Required for 'openai' and 'claude' providers, optional for 'local' provider." + }, + "base_url": { + "type": "string", + "description": "Base URL for the provider. Required for 'local' provider, optional for 'openai' and 'claude'." + }, + "model": { + "type": "string", + "description": "Model name to use. Required for 'local' provider, optional for others." + }, + "ca": { + "type": "string", + "format": "uuid", + "description": "Optional CA certificate UUID from trust store" + }, + "skip_tls_verify": { + "type": "boolean", + "description": "Indicates if TLS verification should be skipped for this provider" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "e384dc7b-17a9-440f-8332-0795d5b8c243", + "created": "2026-08-28T15:13:02.532Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + }, + { + "iid": 226, + "reference": "bf8f3cb8-6fba-4669-8887-b219607c0f73", + "type": "workflow", + "folder": "/Validation", + "document": { + "name": "Validate AIDF", + "description": "Validate AIDF", + "type": "automation", + "font_size": 12, + "tasks": { + "workflow_start": { + "name": "workflow_start", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 0 + } + }, + "a1a1": { + "name": "validateAIDF", + "canvasName": "validateAIDF", + "summary": "validateAIDF", + "description": "validateAIDF", + "location": "Adapter", + "locationType": "F5 Insight:latest", + "app": "F5 Insight:latest", + "type": "automatic", + "displayName": "F5 Insight", + "variables": { + "incoming": { + "adapter_id": "F5 Insight", + "bodyContentType": "application/json", + "requestBodyPayload": "$var.job.spec" + }, + "outgoing": { + "response": null + }, + "error": "", + "decorators": [] + }, + "groups": [], + "actor": "Pronghorn", + "scheduled": false, + "nodeLocation": { + "x": 264, + "y": 150 + } + }, + "workflow_end": { + "name": "workflow_end", + "groups": [], + "nodeLocation": { + "x": 264, + "y": 300 + } + } + }, + "transitions": { + "workflow_start": { + "a1a1": { + "type": "standard", + "state": "success" + } + }, + "a1a1": { + "workflow_end": { + "type": "standard", + "state": "success" + } + }, + "workflow_end": {} + }, + "inputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "endpoint", + "tenant_id", + "tenant_token" + ], + "properties": { + "endpoint": { + "type": "string" + }, + "tenant_id": { + "type": "string" + }, + "tenant_token": { + "type": "string" + } + } + } + }, + "required": [ + "spec" + ] + }, + "outputSchema": { + "type": "object", + "properties": { + "spec": { + "type": "object", + "required": [ + "endpoint", + "tenant_id", + "tenant_token" + ], + "properties": { + "endpoint": { + "type": "string" + }, + "tenant_id": { + "type": "string" + }, + "tenant_token": { + "type": "string" + } + } + }, + "_id": { + "type": "string", + "pattern": "^[0-9a-f]{24}$" + }, + "initiator": { + "type": "string" + } + } + }, + "last_updated": "2026-08-28T15:13:21.885Z", + "last_updated_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "lastUpdatedVersion": "4.69.69", + "uuid": "66a68188-0fd3-4c68-aaf4-b08f7b8f20ee", + "created": "2026-08-28T15:13:02.503Z", + "created_by": { + "provenance": "LDAP", + "username": "admin@itential", + "firstname": "admin@itential", + "inactive": false + }, + "createdVersion": "5.55.5", + "scenarios": [], + "canvasVersion": 3, + "tags": [], + "groups": [], + "migrationVersion": 8 + } + } + ], + "folders": [ + { + "nodeType": "folder", + "name": "Configuration", + "children": [ + { + "iid": 0, + "nodeType": "component" + }, + { + "iid": 1, + "nodeType": "component" + }, + { + "iid": 2, + "nodeType": "component" + }, + { + "iid": 3, + "nodeType": "component" + }, + { + "iid": 4, + "nodeType": "component" + }, + { + "iid": 5, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Audit Console", + "children": [ + { + "iid": 6, + "nodeType": "component" + }, + { + "iid": 7, + "nodeType": "component" + }, + { + "iid": 8, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Device Management", + "children": [ + { + "iid": 9, + "nodeType": "component" + }, + { + "iid": 10, + "nodeType": "component" + }, + { + "iid": 11, + "nodeType": "component" + }, + { + "iid": 12, + "nodeType": "component" + }, + { + "iid": 13, + "nodeType": "component" + }, + { + "iid": 14, + "nodeType": "component" + }, + { + "iid": 15, + "nodeType": "component" + }, + { + "iid": 16, + "nodeType": "component" + }, + { + "iid": 17, + "nodeType": "component" + }, + { + "iid": 18, + "nodeType": "component" + }, + { + "iid": 19, + "nodeType": "component" + }, + { + "iid": 20, + "nodeType": "component" + }, + { + "iid": 21, + "nodeType": "component" + }, + { + "iid": 22, + "nodeType": "component" + }, + { + "iid": 23, + "nodeType": "component" + }, + { + "iid": 24, + "nodeType": "component" + }, + { + "iid": 25, + "nodeType": "component" + }, + { + "iid": 26, + "nodeType": "component" + }, + { + "iid": 27, + "nodeType": "component" + }, + { + "iid": 28, + "nodeType": "component" + }, + { + "iid": 29, + "nodeType": "component" + }, + { + "iid": 30, + "nodeType": "component" + }, + { + "iid": 31, + "nodeType": "component" + }, + { + "iid": 32, + "nodeType": "component" + }, + { + "iid": 33, + "nodeType": "component" + }, + { + "iid": 34, + "nodeType": "component" + }, + { + "iid": 35, + "nodeType": "component" + }, + { + "iid": 36, + "nodeType": "component" + }, + { + "iid": 37, + "nodeType": "component" + }, + { + "iid": 38, + "nodeType": "component" + }, + { + "iid": 39, + "nodeType": "component" + }, + { + "iid": 40, + "nodeType": "component" + }, + { + "iid": 41, + "nodeType": "component" + }, + { + "iid": 42, + "nodeType": "component" + }, + { + "iid": 43, + "nodeType": "component" + }, + { + "iid": 44, + "nodeType": "component" + }, + { + "iid": 45, + "nodeType": "component" + }, + { + "iid": 46, + "nodeType": "component" + }, + { + "iid": 47, + "nodeType": "component" + }, + { + "iid": 48, + "nodeType": "component" + }, + { + "iid": 49, + "nodeType": "component" + }, + { + "iid": 50, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Licensing", + "children": [ + { + "iid": 51, + "nodeType": "component" + }, + { + "iid": 52, + "nodeType": "component" + }, + { + "iid": 53, + "nodeType": "component" + }, + { + "iid": 54, + "nodeType": "component" + }, + { + "iid": 55, + "nodeType": "component" + }, + { + "iid": 56, + "nodeType": "component" + }, + { + "iid": 57, + "nodeType": "component" + }, + { + "iid": 58, + "nodeType": "component" + }, + { + "iid": 59, + "nodeType": "component" + }, + { + "iid": 60, + "nodeType": "component" + }, + { + "iid": 61, + "nodeType": "component" + }, + { + "iid": 62, + "nodeType": "component" + }, + { + "iid": 63, + "nodeType": "component" + }, + { + "iid": 64, + "nodeType": "component" + }, + { + "iid": 65, + "nodeType": "component" + }, + { + "iid": 66, + "nodeType": "component" + }, + { + "iid": 67, + "nodeType": "component" + }, + { + "iid": 68, + "nodeType": "component" + }, + { + "iid": 69, + "nodeType": "component" + }, + { + "iid": 70, + "nodeType": "component" + }, + { + "iid": 71, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Infrastructure Discovery", + "children": [ + { + "iid": 72, + "nodeType": "component" + }, + { + "iid": 73, + "nodeType": "component" + }, + { + "iid": 74, + "nodeType": "component" + }, + { + "iid": 75, + "nodeType": "component" + }, + { + "iid": 76, + "nodeType": "component" + }, + { + "iid": 77, + "nodeType": "component" + }, + { + "iid": 78, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Cloud Environments", + "children": [ + { + "iid": 79, + "nodeType": "component" + }, + { + "iid": 80, + "nodeType": "component" + }, + { + "iid": 81, + "nodeType": "component" + }, + { + "iid": 82, + "nodeType": "component" + }, + { + "iid": 83, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Cloud Providers", + "children": [ + { + "iid": 84, + "nodeType": "component" + }, + { + "iid": 85, + "nodeType": "component" + }, + { + "iid": 86, + "nodeType": "component" + }, + { + "iid": 87, + "nodeType": "component" + }, + { + "iid": 88, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "VM Tasks", + "children": [ + { + "iid": 89, + "nodeType": "component" + }, + { + "iid": 90, + "nodeType": "component" + }, + { + "iid": 91, + "nodeType": "component" + }, + { + "iid": 92, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Device Templates", + "children": [ + { + "iid": 93, + "nodeType": "component" + }, + { + "iid": 94, + "nodeType": "component" + }, + { + "iid": 95, + "nodeType": "component" + }, + { + "iid": 96, + "nodeType": "component" + }, + { + "iid": 97, + "nodeType": "component" + }, + { + "iid": 98, + "nodeType": "component" + }, + { + "iid": 99, + "nodeType": "component" + }, + { + "iid": 100, + "nodeType": "component" + }, + { + "iid": 101, + "nodeType": "component" + }, + { + "iid": 102, + "nodeType": "component" + }, + { + "iid": 103, + "nodeType": "component" + }, + { + "iid": 104, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Observability", + "children": [ + { + "iid": 105, + "nodeType": "component" + }, + { + "iid": 106, + "nodeType": "component" + }, + { + "iid": 107, + "nodeType": "component" + }, + { + "iid": 108, + "nodeType": "component" + }, + { + "iid": 109, + "nodeType": "component" + }, + { + "iid": 110, + "nodeType": "component" + }, + { + "iid": 111, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Jobs", + "children": [ + { + "iid": 112, + "nodeType": "component" + }, + { + "iid": 113, + "nodeType": "component" + }, + { + "iid": 114, + "nodeType": "component" + }, + { + "iid": 115, + "nodeType": "component" + }, + { + "iid": 116, + "nodeType": "component" + }, + { + "iid": 117, + "nodeType": "component" + }, + { + "iid": 118, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Tasks", + "children": [ + { + "iid": 119, + "nodeType": "component" + }, + { + "iid": 120, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Workflows", + "children": [ + { + "iid": 121, + "nodeType": "component" + }, + { + "iid": 122, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Lifecycle", + "children": [ + { + "iid": 123, + "nodeType": "component" + }, + { + "iid": 124, + "nodeType": "component" + }, + { + "iid": 125, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Storage", + "children": [ + { + "iid": 126, + "nodeType": "component" + }, + { + "iid": 127, + "nodeType": "component" + }, + { + "iid": 128, + "nodeType": "component" + }, + { + "iid": 129, + "nodeType": "component" + }, + { + "iid": 130, + "nodeType": "component" + }, + { + "iid": 131, + "nodeType": "component" + }, + { + "iid": 132, + "nodeType": "component" + }, + { + "iid": 133, + "nodeType": "component" + }, + { + "iid": 134, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Schedule", + "children": [ + { + "iid": 135, + "nodeType": "component" + }, + { + "iid": 136, + "nodeType": "component" + }, + { + "iid": 137, + "nodeType": "component" + }, + { + "iid": 138, + "nodeType": "component" + }, + { + "iid": 139, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Backup", + "children": [ + { + "iid": 140, + "nodeType": "component" + }, + { + "iid": 141, + "nodeType": "component" + }, + { + "iid": 142, + "nodeType": "component" + }, + { + "iid": 143, + "nodeType": "component" + }, + { + "iid": 144, + "nodeType": "component" + }, + { + "iid": 145, + "nodeType": "component" + }, + { + "iid": 146, + "nodeType": "component" + }, + { + "iid": 147, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "FQDN Configuration", + "children": [ + { + "iid": 148, + "nodeType": "component" + }, + { + "iid": 149, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Health and Readiness", + "children": [ + { + "iid": 150, + "nodeType": "component" + }, + { + "iid": 151, + "nodeType": "component" + }, + { + "iid": 152, + "nodeType": "component" + }, + { + "iid": 153, + "nodeType": "component" + }, + { + "iid": 154, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Upgrade", + "children": [ + { + "iid": 155, + "nodeType": "component" + }, + { + "iid": 156, + "nodeType": "component" + }, + { + "iid": 157, + "nodeType": "component" + }, + { + "iid": 158, + "nodeType": "component" + }, + { + "iid": 159, + "nodeType": "component" + }, + { + "iid": 160, + "nodeType": "component" + }, + { + "iid": 161, + "nodeType": "component" + }, + { + "iid": 162, + "nodeType": "component" + }, + { + "iid": 163, + "nodeType": "component" + }, + { + "iid": 164, + "nodeType": "component" + }, + { + "iid": 165, + "nodeType": "component" + }, + { + "iid": 166, + "nodeType": "component" + }, + { + "iid": 167, + "nodeType": "component" + }, + { + "iid": 168, + "nodeType": "component" + }, + { + "iid": 169, + "nodeType": "component" + }, + { + "iid": 170, + "nodeType": "component" + }, + { + "iid": 171, + "nodeType": "component" + }, + { + "iid": 172, + "nodeType": "component" + }, + { + "iid": 173, + "nodeType": "component" + }, + { + "iid": 174, + "nodeType": "component" + }, + { + "iid": 175, + "nodeType": "component" + }, + { + "iid": 176, + "nodeType": "component" + }, + { + "iid": 177, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Telemetry Configuration", + "children": [ + { + "iid": 178, + "nodeType": "component" + }, + { + "iid": 179, + "nodeType": "component" + }, + { + "iid": 180, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Compatibility Matrix", + "children": [ + { + "iid": 181, + "nodeType": "component" + }, + { + "iid": 182, + "nodeType": "component" + }, + { + "iid": 183, + "nodeType": "component" + }, + { + "iid": 184, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Inventory", + "children": [ + { + "iid": 185, + "nodeType": "component" + }, + { + "iid": 186, + "nodeType": "component" + }, + { + "iid": 187, + "nodeType": "component" + }, + { + "iid": 188, + "nodeType": "component" + }, + { + "iid": 189, + "nodeType": "component" + }, + { + "iid": 190, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Flight Checks", + "children": [ + { + "iid": 191, + "nodeType": "component" + }, + { + "iid": 192, + "nodeType": "component" + }, + { + "iid": 193, + "nodeType": "component" + }, + { + "iid": 194, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Images", + "children": [ + { + "iid": 195, + "nodeType": "component" + }, + { + "iid": 196, + "nodeType": "component" + }, + { + "iid": 197, + "nodeType": "component" + }, + { + "iid": 198, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Software Distribution", + "children": [ + { + "iid": 199, + "nodeType": "component" + }, + { + "iid": 200, + "nodeType": "component" + }, + { + "iid": 201, + "nodeType": "component" + }, + { + "iid": 202, + "nodeType": "component" + }, + { + "iid": 203, + "nodeType": "component" + }, + { + "iid": 204, + "nodeType": "component" + }, + { + "iid": 205, + "nodeType": "component" + }, + { + "iid": 206, + "nodeType": "component" + }, + { + "iid": 207, + "nodeType": "component" + }, + { + "iid": 208, + "nodeType": "component" + }, + { + "iid": 209, + "nodeType": "component" + }, + { + "iid": 210, + "nodeType": "component" + }, + { + "iid": 211, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Software Installation", + "children": [ + { + "iid": 212, + "nodeType": "component" + }, + { + "iid": 213, + "nodeType": "component" + }, + { + "iid": 214, + "nodeType": "component" + }, + { + "iid": 215, + "nodeType": "component" + }, + { + "iid": 216, + "nodeType": "component" + }, + { + "iid": 217, + "nodeType": "component" + }, + { + "iid": 218, + "nodeType": "component" + }, + { + "iid": 219, + "nodeType": "component" + }, + { + "iid": 220, + "nodeType": "component" + }, + { + "iid": 221, + "nodeType": "component" + }, + { + "iid": 222, + "nodeType": "component" + } + ] + }, + { + "nodeType": "folder", + "name": "Validation", + "children": [ + { + "iid": 223, + "nodeType": "component" + }, + { + "iid": 224, + "nodeType": "component" + }, + { + "iid": 225, + "nodeType": "component" + }, + { + "iid": 226, + "nodeType": "component" + } + ] + } + ], + "createdBy": { + "_id": "699f3e2b85569c9f5d8e1f38", + "provenance": "LDAP", + "username": "admin@itential" + }, + "lastUpdatedBy": { + "_id": "699f3e2b85569c9f5d8e1f38", + "provenance": "LDAP", + "username": "admin@itential" + }, + "created": "2026-08-28T15:13:17.713Z", + "lastUpdated": "2026-08-28T15:13:17.713Z", + "iid": 52, + "thumbnail": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUoAAABkCAYAAADg+Hn3AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAhGVYSWZNTQAqAAAACAAFARIAAwAAAAEAAQAAARoABQAAAAEAAABKARsABQAAAAEAAABSASgAAwAAAAEAAgAAh2kABAAAAAEAAABaAAAAAAAAAEgAAAABAAAASAAAAAEAA6ABAAMAAAABAAEAAKACAAQAAAABAAABSqADAAQAAAABAAAAZAAAAABcVM/PAAAACXBIWXMAAAsTAAALEwEAmpwYAAACymlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+NzI8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4zMzA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjEyMDwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpwIzk+AABAAElEQVR4AXT9C4IjObIsidan76LeSmbns5mZqnwiogYyss8ZBOkOmKmpfQAHnWRk5J9//v/+r//7jz///POPf3/99QedX/z8+ccff/3iifjPX3/8+vMPfv7893R//vnXr3+RaSRSPU/wSf4AB572L7I6d3wndVgwRKutpjwlq590lLP/42/1Q+1IqNoIz4z+fxQZNg3Np/93fiYv3sPUB1tmf5V1Afz5d4H+9Rcl+VM/f/6iEH/8+9cvRn9THBR/6VkpFgx//YGTv6WQ9G8jAPPXH3/+RV+Q4j8JEFE2+EAgIPvk6K10gL/AViAhSpwaf05uiPaVGiIRGgfx5lf2f4rFKQRDDjHbzeY4GyP7ZVoMVOdLf7MUbuC2JhTxFRPBv2M/vXG0eobO0txuKEPdVg99eXLpZI90YSL/jgsvO8E/yN5gutM4CPM9fGw/ukmGPBxpfVqle8H99PiwIn/wh8+acij/Dddg8scliOdgp3c0wQe7mE7vSRsuP+eL9eVFt/rHZwDTZ/d0iVvziVkiywweZiCnJ1sEXfK4Ca3LpqZxkcz+1sLz6dmGH5YgFq7HrsI5KDIP+C4RTnSNkY7LVs2iCSGIjvlsKZirMf2+LkK55Fx3mo+zDgf95WM4jkDz8+uPf+VLfkJ2LAFc2+oQWqdi8vwfHFgKdgAN2xO44jTwikHmxifcunrFWIRiYuiZQLo4fv1yAzU2FYj1/69w7RzTim0FtI5knXvjMkAv+IfurBmglywuuvDwk4tdvwb0x69/pKfLAgoz8szRwNDFr5OMoV9I7GzJQPxy8RkXIf+DvcnrqNcQ1Gz9rSkYuPzJrQ3PvCjYv3/9Zan+/vMfXLWJmR+SdgpY2br+Zcc35l8W2Ea/VULy/6Jnc21MX+7WsvBqbmB6AGNVmhhi2wtTBQdIKf754/8l1yYFzJXOOcZbNQhbFeDDSWLIIcUOSYURQO6G2MrB/l/tWxxGL9dsUGXTNZSZZdOKeuFWzx70Yc4QSV375AZgfhWfkl5hGJtNd68j0fGIHvfsPjzFBxvY8h1FDAWC1XN6dSpjYhqGY8W6Y8IX2kEM40oVqjLTK9J3CmMtMXr4MjlA+Ln88MlAWZs3hJcKwq3JP5l4Y34M1re1y8tl1Ni78uIwz0Ukj13iIBYCb2648bFG7Q+q1KfLSu/f8W6SIL/YgL7pNFwuFgjAi/Ms1Xmdb0ajS0d3NoxCm0SJYG8MDKJJufodUh5LX+Kn5vLA3gUZu7ow4wZsJ50H/RCnNbg6gUY9jFe/qhpXtPdK8BYORrsW3bFMwGpMx1UiqsC1qTxcLBLH1yZrVMC8qrylqnJeXecdtm5DEqDGTbvJP/hCJb3JSGHF/+7Oy7CTcgIXwhSYV/P4032MsUFwcqJsf+d2E8bdXiV3f/oLvKtZCy926d4G/M/ulb07ldiNA6S3khIj+mvL0I0yywvLRQP4b4L7B9Xf0mj06x8PuiPRv9Cp/Q/ZgbZuTvO//3rbR4fA5AT8d6U2LiCg3TYpx1++CHjjWhz//oPd3zKsiNg1P+TihFVmTEyvBN2yVqeS45UFp2ZJ7YlK58XEqLis0d/xO84rwUpmUDzsA/aCuL4XWq936g2D9qbLGTAsw9HvZqQBpbW2qrcMGij42dB9WwHoHbK3JOiaQDg1YjjzaE14RqrmNatuFr57cLnZOgryyaBYb/lNOdxNA/aWGlRXBH1JbHSaHLpXqcKR42FkqkzaKsfASTKccukOXTLGFLZYQBSB5GBJuKGcXTwPhBdrrza5AcrLD0cmgkG2npGo/csAnGuxTy4Q8V9/72rIBo67+tRBoDU4u/RdO5svvU+Omjp0K4SkjcDNKZsdtzg+eKmyZvq44BgYY7Yy6nEQjjwc90odozLgU2lqvOKUT7oYfCcosOpYeJgLBz45u9AR+37PC9X1LYv3kUavm7+oDD4MNxfaoKoOyFYAywpY98gSD+9+3KrVPnIdiHhX78G1R9qBcAvTpcUm6UU4tvy2GpWI8ZpsBW4JuYkgdfpcPfTc5Y0SOFIzrMir+ULBW+H4VnYuF5t9tr1VEJZiWpgJjcFCGZvtFoZuetvLuCKSP6ZgfRACE+ErEfec7OPLeTfCVpqN69f/8VMGHfJSNONfbtBhEcBraL/Amj7czduvv/7Ffmmj5M6ezS+f3dMtKjZkdJsmzjhy0Ht0Z7zp45641wNU2nu7anr1y5Gutjx+/UMn7f9JLawJUGZ8+VKq4DYCu80ZkrgRKNtBFArDMrDR20vvXfhvDZS2xil2Jk2P/kaL8Pz5CqfwNM4D9rP9919AqZ3+8/PSszZxU2L903eob+7qOKyM1s39pTWjbWCW6F+sCmD5wrCsDDYCwqPPTQXycem/ZS8vffEuIpcUk/XHv3+zteLMae5MqblqIUEtnOh4Z4QjeTOuPr94ywXQ0DeFvFAu9k7q9GF9xns5wI4JzRfWyU4UlQ5pucXW9xwaKDXHqWGtSO1D66YwryHe0ZcNHjOWx4XjXYZNhwKBaIfu8a9MIA6SDjvxGEARR1psDAbRwI1HrAce2elLT64G3f/HMlshAM4W8yUnwaLgzO5Th5c5E0C84tvnGXNXqP40VhpzemOXRuGJGYDNobhlkD/I2DYiAOxEus8LqgByMKzpV7U65bSpuPxNhQeRuGViiztP4jz4WJEQkBD67iaQlxtGLDxnQf6tDpC2EZJPdm42eSUb960y652wehl0acs5d5u/3J1MkM2St+FVXLVxEq93pIZQgF0tdLvdMQ7L2KF+MbCxodexMSXaPGFnCM6HXUgLdGLj2qcK2D15AgPRgNh3pi/DP/jhY1hbdWmTZCwMBtMb0+1G4HYnSSc+LUeboA3gPGMrerj5qK8nIKaWfsI7ykaTQpDYjx9iQXLzQI+WK1fdDQDcepgSH+q80Gvh6ElUo3Ob6UdYjQQMbJi39wBZ7MbNq2I5NEESSoVJ9YLDaPlYhufiFjCdjtUJnpsuLubCmmyznPX2U+PQVmzbb6aMEGNCwl10BWIcAj0Ka4dHELM0py6DbQIKfVmWx5D8iAu8S8hY8oG4KmtvQu4snBlqXavfgmEo5jQv7m0gzSb6ZTqcfW3OZLo4I0Le8jUq40Mzg2qiaDFpAbSs7St98aRK2CFPNxncUZZsmyNdNssikYo0Cbu50DNDt+Yrt+e+MSgzLxBafbpe7d5aiadUeii6IJZUPp5G/722ZuemsXeD1lw7weMXb4PhKmapp/vJp6jAzU7bHF1QyMgNM4ReoO1SnOWV/FFfH6HWi6DeGxh7s5Add0h9eaNZPDsWnnlw19Bm6gsOrw6xnr1wAmUjdcGJq56UyelQ6cK3w25luF7PvXA5J5LsswIw1jaXIGgwOxfytdyTLKGquxJzRwpQMT54fEqmxDmUyltffTdhdJpDbH79Pxi4jBCp157T8mbYrqAdjdC8Q1YPDFBHexMwTjflyR9m59VB1Y80sxpcopBeCngq9lPhvtayEiXQaC7GhlqEw14DhC03hQISRHPjwEiNfTbPqzL5Jz8bZUmGGkaJPDmY36vFrKZj3X7nRpGzrQsC1btxbgwTc8E8ZqLQleHnmgjz3qyaux8btWY46gxR4zlm2KarXCcLsYTi6o4vznG8WJbW8Ur1ai8JS1cGzWotC3pdlHEvDGOZpTGaDkNzwtgwz1wQre1eMV0Yb5NWo7DcHNDsZ5svsA0S5sd49AeOM8Gi58sc4+NoHItnd88CoxAIVIOlq12b5BxYsLx77MIsEO9CZmH+qRqbZAJnsrkpibrxYP34fKtgFFeZ70sGgGXrJgCmO885EZ8WI1eLOAnZY8ze3DGatSqsGTL2KqfFcj4ZZC6lubj5P4hc3wqhPmyEsswFUWgsNmqttvFZZmpkEVKBg+NtRr7ShOWrmYRUMX/sfGZgLfZKvpU+nS6WB9RExzJ3Y+uduTkZDSffufshAYhqourystQ9mO9Fjk5/TgWbZqGWOwYG2AuNedA4yWMe8TDWNGGKHDecWH3IcVmaH1qp/kd7fM/uVTV+XDsWYzPf9SbzdZGAvNstrsOkFIhd+A6L7QP5wVNhGK92gCFTZr1k+GxoG8apKtoitOfzBeq5qDhH5/D4EOiiacXHM/PMNWY+0TBOxdismygXlnon7YU3unnWgDl1EJRhNYtjVxvkWjf3EjnogjZZN6TxXwzoxbZ2nCC9J8EqGpf+1pK+tmU+fBwvzOI2HGGYfJr7kGRTpfGAl2/ZERR12hiswwI5IiF1OYJYjkJTmBYDa+5NCXreehen+68F80ePQIzHVxPe2yGgobsYd+fpMuyWx9JRHG16k/eSBe/lLW7EeJRkoZsbLr66+oVlIbBSV+QdUG8M2fOFyBsUa+Bm18Z6lKgMp1lBzQz1ZQhelykdazs9Yb1PI3TTl9Z2eBqiXX1LZ7+wTJe+b0l5peYrmO1t6tJkhM7YZlRK1IyydLPoOsmvX3wZv5F1K17Jqa1U+PEGlMYc6NtJoPF51V9/r787UaQVDgz2Qty5Bv7YFjxX3S5yIHIJ9m6DL2/oicUOv7kD4oyRhzeneughxBHfTWGAVUEV7m7QnHXJeGB4YQD7gVXthqA17twqlvTPFTO9VLVI6R0Ns3kKToQgh/OUP0iLd4r01RDl9073CqBB8zs+c95FLf3yTuOU8TOrN7WX60XSVSLY2HxNbrnKYp+HxpT7VTSh84yOF0+U9/F7YOSe3WCagZsXOZ6e2P/ks1Be/AhE9sXo9UAIhMOxdxYWXydy0hiycDcjcPPtaYn5sSpvQHiitQiYNLGMtQmkuY9csf7JsZojl3LhgbWvBy3f3Wt0CLtudn9JpJJH6ikaRnIuI5elauj0pF8HF0yW2T1BMYyJAGivL/36OKnjAbOPMI/orNk13jMhKA/O29cMIQZdLmW+WojHgnzW/HVQefdSPlXL8H1MbwBlq0c3FKn179NJcIfYqBJsoNLb+ikYNH5EemONViZ5nLuS0itIwyntaLrpwUI+pMTr+imQAjsbVvRkhCUHP5uZxXAVGP8ttKIqYEulh21pLi4Wxa9/2cjcSCPm5EXDInUJFu8uoPwDbqV11/bCd2UZ6D8kZ6hsjHOJzM+IdP2PH8rz41v76gKkL9IICX4hJP7WKu7l4MEORXqbG0lpfcFydSP5Yi12gC9B+WYPUJqbvSqpjaT8dLyLHh2wrvToFmdQKYZvru9uTyfk4jT8fzXtLOsnnsYcUozbHCdwEzFYQQJOzvgxlIcptQbOXgNNOS9/9G0o50R5+HFWENG+MvCTT11BIqz7i+c7RrEwm4dXZYU6e+OVQ1vX3vlqoRen6tOLy0HOUKAqV2ouxnBYCn4Bt88WwZkQXwx9alQerqVdj/Dx0alCmjgMejFt3SFHI3VuPLS2l4lGitJ3iPyErQy45DDKxeJSFxAxJ1R6yMbqEHnbQxIdSO+a0cJxBWrQpKBB/OYtNIRQ4Eauc/U22uqD1CD0Wls/fB9uPbdLrlgVVWQuVL9Wc6wfnGNdCkukTVJWEDmx/5rXkG8vXUzoZf4EMRaQvkc8KecwIHe5vVe+RVwQWvBQstZdmew/ZUJrUDrxEWhnr19prLpmo2kDjm//85U5maqM5s+pKnmGTqy+50ZLBhdE0lWtxeavKrlY9e7C+A/dppHct3E2XqHB7IsssJroS0vmo/f+FhN5Cw2uYnBD1A55YyDovfgW7/xl2KQUhkLDPjf2T/IppRdONQM23LPZBokBnwwsa+y7IXWM3Kobo/lyxDpvx4Ya6qTqnAFG+tD0GTT6r4PctId8I9mSvzAd5Pc8w23ZykPdY0A2W8FGMuZJNUDcSTnPR8fIS6DcjRtyFnrjZYa/+HIQyV4GZF6b2TgsedQpPVwkUt80zhD83UAMyjEiTNoQiYriWs/axeB62Is32/UMeZF1jVwWnVexsxuHPMfR3f75ksKuxRFCVPQ5DT73XHvWQKyAbRZ0kPkdJQKWq0cerWe5JKXFax9dRQarE+l07PVnzbWmpxu6dpbTFpjWtW5P0KYXZ7Ry5cnj7GXPgAN7P3ohfgswCz3iyItRXVEWs8OQHtOJfJvoD6VdOXDjNAl/zdESWSffKI3jgJ/gEnOI4t2FWJQQMFkSI+/x7X6oRPo28pi9o3MxaD9fFtK+kSoy9WJRrcymGrEbkBAItNdEsEhZRpSBQNensymgenvyMU903DTaNJ2FHJPiqnWff86DHBD95W8BuAdLoh0vOrxLf5FDrE+04kUx6LNhlwWy+e3MuGiaCBcTlIqEeCg33TCgL6mELuDuaOorNl7lPJqJs7fAxfV/6JmmenUe19kpRdMByNwOVYHFG5PRffvKNgYN/PWD3OEYU5abcqkDPx+fEiQuS1TZHmmI4ErpmO3MI7N7VRv3lcoF8mqunXSN6zdSkE0vCFURtlycc23aBPXitlQEYTTMr1BryCOt9u4gniVjs9R7MWxSHc2AzejKf8sKrojiZr21sYV9OBGuJmE15yxnV+XbkOQRgociAcNwN0E5lRVNi8v1R57+wkbNAN+NhJtr19bpyMRSYS5vTn6smiULVAAPe8WL596v6dKosrEyCLY5B1X5sQyooNQ4evkTl9yfT+NQMywWzrdhelF0Sy2FLl9mkC+CgiPLcruCSJQ64UETIs/AM81X2HtfAb6rc+LH0HzniJ4BEK5J3K/lLGZduTF2O6PIYt4Ko+Pi8I6ulyNUW6X42WShw776GxFBzNxAuotD14waU29l1dvnafu5qfTt8Vvgq9VQgosB07PtFRRZQ/SluRlarAnUbr05jPK9CKBSsHzpU0vJaE2VduWCDMzWNjIXqcsGndekDW358O132HyeDsERcnYxYzfVfOUsP1dyv3uK7uJUN9HZmaNN0GK2OskU8WN954NjsSEN8LGMYQfRa9oI9zB7+lIAeKzz+Cn3B/fDIwbji5nCfbikHiVnLdTI7BVle7nRxal6p6zaF8OjdrDAYmAijFHu2dn3oxG8qIgdNougWesgcBon99kKkPPFHrHQ5OPqotakoU7QejLXwuKgrx7ykeHFK49mGb0LnBHS3PrZE5dYYbvjDY6W9e6/fNO+ewJJSsgODTOMXJQ48zJcAHtLjloHsIHIgAE9usWLfd6NOjkf6Ln+pG1u0sqhLGy7/6pDZLLkI12gww3/53/8OOX8SUD3cpPyXBWzg7kRUVK9CuTCPdocjMfDyijT+kayC+fyF0eLM6MKY8SwWHLrcnwh/XcvVNHisII05VDgGiB5d58qLIiTZIvrOgLLNgb2GcZiu3pWiD//ZTOutqxGF6Q+stE2n1gQB9FpH8j3Rkbhw1C2ETEw1D4TNK32hYUFk3eGpLhfHu+tvkEWfDtYvxBOAMZnuFKXFTI++kycf3pVykQNSpBUWXlqGWhvdVsSrFd/Is+WdJCVoa/DgWOaeyVukratqZ3DnTjd9ON6goMyDKnb4qY6paXASGgX+GIb/vbSAwx7TB/CJ1Wg7WflmLPczq+a5hK0OdjyB4KxpZt79dP5mqrMyjxdKtQxWG77h8vXpuAj657KWXX5b5/IZoFlDfc22niMrXWJT2MeZHeNUij5LD/6yMRo1to6/zkxcLVsUIUYISLXccuiq0FLfXkdGIq6uJBcAVg3/qK7m5j8cmplUcTwcPlUI7+Jd36R3slFroPcCspEMBhAx4icIIH6rcWEAFcZTMDxCy4Y0UxU//aJV+q47Mhp3t4d03GILKedIRyJZvTV0W4HwwA1/FnSv4L4neWZSQizBZ2pMa+XM3+dhBWnF27pIsQLaAlcDrbCpLsAvfqSVynUF7XIuZmV40LWNRhhNAbNWhJiJzq0GgroTjCUtqLXTLQVeRIjKyzV2wz3Oq9YHXS6kdtBi9nXPJTeTmvvP6UZVCw9DFwF6j6ftCNwnCw8sZ6MrwSp1DUAvecQawD46p8nHsCT3vpFZbpXQnl3446N//qwEMH6St1Gra+VzsiLEfX+BcxWk18XqTFXPdvXml7t1sgGfBFlp3DE1VtwlqY8504SxsdTd3arxeVVXeh73g5ZKHN2frY8ERmmycz2R+0Gf/O528Nzptnzxdmup62hGzCdyNzziQIlg2wc4c2h8WlYjMSgTN0sOtpfqVEqgaMYV4cwydFKlQ7Me33Nt7pDFoNUtqtPy5F1Nj9w+FqMYVW+V61NonLiMY/8w4HD+TwP/RqRfYGcwfnT9pYRti2f/Lc6WgvquvCw4WOf4nbHj8ZafnZ/ZPp0P5t73RSmH5uhaQVGcGEaoDwYcXS5KkDk6FPh0kIYeXODsodcArHSNn532aWgS0OIVrEDqIPbl0S9J4zqyJs9ZwVuzlqo/89pNNBQsghMp4i2tyjUVKM7cIX60uH+6e7S54KpQyyEM0JMRoiM6DVzLJwTmEtuJl1WcEl3mmP+QTLdl3RBTvrVYRc5hyg45lsftKIw88fjilbXK5hToKKSTkYBaQjaNSEVsDiVS9Vrh2/Fzbk7BoSePeXVfOnrQ/yqTSldajaRXB0uAQF2FTcB2LRJePUYnzaZjaskObgj9FBgvA45dRUhm8+PqfStL13HoT+FP850i0HZa3/5LwSWl3VNtYXyEF+TVgLw44z+8X/QdnYNPNxUB5Qjf4zNqfaj/6PLxXz64QaXRw/EXHdjhgjtH+eP7pNXwpcDMFe2MVKxr5nj49fBKiNMbEbJPh+AIdbgVbCeMvG12dT95PuoYG0tfDwSy/rDw8bQKHZs0E2pb0+HtQ7z5eZWHLvzYp25GdLuBSec+xGorfUxA0hWHncNBEPKchq5iwsz70W843Ox3W++dV0RCxoXn5F6OzPX48S00KOYJu6ghzQE3RmMMUOGSGWmyyLSOQGqTqW42bzxp1zqP7FEBbB5X1pZvnm55R9X2P5V84Z5yNuWwYHOs6RYvLvLbtmM3Vsl0mgTNy/LJ9N52tV8VBbVlJdLwpfYbFD4+KF3E3hjZ4q+Wtl7CbgVcqmen+PQ7vPUqA3vyLFwITzDSEsF6o8XUzv/iOcrnr4IaxfF0BdpTsaz19xewsBha5POZ30OxlEWz7mY17/zmUI4Oy2KJZasOfAj17M5HjdWn3D6s3a9H1BVsVcjekA+FvaMSUDnGaoXWFMeCVvFw3MH98SxZTv4bF5/HB+uOI/3+o1O5Gnd6x1vvtD48xDf7iwW40frvDD4oTPmCyta70JPkCbh+VCebpifNK8fMtx4Le/TPV5JXu5vc0sHMDnnd+k83Njmt9pC4ltN6HMgz0V1Dh3xxaFSSJrmnLCQMMqO8V6em+iS2+9ctjK+MaLppR48i+5zFRvbeADowxOHbiy1oc9YJxfrIvzeagggD0BuYsUFViqnSVve97a9+4JgvuDmRz1PfDhO9m41GMvmmz5zHR4h/zIHBgixE8IJXfkw/JFLI9m2GAD20lPds78gxS3sTTEU+vUBls3RTpuiHlXcWfGCEBNqAjdQQvRqn37VtPqvRY6NMzsHmGAXZmSuo0sHFiO0CpyV5/BcFtMj5vwzPpDFrCsJ9pYXp0yBd3WIPv77Ysd/eg7Wt8f7sz/0D6eLXMK5Nw6Gj8QkL7neb9m3pIZdXwQ4byPyq938RMnIza5YBDa9aFLuIsqvrnh2qgjOZePJZWXoQQ93R7H4oJd3SikcKrGYcRTd8XnhGg7HOGXMVLzWn9atkdqT5Ly4kmz44RBUJEpw8KwWI8rDizOsDpw/UaS/0cWiqNgwvlTieZF+VrWkekQw3GOFgUfzTqeovqSfGF6xP7NTgJFGa6+6nehcfXnjLCmR56fkGmfma+EuH81LrPkh4nM3974+xzdMtgBcurNDiwtf5Dkh82jHR8TxD5/hovuUFtl3f9CJyTVjQejrzK2ous0vR+QmNwuLSrw8+KNWhILu2TxU+GIh7ZKSAFQA7gLyw7Arzq1MjR605FeM29a4rJYv51Px1huAvjlJbCgzNSaj6ibGWEVKuKWyt5Nully8WHrdtjM5MfwBgcDqGK4P1NSPiHM+5ww/oZB+QldzzQ32Q4RsRPAtllABtKd9yNxYCiFhg8K4jwxzd2CCrMd5JZi8eErdLAQ1WyidCp2q3MNTrSL2CwX8SiQF7PcoYd3HfgfyZHH57MLKmB/N18eKZKX947ybADSrJbUGa14682WPE33i6PfinAv/ruXkLmztri7ZlHTuNiGMWTZ+kFKaqR+mFVFkr9TZuFKA6NoqEWlVMJIazu/6PD9IpbSBnSWiZLNNyiERxHLbT87R/J4M8aepqUH2tRX5bOseMYgHly/YE1weyE8SNs9XmHLO5mEuqmi9FlBaeE/88M+tLgrGkZ5PBtUR2ehAPz2/edALLwK3EltH9dUd7XvBPPtN3AF9ley6kxM/fXQjV+adja5lZAXuLTA9QXnRp0urs5emjpeyEXEBoLEjG/2gaJT3C+3B50Fft0lm+WLFnLZiEa4dDnPS3W6l291k7rrRaDMapTZ+Rmr8+ph/nGJjbG1dxuDCBuCnDPPJcV1dGHzwop8mfwO/46//eJdniJsXMvQLWOPBvC2BciDVFhYebrveSfkrfm4WRia6vczpJgiC79dynKgr6/ijEC4rhOHpjV7Tb9tm9iQi6jsrdHjo64Rprj8GYrNoou4kZn5ZQGcQydF8S7A/MvE4PfO05vItXc5ORxqyoGDTQUiAzk0vHOWvV7RMS/MszxneXajDF5MvabIWtAaGGrcVYMAycLZy7iT4V4hGXDC9F7E0q728LtQomka5aozeZ7CMP2ILhn+rEeHAk/I+R22aaJyMtc3kmTA4lvRFi4N55vgTfMN46L+18NzPRh8wPmcOU3y1impgFuFnuM5BjWI04xsNR8nPto1GK1e2jj7BPEvEdLWdr+W2fYbqNcX68YYhD1ffHGCIDk4vn6Y0lKuEcWtkayAnz4v102e2491ShL9AULrGrq9foMU3m9lOzbGHM01XXh90fBubEHmNUPerNr57mZF7ixd8Z12w07m5uSGSmKgo2ogeDULc7JtrEANtKXNk2Mp3W49HPTIIHdI/fmX6a0wBtDNz5cU3m4ppTJ+r9PZTUIMTy1z8CCU+uaA/5+/svxHRBd6aIZwSh8lxMLFuDfanrZVaCFhIR8fO1yrD2dBhEmPIfivtX+rekL31ytYdkkzYAxZ+netJPHFqQT5Mq/bODn70y//J/KuOp2v66xPXXdjo/FmlZkOcV+gfnI/fmLFdrFr5DZZhtmDiksy31V1kz3cbC6ZY7L0CnXj0AX6WUD1+Y7GFM8S1z13l7J5YnzJ/cfRWPSiue2DDbdlpw0NYNbVuD9ucjC49qM6IqucrwYUlizkIagkZDdc4RQjhWxvbDfvUBqbCVeeX/5UxEAdkS0kB7ew9jTFph9mhgVzdQf8n7kw+yyMkFo+Qcy8mCk7cP0FUTzCrAP0IELaH6Vefr/TnvdxJKtvFVpwf5+LF+qTnJUe/VekczCRzFJ1XOyfglJyf1zCjCBz3za86m2rbrfxcK3OO0r1/BYbxfFnRYmzbEKXcUnjuKu+12jXry78OmU03SXpOqfToPue3HvzMUBtgNS3ipNPG6yYrD80vORcjQ7jYFUZIHPrUqxIXZhwMW41FPeKPpxxqLtjgymeE0mQLWrOxuL1lVTDo/+N4Sjcot231vGVr15OWZcQf3+bH/vNt9FHqBwdN49zklYjEWpqj9SKjtijygBkK/fi55XxWDmC1ZNf/zDJjoa99+3DpgJOAn7b2V8FZpXuGxOMNGTYzQd4XLMaMuMk3jy9+JMhyhbyXLIYmRkNTiK6cBuot64tL/udTkm4ONEUuRTSe0VkqVRy4qGx2F2O/YqTumul/2qgMURfzfp2JfEcPSISxd+LwbbllaBJbM4D6UGeONFkNfnI8q/E40veC3tGNtL0GOXe0ASvdusVi2cPoPcS50gaBlNGq+6/gjXZtpfvgEH77X8zr5UFuQOabn+PaNYIO4fCvdC2seJXPIz2SvhlHOosVgj4Ohp18MekUL06J2gFi7M5T6Xe6kP8vLZufnGJ+8l3/fHxqYaDeV+zi3PLTsgQ+gbTRuhAwLz/jtAtrTrujbMyBd5RF7CbghREwRo25V0CvOfIO8+bQGg9v/+yuNLtrXQDZad7mo31ciI2x3ZsQwo5z5Lof/w83AHpc3RcRyFoq+PwgrZDj7Fe5ydv//sXf7StNgwHFE6AS9LklYUb8wQYDknB6cGEJ6PYueopEiJThcvA/61Jhe3v4CZ7c1IHz43ltZG908rdTfA0vyllLAYfJ2nCcANaLAXk99TwNzDwd2p7OTHSlXg7SL7mNUbD5//l/tEBfaMta/X+3Zfa4NNiTE6oMqhy2H2s2Fz+EsYqGJO0nBQNxrN9PH8r8gOWO124Yzyg+zM7K47NK9MvrcA6iPFyc6D5xHe6K2Sj+7FwZE4VfmIfhVHxfvUtvQuP49Nb5AT/Kk8z+GxdV+Wb3I+fhFjcML8mLwfRypF90+p9jF+BV67DP17cIPxURrKZPLJUsFdKQcvbhNWIfXThTZeF6y3uxeLAuDY4PfWticI9uICH+Kwdlz3R947lZQwC8uzdvEsT17MSQgTZ7pa42w/zYdRaXd8m1symvVHGAnyHu9MG4GZe8TTaHqmhC1nNUzwNxliL9PRizY/WXjzQXw2T6SZWyDK+mMLrCXJL592bFevEdAm/8LrYP1jr+6e9R9prF/YW3dn7Z7i9s0Ngs6Vr+/BFEuXen7mdbBmrzLfY/+GVs+LcGJDgia31er3pgfzQGXXw/RHZL9GQfAoTZmtXP5i1aih9nup9gtHMZentH9yJqYCUVYu94JjjsH9RMIN5WgteXRZuMPAnxLbKzJZLeoHDxd0X81ttZ24rQyz60P8OgzsTGzt+K1RpOrAPUiukWS9F+TD7prlzvCB7wqL0oxiOXvvIJJ35y3eQDGsyajGf+sppzg6imn2DiNhFtLao2tjb1dTf+cbxVFfjr81kivq5R2HWF2uyvt0Gwj+Dpz1gDM1GPKOk7E2hmHFKfiXm//JTPv73j/uDWmWa1Cj8BYOLG8UcjvOIAOEy6Cie7QmK6PD3N9ulSc3hXvwBI4z0/hfR4tKNu8iY/t6prn44+QVinTtiwDuy6eZnD9oxwxWWYkvphq3p6mdq1l2zZv403/rOTFaS76s9NbzzGhtqge/MUMysEdzY3127UdGoI56tdXqw4Lnd2hr3uzLKy0mV9+x0IgdDf5iy3/S39YWKO6j8x+T5Hd3xqy+ds0OuFS4iLe2+P9NzuqGf/+k77rlY23r7iAQZXBQH36ylpHFnrEi5t4VZResSqTcV6SPA9a//GdRSIinI45T9+n/OL11bja3Vvl9Z1QM80KRpLWUDa3m8SPI7ZsGCIFsxP7hi8GCyByfTaclJELrHw26QVpNSnVITghPVlJQInWkXHPvNcXMfPAE1RLHhx8UlEa/xcOPZ6ujbsG6lc/3ZFBWAVeuJ8I1Gr0dVMwTOOYzbmMQrrMYvepGh9UUgrWqx18Usv/ahWZ8fTz3biw5xWnOH+bM/wv8SP3Jge+Y8SjQHb5yd8UomKlJM5lOHUj+B8Zev0Z7HDy1nxqjH9Xu2CHtfyTxLH/H4K4tBaXfDyVruJPd7PepLO97zGqy3yVnBcDl3Ne2EXuS9tNAbnZz13d1dfIZsLNeBhMbyvoipO4yYdhHtO9sirdlzFe2/t735h2NWrtNz0Hld9EGwRu3ZyCpU1N4FWF1lNb0DoMEfHVc4IoH1zgMcgFrOjSeRWRZJbdrKGXNzrB24B+PsnVqvshPbXdvgvPHDelX0GUHgFs+y96+y3VtTYDORmYd0Fh5pQMk+snxxgsE1ydnoPxmExOsyu2SZDgfS/uI05/riTnJMLR4Dth/B1T/xhi9clSRG6XbHUs1zwM2zGEGhX4+7RlZJ5Qo1ukxTQHA3MvT8IjH1pFNtKcNpXoG4OtPGDkBqYpv/gW0OnOhtGsvtcgaZO8uLRbY2TD4C9q9XmxhGI6ZYj8G+HVklgxXr6Uv4mcZp09/P8RX8tC+mWHNLFLufxTvAZnlRXxzHA1vkDp/5iTvzVjoWX9y/wen5mmutm49UFvCbl8vRV4kWJXi5Ad8oDfS/a6vAU0oQ8YDZiVHDooe5EUzSyVMIk8LylqoCVY7yf1/5nL2q1dZX8mH0t+Hk6uY4T2b1ZlHgYN0EH5N8l8TaqCzjbNqEtmmLTlg6RtMRa4nIgNsz4OLgxEUehneyq0M6SwbYH/xR2CDh/xF0M8kx3qttAPS1IKwLmcZf9gsjFt+tm++LjjKfF9/HtpeGlmYDQXHmZb6WbsPa+qvQhfsoVO7L+l0L/EfSsiop+rnil6Q5JBlfUFhXGxRDv2NXXq/PpV4OMEBnWgpwnI3PD+ZT/2e4829kpuYQ/SsZvyUQ9jE4ELxhtLAeN5Onchqgg2Golz2JLqLZUXV7zuyUha9MhLIVqL6mv3adLepQpameoC/ml+gMeHrbxRoyh/BB8Nkj1iq2Zsahfq9v14GutOSrxpGvjfbh1tlgN5Noox53IYJ9y55/Dn/1PLDiRUd1v+hvr+X/qLrA0rw8OoNP2lWB8rddalT8b+I/Pb7Kz33odWp3AzN8l+4hWp1Vs/tP8wDvWtI39OJTMxQeYWVgT6RYlVHLNMg3w+vgGuoXCWULHN38PVU0wfhziKwVYO5OzEgOK46fNYzj0VGALUqzNpeub7fUda6/EGzk5eC7hPtiaXbxiMV/24QbPYqa3OW9OAOebU/TirE93n5EZxFtEI/B2hdoAwcrbu+40MTfljsTql08mpoijySJosusnS6nOb72d+/pQc+44x6gjCkiPDPjgzrN3UyinOFiGltvQ0HH65IbEx/BqLapnL9CL005t0adwvA74kTgZu5MMPMADp/spX7UtQtL0VlmzDtk3FfQKCvEAqRzx4M5VBhPQLJny51BxhSHn2yTN1jpKBkwz+GfNcQEpvBhFJHzBZsBhbR70MiZfLIzbIh8tfcf6f1aclYF74X8cO4eG5k2B54OaxcNEL5XlK/SxbC6wuaGQr9FGGJxU/xt94DdezWb65kCrQub8SQ/DJ5N0PCK/zdFHEsknouGt089AND2c81TeCP43bqHKPTg7PzFdiMiq4BSHhsu6foI6Ap0ai2tDf3LS17PLKSZl2R3vh8OxWJ8TGo/9xufswb/YZ+MZfPNtsIyzuX68h8W4EIVcPGJnj4zLyASf7771BqnP3pHTb4VuU4s0X5i55IqxAMXZKaj5JMQ5veUpkTYWlL4L78qHw/kkrh4jxh1+X4nvDCkgOPzscL+0L6UJ6t06rkWkjKF+PfN7lCAYC5vO3LX2f+2Co9/f8Y7KEZ9YdnV2dVERovajS9cO0YyyI1QY8H2Q8RsJx+fZ3jVTUN9d21uB8sxeszLBd3U4nsiOwj7qsp2X4/S0txCbzkpBd1HqN3qr9Jpe5eifHzpwVvx7Z7TdfQ05f5uhWYAD5R8Q6DNTa2VYWdI3I1/naPazp0/tisfdqjjyXjrDiq8Wk/l5oyGt2Ory4dTEq9G5tKvsgmz4Drr6fHTJFDm3L9a4AEopmXSuz9EiTZCSnBjku6WI6uJJLfbZrRZVHnF2+qTfSoLGGEb9PbYA5yo/ubrxp/+bjynLYTQJvl18PEPOyo3RHFb/2SswmvQpD6tMe1rXw3ofTqlscn1sf/LYfwT1Rb+AZtEqebFFtpjdTF8U9Z4vBrey6IE1iB72vxbF1kHrEk7vyLfXL+JxGScK7V266nmy9GL0snAuv1/yAPHPsLk5uFa2SbWZOr/4Ozrq6t3cjXXQlwGuUjdeRm24fpA597fS9YsIeX9qrXhEyAeHfv1S+Xa9nKmmwUTozef2wvwoh5O+jvIGLoOuLzjvW5g3X95Rrhga+aeUvBXEfU7OtiifOwNGvZJYLNz4n2PxH6yvHLkDYbh7GGZ80mrLgJ6HFPeLhQnTpZRCUHef9Cx5ggwtUi6+Bkf61D+xzl/2t28sOtmlNJvO9AuIAeky8p8pUd/bcOfAoFlaTpBGPi067VefZFzc6JuZVrhctDvx6sL6IB4xE+NDHp4Pc5HOJ6Btkjtr14Sqpe9igCgn82S5fmvS5g2Db46TuUa2lAwBQFjTkpRQ0S7XUaofh+OvJlsk76z24RaWxOPPMzE+fefPgXguhjg0fkC645rIpV7tnhyl0Iehu/GHQwCIHzgWMEVBcIkv7eeQeD/d1zmKx3kFUatIj1VMyrxPIcxmxeriqH44FNE/ltOJOL1cZ0mPPoptbNiA2RXyw07x7aL6s1atW/kUwOEySZdMdjHqtoQSj75rHQ7XGo634W1fWVTZsh9wbhNCJ1PT4w6RmYTw9dmnTrw0ldX3ytLCfci8VaDHZ9cgZz/m34R8fLJ7yih7NLvsEhnJ4pmPL8xxfjBBqh+tWwVy+UV2O09x9/WBwJwURV58Bz+n2C5Mw4rSyvgBOHod6I9qI+OfjUckA67yG48IjPlqvH/MXqGV0QB9SE4yQqU079AsXcLPKZWJZava2DYkqoFvoyApNBNdFTIr41nN2H6cDsX7y/J+2Gf/LBnBx6sXsoswnXKtvOvUnzxJCsIBw0vUTfXDqmq2YYZ84Sbq88b4NjQc6xgHVLBm9UqxT0CcXcXBFhsjv35aPseFUR9nAo1ENlq5cJ5sF0wL4sWxFEIWj0a1syiYcT25S+PTnv0PkV71azOryqQNoq90DJop87m+uKEW53C/HQXaWJ2rwRPIg23myKIa1/riHGNnTfeQae2g6ZFs6PH4H1/zgf5mINyD5WLZG4sXkkyqm+F6L243mZ96QOHkFn9P8zxf6rXhJoiem+Pj1pdGG3elcLlt1brXje0gylNiA9n+tXMir382N/GuMIdh26Tmohi8jkCCM5keeTcdjLTRowqbPLQ2QvoGK70iD9PTlXSxKgUSCMURSBEeEdr1IxnP4zOAbhMFx2tnzv5D7VhbbkbY4+B+XeOWRJe3Ug0E8DBgoYan00H7FSFDSC2+rxOHfTgTYMZ8uy5CxlE7SDIZAa95R3fudfObAWNFY7IAU2d4d8VszgbwZkUDXT4b667uyd6FUHLPV/w5MnY7EnTsYwde4qxFiZ58EJMQz8OPJ/yvYB3OGafrP06Ga6bsT/b2WVoY9lLL4HBVvqQR+JB7hhpcqR7+cT5jPSlb1HZZVDURDn1G3PFwSN8G9uptPIYYgpU0u3Ov7enLl756VkDU1Ztx8SN6XAtmTPOX0YB3HI/8wxm3RJ4/32QnmU+1KTllm9Ok//NAfI/vAm4F3wHR9O0a0X4Y47IeJf6YR3aiYY1i6+3r62D4fj119B/dj/ny/uFdJqI3B7rFAsHW5E2r4zFNF16M8vloeSk3vOOOt8NhuXa9YB53tncRzaf+uhssKWW75eIOIl/eSWwFu4cVUw51UjiSEwFw8XKTpLdqHBFLYzd6e8qM16hHYFVTKJksn2P1E3zrGX+ALDkc80iH+fQZ9q03zpt7bXivD5GfDrnZLOkWq28Xu3hRt5uacem8y6McELERGodlvKooNMuI2FguMQPlDmh5/UhOOZG8066+hqTpuf7pHw4xDuDyhlkdZ4bfqh1eXdLiOx/TgV0szotlECqCw64dR9pZKTpDr+7XV4Fqlhkz7DcHqJ+bavZCxF2zL6XnM03T221XSqMC4q4150kM6qffhzu4Km71FyeDqTcr6c6nclm9+Gy37Jb/4MlfIC7TlsAL7YNRc8LjLgLxMOTDRBeYkvEe9rwnH36hB3K1gW9O7BskoDg9y3V0Q/5GHTbOifMRGb1POB/dqLZCIj+NzLZ3NobTr2gNP3pU4lPZObjd12SSIl90phPoErzx9SUIX4nf3O+cHFJUx/c8bKzcQMLpT07H+nSc3W6ZghaLeLECuLFLIdb3IWx6vD315V/QX6xxy/+u0G2ECboEpej3NI+LfFtumHuHWQweuno5+9ZX3451a7vtJ4ExeXnjVb3LziXQ2A9SeNPnVd7YuOTzDa08BmSH0boC6PcC4WeTDPI1eWtsv0cZCj27lr4MiU0NPHTm0M0hIRcLIt9G62hf9xAzIx3tLblfKEEzW214CjA6B1azgBUXkB+C+SuRr/U3G9+glBjEt7MsMTyZWAM1xxXj8814OGSeKduzGyqlxoXnyco9zKqPqRu/X/hLg/pI6g8sD/pOu8NMbpy3cpa4/ELvsHO24Y3SWrYkwQizdHB44tMAjtnOhq7iWhrK7uA2vJYKQ+P94HTBiFVxuahRNlcJGVQGVNN+z8AursPf+HmQ2SkwTzl/dPJiLKZYC0CvMzaXnhuEQpes/S0rY0BeTPXCVELselt5xC9mWXJF5/XDI//ZHv6nzBK+alsM7W2d3yAJ1uknjOs52SCj6sNi/242cGIipINXHUXbZ3DK0CsDE/OdHb/6lC6BNt0M3DyUidefH+jNfr443s/j/Y67JPUhh085IPZHf9J3f5OOsdgnC8VchSdylGwBgtqI2EsWc1+4yMvYBfJ8dLPkmL++A4c1sU5at5fozLE/68YvReP5QRvEfxMzFPFRnG3wZ8/gKqSPbq2aAnOh83bv/ElY4+xGOW++IPiljBbGuv/2VCj/QgcZ/wwv3axNAV0+OODSZHtpoIfEvxYEjaH6s0OdZzMptmyS3PU4tFlak/H8Wrtpg/E9bAgPD0qB/OfrDfVzugqJqkh+yuV0docrJWxC+AlxLxCEdP8PN+lMCWbRcbSTP8nfQNlLQaWemXpOreoPVJxhqsBrr1F13833Kiwk6uP0Bb3GaY9Gxa15fDEid8npwsM+EFnwcBkWVJb6/QQC6hzG8Fw5NJpWbmsEm1bd06DL+T50EcqPmX0A9C2gk7i2s7FV2POVa7F0nILFh9WCQvHsZVkO9loccll7BTWjsO3c2kzwpCk/h0OV/1sPKZ/LO7+hfop/Zc6vOkOMq7PjF4fyb2P1NVb70oqPw7MY18M5oyYpx2Yg29AIiSPO/I0j3vPjRry8xM2nem0MoP66c0F/fAm3QgmgVcMlsryyw/T8cW5zdR167UHgPyX0rebukRDLAdy36jlwYvqC6DJD5zwWU1Wd/FZzcboysN1dowuNAEwPUwOZgTGZl0LzTOys0THnpaJiC9PExJhMLEPs34JIlFOVwLaapClSCRXrmX6yXGnnrxiiHDPhYIv4r/ar/iuVpnV2AiWpXVfD90cwdaTPXRmD/cT/tHvyR6cHN6Of8vEpMrB0wovC2SNYpFMo52mzotUIhEUWX5LTQidy7w3ULzn9C9R+G38z896jbobVavD1+nE61r4/Uk/E4vJPt5th6xKeg+5ANOScSS/Ti17BdB5FDlsYZL0Pa772j2fIszh3MaCoJlbMdmlsIB5/p9rFAP6RRiDSWQgpwcd59ZVv0sWd7cke0WECejj+zSdrvXl7Mz2UVdgLwhvv7HHs/z1esD9dvf7Df84oqucDQOX3fCMearP09SW0NXOwxi8Sr2YE/Yh7P/W12/Or6cL/TAXqmDy/uMbPON7pUad3I0oOOJtbcyrd6N4GOd5dEc0tXN5XIVcVTn8sz72NVtWdnAuWPpMgtf8C2PHFxO7Z2KW+NwQynMGYc9BVvbHAAMV/038iP2RyPmDbPvOWhe716nV8G2m8xWv8qAyhzbvZX7xJRWLHf1erYxei98PEzeiG9tRJRa+3xtxayuhBNXdaqY+9ENNYRarmzZ0fkUkQpgPCrJXaosiXSMHG8lb3mYSU+zfTwNFv6gE3OtGM7hjW4oC5uNssF98yR0fHFN/sJPfLJ2OqZBbOOHQ1Th3YL1RF3iXrhxz4NdTjEqTw2uu5VhT3gOPly7hpIRpzC35QTs6s0ayJTeYnNr1Qu06dTn0W1/vtItlGpu5jTifNBI2m9Oikf8Aizm42Zn65h93hxfYyHgNIOoUVj4OjO+E+zUEGkD+UX2ua1t1xZIXxuKrbkRURMe6tjSPbfFVrfX5yGGVTs2U7AccgBlyf0R4ZL+NUp//2C0NsBK2mi2GcieUEsP5tWBdUG5R0zqE8/njmsA1Q/JOnPb2yXQnDb2z/4QWEQRCfY+vR5lhQ0yvHsJ9PX5yb4cXFJAmRm45/sZC+Mgmzb3ryrTxRR/peRY/fGru3crJxri+RrjTRaX2dM7bPHagmcmnm55JdNDkMo1j4DDDZQIGt8LW244JBPz/iokOs6j9WHlVDL7HdDHFmY9C4zyGDAuJ6deOzMTJwjUs4Ot1YD+OWwhR3SysQ4WyzLOQbt5vabzcWq2PO62Z6Dj4c6T6ltXgYkUwxPbvnEFWV+BDaGVJXwej4RyigVGHNFPvBtW8kkExAbwV0yNPWUnHomKffcmvCeAgVCv6rbe0g1OeQ2QsjCK3aLE3rxYNMpMPXmii42hgQ/ozvwZbV4tl6+HLKY875fI45x3NxqP6oXqw/dMX05Azk2+w4cLRIXty3eL4lzEaccDwfd/kne4IQOShvh7Sf+fWJie4qoJpvdRfZYsnwYMo3f0+qYv2dXg7PdrVs5IGn06lLk188npWdbTgPyMV35hg+8W1oCtw4tH3P6Td2RSp/POOXT5vbJzLY54ZgGQ1/fcbvahN/yxXM6vBWa1znp3gWdv4lJR6y5nsdu25cTN77nHWx7sI5302Z77p9m509yXsLcgHeHSn6RJz/A2ev8sUt0lhPv3dujorXQIQxfq957uqCjQuQ36MYlhLfVXEbg5xIPIbzBCBHCJTZ51tvwnxXjj7IuLugMPh1K2+1Wla+dZHHT0sF6Sx2OLgVEI0Mt95GohObm10yTa/4mlA7hOFf2diAYbYKF+EH/8qjibYqTqmbeyRK35yEoSCcRRhvhowe3/EIp7sC2V1u5QfaWW0XLa3pF8NbZvPgUZ41Os8dgnEoY/ATo9dqdWYojaM0PDtYtRM61PzFVqGda9rLOgJA2yTkO4ecsm1OyaMzZDgw1McdGl1YjyqO7SfKSkwD78FcL9Rq6PoqILDEz0FWisWeGi77Rtia04TR1l/SxTfQcHnRZlgNoqg4Zn/jA4we6at3AjHrPOrhMIrgdMfxLmyx2d352Ub1QyZGnSul+WDgMmS4Z3M7THJtfaq/jeuDR7gNVP3X5rupaqP8Ntr/4sDVuPUpFxxtpjr79JFZe2Q9CbwzCG/s/uRX3YRfaL5n+mLbOG/IEnAj2k1XnNKw5Wir3I0K2/v2JR/I924ODD829X2WydgVaQ4ezNkmD72Z12fUJMlxTzruUE7CzGQiDCif3/5cq8JYz1B+auE/YeSlRVYM/Q69UESy87mBGXhMIiBxvxSaj6bDhRwmnKBzVTWXVs4W4FO/iApL/5cBsbw7MleWrS8vru/4Vcj+T9IgbLRV0goIoEmNDTE3NM7CZOwPe74nGqfLVaNNmIpXTbstSWbO4B5eNpw6+ULkYGprDo4zFxNyNDqW0T5Yyf1iQiXQJ4LxcbavyxN8cgMGVcO8q9cY96P41sEXZmW2zpC6SqI8Z8WOfrVafs/GPIa9MwrXy/iQtelxRj7EVpP9F6+lmAUY8fl6sY49RBz0Dvwi/+Jjxf6ABgH2w+1MNLhZB8b0nCNkm6n8v+DeBSrVtz3PM30vLEqfZlTz/JscEsdq2hDOwhx+f47pydS6esb1A0vxrJ9cdsIko39LuOWmv0Ho2T87HThG+WSKtlKVfX1t83z+Tq4eUPvacc79B5eSD+gAVnfVxUwVdj35hY0qP59MK9Tu8jE1J6flW2AyuEpReHcYtxAk8iTbxGrKLLf55WNUSQ0ivRPvQnDH34JAgxVj/pliELyto1xr4rj/CgI9ThHq2rjh9Y6ApqkBd5db5AwExy/G4PuAwhtO4OfMsts8wWjlezsta6hPJ0Ho5N7nHgvj9w3v3KGwBf6v7u5if9Plxzi6JznL2VY2q7NYKrz9QywMdQAAQABJREFUTYkFKMv5ssjOzC2pmfjysBy1w1KDD0/huhrTqD/uiZgo6nvVOuvLR8cRfcYr1OYV7ckHa6CJJNfeJGi3WUW1x0AoLGsxAnFWw4r/0SR8lfP91OIQQMYZT5Lj429jSzDO62LzI0Apro1n2GZKbn7M4YfD0POmfuswxnBoVld0M3sbbIJkXhvoBDyh3Zr50LnCBWH4uVykd/wUH/vF6jDVAR6u3FAU7cPI854A34aFCLmZcYxs/oxZHmXPLpn47IdLFxZ//40/7MNo79PWt+Cc3T/4Xcj5Uv7hevzERiI/4/AGy99NZFfr80l1lZDLyo2quHWCwvur9Met2BalmydqAJsBetXMjBHZ/2xeU2CHpCR2FWp4Kml1vVZMN5MfmWPs09EhVrdX1W4JDyaBa87GW2+OQO7aDPX+iV7T014yGlAaQrSPTQsfd92InqOqIa3Q57MNQz9+GeSOm88XD2cfbwi9ff6DwYSK36wO94DqBdE8m8HZPtltZMyw68CAejYjZ5blyaWxgJ57crCallTbHsUZQA3AXt91D5ipGuxijq1ozh16cIIwleXT4mXkt+TdjRrGEHrJ/zvLoNAW5HH2uXJmj/vZFeoszPDjW9wL/VEW2626L49M5CNIe852XR5qbv3YS/5w5/JjIN9WKJv1qOJ7i/zlbFWNc8TzVSy+gENuuRbP+s/PhfeGYNbe2eAq9Q/gR2cmV5wXx9M9fxJ+pgpq8y0fo3lg5QxmM7yqp07O4OWsJv2WT6OHUZMPjtu8jheDYRz/1LnZblV+9Odb+w+HMgYvzjbX7H7wPh7PxgZhnLOlUm6uyFJ9dFws1MTNT/yuHpXtTH7dqHSpinNTheqwELZjhbMo+tq5k92mTryOB5jIuXXsazrU86ng5J1QEYs1smly/Kf1VDzHkTvv3UyXdugCqQ+V/0aPtqUvqZFdeF0Z2v14WJmRjY+/HhTsuPvrOmfwrBzuijAImmMP3OvSeBt+/hKrzIDTz76rW9WT2S1dFe0pmx4Iu4vMIzNnjj/MKO1vtSh3hPzMg2cYtSmOpestePNiDABxsWDAPlt5lXa2Y8Mof3S9QP1noEMFDfs8mVvYIymexyMNAkPTUtL0+ngtHbAUzSQawZyYpOT2ESS6Xaw66vm/OIsFpDBbpk02W5x8CLIdsJg+cZ1Mo3B0unNlbOmk2fhiEY/cGMpRh7RHI14HQrL4gb3uXTunPz51P9sbn9f4PDj+8J5B2M9hFh97Oi0BsMY77foM2sjEWp/Onz4bjzJtxHkA8V1O3w0xHtT9OhKV+NhhIf7LMT/qf8fMtxuGvX7yObyebxPs9X8xDPs3A2YMxk9s3RGaD052U8aCijsUyAjkdCOcvZNvTBjzmMw7xSYWKnMDrMBwiiMb+koev6r0HR3FVYw31cmG8VrBGqzw1tAc5FdezHm6mQodhs8o/cQBNffKrnpKDuq0JpGdIaHzZUUQpy4sP8YsHJ1L71dKQUvE3htPyg14grurbEoFTfuNnLGlV28stWJoLopRWXZAdN9YAU/SKWE1D4P856VU5Kb5CfCQm954VGPmzx300t00guPjDlmOSnbuCfKizvlsJakXa2HuEDnllJu+/yqJVFseLa7l8kIx0Xd/r4wAefixA9ParGoMTwXwvKEzbjJ7PE79CLi7YpW0TMNnjnTyRsYUIGR4SXeXt7P+tVBmVlwaG2uaBZEYo3aLSjSj2Q8jeDh5uMPIphzlEGTqnrTrzOE1FbXTXkxPeqpKlfEHS+cze0eSk/nSWxe3MOSp7NsjCJdPqT3ZBwfC5QzsVvJsL64uLfvqPeyxs31ztY7qj3tnxvLy02ajf/uPC91HHufpRMml7GHq53I+fuIfTt5yOt5igYq34d4wpJObcZsegXvVOz+G6Tbz5s2tR/961PZqEA/g+0/B4GRzZS3EfR+QakSMyEbc5Ph2n2Wi6YIEM7XrCi8VfroAN8/Axn1HuXch9m9Okv6H+15D9WAaCfHH2cc2AW8sq44QxEZlL776HEhEilrWboY+Dmeedr2okw/6e18/JcWxrAB1vuESphzjMBJKdSUUez4qD0l5Brq7SHr0aQ9vHnIl1a86ngsZAaIO4cQKBXEbi79YPmuB6VExTYePUd7ixUzntlg8yJ7+ozPmyQLhEn+mS7uTeoQuE2upVMni4lh/cTVaTrGOh+6nzRqWJCpm8zDJ4xaAHoGp1sxthsGv+7/3My2zyvhZuASwvD6kc31O2oB1pq/O5uf4npy2HU85rqmV1D4B/y9DuIzqHtGKUlZEU42Gmj8qL3D14R7mv2QCxH82KvHKrlBxZPNZ3q5gSVv1LrfsPfvDpbANELx2CB7Hx07be86+D8py7NjPCuPPXn64MGC4vr7yB8+Tf/xGczGEb/kUE7NofJkXrZ8dyuWdZXUz6PD5CiO8ePxutMvGoVd84bnD2vMKV7CRghDFGXBX+mqAQG2orOfkWaV+GPRQFVRWm5hjb6n7q+KM+Vrb35dkJ9k/tiZWhk0kXr1zG68beu6VzYvsr5Kq/ObcC7d/pw04705L/YtMoJ8+7DI29WXhBW9rGpHq7ESeVs7JrGKhcx5SEgefU6VW1OtVahK4WfpgLSJBZnoe82OfVNb/zl5BrB5Gt1l9cebDOA8fqUsnHkZF7E1yXq2NXUqxroTPVm61455ebwvVMfFx9ENc4rmdNV94Me6qe/aYfdruxsbzQwx+vi7zBQBgNZj5J+4M33pQNz79fOzPY7SuI7Pn8ZOvuJSfvb21yW7BnRaNubn0VLsGroU2JkryOIyoMH+C7BfjsE5vZop/Ay+iJxtOAJzaHDYJg2mUL25DDHNn9cmmlmUb3vmNk8jfBpheHUbbgOSzf+dPHCDxKcanTl2d4h7XbL5jYQ9/JsX64ZYm3+BenAA//j++xxNEm7Ob300Ff7er6S62XXrDEXR3gpe/y/7Zj4qcCMg4bE+n4NP/X+Str0CZzf7iutJnr7YXX8kymq8wzykDdndFLTvPbJiWyQuMUWuNHo/WsEBdck/cdwymfmRdmFpKZ2JesdsJgIjbpjdiiQDf3WQklVGfYG+D7NeCEBnI/Dx/jE8sudM4/QlH+GyGFWA+TQO9KBB4ru92va45GsVV56SaVBBBRGl/9v71YzeyX3/55ZT9i2Od40+4WB6i2UBkTPe+YfHk8sU6GycL8faSi0P+1dsjrRyAoX/cUQmjQzNJVfpZDqOYNsQEzCEBKMASbXaMDUKwp3PyfCl+bMoeVJbpVH8iqa9OP+UG6uE21u5JAP7WluPTei4n/Z5vuW0/MZMge8IEIid44s/5JXEIJ8qIf4iL0U1KCu1muyvpCcwj3QEaQ/J4nIu3sairLxe83ppppufwDNq4bvzsdh6nV7HPn7zqH1aen/3hzoexnv5hxjVOg/mOjfYb1+wYPxlnr043GmxUo2PB0zuM03Z9AQ0DitDgowfnoHFMjodxqRrTtInD7eAY5VsQMxO8Juepo3hyzvyHZt287L9ymBY//OqQs5EZd3WkZrD++nofxflJvdjbFSNnfKCJRSDrjvS+0Q6OpMuYP6bB/x6+oL1xlCSbzvQI4CXUv4t+8gHzn0WXhT2tdzDcT7PL0wdfAJVtuQmYvN5tj+/yVWZMhnDWDOnR5pEs+rM9ChdoU+vnJrYXQiazS36HeE+XgXh3HM6LQeX8t6nwojRixHbM4ZG4G7X6jMkmF2rFm0f6t98q1EdIfVybOM7N/QSGtHwfFnmt6c2J8T6ttNUBjLLKoMkBzn0MireoHQqYcaW4/ldjaT5eFK8hqmLmhCRXHYatG/LZzmw5ra/VNiE5sLjauoyKF9iz9my2jS+eF5bnpwvBWCrjfrGb7xfnW2R9Hybs1QThbKfTrlpx9suMi4A3bF895mDmy/+pUN43dh0wLI7+F0P51Z/84bJB4Y964955XMNNLnZ60C8Oyqfcd5K+l8S4XxXSDmduAdp87x6zY4fhwnzvDMIYq3Ecn/HcI19Ok27GR+f6Fm1LW+dZnXL4h8N8cU7r6NuD1FGYj7TQSSv2lowgtrAz5Fd32tjuN+x0jwnK/SLj96JwUSF2N9KJ1bUkOvJ4Xcz3YuEmScukKs+h/GLTkvQf/4DoKzwkbtDB6JdFO+zJ3knLrDnbfX0vAqs4cXJzNgDmL7/zDcbNQeeiVNXP5ewAtgwk4+kJlB8ue2FViLe6XGb6qQaDerSmy9WRBEupkR8HEBdu4WOJjX84+tVMP9qcMkZt1MtnagE4MJwPJQxoBZqtff+e3WzSA5tTWQXzMIezjeszPD5JaYk7YJtgnlMi8cL0323L5c9nIzr3Y5v+oWK9WJO9ejLwV3CtgXbvmftFIrzyV+1wOc/3KyxXc7ZuknI426Lepl6kF9jXNdgmYuAuarqG+fCvn0Q5gq0k+nTU55mO9G1CyuFNTt+z8veC5zjb5I8T2XHFIZ9jlt7G9ven3D5+1Iv7yZOdvskNfW/zRRzX79j5Lqf8XCwZPl080BA1cq8EOk3Xy4u0ESJNScez/lTQzFVAJ4GTTp7ldE4Fpk1cNkzg6pTBrJ5+JJtkjVyQnPQ7oENmuotwfX8VnHpt8QxVvz+KoS1srGajV94QPi+s+1Zcyr11Hty3y60g/SLyP9ai2xJsE23IgbYdlwxNM/5i3cWvO2x9p650+++qERSbWEYFSN2ubGOV0rYdm86N5dLeAhVnZGgz7dRsiaLSbXzyaG7lEfB6SAkleg9s+RcFbT6uDVXyfafOQa2wVI+Q41RZZDec0v3LIC/fWza5NLeVIxoDNKwGBR1BMTyhXI/7cPq3K3s99Ib47lvtX65xz2xogVELcmbPVhez03gZzkOw/GSSZxEbPeQkT/Y9F9/btc5KU2NyGkU+qlkpNC5P5MX5rfGnf2NNn7F4Hrd8tUk5GceGYlrNjH/TK/9iWl5OjHg50TmL2dg/ucrJn2wC9YLVbZM014dZ3vkT3lPf6Bnoo03w4d0kn0wM/eJJ9vpP7li8PE/2zj94De98ff1dLCZF1cch3+RKnY3FbbSO1V/MjMQ6tn10h1FgPWra0Alvb4+b6ycXwJNJN2fBNxz+2aQE9DgzYdVkM6hvvRH/3pB4R+nLwCm60PxDvUn8Kso/CsEmdHo9hr3rzDGv4e3UV03xZTNgmwDWN6LTcomPmCKrLPY+m6RqdLk9CJxXenRzMTuycHfYVaJh6iUvLsVVHpilLBjr0U6bSStmRhW81ZEf/e9ZBfeCgGguNaZHK6btJvLjV6u0nn5uABCpbDuqHsN10RNefgpvc5hWfApi9mVaFD51W3iCvp3USr53iMdrBYw4Ow9rjqNnqNfQJ/tEcYCH+1hIA0Gn45OsjcY6PbvbeB7E89fmYsr3Y1Z7IM9fx3Cjc0z9VkcBi/0Uy6E4xtORwyef+hmdbJqbuGTfPnYM9mP/PZXctNNrdYs77myIoc0EV16ryhwDn7zx5IiGARj2jcUg0HZvyc823GE/3FHH/Tax3XWe/Hjk96lPN8NvjM8X8p+xHVbc49V6PFPGZ1eMvGfjuHw5fGXTq0D7m5zh/xjP/mYXkmwE0uRU4Okp6juedCfXqbi3IQrqjvKzGWWRFfPmEjNBv/XeekvjgeadXwtMD6TrVQR3rx064bdiuNly2TPCS3gxLna+74pdzeKPAs1KByi64Ivk3Q0++bxxxHcbya7Cr2EA41rWEur0N3v9IDMWw8yk80VnX3un87V5MM/IggupHAO9z20bBdhGMGx2srg5+PoyhODDXm9hjfdhVgZHaTVaI8wn8aXMR6FzahM6gjtlI16XZZTxGIpt0i9u0CJ008m2UTOAu7aihXXler4scZ+UyKFwa+WsF3eOABZLhvUSX4QPku+jmMwjPhZToh0+AjsvGnANl+Vn3rNYDr/P9jNdPMa/HMbYeN7aGOwmYz2YmUc9uwns7IKnL89hW0kMdn644wH49NoY29uAGqt//ACnn7+3WT372Y3v9/5ief6/eHwx6OfiS5ds8X6x5uTzuAiEbuMw1xfzbIbdWLRyW3L9ydBjvPaTfTAIaM9OsJIXQ8rs6yEf3lG9H7qtnrP30y4W6Ys7az+P/H0ZZSLllhn/vyqLMl5viQy5sb8W+m+3kb7LJH7b3SkaKl/2+u56a5IzptGEMwwE/sky3NQv6Kq7K8edVrdeEdkSrlVK/C4T8b69v89CF2Z5CdbuIzKDNjxjtHFCXZqeDe9t3+tnKsU4xNKIe943LkYwFctvusNow3MV1GjjSmA/lHIQbjFrniXXZ0xyyIKgODZK/0LNx1t5QsVMecYJJkXyfKUcf/EskgHCPCyDh/1suAaXEFr1AxwOkQTIrI2V+blJpks9jqCPw7ztG22deo6K+zt6gu/0BvpxMCY/s9xrqIo5eSkr4dJM3nTjr+lRsQg+eWmr749/8pdnsgVcJAhkVKmuzajhD/zTHc6p0+aWXOeNo7mP5IkU4Dgn91J4OP18Nz775zv5uB/Gt+766gueT2xfm5aSvh4GLrqfDTP9G3smjn7s89TunRl+7OLg8OGibA7CKORhPsqW11emOpVxCbmnnfoe6HUyv6aEUYRvPKMwwmmP9zMoJpm6+r7cGp3uY8f4XQZPta9arAAGLBluL13+bJKXmcSCtyqJsw3DjDP5k1/nWxarqj7bJPcbPwjvr6+yGWCEtjtR5MWrX9kv6+MQtkzd+LzjXXB+ZNjvaT71M13uSnvQufaqufJOCIb22Zy0WdSc+6BUNY3QjJjndgdF8s++8/N/OVQ57Nr9NIvb8pS5pf2t8UsCsMlZBKfbZi8U31DB8vSFlNMq5GGW8H8k+tIAgauak34NMQjHsOc3hnwAim2oRXxxp5m2VO0aGhyF6FlSAvWVdU6ZzC/45ItrnozrO55MPslt8lSaHZUn0uYUnMNnc/gPwau+2JG6odQ44YkfqXZ2oNoV47nM6YixhU95qxVdm0bFVb/nNi362pK/ty72k8eCDh7HybFb/3yrE4etX460+TUW55fM6LT54JSPn9Pv/ezAn7+H8xc2itfPNJ9/zn8zlsOm5vkuT+TL43ILo8PffRpdduLzP3ycJxv/4pocBU3f86/l9alvskHgvo56jfD//Dj8aG/Rv3yIfavnAPusTHMLzTqgJGBd1HGOaWtKXu4oKZ9vpPm48k/+bXZe0T95VFbYZc3//dNsxcaWZxIGyokdDEeV1C882CD5fyAM6jKLoUuj0HSJoRPWV93GEpEfVBq4Sxh4bg2qh1eWRLbucOvQv4SeLjH30/FHBubsjghu2KhMPOp+3yR12H8nuVow6tIBd3EZUvYSusDk0rFFse/A7tk55ulP+nThYUy6qi6ZMmJiOlPnJdjbBnn1BO9ng5u6m3+7s/6U5Xl5fh3bjIx5Xkp6v77d78cAw15wWmSpta1IxBfWVltd7jX9siCMcb4FnvkQLDrYrBGs5RIcavTiPi2jicHZeUtEiOla54yuJg5X1ZFML/i/5bPV2uccb6SPZJA9vecuh3TIAaUTQ6e46GxzYV0ch+P4PId9+If9ysNCHN/ZddcZr3htn93O+eMw2+PCe2MO/sjh+H2JMx7j/6mjr+TFefn+9DcdCnVx609ezgp/2CpkiH5nMY5f3Rw92cM6/sjrM8pug4d3Vchb+/1EXFtSGbo+WKG7auwzy4cvbgm6TBHepRbnj4OfUfrl7i1MvHpVunmeBy4YGrLzsrig/9Wf94FYV56kwAqcG8wy8xJQ7SbKmf8bog2V6vJL2zh1MxOqfwzHdOH9GMypydBewg0me/osL3XUEsLc+YwP/3ic1vc33TQYOj/mYFjH0sb3OIt5/guaMVHlKVvpryl9Tq2N+kNq4041IlH540xB6MYYX0VlOLJbjVKNTw+L057ytY+f2HbRdsd3F2FiLDcHcCDQtpCeL10gT0NfsVUrGEPntbW0UCy9w44JpFGeISO7POJbfDsmfDrjuLKEPbmWrbZnojIuNROeaIqOeR99yo0ToF9VFtNcogdnjiHt87SvvKc6OsUS9vpiMNxGM9nDxXc2j8er7F1pw83mp/z1h1sMkxkXeIKQ7+mN6av/KRe7PL426C/mOC7HOF7/5WTuTwbYeL9+1b2aiFp/5//qH4c6gdXwBz4x8vTJ7b+RXPd8slN5UmfjhYBFyCq+33VmMNU2mlDUyAXzW1PRKgLddfJDy20kamfXOznPfeg0ag2/QQKUW0EXLndgXT3v8nB6EnHarxRlHwEbJN8WL7aWjNl05WcU67x5I8JPnj1uxerjtVM7POMfnXVFL6xRhSW/2k7mvW0h8NnRv88ikx7/lTnO+iir8oo3Hwr4WKHoNKb9FvX0SM+4ebIWSTq/VdMkpToivb2qUDZfyzZGfk5ccG5RtveiVj/J9cCW0oXw6mclep1qfufzh+djkHsXdoINC75NCmJDdvM1xSvdLbg5bP5/fMMl9NHIma2dnE+zYxF2UU93EP0Ez0DLBE7LJHcc6OuL8TTixerF7rNrVA7mkbnnntbwcHdWbnMO7Lohvelr0zm79PS/m5r1nN/v5jb+7Djoy83sp238yrN9fJ5ff7px/o6b74f7afNiX25x4/f7i+6Tl7t55+tqQs7FefFwSi9Gq9/Hz2Yc0wUcTrzCa+O4VfBTzpzpMyOw1fsZuUmG3cVhLmvfK5KriI20Lcgtz9u9lPPEWvwEsbXx3nobHVDgfXkidVcVY366IXxj74MSc0hGDNiCMeouhv3hENf9x92nl5+ZoPQnVyVidC9jQ/BXcdTvEOR48vUVB/qpn0m3cM+eV5neZs/Br/319lWYNAjCF4kR0a1QjQjBVyZiqWSns8rZEHLy3fVdtVGpPtevCOJOiq9ypZhIFMb7DBTdtnc7jxxCM7jvwlYLjTPf65fAiZJ/dbi0BCpvZooc/NLX3xleLOrFl99Hd1kI/dH9RPwo0P3Yd+PxTYRsMwN4WAWP7nU+y+RAxd0MnFGn9U35kb308wH+e8cIw5luE4uxIO2pOvX6DOLi8DjVdwcm9vTx00/+bGBwQxLkpta/kMlmm5ZL422M5unTDalNTNvX1z7uwzMQm+1vmMc7HSZwHJZ+n2ueH/lcup7z9/iMT/mdXZdyND4Mp9mIkYfDT5l8Fg9p/OptX/nZae/zsAcb7uSchvG4xwQMzk3r6OLzn1J0u3egbOWw6avDFt6324baXze6FXhADbruHK/19yjN+P2FoDYA3nZ2ifhrPyj3d5IuHZ31y0FEhkhf9SRvszAmP75EIdbL0DBIA87VTkUfoQ7h3tzG1D+d1l6zZkqcDFoqo+MU/1fTb5elpmDsh/LbH0YOHPerS9ztvrEa+fVl04ehIC8e5er9P85xm1xYYFhUa/Na9hto6D99xLokRfk0Hjue/X1VtV+epKJeAoAA88yujUbDjSsHGjbySjNPmZvGypXjRb5Ajgs76+Db6vmHFif5yUZ7AxW1MN7ryAQIlfMMUejwTRBPXPpglLres9k5kvTifsrWV/azvehFx2stINdvz1gW889NbLF40cImMMH5bDwbvXrFeQGKG2fSyQto8rc5bsMZ7WRyfDcLOZ68L1Jw0Dg/32+pjc11Ll+bJbHUP5lzKubp0YJTJm4xaqd8G+/643123/z6VzzHx6nK7a+c0z9OuS1Cv7u5rhWaP+RT6zFYdnE9rHNTTHPwaiYGzdmvvxzo33ymDHXcRujDuTt+LTHof92yJ29Te/0EKj5xuOL5JUaL+ZpGtRO57k3IdiK/9abaaIiyP/Zgv7tDXDjb9FmKZjQ63pqaOM2xqvRyA+JABH6+V0OlWSOBeNWx4wXKNcrAjwltrNUXvss2vhwoBehey5gLGHfFFNcv/pWpgZIKq2aqrn7BI94JR10OxudHrEgb32cZCZ4sOwZZLmiPhkEi7nGuPI7bcFAU2yrsBo1OSUfSiufooPHiToZcXsugzBTGNc9pH+CwszSO8e1OTTOX4fg0scVJIOWpFsWVPr/hjic3HN62pr18xeaB5nwly/B44Z9nAT0wmseM3uH8ODy6aX7Ii4HxmJ3l4zm/GWRsFJeVXdpOxuJgc1ORUWwDGWr6bwy+Axve0/LzorW9C1tyNw1di/AsRnzn32TTPfxnI8tm34fOXts93/jd/X25v5jxzd/j7Jtx4lwcv3MNv7g/eJIPa24vF/rPL6LuJDubEyDr9fiNE3Fx1y1+RauJerHq9Dksg6e39/SJZ2c3fLLMOsSD7bt+jNm+cp8dEOjqDe22PCea3DygUX73RYah5Qfd2hPtekCO+pz4rbf31+DbsXzLHFDUwsnEDHobDLR7enQq3Pu665Sv5YbZvS+sGOCNo9R06lhT7AyG3cb9faA7G/5s0ODY/kn0R9/vmkhWY7kJ4GINadgh5kcPonS6MjkYYZeZYUvU3eOgIgp5vkGzQ4dREe/Oxm5ImquS1328fsP001wI4lVB2WcjjhTYHtFnnDDV68n9geHpSjIhUfgRq59l66U45PJzZ8ugIdLynvZkSLVTK64agrLO/qQ7+7IDyWM8z06OZuy5+XBDK/MnpsJg/EkErb5tul7/51HZ7AfSdPbPTvmzMOZd3Ld9qwCuP5fyWxJb7FrOtkuhvpjgcdrPDt3bOKfv4vvIxi1W2+neebrDp6MPUPlPvP09jeF7J/eREbQ2/a4k2N3pPZ7FPU76GL1432eNz664yK7L+fk09xcPOro/YlkfSJh0hxHY766Ax2r5nA7R8DOMc7IEoNR/MY2RNV2nE9R8avL/b+4MFxzJbSPsu13n/R84t5f6vgJIanZ9thP/CEdqkkChALJJqNXSzEzBhmI1RiwJy+CnN7KuTYm94PrQplNjqLqul6w+/MiXKeEijUnqrmC46QRrInQkCTXCLELA3YWcBfieS0z+Cvpv+W4lCz5kEAHIky+P06Ado90RBcIRrshZESn6wG+w+mR108cfMYxPoD6850fm6B1at9VgbZcWP0obAFwMyvQgzRxOBWIMOj8MHY8IJwaHkANMxugY167zKsfEoGkwRIJnJkuOeHKKCiYqLTgviBRT22BWdqtf4jNFhBcLsRHyU9ooaEGNnCYiG+VRJSoaYBw+CrwoOlzsMZ9Tl2Rdee1od2WKI0A9pkaQ8rK3/Ug0KurYp8G4ROXQdStVZKtoH5BxHEpYRnYgu7lHI2f5CddkE9UmO2TQdfOGHUwOraPLeJkL4qI+iev09woOjrXbpIhNZSSf9WlSjc/83tvlDTk/8qe9vvRrvNgTB/XGVM7GNDp4Mi3ladwxmSvL8sLpz+FLD97gqKNsXNNXNDLaAIzFJky1e+tRUcmLTW1pFa9y2tV1XdvOYWuXQTNV1op7MCt2AcMCuMthyNthTOzE6ir73r0Wikl+s637TpaNmjM0jiZqZ4yVakzqCXxj5D1pPCX84JmaOGImN6C1q0U5iJsWwYCzjdAyDpVW562BgK512/3yX8QNlSGBSUCOG6n3IyPbcEySh2caGy/d/U9r2C6OhrqJ0H5PmBt4case4eYi1Ek1kIswFjCZuP1QmKuzQm6yE79mMW0YsA6RdHnlDAk6x4+WMjpPDtTpE7ETwzECZOCQszEkRk4fBRLmRhjaJsBKRpe4iwUlAw2t7UekZY1sOz1gWKFTVHPI8/KlM5SF4svFVv7FJkZMt0zIht4N33iUD3bx+waDpEFpIosXcBF1s9NGNv1pkyB7ZVVdMRdX/Nvf9st3ZU1m9PNkpAz1+K2cfhNqde2je/tpx5Y5cxxR9q125PnBnq0aKvsbJ1wR1SYNOYkha0Isem0uBgtlg4OA2FuHbPCpaIqltTzIirE17VkzUbFG5QOXsvjT/pC5eMNNxCi6NnfvrQwW2iyttmdfiFfIv/CCJrheIsDFSw+S2OQQH34Qbt+PxcPITAGK2nuaeEqXX3vkbOxO0HPk7FjfkuO0kwJ57ZFNgTf2OOcu3wSB0kD2U2lGTTgtb2edh4PYDyLXZnn72dmqEG4gb942bu3KyULZSX0cEnpIjmbdwPi0H3/iq6olvuEmpFWmX2VrqZq+nEayCWV811dkx2kM6Mqb2GCugV6cSyD+AZNiyxgNnIKREJGxaf11cRlGsCzWnHDUOK1dCdOOf+cbrvQiF3IjylJZGR4p4RtyNuQWr/+nv+dPzuAV50CNzHEgX+4I63f0YyOWtgRjl/YmufJVea4O9VGfmzTxB4dvX8NnIjmyzpFJJwew/koD+GQtrxCPrFd7YqMHa3KMYGVNlvjKzMORePY3dzgX6qNgV9UWff3KEYNvWBlvdcjLFYao7A8XcseXudxYi408QNpwsUJJ4NgipLKd1nJGJF4I69IGUig6RtvILcW4tuhHXs7UdBLTDGXQVh4SigUIdF0zkw1cF0RcR+d4KCuBwB0AyZR+mONoRTPksP9oPBmDH+ZEz20/HXCvkpmbT3z+xh/mjSb3DLUBZSTeLNMLynhG4xAnTio/gMEWjoxGaFpcqUyUWLUQhUMkLIsqDmBTb/8ZIEJu0R11QecIvbfwOBXusJ1qWJezBB0Acb9JUqcAGjHdPBsp47Pj4jhhVVQVZ5L5idu0LCYMpnhxSGcewPS0r5JYEhMKRF+m4sQqPAdwQtvAVnuFgmYcoz9BE0JHBfSIx7HnLtJFMEvGo6/IXbGxCh7mchUDH/1Z1drVuwrU2nlmNKmWoy1p07JOBDN3JFn1Obj6ShPZzFf6s6rFKZdzY+wmLl1tGCdxWEOeDgvfvu3oYgAvdvv0qo2xKy8HPCbZwa0ukLEP7uWKH/liSITnK0WvLxPp8BPP0dXW2JYnOny+V5swnxeMiSMQ/VrjOf0+t11uhFGpMxmMXURYqet8FQSWsjaD0F65itouUJscrBV+aatjTRtzPwdwcQHuvmXet4Bj6Uk49WxH392tKvcouXcY9qxkfhpApsqoeR/NCudWppuAF9hoSFk44CySDPDTK0z3Q3pNP2hSOFv1GIXJMT2QbtKcKy5s/0gILIMUomgLt9OOWxN0PStX0wg54Re6xrJxUIWUhiuDOj1GjLuWg4iGCeDYt7GEu0lIDvW1AtUgozHJtxdbZxUUtm5gOxyYRcJBYd9Dens6Kjw6NaAlO/Oc4L3XqTyH4JmL7TY2vQxvMV0ygIt8E5nGemIOwHN8/BcwppFH7dwMFCtXRYI8cxuMXC/v4amGFft5Hm/cgwhHW/CCnZ7tousHub4Hhyv6TWp1bJIUVBvItIuazQQ7K/LUwdqnBpMaPLLiUqexyQkdH56sn8rTPwlssa9seMduuawf7sNFfPgfHXNCLPuhzSZoZOpmTAc/41w7cYwYzhxOPeNlwMqxG85UclPXT/qjTwWbWNprC0AMQgq+WEor3HZVnlpUW8RNh3PB6qSIyQEZ3fxGzaroKtwDPZVpqPFwHbs9I8uqzO8UMmN+os0QA3KtkkDiinuBRpTLRq4QM0remSOa/xuTlvepANaZ14VxwWpwuwRCiSW/Vx2S+Og2d9r4cIWv6/BlTXFgCSXx7Bjpr64jM6VXSsD4GoxABstj7qF1/53N7OzAubzYNJNpzcHRSMmcgJ16/UQU2lKJJ/Vo0KPjpVkZvgj9uKRD4UNy77nSVtA415/3NvLCxGvTTHFR+Ccm7MYHihSphx/VJrERFTRkBxscLMXUFe3bqpmeUNhA1gaxeBURieqIa99Fy1WyXAQ0OiwZ5nGMILgOh86WtneYQ6HyZ1Rt6gvfYxuxrTEwyQ4h08py5QzRlj+H3oGa9R77TQLW8IWryaQ2yFmJxfWt9uqpmyCxg3ueAWtnH9v7NhzcflrNOD5xT1+OJwb6M476T+KMrGNuzPp3DJXDzdQs3hhHf7GNPWHB3nkCIy62g0dPqfwTh1B5IbYhKrZC2lWkGjK3+GszkMVSs84P/gvWbkDiR0d1+m4Seo2ll4LVs/2/Sw6c1MM6SVbw2zWsV7x63eMn1tJnMSWx5umHHIg0OhUSviWPaadOz9klM90nSYLEHfr82fD2ECpmYoByxcduyhcXA03Te6INtlhBUTFLSkqQ7BOnHb5uEAPgCRPPbiO2sLGi1yJd26nlLYGWQNlRrYOKVDXaluI8qmMuhIfb2UJF6tMQigiQIc4zioanrB05eoIGBTa6EMPNHC0Judd5i6Q6AD8XdYhDQwgyjNC2srScYoBK6/d0q+/5NiJvZTizUcFLocKaI6iemPIpzoGNZtEOXSQxxPbwDN/K0VZUduLgyr029dMNXKTysYGzuNZNLrGFg7nOIgSj3OSDrNyuZnF9q2qiSb/y2IydNe08sUW/V5mV7VUnmDf5XZvFR20832MoFzOUS0Z9MEdplL842jFpkkQHHtnjBz32K6POQ+zOY/Vjix8w1mnTWvzYRuUYBYETOza2c6AeAHqa4qa9WvYCcc9qKKhwkBbs1BPolJVlBSRcklgxWwO7aDqzR1HMGq1Fj7lHmcSYq0pgOMvkTCKM17P54mm+Y8n64WozKItLZ5MfKyokTMBuVNq+EQu+ty0BMHSLg2DTSOfirCK8EeKMqDJOunl63YKfRhuduByqrziG/k02ovDjANSwlM/4AzGhTCwlh6V+9Mt+hpoYHFqajtjxodt5MICgKNqoSBxBShWA/tXDNrjUtnFBccyRYD+K8K1WjskyYl1GJ3Zg83afl0TC03lvH3QS8Us5lGlnbOAyL0rxm1IZ43ZEkRiQGCEz+AlTNUuB9SodHHl2od+5gtd3AQPqzMp45yixeGZm0pyBGaduCTeNCcH2Joa41LG6BqqI8MFQrl3b+FIXBb7w3qvM+miy6NUefvUVKj+gifEm1ftWt/PwfnCDHXhs+4wdfiau2tLPKo+QZe5VKDb2g49APD7H1qtFesRD/GNLsv/mWmc8cD1jmT5y5j+w2KMfTOadmXIO0lA+sQeijvSzeqPBIAU98wmINg3mVLvFyCBkMIMFp2Ht4dFk7FkOFHf14eJ0N250gWqDOuPLKptsRBqLrJ9JDG/6FGTr6672OkCeREn4cc/a3QiZMQpZqXFHQNNogxNPd0y4Ci2wowrEt+p9W20eVR/t71kqbhAEXPVhwbDz9ju9DbLOoosWSPnTMrTAJwTV2BsB9VhqhbC2Dbbo48cugwiGmACBp6mhNXAUdb7QGBmK8uhrQ++nckOK8WjLF9+coRQTB3HgLMVTS3vPYGeA7K5jBrq8+PbsGBC3MZhPWS6P4xoxKrGdD3nso6c38m1GvKd8VIRRJDHDl3LPXnSxvfLqEXTS0iDogHQ71vjVc7jZ9BQ2O/KIxp/djBfAzkKa6Y+Jjt30hZoEiNI5jgxu/PqMFXP3JgliBGMSEbeYta1+cRDB5WbRNvoQwAlHuUhi+FxdfYqJYWMaLC8S8C2X9fTFgpu35fJPf/j1wZhIqszBsd925wpdE11n0xh2LqIMnX5iXg65kHe8Rw5QXeJo0/mol/KQiIERS9dBgcpWjmhw1YJPi6UyxHQp7dcDKwQ1NYX22jG+LJ5VofY8AEa4fJybJVhbsC35FUnfEdOrlVeTDKYZhiuRKOxGwro8BRQiDP31HHQRYDFAd5Ow8MMz5uavOoSu9y5pPfSNYONqHjzqNMzWGBspAr3u1SuXwGyuiQ/ylo1h+6kbLfG01E34WD/8fzXPCvETVENKBgs1Y0NSiyDbtAuexv1AZ/VE6ulMlVuzfsumN32z/JfDzFs+WBIEmhRPSJjjnqGrbCjV5zjIDUsrxEuOEXYAw7GDkmrdoB2F6wG4ZXymjVoa5A2kFbrELx/HAa3bairssngwi8ceg4RYuxeDQ+Tl2Jphu5+ADpzNTwHDnJFgEK2+bcY0+vG/uE0e+zYUFD7Qq5ua/kmEyqoHU2x90O9b6chDVP29EvSKEJso1k4MfpFhg39tXx9wtc9y7RfTK2Ns9UNNHMg7J/ZnPtbfTEH9RRfkwces7cjgod+amdl2GtgkjnNOvuBFYDCN00x/29uAX5iHo12186Gfq1KXc4b4IbTXQ7AP/MgO4kPp/8xBlVDIdaxg2AXFhzOArzSya8wL0ucyB4n4oMUz9UxMt4G2PSAeLiDokzx2m5U2Pf3HovY9Bu8lF7UkHCxInIWdxUg3ScZF+PjcFQjDmpgYGDxT24SN3cp0z0jkVS4+B3ctkjFVjptT4HKaqFEooEonAXSWiAM69I3KQeT1iG9InbsFo9eZi21s4OZUXPrrC+HIHbn+ubJksJYx27lAs6oLMPAgTT7qS+wUCZ8xJArGUu1M3OlHunP86WLwDmPCooLlAk8rDeOQrv7YzJYFWXPYuCY5LGPwaH1miQoPH8utyWI91x764tPHVvtgw9FEknp4YINjkxtYMOcPUky/mPCG5F6lto0OG98uU0//+MIvP7G9b81rs5j98viJMXHJE3L48zhJz34OygKqfv0Gi//gaVB3/Mhqgx2tg5t+bdBdm2Lbj3h0re1DMnIbtCOqdCUr+xn7rhrGsQUO1msSlNLM09kEYNaO+q/KQ8lficigTYLMHgkQdYT5oJuv/jAlpAnOcjTuayaPT2pNRsBIrlxgufW4zyXCEctGNEQ14ZoU/cs62dJejAo9B9xBkp9YcVcH7lGnxo2D7A24KgTgLcUKQRyaiHFM0kBBJRiadNseI/UrQRkMKM1cLc5WGToj1WFzywQfoXLPYlq4E8TQbvEVx9uDCZeaCRw14TENjXWE8GRcag5VugyX02gDrJjBMQcFnyHztj6Q40u97r2QZnyOJKYEdHHYtccxDhLPrB2wV42CXVpQ5PVXPuyKLRdqxzsER+8uvP5pCQl+z8GYuLnrLBKEISQJNX7spo+zCJGbEODUZOqj++yzGqD1qjCG9DZhoeNUtz/yCOBfGZi9oiTB3U+5a2vS1ab94g3VcZAs6yN1iBl/+9T7LP7I0yBm9NYMXduLiyq68UlLP62xaZ+6HJVdPcTVDDY2lBcvRpwaupatjyBS5mz7R7+iEbijp81asUw/c5tt5a4x9lVTL9+kgVd127v4piZR9toL63xn3O2kMoJMihvFG2XlYOAW1cxaMMHnSMdNw0lIjPagksPbZvawREp+7iBwWkupbUPFrhcJuMmRtJ0YME3JAecUZnaadI/3jxeTjubA1tZhxN1L5WhysMSjw8ReNzM69GMkHjAzgXRNJSCeTpPdJqNyBQn54LUKpXedoaYNK5xDmZ5N5YTNYPEABqw+9NdehPj3fcDhAHTRtEhivS3dDWgCNzaiq6E4LJ0sZJJj3agi+nAh5Nqfxbn20cNFwjAad4hk3dhD5ulNmzHik6rzxkuplqPDf+dCTJZQV1FHgA0c9OBUquxJEsi1G5vhMClNG24TT2zh5wl3ryZ7BQi/yYs6HTBNdMSA3dqmlhd5cavr1WKxbXeumlB7GdHf1gnm+Il/ecLn6Vl+5q26+m98+BRnjGNDPOG785U2/X2OHgE4NPIMF53TVx8EpymFsZ3NAB7SKTS3Gwal6nuKj87GAF+b5TEmUgbK8bs6zb4YuRwXQC3o1t+5YHMAXcuOrZcl7MVME0c+H5A4R113a4Zmwk+j2RET2SetpR3Rs8WZ1qaJEJEI/wiFIk5t6ZigHRtsMVdnm5ZJM0djzpG6pms2HrGoAiMG74VY/izbiqEH04kKQH5iu1FrIy4ygeCCoYu1a6IhCJtDo27HwIw4aEoEtBxr2os1MP5APFfsgXECkLVtpGPYWWLo8xBDRE4XXuTtX3PK9op3guZ1hgDyygVF2tcPVLVXNsriNRK7GwOWz6LDitY/HBBM33YQ9Tl4J8L5dLwOHJaCTkwGGzFUE7ptLo9YPZTG2s2oW8FVLoaEh8S30AHZzoENzORoF+kmisrLrW780d77ktiRDK0jR/dxtRjnTX7lJ5Ymz5XXPzKTIHxiNr7pv74ZB7yMRZ+fXBtLdY0nMOMgvsY44wro6BgHOPjBbf22o3eurIdjZRjbLo/dEMGlHN342L4OXQ4DAnOUw+96QNiC/kMUQbxExI4cezAkjEmaco79VnAwR29B9hb/QCPTawLorPRlSodCe/nCWabEYfYic2SPSOnbwZt5YKGTSc7Kj7mppXpnjohIYqVI23f123MiFI67CJpBNMDfQOHhqpV66Nt2zhqWqiYefGPacdQIM+lsTHIqGQBbJiE644omGy7/6iKSGO48DaZG6RgTRjMZ6xqcQWAuCAnnIMkSqw6QSd+h7looZ7DhbFzY50kynPhIkNDJDBvYnQ2mwDZaZ6OfXc3puDOgYanDdH9PW1boo5v2w8hmYHGojp1Lw96Fe3bAWYYjVRcY2sQ13GiLAHBNVCOKK8QmtqMOR+ScI7RU4PU7R/ErT004i2vSqg1tsOj6DMvKYqSOWj+DC5APVl5ZrwaXK3Vsyo3t2g+fXG1vUrYOL1jajiY1N6nobszEyFjbx59IZdVVtvMFNo88GVfbO96IHSt6bEWlJgaMEDEXo2q/KhSgBmPz6FdRu/p1VYKvWTkBpj8izUZ0cBXencDKK+/lOoZP4ysnqq+y/G7iLGB+S5FPAYhy2dk7fvlxzTIQb1sawqC6/MeSPTvm8HI1MzchKy03HOm79Z1pDye8pG2iaLEBHA95bqJ1MxtHcewG5wjc7s5lwR5xNckiZJabTUYt0ZhOrqhfZFkFmBsYXDseaP1HaS+JgCcxEEfGiJhmxyLrQ6NuF8e8cPUT8ZiAM8V1lXae5VpOQBE43c5tIo5FYzcW7BvEYHkJPAOd0OLoxAB6hgVsC02eyqDcQtu8HO3xVcMJQ2T5K0dgK0JqjtVsHWGM2YSjsM0I6SufkyKkxtAu/IwB1Xmm0WSBLD/26xPO7WMgrijb9JtAmuTePsmqV5aDebgXBz8JzgSV2kQa2Sal4tYHfBe/HNo6nkl28bN8G/ti6Vc24398H5uNE07wjmPmQ9nTXszg0sX62GFLsQ4ZddutP/VCsVa5uGO/tq/glSFPOZxu0y/+RlbkPWJzlu9pXP3byn9h5L13/tw3f0x9v9SXTd00FihsXY1psG8RRWiW49qFnen3IasZLOmSnyS9JJgdRsy4SvJMJAMnVRksKQjiSZruMdp1hv8YMpI80262anJtfkR3fXgJ4S6ODNPR7sZ208KmAju33WWQKlr0KPHvP+UIDofol5SOcXbEsLKttfTQpiaPP8wyepykxZHZKi3cO+V/fsv1248seVELuCHcOOI1VP6RJtwz7x3ghMJw1gODgCPfPqj77FZnJ2bJdPDktOKUmQHs6J5hSTDMchkzo5f4zkBP0AQcPkKT7zFGgh07ewote/JVXlnOO75+gUU/7mV5k4kTGADz2mcdnEQxY1sdeES4oU3d5Ias/fvW+asOfZ+bEItlide2nE2A+IRfHzmsrrK5Ig1mudJ0q+jDbYAuVnLUHuzlXR2yO56jx+PgU32208dPIPpce2rKwU9bmXDiqHCgB9tzNHogCwCfQre7ezpTYUdB/57n009jdmiXU1YzCzxlTbWV5CtHbA9oAanhpiRRslcJq1thwZH22iAq17pw7gXNxsH9sEyeyOhyaqFTXqbl0xy3fjOIuUk7DzcvoHaNgy1qoeKPbvBdRkqOcOO4Q2da/KJjZOPJhqCAK4OGFj6NPoJRKYOaIgYdnexEBkMxtvZ6BksrED4n4uH0uwT/nVn5npuv+SPGeQs6LKGNrdONvzokLRFi+mSnjNcYcvCRA/YAuBLnfm5E6xax1rKgmNJMp6HwEPBWGCJRjmfamPifx4gEtriQD0U5nTmDaLRKnZrqQVK214ATevyskCaFAdxzWJkwYhPjFKhQHlnPRkQZAwkkJL3PNZzKAua/FGEDHtXarwyhsjSwMQ7aUEdQPLrRq6vcZBckyY65FKMP9sXg89u4sH3jVOZfjOR8/8Zv6OIHf9y3xDZxZoWhjG0UJrrI8Q/X/mUg2+l7L3J0i9n4exVLjBMDOGKkn13cdnmx1T5RpqmOcVHoE5t12ojp44dSObwjYz2gj2Yg6jhoq1UP2FDKkdr9+thVLQAM1JS3DaclQuSuAap0ji592q99Fn2mQofR3CLHdN/2RdwWiTIPdh8OOXE4SY98x3hz8KqDDcwHDDM2YU7h2EfQb0cCiKxssNYbbGPMwNZTlRGUcGagUmej/zpwBFE3QMKjE3lCHBfDxVebWIl1EaHJQf61GbojezCBEB8qadPAlRw5AwpRgJnadg7ix/JPXtIRkOTgoMocaJJDfTAKM1+HA2x4eHVoexzFIBfvcZ9Bx1UM8mAbGUoP9adfmoSCXv8I8rSvEkBEu6oMjldNFsFOqWElQkyxbKEF0rUxkyAv8oNLK0JcrQwT1PBZJKqW5kXjF/u1rM6kImM4RleKWsub5lp1ckQoky/dJhjiwEf78o0tPH1GnwZ4kyj49LU5tt/YPWSohIxnMBB5SY6dZ6k8wOT2D2HBWe7xEXvj0GfbvTLMck5MG//eczxXkSEJbbmIAfdypWaU+EQ+GFpvPPa1AZ+faTs/+PVZeZq3zyRt/7Ff2anR0UkhLus9sIyU79lXffHoKjIulhBLQJpRHL1IEbWZnafJ004MBUEVeebG/vLQ2TYN1u33Jj+3LaJhSJMZIyRfkNjhnFKMWBD8JFS+PEk9jzqABqaAvZ9JL/gI3HZg4cnzhCPzSu1cDF2S9GTxIYssCp4IOGEljCzDYlUNAwNCVTV4MkIEDCfQq8MkMh6IUbSbxnAou8LDGeD5gAMOOqzwLQWSlGxxcjofuqCZoijHxId+F2F0m2CIh8gGTqBl5gXsw1cQxVY6BFS7UDs+vIVSbMj8k3kTAQQ8ouSuQx5NBOweHKP4l0pMgwM806uVxh42chHiALSHy0yEo2PdlMlWAJ5H2cBHELWrFN14IVxk0hze2oLxiT7tYsNEPwfqk4yCUJ5LNJIOnLm32PCSFFe2NVhO4eHRHjt+yyO6EIjJAR/wrW1r5LU/usO3OmzqB5vji7bjmXEt/45BmxkPMrA50Aq0z2m7DLEPhqJ+cRVpqw7987QzmLUTFxBrsdwDWDsI3iUx8kWh/uBdhXUNHZFAqEhXlBGUPB2wHa9bKt3MnwTEaimdTT/MsYWWzTDxp24SzIiwc5OT+LrpgsvDl05MeGL7eko3V0AEnUAE7HRzXbRxN6ZuAVczXH0Uo/+gcK2XxJOzCjNlB4VOe13iYB6OSy0AHzt1dipts7AeC9Un1DPGjmamYX0zPBZpg4k5q45Chc48o2RdIskP8xU8sxSs89Kxee4QkpKun+GtyUxhmLh6bvqvE4YPHwcf2AWnDAj9PVITTQr3J6k4FGuYLKDjIFf4XCyJKQz0lxLjulD+NCP/6AnbAa4GSGFI4imPKyu1WOYt80Xbp8L2SRzOn1UOBJydiS9V2ETMqfLKSdzK5OXSIPC2AdN+E1IET4KE633LnH7e08JPIjzfh+RESVx8+doODDcTU2M1vmT56jahVpe/IrSL4ze+YG18GRdDqx0xp4OA53DTWxm4Yiqjv3p1dFPEq1v8yLWvQsyAmW79pWYdjumtV1AasdO0wvavyvrCDwUP7KXjyQAqL2KPi5g1vxF9IWTbRiQ9jbz1hoA+yyUtdqurg+6GkZ2Ry8OTLNn5wVSrY9tjkIpHe2Cga2KLLNcnWkRxNi5ivU9tP21CyU+OoGsgrYdxMWCrYHj/bxm5lGFBrGgmaFDI6qNWDhlc9AvR7kxbdXSzExgCc+aQmBJtGCJXtemo35fjiEw5qCQIgiFuEQxoBdR8uNLExCjymHlvfD0L0fC2HNLYSkNkJAblTlU6MpxxnfEpCX4FwdHMBaanrWchoo52PjAauro04DSnjEV6iHjCh946bUs62kTOoK591dhRWD8tiT9tuitCY1uZwz86pv1YMhcfWNZ74pQs9bd8mmVb3CYzZWSdk1D0w6mfpLl1bBdD8vWHeI4AAByfSURBVPMZf8hWzje+evVYrIkVvgD4AUdC9SqWOvbfuNnJiU2y/J57nfJmLOXveM/b++BTPpKkOGMOP8l09PmrQns2ScPOWYdfzogszQoxGo4Rt4+z97lKZKcdvzLNIfJVUYPbNbFyg4xu5Viie/u0VzoRh6sMX7FC51C7dn7CsWxTdoNBx3vmnIr84V5WSzJgwvAz7ygjMVTOTkZJ5kzJb+2wSWnaaOJpny2UFh0btrhdnZuFOQ1lGFPoAYutjZ2dBr3py4Hrm4Pn1e2UTmj9EIdI7MZ6AkDHkCTt8YmrUxHxRgMwo0LCuDUUj6mNwSakxG0uUjI67y5kAeLOA/53yERyHGnQcNOUHlEowZD+qsz2EEpALf1cbce0CxxHwzM4witXFH09cjYdGf2Uxqj3Wq0Te5EHjIhYDop2T4mxOb8MMqi4jMykI1MOkThRbmpmgPOdH2Y3KyoHPORBYjhl/KqiXYg4AnH3A9amhmAUZdDqQx4vRiNBweqiTxjlJXm0jZPaZniiiSkSriYPRnz0TTprq6ljII69l1juYENI2w9lwuSHTN/DSxS8wDKfTxy089nfJEnqXo0Sx++/k8QXn3p/0MlB3XjCc65ywfUDqGubMzVjy4AyVyRix778TGgK5y1XxC5fVpX+I59ky1bJlMYILLa26AQzbWQrh2j7Y7YW4llrW7CnvzzKY7Rc9BfTuRBxDusHwfIio/1ybHt14G8pWl2WLLdLUhwGy602zHpweaThlqEOLm3WuRatPNsIYlwV8g1p23jIzLpZIwOpOcPthxYMuFlKxfTYjGDh422htfysHNmhi+T6bGuPq9EpSFPHaCXARXgf93iRdKbjT17V/bNx9VSH2DQG4KfcKYoosR8yfTpwfpeQla3XNHXtcgUTiGRMmMY7seDVTV1orgwC0GQEQaXF5cswyZK+yRPujpuWQVnnVOju6GZ+o0SEC/3mYCqi1lDXu4LYUlnEgjQCM8NgqfS0kS6EtIsnWXRUvnplQ6TfB/aLFJ9PkDtZzirYRJZzhXuGkz9qq147bOHhQEy2W7MKESjDA23rwQ0eHBiSH3oSBbImK64E2/aKEJ0+ZGLK0ueQIMGNve0c/h6VV5sxkne4yo3tPueK8+iJKT7yXH/E1PjqRx9I9Dt4MNxvnTEZpXbo8dUkGbPTTtMEmSpzwDx3iSHHhtIKtitDjp+/KmP+ydNlLSl619KQvO2Xd3lWdvpp7DpUN4RTHRGNcme9d3U5lnnrLUVHJ12G5QcoT2yc4JziH/mb6E55E053j1dUYY2sUxdv7gT9I+sEsnCh9F7nYISwtmcqiTw9vFDb3bMgEcOg1HXbHJGPjhHGRooBNJdEj9zYM4p08cyj3tLEV/rB1TkvyfTnqhG6jtPI0mPQSrPwxrAfcoHERSPtQOggVhq7qJcnDZpypZ6GQhwaV0fk2Eo0Q9SxBBKGp6ydx5pGYwaDOhLua+4L17hjwAZsWJ3fE11k+C0zQTZc9cZcS/p8zckAWDFwg+1FJyMmqLEui1d7cLDsdJNNWmKWnFdAEkTW+UiNnn6evcqJZmWgCD9kfh0HDNiapA0LP8j6Q3j9qczEFMmboNqODDs4rdunvVh16MU8CWxl+E+7zyTJtPfPoqWp3dUvLzzY1Rbutb9+GQH4xTw1sfKMTltGC8fIkVGQdS6mj2zk1OHOmSqYeQfV3t1ti0e3BaDyFUytbQl+1nyRv13ab/+L8c/dDQANbSMvDB6709g+c0HJcuUbf7TiNGPOysrWUR0IDyYiXwTM1EXrrIwtsPzBGAwzQZjkKglCdxp92nSAiKkfemeEkoG1gcHY0UCmcWv4OJv78bJq9MYWKLsMZUpcvJTQ2OcAgvhScmUHgQ8FiB1zgIUo5jDEbTkqEO74NNiV+akTsoDTkK5TIglSOTnYUNxDVPo9Iudap7QC34kMjVNPBvmJBijn5Yx+jBGHWg5cMGUIuMpkYGift+bhAHXp2+0kkBE6GWLmZdM2BwbMUJyTdmzjaYLAf654d8wl9/ThkVOHj4AzRm24P6ftR1zYA6v9hx57C1FIdWttRhajTSrYm3CCN5GMrqE0uYCtbq7+1mZqvBHPx33IEJB4jh8xkYUI+X89nPi6MXR89M8V6okNXH0Vj2f87LjKE0jjHfmNAYGPjzmESybIVo8kbbiv7C4BoTn0VLtsEZ3ydra99YK+9hvZar/0FvyswYtMK3ogql2Lt921Xsy7htfm5dENJMPHXw9y03Rpu78ZdbpBeJn3JenAlkUPYogbTnYHG8SrtSYz59y1btQ4TYOtmVlnYiMouXtbj1FCuwaYYFBXmvMqZpKAoUF2s8Kd/vkwBxotYpzY7D7U+bXD3WQw8fY62pb4aKjpjhsjyIFwCpwKCPG6uweeeJWlxo6bv7nIyhUcOC7ik6lwkB5zApPdXY0bLwgw5G0DoDfXw7+HzC9r6sHzFYEwo08LD2umt7Jx9IVNpQACQNh4a/daV8fRoT5dZYZAaOmdQLO52HmW5SLM+PCGHmeVn+hmfJiuhboQeo5GWD2adVODnt3I6cJPHVoSA+DKmqyaTBbbBADjsYuNCUNT/Ode4fornTKpozgJK0b8vMlIztjCx/MkPPqR83ZbHnwOF3PWn3J7dYdeno1tamT4RDm1MdgbG9jij0IFlLhaI10ZrQI5FptjHkOvDDmF8dBmzaXFfVGXsXWvGNSDBScWJIKUrVkZt6z06q8usqs+YkQfHCwntChe/NPW5ksfkw+e6MWhSIO/HhR9lhXvl5pOquk6zjVX7shsWtQy08bKZKaw494dHjKKkzpYpWEMxtwZLYCgddW9oSQmwcKUQ7hCMh3B6UMNwnfA3tuTo5FKqOu4x+GUJTVeKeRgHI2hIRtvV0xMG0dTTXqFGBg6BTHAMSeMZyzyYKkSUw1Y6CeODqYXu4Qmhjh3zmj6pU9tGLwhz+j04ViQju6p0wwyKIAgct8I3xkjYC0V0OJ8oRQgugf7jCP4+a2gbiOI8vQcZHHUPjsChsChy7PzCVUKCdAyTnwHjgx6tueXAozllOrobOAiJxufPI7yAk1C6AzCBYmbzAGvfww/shy814acTmcLXdzOmQ6HbqbmdfgkxyjwTfLjLOclLle70Sr7PWcuV4/zNGHRji/wfPioXZoYcE+POezV5nBm7NwaYAquH2S1aRJsDMaPHGrrlUfGtCDjxzqYnVex1dWu2JjULkLsA1ew9gY0GABg1sdAFWb8XXNBhGraYDORTSjAxeqjPfs0P2ScQAveWmitdGu1r+IFrx3goZlqUdb/UPZFQZdB9YqScZFC3C5Z3dzHZT8zNey6SWCKjjt3I6uRkGIbUAswLqJcmIVHxCy7tdg9foHcHqM5vL4VDF1+t9l5NolzAQoiy+Zbf12RqcMpp5gcQOmRhis9vtsERYfRgWFf1TiN5x7L0TEtdIjX2pHw5SjHk0WPNDyjD2i2HGJNbOCXYsUYaY+MFcSqQsYxYscSF20xrjFBZNBWzjZ2HR/WXqbKxLKLiz0nAXEuUY3f/QMnwxdwnRvI+Iwukx+TnCM+QIt9wzZxoY1g53/c4oErahaQd2+Iq26pDSE5nBXD9CnTj9RppWAbBd+fwX8yMrBESE1MqfROBFjMUSxdJi/jl54UIyUBpQ1ViygYkaubdtTpfsjyf1I8td/CS0Ik0eABdhKiH95oF136Jicw8AShLC3+ayK6TZzWzmuY4pT13TliEI0LDtvYpkUfO9afpvSJaf2r1yRSfoiBY2vGRrf+bnvEKMZGGGbtl0K7aZYVLlGNw47zOuc+J1ufwxOVZ2FtNrahOBV6sJRtL0+lzzEAsWuwKvrjiE2/9su3sH+1xp4vnGdp5ZEq5H/m70PyEtFR8qoeVH5jIxBOKgFMFLzz0ybSbMDGxWrPkuYB7Ae3PGeCmLg0EWdqWa9VNCmnE5vuhFxk8b4YfdEl8YbiGIUdF+jridgxd6EFtBMIp+1i0QSYD5WGuWNKx9gQ4nerLMoGWvodSxFz3Dj7SQ7xqNhVcu07HOS4MQBXS50aZVUdEjjuG4bOuYxNOoAVZqihcgqCwEvwJWWiCTxCvW9AvFOPvVtSlpi01LzsyILiCy3SRdqxzG9HmTsAjXF2sC1DSwzWs1bkARqE7a6ZbnVcc5qxngAAzWkmMzAMjiYD5pWBwYUMPyRnepGRSGa80ALBPj86blv7xUfu2DqP/rZMfJCMmgA7BhOkPsrX5Jc28Q0fvm+7XsHJEx36jyRJn4gyBuSNo77LFZF6uOTmnNKwj6HzgAwxDz6FppFjxfCj2Dpt+2ugqYcXUwGSiy9f8UOuvhKAV8esZkxZO5ywW95O287/ANp+MWupDPWWAVF5mtNY9ah2C9ZiheCX439R93uUjDRzn7Hli1WZ6R0js8KAWRRcufhaFi8sUk8ddcL1fXGNCJ6WJ8W3ghFwJQMwR0vPg/OLT2QjijmgEUkFIP21JcmiHjtsi2dpTtNGSRRyUQhBX34Jsf1AplMRYoIkQV7JYN1y9b24J9TT1G2w/Ok1J8HZwKJjXF4NWNZReNGaGRDPaNLuvKdZl87PJE7JQOSPHpv0QSUJgukszxmMLx6hNfgeJx7m4sRCECkdd+A7L5GTXP2gZ2Kd08HY2K+QcD2UaDJAu6nT/rF/jigy5BS/DjhJtJLOP1zpA2vC6XsIaMqPrx1ETyMa4pTaRt7EavAmnPI2ScFR/jFyvsKrF/+tazhdImGGi6tk/UY4S+fIimPK1se08ZH9Unxkf8fnPIl52wHATdnkSA82bXM4cm1GLgJcn0PIiaiEqaNlXJNfq8nOmTmw37i1qzFmh/cRnTiRrfzU0zj9YFiDM7SDX+4yGCKiKWv9LMlHc9DApnNkaTBPvK/actluvKv739Z86h0XuVrIe0sviphy1o6142SjRMbQiQZl8Lwt5t0ZQP5qrecgmGhdeumby+Bx3ZdwdgZEWEIgq3J7SFISF+pMOZez0Rzoi6pYtm3eFAdQFY3uohJF6LAfdXEJec4wwBY0JOEI8qeAehXTwONJM1W+A64Rx2MPxtzuaNKBp4OJnFFKpg0OZVTMIf0c5rUBfOcEYMpMt2MjtSf4bO6JKbaMRZN+HYC9n3MCjmoGi+feKUmNiWmxl0xIUtx8w6fEMBgYv7vDzIbT7Y09XlPO0Hpqs5pJ6s6vs5k+JvjkYGbCjAyBgDDRp1CzqCRHLqAqeCFgWNB4rCF9dcpW3+GIDYwQeFLE6oNemJot02rY4IqhhjvPYDaeSZBUjYIwmargOCu+/S5z72XCByYGtWkfJ3kYFyPxKWfa1KOX1/7KF1v79AxcGxdacczRPPQbF9cX3Pjk8NZf2oJESGVLk2PHyFl+VupZmH1dKki9mh7UP32axxrlAqhTNsac+jecKv9Dx3X5Pc5y7cPZ0hdzuLoIu6kMiXXmDLPHvpFZ08uNySgzF4w/CN6q93Ur3RnODDVXl92onSS9BWOPNDto+zlg7e8KmYCwxQFBRMXbDK9SMxtjh4Fbtts8Zx6LFAmLYq/1gZxeCgmDxW5TFsU9ZFL07CVpRAw5fggCe41yvLvacUgWPQuZ0kDw5HpMfqlvvPIQw6Hw1DBEzC7iPhkcuhG/HSWo4O/pq6e84kXMtU5Oz298PJ5KztxDMXqP+M3TSlxe8ByUYXCvkbtshArET3NSMxrmP1HFAfheb9LpeAOAjmE0rJ0qxlJRPHRQ4VssjpQzSMfMdKeFJ+Gt7U6fM2JM+A41ayAXrhERLtOMDeGi5u1TpsOZUZ+B8QV1fheK2Al/fz+b5OcsYoNx+MQwLoD5jJMhrJ01fZ0uFkRkRT4f/BA31xpouiioiZvRegXMMPWFC7QoU6fhU95yEyd6a/SrGyynjxfQUB6eiNrpFNmtcuSrny4+v5b6GcXq4yXx4/KUn22rfl0fMA24DPpK4Tii9bXqr/2V/wfqpf6epcUq4s4QL5zOZarESv7jWnKGiQVbbl/6uHFZgwgzhGQbNgKxYd8SWxJBmJroGCsy+dNBmbKJI821hCXOgDhxeStrnw+NFHCVExnqJk7kKX7NJyyTPhheC/vvBKYIg3wEpeGB2eg4AN3VhddwJVajbxQISeXU0nmkH6wh0CTKgHI0vTfZMugIZ87UziFV0V6yB81ZIUfDRZn56ujrmPuZbCgo4PdkMWWdYl7SzJ/Zjjj1ARS6gCLIEzcYyBMQ2p0ABgNKGcsibylYLzJ4gAg2MBMK+nECsDMXhDOIM6+0MswmovDHmtGqy+pjBJIxJOQo1YNxRpY/fzQq64XcwhJleaBJHxmuEgpu0uBFOzU4woJmsMONXew5TPYhaZG37RJ3OPkk219RlAsGwwUnL3+0Ypp8GKBNKn2sb3hYbdbwhoInt8AaK3dV4A5m/DALziuxD18R6eCQKmVbF6Mwg4pOUHwxxpxI+nIWkmPtl0uBsrYqv9pthQN6jENbXrr6nMgWi6xyEH9dSnox218uNP8q12X5563l5Pzx1pY1kNVvyVB5j5SzxTJx3I6aM8XgO8vIA2GSY8ue6TRYzWQZejhzFnBowd5HDo7ScxSp+zAQOHPYCccI48YXOcsKQbybtGwSG9EkHIYhMYqUaRPj7RW7femqZ5HbxZTCQhqONIqk4qHDHBxu/4RElsZMxPjFwlWICdghsWtngME1FeE1BXFex9hBLLhM8FGH88xaZkRe7iXqCzfjkKH88IXF0xmefKATNd9i6CaOoJNoEM4RDufFSGrObZy4OQkrejjxulMV4/EIACkRNoyl4nJp9w2+YdUfuJrRaFtrZmA9OA0jjW2vvkxIgZB0TC7SwN2AwoYJUnwb0/pYn4y2c5F1AxHTRy2A009MkYHjDkbk3/Iiwe9lC4tG/wHwVaRNnNRQJLllhuGQp9Q1YJbmXTvA4zKNxkD8xIfvDWk5rdVmGzifuosEUnyVD1v7qSlwqqMNRunU7BCER9cFNSKxtJFey2Oi1ORIPCCYuJxnsOZjLc8prW/clVD7z4A+Rb+CFfGJWxn4jmYl/3699iRKRuQmzBRyddTkqBeSZ5IoS493IqCYqaCsM2amfdZRLKIjX+Xp1MDhFWAY6jE6bJibHtMi96YDeEqvcOEpyljUxXEHL7Xa9ImMd4qr9FzUYayGmHeI/OCxSXEXBczIGcmAEW2JaKREzoZzVxJc+hhOIecUmlrNXBGzWJilA4ZosAs1dshqyhCcKFc5Lw7jCEtQdh0RE1gpXI6gLya5RRK3vOUiKRFR8E1czDkhIeCAW6occ8rJg+xMQ0mbOkfOKiZ5v9ogNEKVp2/TQ7lTiIyyO11/YcJLCf246yQAmTHqd9GYSMjyRxukx4x7fCBMPIw5593pQezmBIUoNfOdWv4c0sQtUjng4ckxKEZl26+Cah6NPCBytZrxZSqdFlzhXA7bcOCLI3ZlbU27skyqL3zyIpMIsHY5OLuYOUW8Jh1bxrA81PxEQCJWHi7GyrTlCjSnl7M19qkxVj8yTotv9enHVlNnLAJkrWyc9sjoH9lpjMwZLpB1uWpmjLZL6bUHuooF/0KE3aPG6p+WxX+1XXf/lCAAsFx6ff/bH3kL7aeRpptounMCIEHaZw0nN7p9IjkrkYxDH0UaWU/tw+w7yl6kZo5CtOs/5rEJILK2YsxS5NThcMSwQamAY1ek1tgR/diLIVrfZKWXWHMYbWBpidmPHtCxaKcIDD2fVIs9BgAI/imE4dtt/KwKhnWZ5ccuV5vk7DcC7LMfGRIF4zzCBLYBKDLYHTdD4O0nC//PP/JSxWsYyxuGTrr4353oKGdnQWhonjLyJPDYcqiOlv/+AS5kLHD0lNAQFH7z7ARoIH+Y2Z5wA85BX2n6IgKP7SGL75g1rQgeP3ggSf/dZdOweA1iA+cYa+7hoTSOtBlFSQ0h3kBHwoNR4uRb1rPzYHiFdzSEHd6G7Z8ZaztH3GV6Yasss/wt76ti4ilsEuTKjWTIknBqeA2a7N0Zrn2GS0h5Yodb5PNcHX7qq9iZ5hJjHXzcECcT29gUX64A6qXcEDFX1moqh62Mt2Zsr1zmlRkLc71W1w6c0lFdRJcB/b5wf9pg12hpPQUh5SGS41P0qoW/h1/yPoCHWum6fCD/sLlphu/UZsU3jqxalppb1zzG6nPqo3G1ZmF4Uy+TmLfrHPGAkgWtfbejaYtlFJWK/Mm1nGvwwdbIqqnDvRXzFoLbokyT0PzwTeNes2DEGpwM5avoDMSlxS2FXFCRnTqVBi9XEgsD5NwRui1qB584CBNtDqMGwtAYNvdLM2a8F2iQIt6DnkKSrSZP8gIcPLlPSM3frnNaAFQGYCzHv9Hk1DBVwWQ0ZgRacDiExOW7AekR9/Jiou/QEKc0eYYkltgaW3jQeZrbwHnsnAzmwZI/m8dqMRNwjyMA/a/emEJpPy/AkzKqhpwp5pFDdExiTgUvzflTPxnOb/yCZzA/vBckjEtcDRhtdFCSQvURO1II41PeAUELOJCpc1skK4UkN4nOK0MowHgPMG10KOQ2VPuZboBhZOqSYfjBJ5sFTwmBfPnDnAk2TBDz5I7I+u0HTPWjLDDCRg4aU/qaps4onXlu6qDUX9mNURyjxxi790lQhy8N9gL6HGykbaGfRnV5IUBIh3FRb5m21dsePSLwXGtkbMmVu2jQJEiU4fSEYIN4ShHtrHjrxfxV/e9g/4rnV7rl5q13vo3Hm0YXXE4NZ8W5Z/kGx4AzdhKLN7gyZu5pkqBmPfq+NwJWvRdzWTTus7nvyeTERWRM5qQtqCleDEHkto0ANFdN+SrOqdNM0SIBukRjn6ssNyueXa3aJjS6wRMOxPVEvoqCmwsAqLY4uEgzBUHnUIv3VG/gzIT22Do9zbhSwbnjYiDQOGCYMn5XIaBo8MmcyHF9YmZs2IKvD4YcEm1j7FRGyVYiecc+OFhwigntNFFl2MxJ+h56nttDOE+T+EwLXFylnr21EwQxlokdJ+lY0doGwzIKziFzY0Rp0/LM+U4FLRHDjG2iyg7LISCYIyUidExe2b2YJish0g6DQCYWhskHQ+1GkXuGcJfa6fQUYM3EkKDEBmObDiKSW4Ihcwkg1DRRMq8pvkxET0gJhyCaEKPPRa197mUuBwRihpE44sHbCbYZZxyYrNNIDLjTJwf86h8Z7WyP378jaZhg09QdTcZg0CvPuhU94sMltgdklLKmET47CPG5gMuM5kBokySVBcu5zBTtKRUoBQie6dCfJmb/b4tfOM8UkvSYyvypIN5gOIQMkf+TmoG4M9Pkgi6dnJo/kgNJh8ydU897Eq4MjqR2VQeXn+DK5tFlwbxwpZQJiy51VOyCvHSbuLl8AW3J2k7P2GKSR0i1hZf8SXEI2IbD7QerheWYNvHHpaHApn58CM1hQolWb5rpL616LGVwBEUespSU5jDlGoCg9YPYNmqYKT3SYmwKToMewaLdoAABsM/JSIB5KJSMeSwmVshduEDKjnSAI0ROUmAg4uvOyPoqRhzRIInN0CtCEgFX7UwpqOCctlwGoSMZ5SKMVzeTStA5MbzRcFypOj7IOV9ZRKEh9RCNQsaR+CKbl25fhrm8IhzSblpA4ExqMpHmj92e15loy8ZqzuN52z0OzuAYRC/GHQpJrzc7GJtJN+GSzGgzMKKUnWSZXl0kXJgR+LNuUk/CIoMo9fwIJTSfqEjU2HOQXyWnvYz+l+kqxHm1CcYpuX4147Albd/PrCyUnsKeAFE2Jy4EQhe//acGU5Atm2yTTAZUxDSHhwTRlF9LV/tzbXxfxL+SfYH8n7r/A6isvic82r4AAAAAAElFTkSuQmCC", + "backgroundColor": "#FFFFFF", + "referencedComponentHashes": [] +} \ No newline at end of file diff --git a/README.md b/README.md index 1d8aaf6..3cc2ede 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Assets are organized by vendor and product. Each folder may contain one or more | **CyberArk** | Conjur (secrets management) | | **Datadog** | Observability | | **Docker** | Docker Engine · Docker Hub | -| **F5** | BIG-IP · BIG-IQ | +| **F5** | BIG-IP · BIG-IQ · Insight | | **Fortinet** | FortiGate | | **GitHub** | GitHub | | **GitLab** | GitLab |