Request(s) and Bundle Requests REST APIs

About XPRESSO Request(s) and Bundle Requests REST APIs

XPRESSO provides public REST APIs to manage requests and retrieve request results.

XPRESSO provides the following public REST APIs to submit, retrieve, and stop Request(s) and Bundled Request information.

Submit Request

Submits an already defined XPRESSO request.

  • URL: /api/v1/requests
  • Method: POST
  • Permission Required: run_request
  • Group: retrieved from headers
  • Data Payload

NOTE 1:
All fields other than profile are optional ways to override the defaults or otherwise customize your request.
NOTE 2:
Payload can either contain testbeds or a topologies list. Providing both returns HTTP 400.

{
  "profile": "964c036a-619e-4001-b62e-4f7f028231dc",
  "testbeds": ["07f3a282-ac12-4993-96b0-181912a41bb1"],
  "submitted_for": "some_cec",
  "compare_baseline": true,
  "is_baseline": true,
  "description": "This is a test run",
  "clean": true,
  "max_request_runtime_seconds": 86400,
  "tags": ["xpresso", "test"],
  "branch": "master",
  "parameters": {
    "env_vars": {
      "ATS_SECURE_HOSTS": "ssr-sjc-vmftp-5 ssr-sjc-vmftp-8 ssr-sjc-vmftp-6"
    },
    "job_args": {
      "--turbo": true,
      "--run-again": "some value"
    },
    "harness_args": {
      "--loglevel": "INFO"
    }
  }
}
  • Success Response

    • Condition: Data provided is valid and User is Authenticated
    • Code: 200 OK
    • Response example:
{
  "username": "some_cec",
  "request_id": "REQ0000426",
  "state": "PREPARING",
  "branch": "N/A",
  "submitter": "my_cec",
  "request_url": "http://asg-server/services/request-detail/REQ0000426",
  "service_url": "http://asg-server/services/request-detail/REQ0000426?share_key=b76a91b2-635a-41ad-89f0-4d07768a5d9d",
  "items": ["REQ0000426-1"]
}
  • Error Response
    • Condition: If provided data is invalid, eg. profile not found
    • Code: 400 BAD REQUEST
    • Response example:
    {
      "Error": "Provided profile is not defined."
    }
    

Submit Bundle Request

Submits an already defined XPRESSO bundle request.

  • URL: /api/v1/requests
  • Method: POST
  • Permission Required: run_request
  • Group: retrieved from headers
  • Data Payload

NOTE:
Testbeds, topologies, and arguments must be pre defined in the bundle, options cannot be passed at this time.

{
  "bundle": "964c036a-619e-4001-b62e-4f7f028231dc",
  "submitted_for": "some_cec",
  "compare_baseline": true,
  "is_baseline": true,
  "description": "This is a test run",
  "clean": true,
  "max_request_runtime_seconds": 86400,
  "tags": ["xpresso", "test"],
  "branch": "master"
}
  • Success Response

    • Condition: Data provided is valid and User is Authenticated
    • Code: 200 OK
    • Response example:
      {
        "username": "some_cec",
        "request_id": "REQ0000426",
        "state": "PREPARING",
        "branch": "N/A",
        "submitter": "my_cec",
        "request_url": "http://asg-server/services/request-detail/REQ0000426",
        "service_url": "http://asg-server/services/request-detail/REQ0000426?share_key=b76a91b2-635a-41ad-89f0-4d07768a5d9d",
        "items": ["REQ0000426-1"]
      }
      
  • Error Response

    • Condition: If provided data is invalid, eg. bundle not found
    • Code: 400 BAD REQUEST
    • Response example:
    {
      "Error": "Provided bundle is not defined."
    }
    

Retrieve Requests

