Scripts? Scripts? We don't need no stinkin' scripts …

Jim Doble has written an interesting new daemon for OpenNMS called ScriptD. This process, governed as usual from a configuration file, allows one to generally or specifically execute actions based on events in OpenNMS.

The scripting language, as I understand it, is beanshell. As Jim writes: You will notice that BeanShell is a lot like Java, but with some relaxed syntax. For example you don’t have to define types for your variables, and attributes for which there are simple get methods can be accessed as properties (i.e. you can say event.uei or event.getUei() interchangably.)

There are 4 types of scripts that can be run: start-script, reload-script, stop-script, and event-script. When ScriptD starts it will run all of the commands in the tags. Likewise, when ScriptD stops, it will run all of the commands in the tags. Also, there is a new event, uei.opennms.org/internal/reloadScriptConfig, which when received will run all of the tags.

The final script type, gets run when events are received. Event scripts can have one or more UEI elements, which specify the UEI’s for which that script should run. If no UEI element is present, the script
will run for all events.

The scripts can make use of the SnmpTrapHelper class, which is a utility to make it easier to manipulate traps from a script.

There is an example scriptd-configuration.xml file included in the $OPENNMS_HOME/etc directory.

If you want to forward all SNMP traps to another machine as an SNMP trap, you would use the following event script:

	<event-script language="beanshell">

		event = bsf.lookupBean("event");

		if (event.snmp != null) {
			log.debug("forwarding a trap");
			snmpTrapHelper.forwardTrap(event, "10.1.1.1", 162);
		}

</event-script>

This will forward the trap to 10.1.1.1, port 162.
Note that the event will have SNMP information if the event is indeed an SNMP trap. Since internal OpenNMS events do not, you could use that to forward OpenNMS events as an SNMP trap to another system:

<event-script language="beanshell">

        event = bsf.lookupBean("event");

        if (event.snmp == null)
        {

                try {

                log.debug("Forwarding an OpenNMS event.");

                SnmpPduTrap trap = snmpTrapHelper.createV1Trap(".1.3.6.1.4.1.5813.1", "10.1.1.16", 6, 1, 0);

                t_dbid = new Integer(event.dbid).toString();
                if (t_dbid != null)
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.1", "OctetString", "text", t_dbid);
                else
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.1", "OctetString", "text", "null");
                if (event.distPoller != null)
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.2", "OctetString", "text", event.distPoller);
                else
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.2", "OctetString", "text", "null");
                if (event.creationTime != null)
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.3", "OctetString", "text", event.creationTime);
                else
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.3", "OctetString", "text", "null");
                if (event.masterStation != null)
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.4", "OctetString", "text", event.masterStation);
                else
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.4", "OctetString", "text", "null");
                if (event.uei != null)
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.6", "OctetString", "text", event.uei);
                else
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.6", "OctetString", "text", "null");
                if (event.source != null)
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.7", "OctetString", "text", event.source);
                else
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.7", "OctetString", "text", "null");
                t_nodeid = new Long(event.nodeid).toString();
                if (t_nodeid != null)
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.8", "OctetString", "text", t_nodeid);
                else
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.8", "OctetString", "text", "null");
                if (event.time != null)
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.9", "OctetString", "text", event.time);
                else
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.9", "OctetString", "text", "null");
                if (event.host != null)
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.10", "OctetString", "text", event.host);
                else
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.10", "OctetString", "text", "null");
                t_interface = event.getInterface();
                if (t_interface != null)
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.11", "OctetString", "text", t_interface);
                else
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.11", "OctetString", "text", "null");
                if (event.snmphost != null)
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.12", "OctetString", "text", event.snmphost);
                else
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.12", "OctetString", "text", "forge.blast.com");
                if (event.service != null)
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.13", "OctetString", "text", event.service);
                else
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.13", "OctetString", "text", "null");
                if (event.descr != null)
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.16", "OctetString", "text", event.descr);
                else
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.16", "OctetString", "text", "null");
                if (event.severity != null)
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.18", "OctetString", "text", event.severity);
                else
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.18", "OctetString", "text", "null");
                if (event.pathoutage != null)
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.19", "OctetString", "text", event.pathoutage);
                else
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.19", "OctetString", "text", "null");
                if (event.operinstruct != null)
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.20", "OctetString", "text", event.operinstruct);
                else
                        snmpTrapHelper.addVarBinding(trap, ".1.3.6.1.4.1.5813.2.20", "OctetString", "text", "null");

                snmpTrapHelper.sendTrap("public", trap, "10.1.1.15", 162);

                }

                catch (e) {
                    sw = new StringWriter();
                    pw = new PrintWriter(sw);
                    e.printStackTrace(pw);
                    log.debug(sw.toString());
                }
        }

</event-script>

This will send an newly defined OpenNMS trap with the important event information embedded as varbinds.

If you wanted to limit the forwarded OpenNMS events to nodeLostService and nodeRegainedService, you can add a tag:

	<event-script language="beanshell">
		<uei name="uei.opennms.org/nodes/nodeLostService"/>
		<uei name="uei.opennms.org/nodes/nodeRegainedService"/>

To the first part of the tag.

Hats off to Jim for this work.