This is part one of a three part series exploring how to automate the experience of alerting your sysadmin that PaperCut MF has a new version available:
PART 2 - What’s the latest and greatest release of PaperCut MF? - Alec explains how to identify the most current PaperCut MF release version available
PART 3 - Upgrade Automation: Putting it all together - Alec ties it all together so that a review ticket gets assigned to the correct application administrator for action if a new release appears.
When you are a PaperCut MF or PaperCut NG administrator you need to make sure your software is up to date. Not only do your users crave the latest features, but you need to make sure you’ve got all the latest security patches.
You can discover the latest release of PaperCut MF by looking at our Atom feed here:
https://www.papercut.com/products/mf/release-history.atom
If you have a feed reader installed (for example Feeder in Chrome ), you can get a nice pretty display.
Screenshot of our releases feed, displayed in an appropriate reader
You can click the subscribe button and ask Feeder to send an email every time we release a new version. But that is so old school!
I am lazy, so let’s write a script that will create a job ticket when a new MF release is available and assign it to the appropriate person, so they get prompted to investigate.
Notes:
- These notes talk about PaperCut MF, but it’s easy enough to adapt for PaperCut NG.
- I’ll be demonstrating scripts for POSIX style (Linux and macOS) shells and PowerShell , but you can use whatever scripting language you like (for example Python )
We need to do three things:
- Discover which version of PaperCut MF is currently running on our server
- Get the latest PaperCut MF release version from the PaperCut website
- If the version has changed since we last checked, then create a review ticket.
This splits what could be a long article up into three convenient standalone posts.
Warning: This article assumes moderately advanced script writing and PaperCut MF administration knowledge. You should test in your own environment before deploying to production.
Discover which version of PaperCut MF is currently running on our server
We can retrieve the PaperCut MF server version through the health API. But, for security reasons, in order to use the health API we need the health API key.
We can retrieve the health API key from the PaperCut MF server, either via the web services API, or via the
server-command
utility.
Again for security reasons, the web services API also needs a separate security auth token to work. The auth token needs to be configured by the PaperCut administrator (by
editing
the advanced config key
auth.webservices.auth-token
).
I’ll provide examples for POSIX shells (specifically the Dash shell) and PowerShell .
Retrieve the health API key in a POSIX shell
Let’s assume we have the web services API auth token stored in a local file ~/.PAPERCUT_API_TOKEN
, because it’s bad practice to embed secrets into script files.
Use this code to get the health API key key:
#!/bin/dash
# Use the Dash shell. It's smaller and faster
API_TOKEN="$(cat ~/.PAPERCUT_API_TOKEN)" # Don't hard code API tokens
MF_HOST="$(hostname).local" # Modify to suit
# We need the health API key. Get it via the web services API
# Config key is health.api.key
# Use XMLLint to parse XML-RPC output
HEALTH_API_KEY=$(curl -s -H "content-type:text/xml" --data @- \
"http://${MF_HOST}:9191/rpc/api/xmlrpc" <<EOF | \
xmllint --xpath '//methodResponse/params/param/value/text()' -
<?xml version="1.0"?>
<methodCall>
<methodName>
api.getConfigValue
</methodName>
<params>
<param>
<value>
${API_TOKEN}
</value>
</param>
<param>
<value>
health.api.key
</value>
</param>
</params>
</methodCall>
EOF
)
echo $HEALTH_API_KEY
This code should echo a random string.
NOTE: You will need to make sure xmllint is installed (Tip: In Debian, that’s package libxml2-utils).
If your script is running on the PaperCut MF server, then you can make your life a lot easier by using the server-command
utility instead of the web services API. Just make sure you are running as the PaperCut user on Linux.
For example use this code to get the API key, this will use server command, or the web services API if server-command does not work.
#!/bin/dash
MF_HOST="$(hostname).local" # Modify to suit
HEALTH_API_KEY=$($HOME/server/bin/linux-x64/server-command get-config health.api.key)
if [ -z "$HEALTH_API_KEY" ] ; then
HEALTH_API_KEY=$(curl -s -H "content-type:text/xml" --data @- \
"http://${MF_HOST}:9191/rpc/api/xmlrpc" <<EOF | \
xmllint --xpath '//methodResponse/params/param/value/text()' -
<?xml version="1.0"?>
<methodCall>
<methodName>
api.getConfigValue
</methodName>
<params>
<param>
<value>
$(cat ~/.PAPERCUT_API_TOKEN)
</value>
</param>
<param>
<value>
health.api.key
</value>
</param>
</params>
</methodCall>
EOF
)
fi
echo $HEALTH_API_KEY
Discover the server version in a POSIX shell
(these code fragments assume we still have the HEALTH_API_KEY
and MF_HOST
variables set from the previous section).
Now we have the correct health API key we can make calls to the health API to discover the server version. As an experiment, run the following from the Linux command line:
curl -s -H "Authorization:$HEALTH_API_KEY" "http://${MF_HOST}:9191/api/health" | head -10
The output is JSON, but if if we install the jq JSON processor we can extract the version string
curl -s -H "Authorization:$HEALTH_API_KEY" "http://${MF_HOST}:9191/api/health" |
jq '.applicationServer.systemInfo.version'
Which displays something like 21.2.10 (Build 62186)
. What we really need are the MAJOR, MINOR, PATCH values from the
semantic version
. In this example, they are 21, 2, and 10. This requires some string extraction and on POSIX I prefer to use the sed editor.
INSTALLED_RELEASE=$(curl -s -H "Authorization:$HEALTH_API_KEY" "http://${MF_HOST}:9191/api/health" |
jq '.applicationServer.systemInfo.version' |
sed -Ee 's/^"([0-9]+\.[0-9]+\.[0-9]+).+$/\1/')
echo $INSTALLED_RELEASE
Now we know which PaperCut MF release is running on our server.
Retrieve the health API key in modern PowerShell
Note: These examples were tested on PowerShell V 7.2
$MF_HOST = "$(hostname).local" # Modify to suit
$API_TOKEN = (Get-Content -raw ~/.PAPERCUT_API_TOKEN).trim() # Don't hard code API tokens
$uri = [Uri] "http://${MF_HOST}:9191/rpc/api/xmlrpc"
$HEALTH_API_KEY = (@"
<?xml version="1.0"?>
<methodCall>
<methodName>api.getConfigValue</methodName>
<params>
<param>
<value>${API_TOKEN}</value>
</param>
<param>
<value>health.api.key</value>
</param>
</params>
</methodCall>
"@ | Invoke-RestMethod -Method 'Post' -Uri $uri | Select-Xml -XPath "/methodResponse/params/param/value").toString()
Write-Output $HEALTH_API_KEY
Notice that PowerShell has build in support for XML so no need to install further packages.
If we assume that the script will run on the PaperCut MF server system them we can use server-command.exe
to retrieve the health API key, instead of using web services API.
Note: On Windows PowerShell will need to be running with elevated privilege to execute server-command.exe
.
$HEALTH_API_KEY = & "$((Get-ItemProperty `
-Path 'HKLM:\HKEY_LOCAL_MACHINE\SOFTWARE\PaperCut MF').InstallPath)\server\bin\win\server-command.exe" `
get-config health.api.key
Write-Output $HEALTH_API_KEY
(more information on how to locate the PaperCut MF installation in this note .)
Discover the server version in Modern PowerShell
These code fragments assume we still have the HEALTH_API_KEY
and MF_HOST
variables set from the previous section.
Now we have the correct health API key we can make calls to the health API to discover the server version. You may like to look at the POSIX example above to understand how to locate the correct information in the JSON response.
(Invoke-RestMethod -Uri "http://${MF_HOST}:9191/api/health" -Method Get `
-Headers @{'Authorization' = $HEALTH_API_KEY}).applicationServer.systemInfo.Version
Notice that PowerShell has build in support for JSON so no need to install further packages like jq
.
We get a string that looks like “21.2.10 (Build 62186)”. But what we really need are the MAJOR, MINOR, PATCH values from the
semantic version
. In my example they are 21, 2, and 10. PowerShell provides a handy -replace
operator and we can use a regex to extract the information we need:
$INSTALLED_RELEASE = (Invoke-RestMethod -Uri "http://${MF_HOST}:9191/api/health" -Method Get `
-Headers @{'Authorization' = $HEALTH_API_KEY}).applicationServer.systemInfo.Version `
-replace '^(\d+\.\d+\.\d+).+','$1'
Write-Output $INSTALLED_RELEASE
Job done!
In the next post in this three-part series, we’ll get the current PaperCut MF release version from the website Atom feed at http://www.papercut.com/products/mf/release-history.atom