{
  "openapi": "3.0.3",
  "info": {
    "title": "Devices & Inventory API",
    "version": "1.0.0",
    "description": "The device inventory shared across features \u2014 devices, groups, firmware, upgrades, and lifecycle."
  },
  "servers": [
    {
      "url": "https://versus-demo.com"
    }
  ],
  "paths": {
    "/api/device-groups/": {
      "get": {
        "operationId": "device_groups_list",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "Which field to use when ordering the results.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "A page number within the paginated result set.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "page_size",
            "required": false,
            "in": "query",
            "description": "Number of results to return per page.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "A search term.",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "vendor",
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "device-groups"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedDeviceGroupList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "List device groups"
      },
      "post": {
        "operationId": "device_groups_create",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "tags": [
          "device-groups"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceGroupRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceGroupRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceGroupRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceGroup"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Create device group"
      }
    },
    "/api/device-groups/{id}/": {
      "get": {
        "operationId": "device_groups_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device group.",
            "required": true
          }
        ],
        "tags": [
          "device-groups"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceGroup"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Retrieve device group"
      },
      "put": {
        "operationId": "device_groups_update",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device group.",
            "required": true
          }
        ],
        "tags": [
          "device-groups"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceGroupRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceGroupRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceGroupRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceGroup"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Update device group"
      },
      "patch": {
        "operationId": "device_groups_partial_update",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device group.",
            "required": true
          }
        ],
        "tags": [
          "device-groups"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchedDeviceGroupRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/PatchedDeviceGroupRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/PatchedDeviceGroupRequest"
              }
            }
          }
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceGroup"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Update device group"
      },
      "delete": {
        "operationId": "device_groups_destroy",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device group.",
            "required": true
          }
        ],
        "tags": [
          "device-groups"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "No response body"
          }
        },
        "summary": "Delete device group"
      }
    },
    "/api/device-lifecycle/": {
      "get": {
        "operationId": "device_lifecycle_list",
        "parameters": [
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "Which field to use when ordering the results.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "A page number within the paginated result set.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "page_size",
            "required": false,
            "in": "query",
            "description": "Number of results to return per page.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "record_type",
            "schema": {
              "type": "string",
              "enum": [
                "hardware",
                "module",
                "software"
              ]
            },
            "description": "* `hardware` - Hardware Platform\n* `software` - Software / Firmware\n* `module` - Software Module / License"
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "A search term.",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "vendor",
            "schema": {
              "type": "string",
              "enum": [
                "a10",
                "arista",
                "checkpoint",
                "cisco",
                "citrix",
                "f5",
                "fortinet",
                "juniper",
                "kemp",
                "other",
                "palo_alto",
                "radware",
                "vmware"
              ]
            },
            "description": "* `f5` - F5 Networks\n* `citrix` - Citrix / NetScaler\n* `a10` - A10 Networks\n* `radware` - Radware / Alteon\n* `kemp` - Kemp / Progress\n* `palo_alto` - Palo Alto Networks\n* `fortinet` - Fortinet\n* `checkpoint` - Check Point\n* `cisco` - Cisco\n* `juniper` - Juniper Networks\n* `arista` - Arista\n* `vmware` - VMware / Broadcom\n* `other` - Other"
          }
        ],
        "tags": [
          "device-lifecycle"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedDeviceLifecycleList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "List device lifecycles"
      },
      "post": {
        "operationId": "device_lifecycle_create",
        "tags": [
          "device-lifecycle"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceLifecycleRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceLifecycleRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceLifecycleRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceLifecycle"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Create device lifecycle"
      }
    },
    "/api/device-lifecycle/{id}/": {
      "get": {
        "operationId": "device_lifecycle_retrieve",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device lifecycle.",
            "required": true
          }
        ],
        "tags": [
          "device-lifecycle"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceLifecycle"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Retrieve device lifecycle"
      },
      "put": {
        "operationId": "device_lifecycle_update",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device lifecycle.",
            "required": true
          }
        ],
        "tags": [
          "device-lifecycle"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceLifecycleRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceLifecycleRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceLifecycleRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceLifecycle"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Update device lifecycle"
      },
      "patch": {
        "operationId": "device_lifecycle_partial_update",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device lifecycle.",
            "required": true
          }
        ],
        "tags": [
          "device-lifecycle"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchedDeviceLifecycleRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/PatchedDeviceLifecycleRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/PatchedDeviceLifecycleRequest"
              }
            }
          }
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceLifecycle"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Update device lifecycle"
      },
      "delete": {
        "operationId": "device_lifecycle_destroy",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device lifecycle.",
            "required": true
          }
        ],
        "tags": [
          "device-lifecycle"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "No response body"
          }
        },
        "summary": "Delete device lifecycle"
      }
    },
    "/api/device-lifecycle/{id}/devices/": {
      "get": {
        "operationId": "device_lifecycle_devices_retrieve",
        "description": "Return the devices that match this lifecycle record's vendor.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device lifecycle.",
            "required": true
          }
        ],
        "tags": [
          "device-lifecycle"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceLifecycle"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Devices: device lifecycle"
      }
    },
    "/api/device-lifecycle/summary/": {
      "get": {
        "operationId": "device_lifecycle_summary_retrieve",
        "description": "Return summary counts by status for the dashboard cards.",
        "tags": [
          "device-lifecycle"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceLifecycle"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "List summarys"
      }
    },
    "/api/devices/": {
      "get": {
        "operationId": "devices_list",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "query",
            "name": "device_type",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "aci_controller",
                  "aci_fabric",
                  "adc",
                  "adc_controller",
                  "chassis",
                  "cloud_alb",
                  "cloud_security",
                  "dns_ipam",
                  "firewall",
                  "firewall_controller",
                  "firewall_manager",
                  "npb",
                  "pcap",
                  "router",
                  "sdn_controller",
                  "sdn_edge",
                  "sdn_transport",
                  "switch"
                ]
              }
            },
            "description": "Multiple values may be separated by commas.",
            "explode": false,
            "style": "form"
          },
          {
            "in": "query",
            "name": "group",
            "schema": {
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "location",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "Which field to use when ordering the results.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "A page number within the paginated result set.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "page_size",
            "required": false,
            "in": "query",
            "description": "Number of results to return per page.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "A search term.",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "vendor",
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedDeviceListList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "List devices"
      },
      "post": {
        "operationId": "devices_create",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Create device"
      }
    },
    "/api/devices/{id}/": {
      "get": {
        "operationId": "devices_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceDetail"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Retrieve device"
      },
      "put": {
        "operationId": "devices_update",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Update device"
      },
      "patch": {
        "operationId": "devices_partial_update",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchedDeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/PatchedDeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/PatchedDeviceListRequest"
              }
            }
          }
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Update device"
      },
      "delete": {
        "operationId": "devices_destroy",
        "description": "Delete a device, gracefully handling protected references. Some records\n(e.g. FirewallMigrationPlan / A10ToAviMigrationPlan.target_device) use\non_delete=PROTECT, so a plain delete 500s. Return a clear 409 listing\nthe blockers; with ?force=true, remove those PROTECT references first.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "No response body"
          }
        },
        "summary": "Delete device"
      }
    },
    "/api/devices/{id}/add_stats/": {
      "post": {
        "operationId": "devices_add_stats_create",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Add stats: device"
      }
    },
    "/api/devices/{id}/arp_table/": {
      "get": {
        "operationId": "devices_arp_table_retrieve",
        "description": "Live/dynamically-learned ARP via SSH tmsh, REST fallback if SSH fails.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Arp table: device"
      }
    },
    "/api/devices/{id}/auth_mechanism/": {
      "get": {
        "operationId": "devices_auth_mechanism_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Auth mechanism: device"
      }
    },
    "/api/devices/{id}/avi_clouds/": {
      "get": {
        "operationId": "devices_avi_clouds_retrieve",
        "description": "Return AVI cloud names and SE groups for this AVI controller device.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Avi clouds: device"
      }
    },
    "/api/devices/{id}/avi_tier1_lrs/": {
      "get": {
        "operationId": "devices_avi_tier1_lrs_retrieve",
        "description": "Return NSX-T Tier-1 LRs from AVI cloud config (fallback path).\nReturns [{name, id}] where id is the full NSX-T path.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Avi tier1 lrs: device"
      }
    },
    "/api/devices/{id}/backups/": {
      "get": {
        "operationId": "devices_backups_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Backups: device"
      }
    },
    "/api/devices/{id}/cf_credentials/": {
      "get": {
        "operationId": "devices_cf_credentials_retrieve",
        "description": "Return Cloudflare credentials stored on a cloudflare-vendor device.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Cf credentials: device"
      }
    },
    "/api/devices/{id}/configure_syslog/": {
      "post": {
        "operationId": "devices_configure_syslog_create",
        "description": "Adds Versus as a remote-syslog target on the device (UDP, via the\nF5's standard sys/syslog remoteServers config) \u2014 used by both the Add\nDevice wizard's on-by-default checkbox and the Base Settings tab\ntoggle. Requires a syslog_target_host to be set in Settings first,\nsince the device needs a real address it can reach; there's no safe\nway to infer that from the current HTTP request context.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Configure syslog: device"
      }
    },
    "/api/devices/{id}/create_backup/": {
      "post": {
        "operationId": "devices_create_backup_create",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Create backup: device"
      }
    },
    "/api/devices/{id}/customer_edges/": {
      "get": {
        "operationId": "devices_customer_edges_retrieve",
        "description": "Return F5 Distributed Cloud (XC) Customer Edge (CE) sites discovered\nunder this device's tenant (or demo CE sites if the tenant has none \u2014\nsee CustomerEdgeSite.is_demo_data / apps.devices.xc_ce_discovery).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Customer edges: device"
      }
    },
    "/api/devices/{id}/discover_vs_fqdns/": {
      "post": {
        "operationId": "devices_discover_vs_fqdns_create",
        "description": "Reverse-DNS (PTR) lookup of each Virtual Server's VIP address\nagainst the default IPAM instance, populating discovered_fqdn.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Discover vs fqdns: device"
      }
    },
    "/api/devices/{id}/discover_wideip_targets/": {
      "post": {
        "operationId": "devices_discover_wideip_targets_create",
        "description": "Forward DNS (A record) lookup of each GTM WideIP's name (the\nWideIP name IS the FQDN) against the default IPAM instance,\npopulating discovered_ip \u2014 the public IP the name currently\nresolves to, useful for WAF-linking comparison.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Discover wideip targets: device"
      }
    },
    "/api/devices/{id}/dns_config/": {
      "get": {
        "operationId": "devices_dns_config_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Dns config: device"
      }
    },
    "/api/devices/{id}/fetch_cert_keys/": {
      "post": {
        "operationId": "devices_fetch_cert_keys_create",
        "description": "SCP SSL cert and private key PEM files from an A10 device via SSH/SFTP.\nBody: {ssh_username, ssh_password, cert_names (optional list)}\nStores cert_pem plaintext and key_pem encrypted in the Certificate records.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Fetch cert keys: device"
      }
    },
    "/api/devices/{id}/generate_qkview/": {
      "post": {
        "operationId": "devices_generate_qkview_create",
        "description": "Start a QKView generation + iHealth upload job for this device.\nBody: client_id, client_secret \u00e2\u20ac\u201d optional if a valid saved credential exists.\nIf provided, they are saved (encrypted) for reuse until they expire (180 days).\n(Obtain from https://ihealth.f5.com \u00e2\u2020\u2019 Settings \u00e2\u2020\u2019 API Tokens \u00e2\u2020\u2019 Generate New Token)",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Generate qkview: device"
      }
    },
    "/api/devices/{id}/gtm_wideips/": {
      "get": {
        "operationId": "devices_gtm_wideips_retrieve",
        "description": "Return GTM Wide IPs imported from this device (F5 GTM/LTM only).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Gtm wideips: device"
      }
    },
    "/api/devices/{id}/import_jobs/": {
      "get": {
        "operationId": "devices_import_jobs_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Import jobs: device"
      }
    },
    "/api/devices/{id}/ipam_allocate/": {
      "post": {
        "operationId": "devices_ipam_allocate_create",
        "description": "Allocate the next available IP from a DNS/IPAM device.\nBody: { network: \"10.0.0.0/24\", fqdn: \"myapp-vip.example.com\", comment: \"...\" }\nReturns: { ip, fqdn, ref }",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Ipam allocate: device"
      }
    },
    "/api/devices/{id}/ipam_networks/": {
      "get": {
        "operationId": "devices_ipam_networks_retrieve",
        "description": "Return the list of IP networks from a DNS/IPAM device.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Ipam networks: device"
      }
    },
    "/api/devices/{id}/license_info/": {
      "get": {
        "operationId": "devices_license_info_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "License info: device"
      }
    },
    "/api/devices/{id}/ntp_config/": {
      "get": {
        "operationId": "devices_ntp_config_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Ntp config: device"
      }
    },
    "/api/devices/{id}/qkview_jobs/": {
      "get": {
        "operationId": "devices_qkview_jobs_retrieve",
        "description": "List QKView jobs for this device.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Qkview jobs: device"
      }
    },
    "/api/devices/{id}/relicense/": {
      "post": {
        "operationId": "devices_relicense_create",
        "description": "Re-installs the device's registration key \u2014 this can reset\nlicensing state on the unit. The frontend gates this behind a\ntype-the-device-name-to-confirm modal; this re-checks the same\nconfirmation server-side so the safety gate can't be bypassed by a\ndirect API call.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Relicense: device"
      }
    },
    "/api/devices/{id}/remove_syslog/": {
      "post": {
        "operationId": "devices_remove_syslog_create",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Remove syslog: device"
      }
    },
    "/api/devices/{id}/routing_table/": {
      "get": {
        "operationId": "devices_routing_table_retrieve",
        "description": "Live routing table via SSH tmsh, REST fallback if SSH fails.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Routing table: device"
      }
    },
    "/api/devices/{id}/run_security_audit/": {
      "post": {
        "operationId": "devices_run_security_audit_create",
        "description": "Run the F5 hardening audit against this single device synchronously\nand persist it as a WorkflowStepRun \u2014 same shape the 'F5 Security\nAudit' workflow produces, so the existing GET security_audit action\nand VulnerabilitiesTab pick it up with no changes on their end. Bypasses\nthe WorkflowRun/DeviceGroup HA-pair machinery entirely since that only\nsupports auditing both members of an HA pair (or every F5 device in\ninventory when ungrouped) \u2014 neither fits a single-device button.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Run security audit: device"
      }
    },
    "/api/devices/{id}/se_vip_subnets/": {
      "get": {
        "operationId": "devices_se_vip_subnets_retrieve",
        "description": "List or create Avi SE group VIP subnet entries for this device.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Se vip subnets: device"
      },
      "post": {
        "operationId": "devices_se_vip_subnets_create",
        "description": "List or create Avi SE group VIP subnet entries for this device.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Se vip subnets: device"
      }
    },
    "/api/devices/{id}/se_vip_subnets/{entry_id}/": {
      "delete": {
        "operationId": "devices_se_vip_subnets_destroy",
        "description": "Delete a single Avi SE group VIP subnet entry.",
        "parameters": [
          {
            "in": "path",
            "name": "entry_id",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "No response body"
          }
        },
        "summary": "Delete se vip subnet"
      }
    },
    "/api/devices/{id}/security_audit/": {
      "get": {
        "operationId": "devices_security_audit_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Security audit: device"
      }
    },
    "/api/devices/{id}/self_ips/": {
      "get": {
        "operationId": "devices_self_ips_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Self ips: device"
      }
    },
    "/api/devices/{id}/start_import/": {
      "post": {
        "operationId": "devices_start_import_create",
        "description": "Trigger a background inventory import for this device.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Start import: device"
      }
    },
    "/api/devices/{id}/stats_history/": {
      "get": {
        "operationId": "devices_stats_history_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Stats history: device"
      }
    },
    "/api/devices/{id}/sync_status/": {
      "get": {
        "operationId": "devices_sync_status_retrieve",
        "description": "Tries the cm/sync-status REST endpoint first, falls back to SSH\ntmsh if it's unavailable on this TMOS version. Deliberately not baked\ninto the main device serializer \u2014 this is a live device round-trip\nand would slow down every page load if fetched eagerly.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Sync status: device"
      }
    },
    "/api/devices/{id}/syslog_config/": {
      "get": {
        "operationId": "devices_syslog_config_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Syslog config: device"
      }
    },
    "/api/devices/{id}/test_dns/": {
      "post": {
        "operationId": "devices_test_dns_create",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Test dns: device"
      }
    },
    "/api/devices/{id}/test_ntp/": {
      "post": {
        "operationId": "devices_test_ntp_create",
        "description": "Re-runs 'ntpq -pn' live \u2014 this IS the refresh action, there's no\nseparate cached read vs. live test for NTP peer status.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Test ntp: device"
      }
    },
    "/api/devices/{id}/tier1_lrs/": {
      "get": {
        "operationId": "devices_tier1_lrs_retrieve",
        "description": "Return NSX-T Tier-1 gateways directly from an NSX-T Manager device.\nAlways returns HTTP 200 so the frontend can display the error inline.\nReturns [{name, id}] where id is the full NSX-T path (/infra/tier-1s/...).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Tier1 lrs: device"
      }
    },
    "/api/devices/{id}/virtual_servers/": {
      "get": {
        "operationId": "devices_virtual_servers_retrieve",
        "description": "Return the list of VirtualServer objects discovered from this device.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Virtual servers: device"
      }
    },
    "/api/devices/{id}/vlans/": {
      "get": {
        "operationId": "devices_vlans_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Vlans: device"
      }
    },
    "/api/devices/{id}/xc_credentials/": {
      "get": {
        "operationId": "devices_xc_credentials_retrieve",
        "description": "Return F5 XC credentials stored on an f5_xc/f5_xc_waf-vendor device.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this device.",
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Xc credentials: device"
      }
    },
    "/api/devices/discover/": {
      "post": {
        "operationId": "devices_discover_create",
        "description": "Quick probe: connect to a device and return hostname, version, HA status,\nand any HA peers. Does NOT save anything.\nAccepts either (mgmt_ip + username + password) or (mgmt_ip + credential_id).",
        "tags": [
          "devices"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DeviceListRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Create discover"
      }
    },
    "/api/devices/discover-status/{job_id}/": {
      "get": {
        "operationId": "devices_discover_status_retrieve",
        "description": "Poll an async discover job (discover()'s async mode fires a collector\ndispatch and returns a job_id). Returns {status: pending|success|failed}\nplus the device data on success \u2014 so a slow/proxied collector's discovery\ncompletes without holding a single long HTTP request open.",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "schema": {
              "type": "string",
              "pattern": "^[^/]+$"
            },
            "required": true
          }
        ],
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Retrieve discover statu"
      }
    },
    "/api/devices/ihealth_credential_status/": {
      "get": {
        "operationId": "devices_ihealth_credential_status_retrieve",
        "description": "Whether a saved iHealth API credential exists and is still valid.",
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "List ihealth credential status"
      }
    },
    "/api/devices/summary/": {
      "get": {
        "operationId": "devices_summary_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "tags": [
          "devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "List summarys"
      }
    },
    "/api/firmware-images/": {
      "get": {
        "operationId": "firmware_images_list",
        "parameters": [
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "Which field to use when ordering the results.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "A page number within the paginated result set.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "page_size",
            "required": false,
            "in": "query",
            "description": "Number of results to return per page.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "A search term.",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "vendor",
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "firmware-images"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedFirmwareImageList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "List firmware images"
      },
      "post": {
        "operationId": "firmware_images_create",
        "tags": [
          "firmware-images"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FirmwareImageRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/FirmwareImageRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/FirmwareImageRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmwareImage"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Create firmware image"
      }
    },
    "/api/firmware-images/{id}/": {
      "get": {
        "operationId": "firmware_images_retrieve",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this firmware image.",
            "required": true
          }
        ],
        "tags": [
          "firmware-images"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmwareImage"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Retrieve firmware image"
      },
      "put": {
        "operationId": "firmware_images_update",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this firmware image.",
            "required": true
          }
        ],
        "tags": [
          "firmware-images"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FirmwareImageRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/FirmwareImageRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/FirmwareImageRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmwareImage"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Update firmware image"
      },
      "patch": {
        "operationId": "firmware_images_partial_update",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this firmware image.",
            "required": true
          }
        ],
        "tags": [
          "firmware-images"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchedFirmwareImageRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/PatchedFirmwareImageRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/PatchedFirmwareImageRequest"
              }
            }
          }
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmwareImage"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Update firmware image"
      },
      "delete": {
        "operationId": "firmware_images_destroy",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this firmware image.",
            "required": true
          }
        ],
        "tags": [
          "firmware-images"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "No response body"
          }
        },
        "summary": "Delete firmware image"
      }
    },
    "/api/firmware-images/{id}/download/": {
      "get": {
        "operationId": "firmware_images_download_retrieve",
        "description": "Serve the firmware file for device-initiated downloads (e.g. Cisco copy http:// flash:).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this firmware image.",
            "required": true
          }
        ],
        "tags": [
          "firmware-images"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmwareImage"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Download: firmware image"
      }
    },
    "/api/firmware-images/collector_files/": {
      "get": {
        "operationId": "firmware_images_collector_files_retrieve",
        "description": "List firmware files collectors report having in their local firmware\ndir \u2014 the candidates for collector-local registration. Optionally\nfiltered by ?collector_id= or ?site=.",
        "tags": [
          "firmware-images"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmwareImage"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "List collector files"
      }
    },
    "/api/firmware-images/register_collector/": {
      "post": {
        "operationId": "firmware_images_register_collector_create",
        "description": "Register a collector-local firmware image (no upload): the file lives\non the named collector's host and is copied to the device locally at\nupgrade time. Accepts the same filename formats as upload.",
        "tags": [
          "firmware-images"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FirmwareImageRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/FirmwareImageRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/FirmwareImageRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmwareImage"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Create register collector"
      }
    },
    "/api/firmware-images/upload/": {
      "post": {
        "operationId": "firmware_images_upload_create",
        "tags": [
          "firmware-images"
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/FirmwareImageRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/FirmwareImageRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmwareImage"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Create upload"
      }
    },
    "/api/managed-devices/": {
      "get": {
        "operationId": "managed_devices_list",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "query",
            "name": "controller",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "Which field to use when ordering the results.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "A page number within the paginated result set.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "page_size",
            "required": false,
            "in": "query",
            "description": "Number of results to return per page.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "role",
            "schema": {
              "type": "string",
              "enum": [
                "blade",
                "edge",
                "firewall",
                "guest",
                "server",
                "service_engine",
                "tenant"
              ]
            },
            "description": "* `service_engine` - Service Engine\n* `firewall` - Firewall\n* `edge` - NSX Edge\n* `tenant` - F5OS Tenant\n* `guest` - vCMP Guest\n* `blade` - Chassis Blade / Slot\n* `server` - Server (ServiceNow CMDB)"
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "A search term.",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "managed-devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedManagedDeviceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "List managed devices"
      }
    },
    "/api/managed-devices/{id}/": {
      "get": {
        "operationId": "managed_devices_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this managed device.",
            "required": true
          }
        ],
        "tags": [
          "managed-devices"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ManagedDevice"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Retrieve managed device"
      }
    },
    "/api/panos-versions/": {
      "get": {
        "operationId": "panos_versions_retrieve",
        "description": "Detect internet access on a Palo Alto device and return available PAN-OS versions.\n\nGET /api/workflows/panos-versions/?device_group=<id>\n\nConnects to the first available device in the group, checks internet access\nby running 'request system software check' (returns a job ID only when the\ndevice can reach the Palo Alto update server), and returns the software catalog.\n\nResponse:\n  {internet_access: bool, current_version: str, versions: [{version, downloaded, current, min_content}]}",
        "tags": [
          "panos-versions"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "No response body"
          }
        },
        "summary": "List panos versions"
      }
    },
    "/api/upgrades/": {
      "get": {
        "operationId": "upgrades_list",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "query",
            "name": "device_group",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "Which field to use when ordering the results.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "A page number within the paginated result set.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "page_size",
            "required": false,
            "in": "query",
            "description": "Number of results to return per page.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "A search term.",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "type": "string",
              "enum": [
                "completed",
                "failed",
                "in_progress",
                "pending",
                "rolled_back"
              ]
            },
            "description": "* `pending` - Pending\n* `in_progress` - In Progress\n* `completed` - Completed\n* `failed` - Failed\n* `rolled_back` - Rolled Back"
          },
          {
            "in": "query",
            "name": "vendor",
            "schema": {
              "type": "string",
              "enum": [
                "alteon",
                "f5",
                "netscaler"
              ]
            },
            "description": "* `f5` - F5 BIG-IP\n* `netscaler` - NetScaler\n* `alteon` - Alteon"
          }
        ],
        "tags": [
          "upgrades"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedUpgradeListList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "List upgrades"
      },
      "post": {
        "operationId": "upgrades_create",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "tags": [
          "upgrades"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpgradeRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/UpgradeRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/UpgradeRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Upgrade"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Create upgrade"
      }
    },
    "/api/upgrades/{id}/": {
      "get": {
        "operationId": "upgrades_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this upgrade.",
            "required": true
          }
        ],
        "tags": [
          "upgrades"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Upgrade"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Retrieve upgrade"
      },
      "put": {
        "operationId": "upgrades_update",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this upgrade.",
            "required": true
          }
        ],
        "tags": [
          "upgrades"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpgradeRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/UpgradeRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/UpgradeRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Upgrade"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Update upgrade"
      },
      "patch": {
        "operationId": "upgrades_partial_update",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this upgrade.",
            "required": true
          }
        ],
        "tags": [
          "upgrades"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchedUpgradeRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/PatchedUpgradeRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/PatchedUpgradeRequest"
              }
            }
          }
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Upgrade"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Update upgrade"
      },
      "delete": {
        "operationId": "upgrades_destroy",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this upgrade.",
            "required": true
          }
        ],
        "tags": [
          "upgrades"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "No response body"
          }
        },
        "summary": "Delete upgrade"
      }
    },
    "/api/upgrades/{id}/execute_step/": {
      "post": {
        "operationId": "upgrades_execute_step_create",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this upgrade.",
            "required": true
          }
        ],
        "tags": [
          "upgrades"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpgradeRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/UpgradeRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/UpgradeRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Upgrade"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Execute step: upgrade"
      }
    },
    "/api/upgrades/{id}/mark_step/": {
      "post": {
        "operationId": "upgrades_mark_step_create",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this upgrade.",
            "required": true
          }
        ],
        "tags": [
          "upgrades"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpgradeRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/UpgradeRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/UpgradeRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Upgrade"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Mark step: upgrade"
      }
    },
    "/api/velos-chassis/": {
      "get": {
        "operationId": "velos_chassis_retrieve",
        "tags": [
          "velos-chassis"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "No response body"
          }
        },
        "summary": "List velos chassis"
      }
    },
    "/api/velos-chassis/{id}/": {
      "get": {
        "operationId": "velos_chassis_retrieve_2",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this velos chassis.",
            "required": true
          }
        ],
        "tags": [
          "velos-chassis"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "No response body"
          }
        },
        "summary": "Retrieve velos chassi"
      }
    }
  },
  "components": {
    "schemas": {
      "ManagedDeviceRoleEnum": {
        "enum": [
          "service_engine",
          "firewall",
          "edge",
          "tenant",
          "guest",
          "blade",
          "server"
        ],
        "type": "string",
        "description": "* `service_engine` - Service Engine\n* `firewall` - Firewall\n* `edge` - NSX Edge\n* `tenant` - F5OS Tenant\n* `guest` - vCMP Guest\n* `blade` - Chassis Blade / Slot\n* `server` - Server (ServiceNow CMDB)"
      },
      "PaginatedDeviceListList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=4"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=2"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeviceList"
            }
          }
        }
      },
      "PaginatedDeviceLifecycleList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=4"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=2"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeviceLifecycle"
            }
          }
        }
      },
      "DeviceLifecycleVendorEnum": {
        "enum": [
          "f5",
          "citrix",
          "a10",
          "radware",
          "kemp",
          "palo_alto",
          "fortinet",
          "checkpoint",
          "cisco",
          "juniper",
          "arista",
          "vmware",
          "other"
        ],
        "type": "string",
        "description": "* `f5` - F5 Networks\n* `citrix` - Citrix / NetScaler\n* `a10` - A10 Networks\n* `radware` - Radware / Alteon\n* `kemp` - Kemp / Progress\n* `palo_alto` - Palo Alto Networks\n* `fortinet` - Fortinet\n* `checkpoint` - Check Point\n* `cisco` - Cisco\n* `juniper` - Juniper Networks\n* `arista` - Arista\n* `vmware` - VMware / Broadcom\n* `other` - Other"
      },
      "DeviceListRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "hostname": {
            "type": "string",
            "maxLength": 200
          },
          "mgmt_ip": {
            "type": "string",
            "nullable": true
          },
          "vendor": {
            "$ref": "#/components/schemas/Vendor16bEnum"
          },
          "device_type": {
            "$ref": "#/components/schemas/DeviceTypeEnum"
          },
          "version": {
            "type": "string",
            "maxLength": 50
          },
          "status": {
            "$ref": "#/components/schemas/Status14bEnum"
          },
          "ha_status": {
            "type": "string",
            "maxLength": 20
          },
          "group": {
            "type": "integer",
            "nullable": true
          },
          "location": {
            "type": "integer",
            "nullable": true
          },
          "environment": {
            "type": "integer",
            "nullable": true
          },
          "clients": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "ha_peer": {
            "type": "integer",
            "nullable": true
          },
          "credential": {
            "type": "integer",
            "nullable": true
          },
          "ssh_credential": {
            "type": "integer",
            "nullable": true
          },
          "site": {
            "type": "integer",
            "nullable": true
          },
          "credential_source": {
            "type": "string",
            "minLength": 1,
            "maxLength": 32
          },
          "external_secret": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "last_synced": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "notes": {
            "type": "string"
          },
          "extra_config": {}
        },
        "required": [
          "name"
        ]
      },
      "UpgradeList": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "vendor": {
            "$ref": "#/components/schemas/Vendor948Enum"
          },
          "status": {
            "$ref": "#/components/schemas/Status294Enum"
          },
          "target_version": {
            "type": "string",
            "maxLength": 50
          },
          "current_step": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": -2147483648
          },
          "total_steps": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": -2147483648
          },
          "progress_percent": {
            "type": "string",
            "readOnly": true
          },
          "device_group_name": {
            "type": "string",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "created_at",
          "device_group_name",
          "id",
          "name",
          "progress_percent",
          "target_version"
        ]
      },
      "ManagedDevice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "controller_name": {
            "type": "string",
            "readOnly": true
          },
          "tenant_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "role": {
            "$ref": "#/components/schemas/ManagedDeviceRoleEnum"
          },
          "mgmt_ip": {
            "type": "string",
            "nullable": true
          },
          "version": {
            "type": "string",
            "maxLength": 50
          },
          "status": {
            "type": "string",
            "maxLength": 50
          },
          "se_group": {
            "type": "string",
            "maxLength": 200
          },
          "cloud": {
            "type": "string",
            "maxLength": 200
          },
          "raw_data": {},
          "snow_ci_sys_id": {
            "type": "string",
            "maxLength": 64
          },
          "last_synced": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "controller": {
            "type": "integer",
            "nullable": true
          }
        },
        "required": [
          "controller",
          "controller_name",
          "created_at",
          "id",
          "name"
        ]
      },
      "DeviceTypeEnum": {
        "enum": [
          "adc",
          "adc_controller",
          "chassis",
          "cloud_alb",
          "firewall_controller",
          "firewall_manager",
          "firewall",
          "router",
          "switch",
          "cloud_security",
          "aci_controller",
          "aci_fabric",
          "sdn_controller",
          "sdn_edge",
          "sdn_transport",
          "dns_ipam",
          "pcap",
          "npb"
        ],
        "type": "string",
        "description": "* `adc` - Application Delivery Controller\n* `adc_controller` - ADC Controller\n* `chassis` - Chassis / Hypervisor Platform\n* `cloud_alb` - Cloud Application Load Balancer\n* `firewall_controller` - Firewall Controller\n* `firewall_manager` - Firewall Manager\n* `firewall` - Standalone Firewall\n* `router` - Router\n* `switch` - Switch\n* `cloud_security` - Cloud Security Service\n* `aci_controller` - ACI Controller\n* `aci_fabric` - ACI Fabric Node\n* `sdn_controller` - SDN Controller\n* `sdn_edge` - SDN Edge Node\n* `sdn_transport` - SDN Transport / Hypervisor Node\n* `dns_ipam` - DNS / IPAM\n* `pcap` - PCAP / Packet Capture\n* `npb` - Network Packet Broker"
      },
      "DeviceLifecycleRequest": {
        "type": "object",
        "properties": {
          "vendor": {
            "$ref": "#/components/schemas/DeviceLifecycleVendorEnum"
          },
          "record_type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DeviceLifecycleRecordTypeEnum"
              }
            ],
            "default": "hardware"
          },
          "product_family": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "model": {
            "type": "string",
            "minLength": 1,
            "description": "Platform model or software version string, e.g. \"i5800\" or \"14.1.x\"",
            "maxLength": 200
          },
          "description": {
            "type": "string"
          },
          "announced_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Date EOL/EOS was publicly announced"
          },
          "last_order_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of Sale \u2014 last day new units can be ordered"
          },
          "end_of_new_development": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of new feature / enhancement development"
          },
          "end_of_bug_fix": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of bug-fix and maintenance releases"
          },
          "end_of_security_fix": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of security / vulnerability patches (EOVS)"
          },
          "end_of_sw_maintenance": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of all software maintenance (EOSM)"
          },
          "end_of_tech_support": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of Technical Support \u2014 no more TAC/support cases"
          },
          "end_of_life": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of Life \u2014 all vendor support ends"
          },
          "end_of_hw_maintenance": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of hardware maintenance / spare parts"
          },
          "end_of_rma": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of RMA / hardware replacement programme"
          },
          "end_of_service_contract": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Last date to renew a support/service contract"
          },
          "source_url": {
            "type": "string",
            "format": "uri",
            "description": "Official vendor EOL/EOS announcement URL",
            "maxLength": 200
          },
          "notes": {
            "type": "string"
          }
        },
        "required": [
          "model",
          "product_family",
          "vendor"
        ]
      },
      "UpgradeStepStatusEnum": {
        "enum": [
          "pending",
          "running",
          "success",
          "failed",
          "skipped"
        ],
        "type": "string",
        "description": "* `pending` - Pending\n* `running` - Running\n* `success` - Success\n* `failed` - Failed\n* `skipped` - Skipped"
      },
      "Vendor948Enum": {
        "enum": [
          "f5",
          "netscaler",
          "alteon"
        ],
        "type": "string",
        "description": "* `f5` - F5 BIG-IP\n* `netscaler` - NetScaler\n* `alteon` - Alteon"
      },
      "Status14bEnum": {
        "enum": [
          "active",
          "standby",
          "offline",
          "unknown"
        ],
        "type": "string",
        "description": "* `active` - Active\n* `standby` - Standby\n* `offline` - Offline\n* `unknown` - Unknown"
      },
      "DeviceDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "group_name": {
            "type": "string",
            "readOnly": true
          },
          "location_name": {
            "type": "string",
            "readOnly": true
          },
          "environment_name": {
            "type": "string",
            "readOnly": true
          },
          "client_names": {
            "type": "string",
            "readOnly": true
          },
          "ha_peer_name": {
            "type": "string",
            "readOnly": true
          },
          "credential_username": {
            "type": "string",
            "readOnly": true
          },
          "ssh_credential_username": {
            "type": "string",
            "readOnly": true
          },
          "recent_stats": {
            "type": "string",
            "readOnly": true
          },
          "backup_count": {
            "type": "string",
            "readOnly": true
          },
          "config_shared_with": {
            "type": "string",
            "readOnly": true
          },
          "velos_chassis_id": {
            "type": "string",
            "readOnly": true
          },
          "tenant_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "hostname": {
            "type": "string",
            "maxLength": 200
          },
          "mgmt_ip": {
            "type": "string",
            "nullable": true
          },
          "extra_config": {},
          "vendor": {
            "$ref": "#/components/schemas/Vendor16bEnum"
          },
          "device_type": {
            "$ref": "#/components/schemas/DeviceTypeEnum"
          },
          "version": {
            "type": "string",
            "maxLength": 50
          },
          "status": {
            "$ref": "#/components/schemas/Status14bEnum"
          },
          "ha_status": {
            "type": "string",
            "maxLength": 20
          },
          "license_reg_key": {
            "type": "string",
            "maxLength": 100
          },
          "serial_number": {
            "type": "string",
            "maxLength": 100
          },
          "cpu_threshold": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": -2147483648
          },
          "mem_threshold": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": -2147483648
          },
          "disk_threshold": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": -2147483648
          },
          "last_synced": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "notes": {
            "type": "string"
          },
          "credential_source": {
            "type": "string",
            "maxLength": 32
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "ha_peer": {
            "type": "integer",
            "nullable": true
          },
          "group": {
            "type": "integer",
            "nullable": true
          },
          "location": {
            "type": "integer",
            "nullable": true
          },
          "site": {
            "type": "integer",
            "nullable": true
          },
          "environment": {
            "type": "integer",
            "nullable": true
          },
          "credential": {
            "type": "integer",
            "nullable": true
          },
          "ssh_credential": {
            "type": "integer",
            "nullable": true
          },
          "external_secret": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "clients": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          }
        },
        "required": [
          "backup_count",
          "client_names",
          "config_shared_with",
          "created_at",
          "credential_username",
          "environment_name",
          "group_name",
          "ha_peer_name",
          "id",
          "location_name",
          "name",
          "recent_stats",
          "ssh_credential_username",
          "updated_at",
          "velos_chassis_id"
        ]
      },
      "PatchedFirmwareImageRequest": {
        "type": "object",
        "properties": {
          "vendor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 20
          },
          "version": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50
          },
          "build": {
            "type": "string",
            "maxLength": 50
          },
          "filename": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "file_path": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "file_size": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": -9223372036854775808,
            "format": "int64"
          },
          "md5_hash": {
            "type": "string",
            "maxLength": 64
          },
          "location": {
            "$ref": "#/components/schemas/LocationEnum"
          },
          "collector": {
            "type": "string",
            "minLength": 1,
            "nullable": true
          }
        }
      },
      "PatchedDeviceGroupRequest": {
        "type": "object",
        "properties": {
          "tenant_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "description": {
            "type": "string"
          },
          "location": {
            "type": "integer",
            "nullable": true
          }
        }
      },
      "DeviceLifecycleRecordTypeEnum": {
        "enum": [
          "hardware",
          "software",
          "module"
        ],
        "type": "string",
        "description": "* `hardware` - Hardware Platform\n* `software` - Software / Firmware\n* `module` - Software Module / License"
      },
      "PatchedDeviceLifecycleRequest": {
        "type": "object",
        "properties": {
          "vendor": {
            "$ref": "#/components/schemas/DeviceLifecycleVendorEnum"
          },
          "record_type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DeviceLifecycleRecordTypeEnum"
              }
            ],
            "default": "hardware"
          },
          "product_family": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "model": {
            "type": "string",
            "minLength": 1,
            "description": "Platform model or software version string, e.g. \"i5800\" or \"14.1.x\"",
            "maxLength": 200
          },
          "description": {
            "type": "string"
          },
          "announced_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Date EOL/EOS was publicly announced"
          },
          "last_order_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of Sale \u2014 last day new units can be ordered"
          },
          "end_of_new_development": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of new feature / enhancement development"
          },
          "end_of_bug_fix": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of bug-fix and maintenance releases"
          },
          "end_of_security_fix": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of security / vulnerability patches (EOVS)"
          },
          "end_of_sw_maintenance": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of all software maintenance (EOSM)"
          },
          "end_of_tech_support": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of Technical Support \u2014 no more TAC/support cases"
          },
          "end_of_life": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of Life \u2014 all vendor support ends"
          },
          "end_of_hw_maintenance": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of hardware maintenance / spare parts"
          },
          "end_of_rma": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of RMA / hardware replacement programme"
          },
          "end_of_service_contract": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Last date to renew a support/service contract"
          },
          "source_url": {
            "type": "string",
            "format": "uri",
            "description": "Official vendor EOL/EOS announcement URL",
            "maxLength": 200
          },
          "notes": {
            "type": "string"
          }
        }
      },
      "PatchedDeviceListRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "hostname": {
            "type": "string",
            "maxLength": 200
          },
          "mgmt_ip": {
            "type": "string",
            "nullable": true
          },
          "vendor": {
            "$ref": "#/components/schemas/Vendor16bEnum"
          },
          "device_type": {
            "$ref": "#/components/schemas/DeviceTypeEnum"
          },
          "version": {
            "type": "string",
            "maxLength": 50
          },
          "status": {
            "$ref": "#/components/schemas/Status14bEnum"
          },
          "ha_status": {
            "type": "string",
            "maxLength": 20
          },
          "group": {
            "type": "integer",
            "nullable": true
          },
          "location": {
            "type": "integer",
            "nullable": true
          },
          "environment": {
            "type": "integer",
            "nullable": true
          },
          "clients": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "ha_peer": {
            "type": "integer",
            "nullable": true
          },
          "credential": {
            "type": "integer",
            "nullable": true
          },
          "ssh_credential": {
            "type": "integer",
            "nullable": true
          },
          "site": {
            "type": "integer",
            "nullable": true
          },
          "credential_source": {
            "type": "string",
            "minLength": 1,
            "maxLength": 32
          },
          "external_secret": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "last_synced": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "notes": {
            "type": "string"
          },
          "extra_config": {}
        }
      },
      "DeviceList": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "hostname": {
            "type": "string",
            "maxLength": 200
          },
          "mgmt_ip": {
            "type": "string",
            "nullable": true
          },
          "vendor": {
            "$ref": "#/components/schemas/Vendor16bEnum"
          },
          "device_type": {
            "$ref": "#/components/schemas/DeviceTypeEnum"
          },
          "version": {
            "type": "string",
            "maxLength": 50
          },
          "status": {
            "$ref": "#/components/schemas/Status14bEnum"
          },
          "ha_status": {
            "type": "string",
            "maxLength": 20
          },
          "group": {
            "type": "integer",
            "nullable": true
          },
          "group_name": {
            "type": "string",
            "readOnly": true
          },
          "location": {
            "type": "integer",
            "nullable": true
          },
          "location_name": {
            "type": "string",
            "readOnly": true
          },
          "environment": {
            "type": "integer",
            "nullable": true
          },
          "environment_name": {
            "type": "string",
            "readOnly": true
          },
          "clients": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "client_names": {
            "type": "string",
            "readOnly": true
          },
          "ha_peer": {
            "type": "integer",
            "nullable": true
          },
          "credential": {
            "type": "integer",
            "nullable": true
          },
          "credential_username": {
            "type": "string",
            "readOnly": true
          },
          "ssh_credential": {
            "type": "integer",
            "nullable": true
          },
          "ssh_credential_username": {
            "type": "string",
            "readOnly": true
          },
          "site": {
            "type": "integer",
            "nullable": true
          },
          "credential_source": {
            "type": "string",
            "maxLength": 32
          },
          "external_secret": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "last_synced": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "latest_stats": {
            "type": "string",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "notes": {
            "type": "string"
          },
          "extra_config": {}
        },
        "required": [
          "client_names",
          "created_at",
          "credential_username",
          "environment_name",
          "group_name",
          "id",
          "latest_stats",
          "location_name",
          "name",
          "ssh_credential_username"
        ]
      },
      "UpgradeRequest": {
        "type": "object",
        "properties": {
          "tenant_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "vendor": {
            "$ref": "#/components/schemas/Vendor948Enum"
          },
          "status": {
            "$ref": "#/components/schemas/Status294Enum"
          },
          "target_version": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50
          },
          "image_path": {
            "type": "string",
            "maxLength": 500
          },
          "current_step": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": -2147483648
          },
          "total_steps": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": -2147483648
          },
          "notes": {
            "type": "string"
          },
          "created_by": {
            "type": "string",
            "maxLength": 100
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "device_group": {
            "type": "integer",
            "nullable": true
          }
        },
        "required": [
          "name",
          "target_version"
        ]
      },
      "PatchedUpgradeRequest": {
        "type": "object",
        "properties": {
          "tenant_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "vendor": {
            "$ref": "#/components/schemas/Vendor948Enum"
          },
          "status": {
            "$ref": "#/components/schemas/Status294Enum"
          },
          "target_version": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50
          },
          "image_path": {
            "type": "string",
            "maxLength": 500
          },
          "current_step": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": -2147483648
          },
          "total_steps": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": -2147483648
          },
          "notes": {
            "type": "string"
          },
          "created_by": {
            "type": "string",
            "maxLength": 100
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "device_group": {
            "type": "integer",
            "nullable": true
          }
        }
      },
      "LocationEnum": {
        "enum": [
          "cloud",
          "collector"
        ],
        "type": "string",
        "description": "* `cloud` - Cloud\n* `collector` - Collector"
      },
      "Vendor16bEnum": {
        "enum": [
          "f5_bigip",
          "f5os",
          "viprion",
          "netscaler",
          "kemp",
          "a10",
          "alteon",
          "nginx",
          "azure_alb",
          "azure_lb",
          "aws_alb",
          "f5_xc",
          "nsx_firewall",
          "fortimanager",
          "checkpoint_sms",
          "cisco_asa",
          "cisco_ftd",
          "fortigate",
          "paloalto_fw",
          "checkpoint_gw",
          "sonicwall",
          "watchguard",
          "barracuda_fw",
          "sophos_xg",
          "juniper_srx",
          "pfsense",
          "opnsense",
          "meraki_mx",
          "forcepoint",
          "cisco_router",
          "cisco_iosxr",
          "juniper_router",
          "arista_router",
          "cisco_switch",
          "cisco_nxos",
          "juniper_switch",
          "arista_switch",
          "aruba_cx",
          "cisco_apic",
          "cisco_aci_spine",
          "cisco_aci_leaf",
          "nsx_edge",
          "nsx_transport",
          "avi",
          "nsx_manager",
          "infoblox",
          "bluecat",
          "efficientip",
          "zscaler",
          "cloudflare",
          "imperva",
          "akamai",
          "f5_xc_waf",
          "barracuda_waf",
          "radware_cloud",
          "azure_front_door",
          "aws_nlb",
          "aws_gwlb",
          "aws_elb",
          "aws_global_accel",
          "aws_net_firewall",
          "aws_sg",
          "aws_nacl",
          "aws_waf",
          "aws_shield",
          "aws_fw_manager",
          "aws_vpc",
          "aws_transit_gw",
          "aws_vpn_gw",
          "aws_direct_connect",
          "aws_nat_gw",
          "aws_inet_gw",
          "aws_route_table",
          "aws_vpc_peering",
          "aws_privatelink",
          "aws_cloud_wan",
          "aws_route53",
          "aws_cloudfront",
          "azure_traffic_mgr",
          "azure_firewall",
          "azure_nsg",
          "azure_waf",
          "azure_ddos",
          "azure_vnet",
          "azure_vnet_peer",
          "azure_vpn_gw",
          "azure_expressroute",
          "azure_route_tbl",
          "azure_nat_gw",
          "azure_vwan",
          "azure_priv_link",
          "azure_bastion",
          "azure_route_svr",
          "azure_dns",
          "azure_cdn",
          "gcp_lb_ext",
          "gcp_lb_int",
          "gcp_lb_network",
          "gcp_cloud_armor",
          "gcp_firewall",
          "gcp_fw_policy",
          "gcp_cloud_ids",
          "gcp_vpc",
          "gcp_cloud_router",
          "gcp_cloud_vpn",
          "gcp_interconnect",
          "gcp_cloud_nat",
          "gcp_vpc_peering",
          "gcp_ncc",
          "gcp_psc",
          "gcp_cloud_dns",
          "gcp_cloud_cdn",
          "pcap_scp_server",
          "pcap_tap",
          "keysight"
        ],
        "type": "string",
        "description": "* `f5_bigip` - F5 BIG-IP\n* `f5os` - F5OS (rSeries / VELOS)\n* `viprion` - F5 VIPRION Chassis\n* `netscaler` - Citrix NetScaler / ADC\n* `kemp` - Kemp LoadMaster\n* `a10` - A10 Networks Thunder\n* `alteon` - Radware Alteon\n* `nginx` - F5 NGINX Plus (ADC)\n* `azure_alb` - Azure Application Gateway / ALB\n* `azure_lb` - Azure Load Balancer (Standard)\n* `aws_alb` - AWS Application Load Balancer\n* `f5_xc` - F5 Distributed Cloud (XC)\n* `nsx_firewall` - VMware NSX Firewall\n* `fortimanager` - Fortinet FortiManager\n* `checkpoint_sms` - Check Point SmartCenter / SMS\n* `cisco_asa` - Cisco ASA Firewall\n* `cisco_ftd` - Cisco Firepower / FTD\n* `fortigate` - Fortinet FortiGate\n* `paloalto_fw` - Palo Alto Firewall (direct)\n* `checkpoint_gw` - Check Point Gateway\n* `sonicwall` - SonicWall Firewall\n* `watchguard` - WatchGuard Firebox\n* `barracuda_fw` - Barracuda CloudGen Firewall\n* `sophos_xg` - Sophos XG / XGS Firewall\n* `juniper_srx` - Juniper SRX Firewall\n* `pfsense` - pfSense Firewall\n* `opnsense` - OPNsense Firewall\n* `meraki_mx` - Cisco Meraki MX\n* `forcepoint` - Forcepoint NGFW\n* `cisco_router` - Cisco Router (IOS/IOS-XE)\n* `cisco_iosxr` - Cisco Router (IOS-XR)\n* `juniper_router` - Juniper Router (MX Series)\n* `arista_router` - Arista Router (EOS)\n* `cisco_switch` - Cisco Switch (Catalyst / IOS-XE)\n* `cisco_nxos` - Cisco Nexus Switch (NX-OS)\n* `juniper_switch` - Juniper Switch (EX / QFX)\n* `arista_switch` - Arista Switch (EOS)\n* `aruba_cx` - HPE Aruba Switch (AOS-CX)\n* `cisco_apic` - Cisco APIC Controller\n* `cisco_aci_spine` - Cisco ACI Spine Switch\n* `cisco_aci_leaf` - Cisco ACI Leaf Switch\n* `nsx_edge` - VMware NSX-T Edge Node\n* `nsx_transport` - VMware NSX-T Transport Node\n* `avi` - VMware NSX ALB / AVI Controller\n* `nsx_manager` - VMware NSX-T Manager\n* `infoblox` - Infoblox NIOS\n* `bluecat` - BlueCat Address Manager\n* `efficientip` - EfficientIP SOLIDserver\n* `zscaler` - Zscaler ZIA / ZPA\n* `cloudflare` - Cloudflare WAF / CDN\n* `imperva` - Imperva WAF / DDoS / CDN\n* `akamai` - Akamai Edge / WAF / CDN\n* `f5_xc_waf` - F5 Distributed Cloud (XC) WAF\n* `barracuda_waf` - Barracuda WAF\n* `radware_cloud` - Radware Cloud WAF (Cloud WAAP)\n* `azure_front_door` - Azure Front Door (WAF / CDN)\n* `aws_nlb` - AWS Network Load Balancer\n* `aws_gwlb` - AWS Gateway Load Balancer\n* `aws_elb` - AWS Classic Load Balancer (ELB)\n* `aws_global_accel` - AWS Global Accelerator\n* `aws_net_firewall` - AWS Network Firewall\n* `aws_sg` - AWS Security Group\n* `aws_nacl` - AWS Network ACL\n* `aws_waf` - AWS WAF\n* `aws_shield` - AWS Shield (DDoS)\n* `aws_fw_manager` - AWS Firewall Manager\n* `aws_vpc` - AWS VPC\n* `aws_transit_gw` - AWS Transit Gateway\n* `aws_vpn_gw` - AWS Site-to-Site VPN\n* `aws_direct_connect` - AWS Direct Connect\n* `aws_nat_gw` - AWS NAT Gateway\n* `aws_inet_gw` - AWS Internet Gateway\n* `aws_route_table` - AWS Route Table\n* `aws_vpc_peering` - AWS VPC Peering\n* `aws_privatelink` - AWS PrivateLink / VPC Endpoint\n* `aws_cloud_wan` - AWS Cloud WAN\n* `aws_route53` - AWS Route 53 (DNS)\n* `aws_cloudfront` - AWS CloudFront (CDN)\n* `azure_traffic_mgr` - Azure Traffic Manager\n* `azure_firewall` - Azure Firewall\n* `azure_nsg` - Azure Network Security Group\n* `azure_waf` - Azure WAF\n* `azure_ddos` - Azure DDoS Protection\n* `azure_vnet` - Azure Virtual Network (VNet)\n* `azure_vnet_peer` - Azure VNet Peering\n* `azure_vpn_gw` - Azure VPN Gateway\n* `azure_expressroute` - Azure ExpressRoute\n* `azure_route_tbl` - Azure Route Table (UDR)\n* `azure_nat_gw` - Azure NAT Gateway\n* `azure_vwan` - Azure Virtual WAN\n* `azure_priv_link` - Azure Private Link / Endpoint\n* `azure_bastion` - Azure Bastion\n* `azure_route_svr` - Azure Route Server\n* `azure_dns` - Azure DNS\n* `azure_cdn` - Azure CDN\n* `gcp_lb_ext` - GCP External Load Balancer\n* `gcp_lb_int` - GCP Internal Load Balancer\n* `gcp_lb_network` - GCP Network (Passthrough) LB\n* `gcp_cloud_armor` - GCP Cloud Armor (WAF)\n* `gcp_firewall` - GCP VPC Firewall Rules\n* `gcp_fw_policy` - GCP Hierarchical Firewall Policy\n* `gcp_cloud_ids` - GCP Cloud IDS\n* `gcp_vpc` - GCP VPC Network\n* `gcp_cloud_router` - GCP Cloud Router\n* `gcp_cloud_vpn` - GCP Cloud VPN\n* `gcp_interconnect` - GCP Cloud Interconnect\n* `gcp_cloud_nat` - GCP Cloud NAT\n* `gcp_vpc_peering` - GCP VPC Peering\n* `gcp_ncc` - GCP Network Connectivity Center\n* `gcp_psc` - GCP Private Service Connect\n* `gcp_cloud_dns` - GCP Cloud DNS\n* `gcp_cloud_cdn` - GCP Cloud CDN\n* `pcap_scp_server` - PCAP SCP / SFTP Server\n* `pcap_tap` - PCAP Network Tap\n* `keysight` - Keysight Technologies (Ixia)"
      },
      "Upgrade": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UpgradeStep"
            },
            "readOnly": true
          },
          "progress_percent": {
            "type": "string",
            "readOnly": true
          },
          "tenant_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "vendor": {
            "$ref": "#/components/schemas/Vendor948Enum"
          },
          "status": {
            "$ref": "#/components/schemas/Status294Enum"
          },
          "target_version": {
            "type": "string",
            "maxLength": 50
          },
          "image_path": {
            "type": "string",
            "maxLength": 500
          },
          "current_step": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": -2147483648
          },
          "total_steps": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": -2147483648
          },
          "notes": {
            "type": "string"
          },
          "created_by": {
            "type": "string",
            "maxLength": 100
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "device_group": {
            "type": "integer",
            "nullable": true
          }
        },
        "required": [
          "created_at",
          "id",
          "name",
          "progress_percent",
          "steps",
          "target_version",
          "updated_at"
        ]
      },
      "UpgradeStep": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "device_name": {
            "type": "string",
            "readOnly": true
          },
          "tenant_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "step_number": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": -2147483648
          },
          "step_name": {
            "type": "string",
            "maxLength": 200
          },
          "status": {
            "$ref": "#/components/schemas/UpgradeStepStatusEnum"
          },
          "log": {
            "type": "string"
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "upgrade": {
            "type": "integer"
          },
          "device": {
            "type": "integer"
          }
        },
        "required": [
          "device",
          "device_name",
          "id",
          "step_name",
          "step_number",
          "upgrade"
        ]
      },
      "DeviceGroup": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "location_name": {
            "type": "string",
            "readOnly": true
          },
          "device_count": {
            "type": "string",
            "readOnly": true
          },
          "primary_vendor": {
            "type": "string",
            "readOnly": true
          },
          "tenant_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "description": {
            "type": "string"
          },
          "location": {
            "type": "integer",
            "nullable": true
          }
        },
        "required": [
          "device_count",
          "id",
          "location_name",
          "name",
          "primary_vendor"
        ]
      },
      "DeviceLifecycle": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "vendor": {
            "$ref": "#/components/schemas/DeviceLifecycleVendorEnum"
          },
          "vendor_display": {
            "type": "string",
            "readOnly": true
          },
          "record_type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DeviceLifecycleRecordTypeEnum"
              }
            ],
            "default": "hardware"
          },
          "record_type_display": {
            "type": "string",
            "readOnly": true
          },
          "product_family": {
            "type": "string",
            "maxLength": 200
          },
          "model": {
            "type": "string",
            "description": "Platform model or software version string, e.g. \"i5800\" or \"14.1.x\"",
            "maxLength": 200
          },
          "description": {
            "type": "string"
          },
          "announced_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Date EOL/EOS was publicly announced"
          },
          "last_order_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of Sale \u2014 last day new units can be ordered"
          },
          "end_of_new_development": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of new feature / enhancement development"
          },
          "end_of_bug_fix": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of bug-fix and maintenance releases"
          },
          "end_of_security_fix": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of security / vulnerability patches (EOVS)"
          },
          "end_of_sw_maintenance": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of all software maintenance (EOSM)"
          },
          "end_of_tech_support": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of Technical Support \u2014 no more TAC/support cases"
          },
          "end_of_life": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of Life \u2014 all vendor support ends"
          },
          "end_of_hw_maintenance": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of hardware maintenance / spare parts"
          },
          "end_of_rma": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "End of RMA / hardware replacement programme"
          },
          "end_of_service_contract": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Last date to renew a support/service contract"
          },
          "source_url": {
            "type": "string",
            "format": "uri",
            "description": "Official vendor EOL/EOS announcement URL",
            "maxLength": 200
          },
          "notes": {
            "type": "string"
          },
          "computed_status": {
            "type": "string",
            "readOnly": true
          },
          "days_until_eol": {
            "type": "integer",
            "readOnly": true
          },
          "next_milestone": {
            "type": "object",
            "additionalProperties": {},
            "readOnly": true,
            "nullable": true
          },
          "matched_device_count": {
            "type": "integer",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "computed_status",
          "created_at",
          "days_until_eol",
          "id",
          "matched_device_count",
          "model",
          "next_milestone",
          "product_family",
          "record_type_display",
          "updated_at",
          "vendor",
          "vendor_display"
        ]
      },
      "PaginatedUpgradeListList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=4"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=2"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UpgradeList"
            }
          }
        }
      },
      "PaginatedFirmwareImageList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=4"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=2"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FirmwareImage"
            }
          }
        }
      },
      "DeviceGroupRequest": {
        "type": "object",
        "properties": {
          "tenant_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "description": {
            "type": "string"
          },
          "location": {
            "type": "integer",
            "nullable": true
          }
        },
        "required": [
          "name"
        ]
      },
      "PaginatedManagedDeviceList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=4"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=2"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ManagedDevice"
            }
          }
        }
      },
      "FirmwareImage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "collector_id_str": {
            "type": "string",
            "readOnly": true
          },
          "vendor": {
            "type": "string",
            "maxLength": 20
          },
          "version": {
            "type": "string",
            "maxLength": 50
          },
          "build": {
            "type": "string",
            "maxLength": 50
          },
          "filename": {
            "type": "string",
            "maxLength": 200
          },
          "file_path": {
            "type": "string",
            "maxLength": 500
          },
          "file_size": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": -9223372036854775808,
            "format": "int64"
          },
          "md5_hash": {
            "type": "string",
            "maxLength": 64
          },
          "location": {
            "$ref": "#/components/schemas/LocationEnum"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "collector": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "collector_id_str",
          "created_at",
          "file_path",
          "filename",
          "id",
          "vendor",
          "version"
        ]
      },
      "PaginatedDeviceGroupList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=4"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=2"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeviceGroup"
            }
          }
        }
      },
      "FirmwareImageRequest": {
        "type": "object",
        "properties": {
          "vendor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 20
          },
          "version": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50
          },
          "build": {
            "type": "string",
            "maxLength": 50
          },
          "filename": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "file_path": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "file_size": {
            "type": "integer",
            "maximum": 9223372036854775807,
            "minimum": -9223372036854775808,
            "format": "int64"
          },
          "md5_hash": {
            "type": "string",
            "maxLength": 64
          },
          "location": {
            "$ref": "#/components/schemas/LocationEnum"
          },
          "collector": {
            "type": "string",
            "minLength": 1,
            "nullable": true
          }
        },
        "required": [
          "file_path",
          "filename",
          "vendor",
          "version"
        ]
      },
      "Status294Enum": {
        "enum": [
          "pending",
          "in_progress",
          "completed",
          "failed",
          "rolled_back"
        ],
        "type": "string",
        "description": "* `pending` - Pending\n* `in_progress` - In Progress\n* `completed` - Completed\n* `failed` - Failed\n* `rolled_back` - Rolled Back"
      }
    }
  }
}