Run Splunk AppInspect requests through the API

There are four steps in the basic Splunk AppInspect API flow:

  1. Log in to Splunkbase using HTTP basic authentication and retrieve a token. This returns an authentication token to use for the Splunk AppInspect Web service.
  2. Submit an app for validation. This returns a request ID to use to retrieve the status and final report.
  3. Retrieve the status of a validation that is in progress using the request ID.
  4. Retrieve the report results of the validation that was performed using the request ID.

Authenticate and retrieve a JSON Web Token

You authenticate to the Splunk AppInspect API using HTTP basic authentication through a JSON Web Token (JWT).
To obtain a JWT, send a GET request that contains your splunk.com username and password to the api.splunk.com login endpoint at https://api.splunk.com/2.0/reset/login/splunk, as shown in the following cURL request:

curl -X GET \
     -u <username> \
     --url "https://api.splunk.com/2.0/rest/login/splunk"

Replace <username> with your splunk.com username. The API server asks for your password.

The password you enter here is transmitted in plaintext.

The API server responds with a JSON object. The following is a typical response:

{
    "status_code": 200,
    "status": "success",
    "msg": "Successfully authenticated user and assigned a token",
    "data": {
        "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjp7InVpZCI6IjEwNDY2IiwidW5hbWUiOiJxYWVudmFkbWluIiwibmFtZSI6IlFBTk9ERUVOViBBRE1JTiIsImVtYWlsIjoicWFlbnZhZG1pbkBtYWlsaW5hdG9yLmNvbSIsImRhdGVfcmVnIjoiMTQ1MzQxNzI2OSIsInN0YXRlIjoiMyIsInNhbGVzZm9yY2VfaWQiOiIwMFEyMjAwMDAwMTF3ZjVFQUEiLCJzYWxlc2ZvcmNlX3VzZXJfaWQiOiIwIiwiaXNfb25ldGltZV9lbWFpbF9ieXBhc3Nfb24iOiIwIiwicGFyZW50cyI6WyJBZG1pbmlzdHJhdG9ycyIsIkJldGEgVXNlcnMiLCJEZWNyeXB0IEpXVCBUb2tlbiJdLCJ2YWxpZGF0ZWRfZW1haWwiOiIifSwiaWF0IjoxNDcwNjQ3Nzg4LCJleHAiOjE0NzA3MzQxODgsImF1ZCI6InNwbHVuay5jb20iLCJpc3MiOiJzcGx1bmsuY29tIn0.WhRr4y5cZzwEuH4H02KSPD2xjrXNozEmWza_pznhgFs",
        "user": {
            "name": "SPLUNK USER",
            "email": "splunker@example.com",
            "username": "splunkuser",
            "groups": [
                "Administrators",
                "Beta Users",
                "Decrypt JWT Token"
            ]
        }
    }
}

Submit an app for validation

Submit your app for validation by sending a POST request to the validation endpoint at https://appinspect.splunk.com/v1/app/validate. The endpoint returns a request ID. You'll need the request ID for the following two steps.

See the following cURL example:

curl -X POST \
     -H "Authorization: bearer <token>" \
     -H "Cache-Control: no-cache" \
     -F "app_package=@\"/path/to/splunk/app.tgz\"" \
     --url "https://appinspect.splunk.com/v1/app/validate"

Review an app for compliance with Cloud requirements

In this example, verify that you've fulfilled all of the Splunk Cloud requirements by running the AppInspect tool with the cloud tag:

curl -X POST \
	-H "Authorization: bearer <token>" \
	-H "Cache-Control: no-cache" \
	-F "app_package=@\"/path/to/splunk/app.tgz\"" \
	-F "included_tags=cloud" \
	--url "https://appinspect.splunk.com/v1/app/validate"
 

Review an app for compatibility with Python 3

In this example, verify that your app is compatible with Python 3 by running the AppInspect tool with the py3_migration tag:

curl -X POST \
	-H "Authorization: bearer <token>" \
	-H "Cache-Control: no-cache" \
	-F "app_package=@\"/path/to/splunk/app.tgz\"" \
	-F "included_tags=py3_migration" \
	--url "https://appinspect.splunk.com/v1/app/validate"
 

In this example, the token is represented by <token>. In response, you might see a response like the following:

{
    "links": [
        {
            "href": "/v1/app/validate/status/{request ID}",
            "rel": "status"
        },
        {
            "href": "/v1/app/report/{request id}",
            "rel": "report"
        }
    ],
    "message": "Validation request submitted.",
    "request_id": "93cad1ef-925f-45cd-b385-1083285c3109"
}

