Skip to content

Latest commit

 

History

History

README.md

Scantron API Client

A Python API client for interacting with the Scantron console. For Create/Retrieve/Update/Delete functions, a Python requests object is returned with the standard requests attributes:

import scantron_api_client

sc = scantron_api_client.ScantronClient()
engine_id = 3
response = sc.retrieve_engine(engine_id)

print(response.status_code)
print(response.json())

For functions to query all values from an endpoint, a JSON dictionary is returned:

sites = sc.retrieve_sites()

Installation

git clone https://github.com/rackerlabs/scantron.git
cd scantron_api_client
virtualenv -p python3 .venv  # If using a virtual environment.
source .venv/bin/activate  # If using a virtual environment.
pip install -r requirements.txt

Update Credentials

Update the scantron_api_secrets.json file with the host, port, and API key for an admin / superuser. The token should be 40 characters.

{
    "host": "scantron-console.mydomain.com",
    "port": 443,
    "token": "7a4d...b388"
}

Usage

Instantiate the client.

import scantron_api_client
sc = scantron_api_client.ScantronClient()

Retrieve all sites

sites = sc.retrieve_sites()

Create a scan command

payload = {
  "scan_binary": "nmap",
  "scan_command_name": "Top 20 TCP",
  "scan_command": "--top-ports 20 -sV -n -Pn --open",
}

response = sc.create_scan_command(payload)
print(response.status_code)
print(response.json())

Retrieve all engines

engines = sc.retrieve_engines()

Create a site

It requires the Scan Command ID and Scan Engine ID.

payload = {
  "site_name": "DMZ",
  "description": "DMZ Assets",
  "targets": "192.168.1.1/24 fw1.example.com",
  "excluded_targets": "192.168.1.100",
  "scan_command": 1,
  "scan_engine": 1,
  "email_scan_alerts": True,
  "email_alert_addresses": "alice@example.com,bob@example.com",
}

response = sc.create_site(payload)
print(response.status_code)
print(response.json())

Create a scan

The recurrences value can be tricky. If you are using a complicated one, open developer tools in your browser, create the scan through the web GUI, and inspect the POST request. Note there is a newline (\n) between RRULE and RDATE. RRULE isn't required, but at a minimum you need to include RDATE: for a single non-recurring scan.

recurrences

# Option 1 - Scan at a future time.
payload = {
    "site": 1,
    "scan_name": "DMZ Scan",
    "enable_scan": True,
    "start_time": "16:00",
    "recurrences": "RRULE:FREQ=WEEKLY;BYDAY=MO",
}

# Option 2 - Schedule at the next available start time.
next_eligible_scan_string = sc.retrieve_next_available_scan_time()

payload = {
    "site": 1,
    "scan_name": "DMZ Scan",
    "enable_scan": True,
    "start_time": next_eligible_scan_string,
    "recurrences": "RRULE:FREQ=WEEKLY;BYDAY=MO",
}

response = sc.create_scan(payload)
print(response.status_code)
print(response.json())

Retrieve scan results

Requires the scan ID.

scans = sc.retrieve_scans()

nmap_scan_results = sc.retrieve_scan_results(1, "nmap")
xml_scan_results = sc.retrieve_scan_results(1, "xml")
json_scan_results = sc.retrieve_scan_results(3, "json")