Returns requests defined under group.

  • URL: /api/v1/requests
  • Method: GET
  • Permission Required: No permission required.
  • Group: retrieved from headers
  • Success Response
    • Condition: Authorized User.
    • Code: 200 OK
    • Response example:
      [
        {
          "source": "API",
          "service_url": "http://xpresso-server/services/request-detail/REQ0001446?share_key=dd24370a-95be-472d-b06d-dd8ae5515581",
          "instance_url": "http://xpresso-server/",
          "date_created": "2019-08-27T15:16:14.247943Z",
          "name": "Job_VIRL",
          "verdict": null,
          "interest_list": "['user@company.com']",
          "schedule_id": null,
          "consolidated_summary": {
            "applicable_tasks": 0,
            "abort": 0,
            "passx": 0,
            "success_rate_rule": "('passed' + 'passx' + 'skip')/total_tasks * 100.0",
            "fail": 0,
            "block": 0,
            "total_tasks": 0,
            "skip": 0,
            "error": 0,
            "pass": 0,
            "unknown": 0,
            "success_rate": 0
          },
          "description": null,
          "items": [
            {
              "call_stack_report": [
                {
                  "headers": {},
                  "start_time": null,
                  "service_name": "cdets",
                  "item_state": "FINALIZING",
                  "meta": {},
                  "return_code": 0,
                  "retry_count": 0,
                  "uuid": null,
                  "description": "optional",
                  "state": "INIT",
                  "end_time": null,
                  "detail": null,
                  "callback_url": null
                }
              ],
              "parent": null,
              "priority_history": [],
              "harness_config": [
                {
                  "easypy": ""
                }
              ],
              "results": {
                "run": {
                  "start_time": "2019-08-27T15:17:04.368598Z",
                  "completion_time": "2019-08-27T15:17:44.932012Z",
                  "state": "FAILED",
                  "summary": {
                    "applicable_tasks": 0,
                    "total_tasks": 0,
                    "unknown": 0,
                    "abort": 0,
                    "fail": 0,
                    "pass": 0,
                    "block": 0,
                    "passx": 0,
                    "skip": 0,
                    "error": 0,
                    "success_rate": 0
                  },
                  "uid": "REQ0001446-1-run"
                },
                "clean": {
                  "start_time": null,
                  "completion_time": null,
                  "state": null,
                  "summary": {},
                  "uid": null
                }
              },
              "reservations": [],
              "options": {
                "-trigger_groups": "And('pyats', Not('physical'))",
                "callback_notify": "http://xpresso-server/#Jwt+eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VybmFtZSI6InRhaGlnYXNoIiwidG9rZW5fdHlwZSI6ImFwaS10b2tlbiIsImV4cCI6MTU2NzUyMzc3MywiZGF0ZV9jcmVhdGVkIjoiMjAxOS0wOC0yN1QxNToxNjoxMy41MDdaIiwiZ3JvdXAiOiJLYXphYW0ifQ.iy3bV_OxEVSEtIfQJxBRilJZe6yEBtU0oHZTQMwhengfhUqOknDHuoCzRBpo27Y5wwLY2wzHekEOJOj0KDcOu9eUjC5eV4IgvcZYxvfjZ7On7lKq_QuDeHEs2P34wIdy_WiKyRuPNoAomVyh5piM_41weBTFx11eUgdSgei59pjQynxsZ6PEZwDkXxv1QuGfLvVwS_Z41Q0K19kfdXifsF2zPDORHemW-21yJ95Qn5G7ELHYydvJOWsufTCM29s9BrkIj9aoBTD5tObzOkPW9TTQwNPWoaFrYD3er-hQDgHFzQj9Vq-Ef4QsjFuLTM5lhiAs7DhHh8ihmenCq9ANhA"
              },
              "submitted_testbeds": [
                {
                  "name": "pyATS_pod12_shared",
                  "uuid": "22a5dd98-63e1-46b1-b0c1-88833b24da14",
                  "reservations": []
                },
                {
                  "name": "pyATS_pod13_shared",
                  "uuid": "dacba4c8-22ff-4b5b-b4a4-4d69376b8b90",
                  "reservations": []
                }
              ],
              "job": {
                "name": "Job_VIRL",
                "path": "/path/to/job_file.py",
                "uuid": "ddc7fe54-ee75-4a8d-a543-23ff36c9b8ea"
              },
              "completion_time": "2019-08-27T15:17:45.205558Z",
              "s3_reason": null,
              "labels": [],
              "state": "FAILED",
              "stop_requested": {},
              "harness_instances": [
                {
                  "oper_state": "ONLINE",
                  "config_state": "ENABLED",
                  "bldg": "ALL",
                  "site": "SJC",
                  "deleted": false,
                  "name": "genie_env",
                  "path": "/path/to/genie",
                  "harness": {
                    "name": "pyATS",
                    "run": "easypy",
                    "clean": "kleenex"
                  },
                  "config": "",
                  "uuid": "189f30a8-c475-4303-b638-77cc93f4073b",
                  "support_liveview": true
                }
              ],
              "item_id": "REQ0001446-1",
              "max_clean_runtime_seconds": 0,
              "priority": 4,
              "meta": {},
              "rerun_root": null,
              "selected_testbed": {
                "name": "pyATS_pod12_shared",
                "uuid": "22a5dd98-63e1-46b1-b0c1-88833b24da14"
              },
              "children": [],
              "error_detail": null,
              "topology": {},
              "engine": {
                "name": "jenkins",
                "type": "jenkins",
                "uuid": "75e32472-e6d9-425f-be88-49be550c2ef1"
              },
              "bugs": [],
              "profile": {
                "name": "DEFAULT",
                "uuid": "b7672128-d6c1-40b3-b30c-80fa50edca03"
              },
              "max_runtime_seconds": 43200,
              "comparison": {},
              "env": {
                "PYTHONPATH": "/path/to/PYTHONPATH/pypi/"
              },
              "start_time": "2019-08-27T15:17:04.374871Z",
              "selected_reservation": null
            }
          ],
          "state": "FAILED",
          "max_request_runtime_seconds": 43200,
          "request_id": "REQ0001446",
          "date_completed": "2019-08-27T15:17:46.561527Z",
          "branch": "",
          "call_stack": null,
          "submitter": "user",
          "requeue": false,
          "meta": "{}",
          "rerun_root": "REQ0001446",
          "children": [],
          "instance_id": "xpresso-server",
          "request_url": "http://xpresso-server/services/request-detail/REQ0001446",
          "postback_token": "Jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VybmFtZSI6InRhaGlnYXNoIiwidG9rZW5fdHlwZSI6ImFwaS10b2tlbiIsImV4cCI6MTU2NzUyMzc3MywiZGF0ZV9jcmVhdGVkIjoiMjAxOS0wOC0yN1QxNToxNjoxMy41MDdaIiwiZ3JvdXAiOiJLYXphYW0ifQ.iy3bV_OxEVSEtIfQJxBRilJZe6yEBtU0oHZTQMwhengfhUqOknDHuoCzRBpo27Y5wwLY2wzHekEOJOj0KDcOu9eUjC5eV4IgvcZYxvfjZ7On7lKq_QuDeHEs2P34wIdy_WiKyRuPNoAomVyh5piM_41weBTFx11eUgdSgei59pjQynxsZ6PEZwDkXxv1QuGfLvVwS_Z41Q0K19kfdXifsF2zPDORHemW-21yJ95Qn5G7ELHYydvJOWsufTCM29s9BrkIj9aoBTD5tObzOkPW9TTQwNPWoaFrYD3er-hQDgHFzQj9Vq-Ef4QsjFuLTM5lhiAs7DhHh8ihmenCq9ANhA",
          "parent_request": null,
          "username": "user",
          "uuid": "dd24370a-95be-472d-b06d-dd8ae5515581"
        },
      ]
      

