In previous posts, I covered:
- Running WebHelpDesk in Docker
- Running Sal in Docker
- Importing JAMF Casper Suite into WebHelpDesk (also in Docker)
WebHelpDesk, among its other features, makes a great inventory aggregate collector thanks to its use of discovery connections. Inventory data can be easily pulled from any flat database. Sal is a reporting engine for Munki that collects inventory data about OS X Munki clients, and JAMF Casper as an iOS MDM (referred to as Casper or “JSS” from here on out) stores inventory data about iOS clients.
We can set up scripts to pull data from Sal, using Sal-WHDImport, and from Casper, using JSSImport. This makes for a great triangle, allowing inventory aggregation into WebHelpDesk, and this is relatively trivial with Docker.
To save some time, I’ve incorporated the Sal-WHDImport script into Sal itself in a Dockerfile, available as the Sal-WHD container. We’ll be using this container below.
I’ve done the same thing with the JSSImport script, creating the JSSImport container.
Preparing Data Files:
Sal requires some modification in order to talk to WebHelpDesk. We’re going to use a plugin Graham Gilbert wrote called WHDImport to sync the Sal data into a single flat database for WebHelpDesk to pull from.
First, we’ll need to modify settings.py. On the Docker host:
mkdir -p /usr/local/sal_data/settings/
curl -o /usr/local/sal_data/settings/settings.py https://raw.githubusercontent.com/macadmins/sal/master/settings.py
Make the following changes to settings.py:
Add 'whdimport',
(with the comma) to the end of the list of INSTALLED_APPS
.
Next, we’ll clone a copy of MacModelShelf:
git clone https://github.com/nmcspadden/MacModelShelf.git /usr/local/sal_data/macmodelshelf
MacModelShelf was originally developed by Per Oloffson, but this version is my fork that uses a JSON database, which seems to improve cross-platform compatibility. The purpose of cloning a local copy is to keep the JSON database, which is automatically populated with model lookups. By keeping a local copy, we can safely spin up and down WebHelpDesk containers without losing any of our lookup data (which may save milliseconds in future lookups).
Run the Sal DB and Setup Scripts:
First, we create a data-only container for Sal’s Postgres database, and then run the Postgres database. We can specify all the variables at runtime using the -e arguments. The only thing you’ll need to change below is the password.
docker run --name "sal-db-data" -d --entrypoint /bin/echo grahamgilbert/postgres Data-only container for postgres-sal
docker run --name "postgres-sal" -d --volumes-from sal-db-data -e DB_NAME=sal -e DB_USER=saldbadmin -e DB_PASS=password --restart="always" grahamgilbert/postgres
Run the JSS Import DB:
We do the same thing with the JSS Import container’s database. Again, change the password only. Note that we’re using a slightly different Postgres container for this – the macadmins/postgres
instead of grahamgilbert/postgres
.
docker run --name "jssi-db-data" -d --entrypoint /bin/echo macadmins/postgres Data-only container for jssimport-db
docker run --name "jssimport-db" -d --volumes-from jssi-db-data -e DB_NAME=jssimport -e DB_USER=jssdbadmin -e DB_PASS=password --restart="always" macadmins/postgres
Run the WHD DB:
There’s a theme here – change the password for WebHelpDesk’s Postgres database.
docker run -d --name whd-db-data --entrypoint /bin/echo macadmins/postgres Data-only container for postgres-whd
docker run -d --name postgres-whd --volumes-from whd-db-data -e DB_NAME=whd -e DB_USER=whddbadmin -e DB_PASS=password --restart="always" macadmins/postgres
Run Temporary Sal to Prepare Initial Data Migration:
Load a temporary container just for the purpose of setting up Sal’s Django backend to incorporate the WHDImport addition.
Note that we’re using --rm
with this docker run
command, because this is intended only to be a transient container for the purpose of setting up the database. It will remove itself when complete, but the changes to the database will be permanent.
docker run --name "sal-loaddata" --link postgres-sal:db -e ADMIN_PASS=password -e DB_NAME=sal -e DB_USER=saldbadmin -e DB_PASS=password -it --rm -v /usr/local/sal_data/settings/settings.py:/home/docker/sal/sal/settings.py macadmins/salwhd /bin/bash
This opens a Bash shell. From that Bash shell:
cd /home/docker/sal
python manage.py syncdb --noinput
python manage.py migrate --noinput
echo "TRUNCATE django_content_type CASCADE;" | python manage.py dbshell | xargs
python manage.py schemamigration whdimport --auto
python manage.py migrate whdimport
exit
- After exiting, the temporary “sal-loaddata” container is removed.
Run Sal and Sync the Database:
Load up the Sal container and run “syncmachines” to get started. Change the passwords here to match what you used previously:
docker run -d --name sal -p 80:8000 --link postgres-sal:db -e ADMIN_PASS=password -e DB_NAME=sal -e DB_USER=saldbadmin -e DB_PASS=password -v /usr/local/sal_data/settings/settings.py:/home/docker/sal/sal/settings.py --restart="always" macadmins/salwhd
docker exec sal python /home/docker/sal/manage.py syncmachines
Run JSSImport and Sync the Database:
Run the JSSImport container, which will pull the device list from Casper and sync it into the jssimport database.
If you haven’t already, set up an API-only user account in the JSS, and use those credentials below. Change the URL to match your Casper instance.
docker run --rm --name jssi --link jssimport-db:db -e DB_NAME=jssimport -e DB_USER=jssdbadmin -e DB_PASS=password -e JSS_USER=user -e JSS_PASS=password -e JSS_URL=https://casper.domain.com:8443 --restart="always" macadmins/jssimport
Although I haven’t tested this particular permutation, you could theoretically build a JSS Docker instance, and then link it to the jssimport container (--link jss:jss
), and just use the URL -e JSS_URL=https://casper
.
Run WHD with its data-only container:
Now run WebHelpDesk with its linked databases.
docker run -d --name whd-data --entrypoint /bin/echo macadmins/whd Data-only container for whd
docker run -d -p 8081:8081 --link postgres-sal:saldb --link postgres-whd:db --link jssimport-db:jdb --name "whd" --volumes-from whd-data --restart="always" macadmins/whd
WebHelpDesk now has direct access to three linked databases – its own Postgres database, as db
; the Sal database, known as saldb
; and the JSS Import database, known as jdb
. This will make it trivially easy to pull the data it needs.
Configure WHD Through Browser:
- Open your web browser on the Docker host: http://localhost:8081
- Set up using Custom SQL Database:
- Database type: postgreSQL (External)
- Host: db
- Port: 5432
- Database Name: whd
- Username: whddbadmin
- Password: password
- Skip email customization
- Setup administrative account/password
- Skip the ticket customization
Setup Discovery Connections:
In WebHelpDesk, go to Setup > Assets > Discovery Connections. Make your two connections for Sal and the JSS.
- Setup discovery disconnection “Sal”:
- Connection Name: “Sal” (whatever you want)
- Discovery Tool: Database Table or View
- Database Type: PostgreSQL – uncheck Use Embedded Database
- Host: saldb
- Port: 5432
- Database Name: sal
- Username: saldbadmin
- Password: password
- Schema: Public
- Table or View: whdimport_whdmachine
- Sync Column: serial
- Setup discovery connection “Casper”:
- Connection Name: “Casper” (whatever you want)
- Discovery Tool: Database Table or View
- Database Type: PostgreSQL – uncheck Use Embedded Database
- Host: jdb
- Port: 5432
- Database Name: jssimport
- Username: jssdbadmin
- Password: password
- Schema: Public
- Table or View: casperimport
- Sync Column: serial
Now, you have a single web service that handles all inventory collection.
From here, if you wanted to schedule this for automation, you’d only need to run these two tasks regularly:
docker exec sal python /home/docker/sal/manage.py syncmachines
(since thesal
container is daemonized and runs persistently).docker run --rm --name jssi --link jssimport-db:db -e DB_NAME=jssimport -e DB_USER=jssdbadmin -e DB_PASS=password -e JSS_USER=user -e JSS_PASS=password -e JSS_URL=https://casper.domain.com:8443 macadmins/jssimport
(since this container is a fire-and-forget container that self-deletes on completion).
You could set up a crontab to run those two tasks nightly, and then set up WebHelpDesk’s internal syncs to its discovery connections to occur just an hour or so afterwards.
Once your inventory data is aggregated, you could use other tools like my WHD-CLI script to access WebHelpDesk via a Python interpreter, allowing for more scriptability. This is also available in a Docker container.
Using WHD-CLI, you have instant scriptable access to your inventory system, which could be used for lots of neat things, including a way to guarantee that a Puppetmaster only signs approved devices. Lots to explore!