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()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.txtUpdate 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"
}Instantiate the client.
import scantron_api_client
sc = scantron_api_client.ScantronClient()sites = sc.retrieve_sites()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())engines = sc.retrieve_engines()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())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.
# 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())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")