Retrieve Request

Returns request information including result information.

  • URL: /api/v1/requests/:request_id

  • Method: GET

  • Permission Required: No permission required. User needs to be a member of the group that owns the request.

  • Group: retrieved from headers

  • Success Response

    • Condition: If request exists and Authorized User is a member of the group.
    • Code: 200 OK
    • Response example:
      {
        "source": "API",
        "service_url": "http://xpresso-server/services/request-detail/REQ0001446?share_key=dd24370a-95be-472d-b06d-dd8ae5515581",
        "instance_url": "http://xpresso-server/",
        "date_created": "2019-08-27T15:16:14.247943Z",
        "name": "Job_VIRL",
        "verdict": null,
        "interest_list": "['user@company.com']",
        "schedule_id": null,
        "consolidated_summary": {
          "applicable_tasks": 0,
          "abort": 0,
          "passx": 0,
          "success_rate_rule": "('passed' + 'passx' + 'skip')/total_tasks * 100.0",
          "fail": 0,
          "block": 0,
          "total_tasks": 0,
          "skip": 0,
          "error": 0,
          "pass": 0,
          "unknown": 0,
          "success_rate": 0
        },
        "description": null,
        "items": [
          {
            "call_stack_report": [
              {
                "headers": {},
                "start_time": null,
                "service_name": "cdets",
                "item_state": "FINALIZING",
                "meta": {},
                "return_code": 0,
                "retry_count": 0,
                "uuid": null,
                "description": "optional",
                "state": "INIT",
                "end_time": null,
                "detail": null,
                "callback_url": null
              }
            ],
            "parent": null,
            "priority_history": [],
            "harness_config": [
              {
                "easypy": ""
              }
            ],
            "results": {
              "run": {
                "scripts": [
                  {
                    "meta": {
                      "task_id": "Task-1",
                      "name": "genie_testscript.py",
                      "path": "/path/to/harness"
                    },
                    "sections": [
                      {
                        "section_id": "Task-1",
                        "source_file": "/path/to/genie_testscript.py",
                        "sequence_number": 1,
                        "section_name": "genie_testscript.py",
                        "result": "",
                        "run_time": "1.0",
                        "parent_id": null,
                        "log_start_line": 0,
                        "id": "0f9720a8-2c18-4f90-8a24-3212d6555e8e",
                        "description": "",
                        "log_size_line": 60,
                        "log_size": -1,
                        "script_id": 1007,
                        "log_start": 0,
                        "section_type": "testscript",
                        "source_line": 0,
                        "stop_time": "2019-08-27T08:21:44Z",
                        "log_file": "TaskLog.Task-1",
                        "start_time": "2019-08-27T08:21:43Z"
                      }
                    ],
                    "summary": {
                      "applicable_tasks": 0,
                      "total_tasks": 0,
                      "unknown": 0,
                      "abort": 0,
                      "fail": 0,
                      "pass": 0,
                      "block": 0,
                      "passx": 0,
                      "skip": 0,
                      "error": 0,
                      "success_rate": 0
                    }
                  }
                ],
                "start_time": "2019-08-27T15:17:04.368598Z",
                "completion_time": "2019-08-27T15:17:44.932012Z",
                "state": "FAILED",
                "summary": {
                  "applicable_tasks": 0,
                  "total_tasks": 0,
                  "unknown": 0,
                  "abort": 0,
                  "fail": 0,
                  "pass": 0,
                  "block": 0,
                  "passx": 0,
                  "skip": 0,
                  "error": 0,
                  "success_rate": 0
                },
                "uid": "REQ0001446-1-run",
                "results_meta": {
                  "created_by": "",
                  "testbed": "pyATS_pod12_shared",
                  "suite_name": "job_virl",
                  "last_accessed": "2019-08-27T15:17:41.253117Z",
                  "meta_info": {},
                  "status": "completed",
                  "stop_time": "2019-08-27T08:21:44Z",
                  "component": "N/A",
                  "date_created": "2019-08-27T15:17:41.000426Z",
                  "submitter": "user",
                  "ats_tree": "/path/to/genie_group",
                  "result_format": "trade",
                  "result_id": "REQ0001446-1-run",
                  "id": 1047,
                  "related_id": "REQ0001446-1",
                  "job": "job_virl",
                  "exec_host": "pyats-training.cisco.com",
                  "run_time": "10.0",
                  "branch": "N/A",
                  "start_time": "2019-08-27T08:21:34Z",
                  "archive_location": "/path/to/REQ_run.zip"
                }
              },
              "clean": {
                "scripts": [],
                "start_time": null,
                "completion_time": null,
                "state": null,
                "summary": {},
                "uid": null,
                "results_meta": {}
              }
            },
            "reservations": [],
            "options": {
              "-trigger_groups": "And('pyats', Not('physical'))",
              "callback_notify": "http://xpresso-server/#Jwt+eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VybmFtZSI6InRhaGlnYXNoIiwidG9rZW5fdHlwZSI6ImFwaS10b2tlbiIsImV4cCI6MTU2NzUyMzc3MywiZGF0ZV9jcmVhdGVkIjoiMjAxOS0wOC0yN1QxNToxNjoxMy41MDdaIiwiZ3JvdXAiOiJLYXphYW0ifQ.iy3bV_OxEVSEtIfQJxBRilJZe6yEBtU0oHZTQMwhengfhUqOknDHuoCzRBpo27Y5wwLY2wzHekEOJOj0KDcOu9eUjC5eV4IgvcZYxvfjZ7On7lKq_QuDeHEs2P34wIdy_WiKyRuPNoAomVyh5piM_41weBTFx11eUgdSgei59pjQynxsZ6PEZwDkXxv1QuGfLvVwS_Z41Q0K19kfdXifsF2zPDORHemW-21yJ95Qn5G7ELHYydvJOWsufTCM29s9BrkIj9aoBTD5tObzOkPW9TTQwNPWoaFrYD3er-hQDgHFzQj9Vq-Ef4QsjFuLTM5lhiAs7DhHh8ihmenCq9ANhA"
            },
            "submitted_testbeds": [
              {
                "name": "GICT-pyATS_pod12_shared-7chuTf",
                "uuid": "22a5dd98-63e1-46b1-b0c1-88833b24da14",
                "reservations": []
              },
              {
                "name": "GICT-pyATS_pod13_shared-_8X6N3",
                "uuid": "dacba4c8-22ff-4b5b-b4a4-4d69376b8b90",
                "reservations": []
              }
            ],
            "job": {
              "name": "Job_VIRL",
              "path": "/path/to/job_virl.py",
              "uuid": "ddc7fe54-ee75-4a8d-a543-23ff36c9b8ea"
            },
            "completion_time": "2019-08-27T15:17:45.205558Z",
            "s3_reason": null,
            "labels": [],
            "state": "FAILED",
            "stop_requested": {},
            "harness_instances": [
              {
                "oper_state": "ONLINE",
                "config_state": "ENABLED",
                "bldg": "ALL",
                "site": "SJC",
                "deleted": false,
                "name": "user_group_env",
                "path": "/path/to/genie_group",
                "harness": {
                  "name": "pyATS",
                  "run": "easypy",
                  "clean": "kleenex"
                },
                "config": "",
                "uuid": "189f30a8-c475-4303-b638-77cc93f4073b",
                "support_liveview": true
              }
            ],
            "item_id": "REQ0001446-1",
            "max_clean_runtime_seconds": 0,
            "priority": 4,
            "meta": {},
            "rerun_root": null,
            "selected_testbed": {
              "name": "GICT-pyATS_pod12_shared-7chuTf",
              "uuid": "22a5dd98-63e1-46b1-b0c1-88833b24da14"
            },
            "children": [],
            "error_detail": null,
            "topology": {},
            "engine": {
              "name": "jenkins",
              "type": "jenkins",
              "uuid": "75e32472-e6d9-425f-be88-49be550c2ef1"
            },
            "bugs": [],
            "profile": {
              "name": "DEFAULT",
              "uuid": "b7672128-d6c1-40b3-b30c-80fa50edca03"
            },
            "max_runtime_seconds": 43200,
            "comparison": {},
            "env": {
              "PYTHONPATH": "/path/to/genie_group/pypi/"
            },
            "start_time": "2019-08-27T15:17:04.374871Z",
            "selected_reservation": null
          }
        ],
        "state": "FAILED",
        "max_request_runtime_seconds": 43200,
        "request_id": "REQ0001446",
        "date_completed": "2019-08-27T15:17:46.561527Z",
        "branch": "",
        "call_stack": null,
        "submitter": "user",
        "requeue": false,
        "meta": "{}",
        "rerun_root": "REQ0001446",
        "children": [],
        "instance_id": "xpresso-server",
        "request_url": "http://xpresso-server/services/request-detail/REQ0001446",
        "postback_token": "Jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VybmFtZSI6InRhaGlnYXNoIiwidG9rZW5fdHlwZSI6ImFwaS10b2tlbiIsImV4cCI6MTU2NzUyMzc3MywiZGF0ZV9jcmVhdGVkIjoiMjAxOS0wOC0yN1QxNToxNjoxMy41MDdaIiwiZ3JvdXAiOiJLYXphYW0ifQ.iy3bV_OxEVSEtIfQJxBRilJZe6yEBtU0oHZTQMwhengfhUqOknDHuoCzRBpo27Y5wwLY2wzHekEOJOj0KDcOu9eUjC5eV4IgvcZYxvfjZ7On7lKq_QuDeHEs2P34wIdy_WiKyRuPNoAomVyh5piM_41weBTFx11eUgdSgei59pjQynxsZ6PEZwDkXxv1QuGfLvVwS_Z41Q0K19kfdXifsF2zPDORHemW-21yJ95Qn5G7ELHYydvJOWsufTCM29s9BrkIj9aoBTD5tObzOkPW9TTQwNPWoaFrYD3er-hQDgHFzQj9Vq-Ef4QsjFuLTM5lhiAs7DhHh8ihmenCq9ANhA",
        "parent_request": null,
        "username": "user",
        "uuid": "dd24370a-95be-472d-b06d-dd8ae5515581",
        "tags": []
      }
      
  • Error Response

    • Condition: If request does not exist with provided request_id
    • Code: 404 NOT FOUND
    • Response example: {}

Stop Request

Terminates an already submitted request.

  • URL: /api/v1/requests/:request_id/stop
  • Method: PATCH
  • Permission Required: stop_request
  • Group: retrieved from headers
  • Data Payload
{
  "reason": "Resource urgently needed for another request"
}
  • Success Response
    • Condition: If request exists and in RUNNING state and Authorized User has permission to stop request.
    • Code: 200 OK
    • Response example:
      {
        "state": "STOPPED",
        "branch": "N/A",
        "request_url": "http://asg-server/services/request-detail/REQ0000427",
        "request_id": "REQ0000427",
        "username": "user",
        "service_url": "http://asg-server/services/request-detail/REQ0000427?share_key=9e8fa6f5-b968-4fa5-8c93-29acb78293c6",
        "submitter": "user2",
        "items": ["REQ0000427-1"]
      }
      
  • Error Response
    • Condition: If request does not exist with provided request_id
    • Code: 404 NOT FOUND
    • Response example: {}