Retrieve the status of the validation

Retrieve the status of the validation to see its progress. Send a GET request to the status endpoint https://appinspect.splunk.com/v1/app/validate/status/{request_id} where {request_id} represents the request ID that was returned in the previous step. The endpoint returns status information.

See the following cURL example:

curl -X GET \
	-H "Authorization: bearer <token>" \
        --url https://appinspect.splunk.com/v1/app/validate/status/<request_id>

In response, you might get something like the following, which indicates the progress of the validation. In this case, the validation is still in progress:

{
 "info": {
    "app_name": "An Example Splunk App",
    "app_version": "0.1",
    "checks":
        inprogress: 10
        completed: [
            {
            error: 6,
            failure: 2,
            manual_check: 20,
            not_applicable: 30,
            skipped: 1,
            success: 74
            }
        ]
 },
 "request_id": "93cad1ef-925f-45cd-b385-1083285c3109",
 "status": "PROCESSING"
}

Retrieve the report results of the validation

After the status of the validation is complete, you can retrieve the validation report. Send a GET request to the report endpoint https://appinspect.splunk.com/v1/app/report/{request_id}, where {request_id} is the same request ID that was returned in the submit step. You can instruct the AppInspect API to return the validation report in HTML (text/html) or JSON (application/json) format by setting the Content-Type request header. For example, the following GET request asks for a report in HTML:

curl -X GET \
         -H "Authorization: bearer <token>" \
         -H "Cache-Control: no-cache" \
         -H "Content-Type: text/html" \
         --url "https://appinspect.splunk.com/v1/app/report/4281db6a-ae3b-4637-b52d-d21ef1bb3b5d"

The endpoint returns a validation report in HTML or JSON format, depending on what you specify in the request header. The report might look like the following response in JSON:

{
  "cloc": "      10 text files.",
  "links": [
    {
      "href": "/v1/app/report/7779ce08-1adf-489f-870a-6c1ea6a47948",
      "rel": "self"
    }
  ],
  "reports": [
    {
      "app_author": "The App Author in app.conf",
      "app_description": "The App Description in app.conf.",
      "app_hash": "bb4230ee815dd62b02e0b66780809823",
      "app_name": "The App Name in app.conf",
      "app_version": "The App Version",
      "groups": [
        {
          "checks": [
            {
              "description": "Check that changes made to default/limits.conf are documented.",
              "messages": [
                {
                  "code": "reporter.not_applicable(\"No limits.conf found.\")",
                  "filename": "check_limits_configuration_file.py",
                  "line": 23,
                  "message": "No limits.conf found.",
                  "result": "not_applicable"
                }
              ],
              "name": "check_limits_conf",
              "result": "not_applicable"
            }
          ],
          "description": "Limits.conf file standards",
          "name": "check_limits_configuration_file"
        } 
      ],
      "metrics": {
        "end_time": "2016-09-09T04:50:40.723074",
        "execution": 20.650866,
        "start_time": "2016-09-09T04:50:20.072208"
      },
      "run_parameters": {
        "api_request_id": "e815de54-7648-11e6-93d8-0242ac120007",
        "excluded_tag": null,
        "identity": "my_id",
        "package_location": "/opt/packages/e815de54-7648-11e6-93d8-0242ac120007-app.tgz",
        "splunk_version": null,
        "splunkbase_id": "unknown",
        "tag": null,
        "version": null
      },
      "summary": {
        "error": 0,
        "failure": 3,
        "manual_check": 28,
        "not_applicable": 52,
        "skipped": 0,
        "success": 83,
        "warning": 0
      }
    }
  ],
  "request_id": "7779ce08-1adf-489f-870a-6c1ea6a47948",
  "summary": {
    "error": 0,
    "failure": 3,
    "manual_check": 28,
    "not_applicable": 52,
    "skipped": 0,
    "success": 83,
    "warning": 0
  }
}

The report looks like the following screenshot in HTML:

Screen shot of example AppInspect HTML results page
You typically see only one report in the response. If the uploaded package contained sub-apps or supports apps included within the main app, a report is included for the main app and for each sub-app. In this case, the first report in the response always corresponds to the main app.

Other actions

The AppInspect API includes other endpoints for actions such as listing reports and checks. For more information, see the AppInspect REST API endpoint reference.