vSRX license monitoring, the dirty way

- Posted in Juniper by

In case monitoring of vSRX/SRX-licensing isn't available from the official solutions from Juniper, one still might want to be in the know, before Junos stops pushing packets.

Managing a growing number of vSRX'es deployed around the world, I didn't want to manually check licenses. I had to make a quick'n'dirty solution. So I did.

The "solution" is rather simple; create a read-only user in Junos. Run a command via SSH, store the result and repeat. It has been a while, so you'd need some old repo's or rewrite some stuff.

Tested with versions:

php-cli 5.5.9
sed (GNU sed) 4.2.2

0) Create read-only users on each device (assuming 'readonlyuser' in this example) and replace 'SECRETPASSWORD' with your set password for 'readonlyuser'.

0.1) Connect to the devices with ssh to accept their keys. There might be a way to accomplish this blindly, however that is beyond the scope of this post.

1) Create a table for storing license data:

CREATE TABLE `vsrx-licenses` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `timestamp` int(12) DEFAULT NULL,
  `host` varchar(64) DEFAULT NULL,
  `expirationdate` varchar(10) DEFAULT NULL,
  `daystoexpire` int(3) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

2) Create file parseXML.php in /home/derp/vsrx-fetch-license/

<?php
// Configure database connection
function connectToDatabase($database) {
  $link = mysql_connect("DBHOST","DBUSER","DBPASS");
  $db = mysql_select_db($database, $link);
  mysql_set_charset('utf8',$link);
}

// Define function to calc days to expire
function daysToExpire($expireDate) {
  $todaysDate = date("Y-m-j");
  $origin = new DateTime($todaysDate);
  $target = new DateTime($expireDate);
  $interval = $origin->diff($target);
  return $interval->format('%a');
}

// Execute magics
connectToDatabase('DBNAME');
$timeNow = time();

$xmlFile = '/home/derp/vsrx-fetch-license/'.$argv[1];
$licenses = json_decode(json_encode((array) simplexml_load_file($xmlFile)), 1);
$licenseDetails = array_column($licenses, 'feature-summary');

// 
$deviceNoExt = substr($argv[1], 0, -4);
$deviceClean = substr($deviceNoExt, 34);

// Clear existing count to reduce db-size, optional
#mysql_query("DELETE FROM `vsrx-licenses`");

foreach ($licenseDetails[0] as $element) {
    if ($element['licensed'] != 0 && isset($element['end-date'])) {
    $deviceEndDate = $element['end-date'];
    $deviceDaysToExpire = daysToExpire($deviceEndDate);

    mysql_query("INSERT INTO `vsrx-licenses`
    (id, timestamp, host, expirationdate, daystoexpire)
    VALUES (null, '$timeNow', '$deviceNoExt', '$deviceEndDate', '$deviceDaysToExpire')") or die(mysql_error());
        echo 'License for device '.$deviceNoExt.' expires: '.$deviceEndDate.'
';
    }
}

3) Create file fetch-licenses.sh in /home/derp/vsrx-fetch-license/. Replace vsrx01.domain.tld ... with the hostnames of your devices

#!/bin/bash
# Clear old logs
napTime=3
/bin/rm /home/derp/vsrx-fetch-license/*.xml
/usr/bin/php /home/derp/vsrx-fetch-license/wipeDB.php
vsrxDevices=("vsrx01.domain.tld" "vsrx02.domain.tld" "vsrx03.domain.tld")
echo "Fetching licenses..."
for device in ${vsrxDevices[@]}; do
  echo "Fetching license details for device $device"
  /home/derp/vsrx-fetch-license/vsrx-expect.sh $device > /home/derp/vsrx-fetch-license/$device.xml
  /bin/sed -i -n '2,$p' /home/derp/vsrx-fetch-license/$device.xml
  /bin/sed -i -n '2,$p' /home/derp/vsrx-fetch-license/$device.xml
  /usr/bin/php /home/derp/vsrx-fetch-license/parseXML.php $device.xml
  echo "Napping for $napTime seconds..."
  sleep $napTime
done
echo "All done!"

4) Add execution to cron:

0 * * * * /bin/bash /home/derp/vsrx-fetch-license/fetch-licenses.sh > /home/derp/vsrx-fetch-license/fetch.log 2>&1

5) Create file vsrx-expect.sh in /home/derp/vsrx-fetch-license/ and replace values.

#!/usr/bin/expect -f
set timeout 20000
match_max 100000
set vsrxhost [lindex $argv 0];
spawn ssh -o "StrictHostKeyChecking=no" readonlyuser@$vsrxhost "show system license usage |display xml|no-more"
expect "Password:"
send "SECRETPASSWORD\r"
expect "*>"
expect eof

If all goes well, the database is updated every hour. Each run takes around 5 minutes in my case. Check the logfile /home/derp/vsrx-fetch-license/fetch.log for details after the first run.

I've added a panel in Grafana:

Query is configured as follows:

SELECT host as "Hostname", FROM_UNIXTIME(timestamp-3600) as "Licens opdateret", expirationdate as "Udløbsdato", daystoexpire as "Dage til udløb"
FROM `vsrx-licenses`
ORDER BY daystoexpire asc

Good luck.