-
Notifications
You must be signed in to change notification settings - Fork 138
There is a Datatables API that is used for accessing reports. To help you get started use the shell script and python script examples below.
-
Retrieve Data
- Shell Version
- Python Version
- [Specific Endpoint] (#specific)
- Detele Data
- Convert Output to CSV
To get the data to CSV format, pipe the output to JSON to CSV parser (see below).
Note: starting with MunkiReport v5.3.1 you need to send a CSRF token with the API request. Check the Shell script below for the details.
#!/bin/sh
#
# Script to run automated queries against the munkireport datatables API
#
# Results are returned in JSON format
# The actual entries are in the 'data' variable
#
# To make this work, set up a regular user in munkireport and adjust the
# proper values below
#
# Author: Arjen van Bochoven
# Date: 2015-11-06
# Modified: 2020-03-31 Added CSRF support
# Retrieve data from munkireport
# DEBUG=1
MR_BASE_URL='http://localhost:8888/index.php?'
MR_DATA_QUERY='/datatables/data'
MR_LOGIN='test'
MR_PASSWORD='test'
CLIENT_COLUMNS=(
"machine.serial_number"
"machine.hostname"
"machine.machine_desc"
"reportdata.timestamp"
"reportdata.console_user"
"machine.os_version"
"reportdata.remote_ip"
"munkireport.manifestname"
)
# Create query from columns
columns_to_query()
{
# Pick up array as argument
declare -a COLUMNS=("${!1}")
MR_QUERY=""
COL=0
for i in "${COLUMNS[@]}"; do
MR_QUERY="${MR_QUERY}columns[${COL}][name]=${i}&"
COL=$((COL+1))
done
}
# Authenticate and capture cookie
if [ $DEBUG ]; then echo 'Authenticating to munkireport..'; fi
COOKIE_JAR=$(curl -s --cookie-jar - --data "login=${MR_LOGIN}&password=${MR_PASSWORD}" ${MR_BASE_URL}/auth/login)
SESSION_COOKIE=$(echo $COOKIE_JAR | sed -n 's/.*PHPSESSID[[:space:]]/PHPSESSID=/p')
CSRF_TOKEN=$(echo "$COOKIE_JAR" | sed -n 's/.*CSRF-TOKEN[[:space:]]/X-CSRF-TOKEN: /p')
# Retrieve data with session cookie
columns_to_query CLIENT_COLUMNS[@]
if [ $DEBUG ]; then echo 'Retrieving client data..'; fi
echo $(curl -s -H "$CSRF_TOKEN" --cookie "$SESSION_COOKIE" --data $MR_QUERY ${MR_BASE_URL}${MR_DATA_QUERY})
#!/usr/bin/env python3
import requests
base_url = "https://munkireport.example.com/index.php?"
login = ""
password = ""
columns = [
"machine.serial_number",
"machine.hostname",
"machine.machine_desc",
"reportdata.timestamp",
"reportdata.console_user",
"machine.os_version",
"reportdata.remote_ip",
"munkireport.manifestname",
]
# authenticate and get a session cookie
auth_url = f"{base_url}/auth/login"
query_url = f"{base_url}/datatables/data"
session = requests.Session()
auth_request = session.post(auth_url, data={"login": login, "password": password})
if auth_request.status_code != 200:
print("Invalid url!")
raise SystemExit
headers = {"x-csrf-token": session.cookies["CSRF-TOKEN"]}
def generate_query():
q = {f"columns[{i}][name]": c for i, c in enumerate(columns)}
return q
query_data = session.post(query_url, data=generate_query(), headers=headers)
print(query_data.json())
s_groening reports that you can get data for a specific endpoint by appending the serial number:
https://munkireport.example.com/index.php?/module/reportdata/report/<serialnumber>
#!/usr/bin/env python3
# Code to delete array of SNs from MunkiReport
# Requires requests python module - `sudo pip install requests`
import requests
def munkireport_delete_machine(serial_number, MRadmin, MRpassword):
base_url = "https://munkireport.example.com/index.php?"
auth_url = base_url + "/auth/login"
delete_url = base_url + "/manager/delete_machine/" + serial_number
ses = requests.session()
response = ses.post(auth_url, data={'login': MRadmin, 'password': MRpassword})
headers = {"x-csrf-token": ses.cookies["CSRF-TOKEN"]}
delete_result = ses.delete(delete_url, headers=headers)
if delete_result.status_code != 200:
print(" Error on MunkiReport delete")
raise SystemExit
else:
print((' {} deleted from MunkiReport'.format(serial_number)))
return delete_result.status_code
def main():
MRadmin = ""
MRpassword = ""
serial_numbers = ['ARRAY', 'OF', 'SERIALNUMBERS']
for serial_number in serial_numbers:
print ('============================')
print(('Checking MunkiReport for {}'.format(serial_number)))
if not serial_number is None:
munkireport_delete_machine(serial_number, MRadmin, MRpassword)
else:
print((' Serial number invalid'.format(serial_number)))
print ('============================')
if __name__ == "__main__":
main()
If you need the data in Comma Separated Value format (csv), you could alter the above script to output in CSV format:
#!/usr/bin/python
import requests
import csv, json, sys
base_url='https://domain.example.com/report/index.php?'
login='tim_apple'
password=''
columns=[
"machine.serial_number",
"machine.hostname",
"localadmin.users"
]
# authenticate and get a session cookie
auth_url ='{0}/auth/login'.format(base_url)
query_url='{0}/datatables/data'.format(base_url)
session = requests.Session()
auth_request = session.post(auth_url, data={'login': login , 'password': password})
if auth_request.status_code != 200:
print('Invalid url!')
raise SystemExit
headers = {"x-csrf-token": session.cookies["CSRF-TOKEN"]}
def generate_query():
q = {'columns[{0}][name]'.format(i): c for i, c in enumerate(columns)}
return q
query_data = session.post(query_url, data=generate_query(), headers=headers)
data = query_data.json()['data']
class SKV(csv.excel):
# like excel, but uses semicolons
delimiter = ";"
csv.register_dialect("SKV", SKV)
output = csv.writer(sys.stdout, "SKV")
for row in data:
output.writerow(row)
There is also a Postman collection available at https://github.com/joncrain/munkireport-postman-collection with some other samples of the API.
There is also a FileMaker Pro template to gather and display info via the munkireport API available at https://www.precursor.ca/mrq/ . This was part of a presentation at MacTech Conference 2019 with slides available at: https://pics.mactech.com/PresentationFiles/MTC-2019/191016-MTC-Alex-Narvey-Going-API-With-FileMaker.zip
You can still call the old API in version 6 (at least at the time of this writing) but it is now a three stage rather than a two stage process.
curl -v 'https://mr6.example.com/login' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-c '/Path/To/cookie.txt'
A CSRF Token will be supplied in two places in the resulting HTML result:
in the header it appears in a meta tag e.g.
<meta name="csrf-token" content="Mb372xvNwBKxZ7jprstigDcnoEKbw6QLKfawse3r">
and in the body it appears as a hidden form item: e.g.
<input type="hidden" name="_token" value="Mb372xvNwBKxZ7jprstigDcnoEKbw6QLKfawse3r">
Stage 2: cURL to authenticate using your email address, password, CSRF token (from Stage 1) and Session cookie (from your Cookie-Jar, also Stage 1):
curl -v 'https://mr6.example.com/login' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-raw '_token=Mb372xvNwBKxZ7jprstigDcnoEKbw6QLKfawse3r&email=yourname@example.com&password=YourPassword' \
-b '/Path/To/cookie.txt'
This will return a Session ID in the returned HEADER (not the HTML) which you will use to get data.
The Session ID you need is under the Set-Cookie (not Cookie) tag :
< Set-Cookie: munkireport_session=eyJpdiI6IkUzMzhvSHpPZjVsMFpMQnQ1M1R6dHc9PSIsInZhbHVlIjoibVA1WFNXNVQ2WG9vZERCWm5UbUo5aVRsOVBQVDZpazFNeFFWeUFxZXFGMnE1UzhWVDArcG9hVGFxMUZBMlVTWUlUSTVtTEZNQm1TSTNiY1o5SGtHV28zY3NpbXl3Wk92YnAvdktSa09vVURRNkMweWtXSlJaWHo3OVFMOTBkTWoiLCJtYWMiOiJmNjkwNTA4NWJlZDM2YWZlOTQ4ZGVkZGI0MWZjMjcyMTFhNTBhNzMyODk2ZjIzMjM4NDk4MWY1YjUxZjkyNWYzIiwidGFnIjoiIn0%3D
You now use the CSRF Token from step 1 with the munkireport_session you got from the Header in step 2. Lets say you are getting data from the function module/reportdata/getUptimeStats
curl 'https://mr6.example.com/module/reportdata/getUptimeStats' \
-H 'Accept: application/json' \
-H 'Cookie: munkireport_session=eyJpdiI6IkUzMzhvSHpPZjVsMFpMQnQ1M1R6dHc9PSIsInZhbHVlIjoibVA1WFNXNVQ2WG9vZERCWm5UbUo5aVRsOVBQVDZpazFNeFFWeUFxZXFGMnE1UzhWVDArcG9hVGFxMUZBMlVTWUlUSTVtTEZNQm1TSTNiY1o5SGtHV28zY3NpbXl3Wk92YnAvdktSa09vVURRNkMweWtXSlJaWHo3OVFMOTBkTWoiLCJtYWMiOiJmNjkwNTA4NWJlZDM2YWZlOTQ4ZGVkZGI0MWZjMjcyMTFhNTBhNzMyODk2ZjIzMjM4NDk4MWY1YjUxZjkyNWYzIiwidGFnIjoiIn0%3D' \
-H 'X-CSRF-TOKEN: Mb372xvNwBKxZ7jprstigDcnoEKbw6QLKfawse3r'
The result will be some json resembling:
{"total":2,"oneday":1,"oneweek":1,"oneweekplus":null}
- General Upgrade Procedures
- How to Upgrade Versions
- Troubleshooting Upgrades
- Migrating sqlite to MySQL