/* * Author : Curtis Call * Version : 1.3 * Last Modified : August 25, 2010 * Platform : all * Release : 9.3 and above * * Description : This event script automatically writes the receive optic laser * levels into the Utility MIB every thirty seconds. * * Only interfaces that show up in "show interfaces diagnostics optics" are included. * * All values are recorded under the following OID: * enterprises.juniperMIB.jnxMibs.jnxUtilMibRoot.jnxUtil.jnxUtilData.jnxUtilStringTable.jnxUtilStringEntry.jnxUtilStringValue.111.112.116.105.99.115 * .1.3.6.1.4.1.2636.3.47.1.1.5.1.2.111.112.116.105.99.115 * * There are three values recorded per interface: * * Interface Name: * jnxUtilStringValue.111.112.116.105.99.115.78 * * Receive Power: * jnxUtilStringValue.111.112.116.105.99.115.80 * * Receive Power dBm: * jnxUtilStringValue.111.112.116.105.99.115.68 * * Interfaces are differentiated by their ifIndex which appears at the end of the OID as the ascii values of each ifIndex character. * * For example, ifIndex 153 results in the following OIDs: * jnxUtilStringValue.111.112.116.105.99.115.68.49.53.51 = -5.21 * jnxUtilStringValue.111.112.116.105.99.115.78.49.53.51 = ge-1/0/0 * jnxUtilStringValue.111.112.116.105.99.115.80.49.53.51 = 0.3015 * * Revisions: * 1.2 - Switched from recursive template design to for-each design in order to conserve memory usage. * - Added new "opowner" instance to track the current script owner. When an older instance detects * that a new one has started then the old instance will exit. * - Added new daemon.info messages to describe the starting and stopping of the script. * 1.3 - Changed from "show interfaces" to "show interfaces media" because of a bug in 10.2R2 that caused * the script to hang. * * License : BSD-Style * Copyright (c) 2010 Curtis Call. All Rights Reserved. * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ version 1.0; ns junos = "http://xml.juniper.net/junos/*/junos"; ns xnm = "http://xml.juniper.net/xnm/1.1/xnm"; ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0"; import "../import/junos.xsl"; /* Embedded event policy */ var $event-definition = { { { "5-minutes"; "300"; } { "record-optics"; "5-minutes"; { { "record-optics.slax"; } } } } } var $owner-instance = "opowner"; var $owner-oid = "jnxUtilStringValue.o.p.o.w.n.e.r"; var $connection = jcs:open(); match / { expr jcs:syslog( "daemon.info", "Starting new record optics instance" ); /* Loop through ten times */ var $loop := { call build-loop(); } /* Record self as new mcast owner */ call write-owner(); for-each( $loop/loop ) { /* Verify that we are still optics owner */ var $current-owner = { call read-owner(); } if( $current-owner != $localtime-iso ) { expr jcs:syslog( "daemon.info", "New optics instance has assumed ownership, exiting" ); "New instance has take over"; } /* Read the current optic output */ var $interface-optics = jcs:execute( $connection, "get-interface-optics-diagnostics-information" ); /* Read the current interfaces - for their ifIndexes */ var $interface-rpc = { { ; } } var $interfaces = jcs:execute( $connection, $interface-rpc ); /* Populate the Utility MIB - and build set of used instances while we are at it */ var $used-instance-set := { for-each( $interface-optics/physical-interface ) { var $name = name; var $interface = $interfaces/physical-interface[name == $name]; var $ifIndex = $interface/snmp-index; /* Only go on if there is an ifIndex */ if( string-length( $ifIndex ) > 0 ) { /* Write interface name */ var $name-instance = { call build-instance-name( $instance-type = "N", $ifIndex ); } "jnxUtilStringValue." _ $name-instance; call set-instance( $connection, $instance = $name-instance, $type = "string", $value = $name ); /* Write receive power */ var $receive-instance = { call build-instance-name( $instance-type = "P", $ifIndex ); } "jnxUtilStringValue." _ $receive-instance; var $power = { if( optics-diagnostics/rx-signal-avg-optical-power ) { expr optics-diagnostics/rx-signal-avg-optical-power; } else if( optics-diagnostics/laser-rx-optical-power ){ expr optics-diagnostics/laser-rx-optical-power; } else { expr "0.0000"; } } call set-instance( $connection, $instance = $receive-instance, $type = "string", $value = $power ); /* Write receive dbm */ var $dbm-instance = { call build-instance-name( $instance-type = "D", $ifIndex ); } "jnxUtilStringValue." _ $dbm-instance; var $dbm = { if( optics-diagnostics/rx-signal-avg-optical-power-dbm ) { expr optics-diagnostics/rx-signal-avg-optical-power-dbm; } else if( optics-diagnostics/laser-rx-optical-power-dbm ){ expr optics-diagnostics/laser-rx-optical-power-dbm; } else { expr "0"; } } call set-instance( $connection, $instance = $dbm-instance, $type = "string", $value = $dbm ); } else { expr jcs:syslog( "daemon.error", "Interface ", $name, " does not have ifIndex." ); } } } expr jcs:syslog( "daemon.info", "Updated ", ( count( $used-instance-set/instance ) div 3 ), " interface optic values in the Utility MIB. (", position(), " of 10)" ); /* Remove old interfaces from Utility MIB */ var $oids := { call walk-mib(); } for-each( $oids/instance ) { var $instance = .; /* If it doesn't exist in the used instances then clear it because it has been removed */ if( jcs:empty( $used-instance-set[instance == $instance] ) ) { call clear-instance($connection, $instance = substring-after( $instance, "." ), $type = "string" ); expr jcs:syslog( "daemon.info", "Clearing instance ", $instance, " from Utility MIB because interface is not present." ); } } /* Pause 30 seconds, Repeat ten times */ if( position() < 10 ) { expr jcs:sleep(30); } } expr jcs:syslog( "daemon.info", "Current instance has finished cycle, exiting" ); expr jcs:close( $connection ); } /* * Assembles an instance name. The format is: * optics + [N/P/D] + ifIndex * $instance-type = N/P/D */ template build-instance-name( $instance-type, $ifIndex ) { expr "optics" _ $instance-type _ $ifIndex; } /* * set-instance - Sets the instance in the MIB */ template set-instance($connection, $instance, $type, $value) { /* Build RPC and invoke it */ var $rpc = { { $instance; $type; $value; } } var $results = jcs:execute( $connection, $rpc ); } /* * clear-instance - Removes the instance from the MIB */ template clear-instance($connection, $instance, $type) { /* Build RPC and invoke it */ var $rpc = { { $instance; $type; } } var $results = jcs:execute( $connection, $rpc ); } /* * walk-mib - Walks the Utility MIB in ascii or oid mode */ template walk-mib() { /* Gather walk output */ var $walk-rpc = { { ".1.3.6.1.4.1.2636.3.47.1.1.5.1.2.111.112.116.105.99.115"; } } var $mib-objects = jcs:invoke( $walk-rpc ); for-each( $mib-objects/snmp-object[ jcs:regex( "jnxUtil.*Value\\.", name ) ] ) { var $name = { call translate-to-instance-format( $oid-name = name ); } $name; } } /* * translate-to-instance-format - Translates an OID name into a corresponding * instance name * * $oid-name - The oid name returned by . * * Returns the instance formatted name in the result tree */ template translate-to-instance-format( $oid-name ) { /* Get the type portion of name */ var $type-name = substring-before( $oid-name, "." ); /* The oid portion */ var $oid = substring-after( $oid-name, "." ); /* Break up the parts into different numbers */ var $number-set = jcs:split("\\.", $oid ); /* Convert everything to characters */ var $instance-name = { for-each( $number-set ) { var $number = .; /* Use substring to workaround PR 436699 */ expr substring( $ascii-set/char[num == $number]/sym, 1, 1 ); } } /* Combine the two parts and write to result tree */ expr $type-name _ "." _ $instance-name; } var $ascii-set := { { 32; " "; } { 33; "!"; } { 34; "\""; } { 35; "#"; } { 36; "$"; } { 37; "%"; } { 38; "&"; } { 39; "'"; } { 40; "("; } { 41; ")"; } { 42; "*"; } { 43; "+"; } { 44; ","; } { 45; "-"; } { 46; "."; } { 47; "/"; } { 48; "0"; } { 49; "1"; } { 50; "2"; } { 51; "3"; } { 52; "4"; } { 53; "5"; } { 54; "6"; } { 55; "7"; } { 56; "8"; } { 57; "9"; } { 58; ":"; } { 59; ";"; } { 60; "<"; } { 61; "="; } /* >" */ { 62; ">"; } { 63; "?"; } { 64; "@"; } { 65; "A"; } { 66; "B"; } { 67; "C"; } { 68; "D"; } { 69; "E"; } { 70; "F"; } { 71; "G"; } { 72; "H"; } { 73; "I"; } { 74; "J"; } { 75; "K"; } { 76; "L"; } { 77; "M"; } { 78; "N"; } { 79; "O"; } { 80; "P"; } { 81; "Q"; } { 82; "R"; } { 83; "S"; } { 84; "T"; } { 85; "U"; } { 86; "V"; } { 87; "W"; } { 88; "X"; } { 89; "Y"; } { 90; "Z"; } { 91; "["; } { 92; "\\"; } { 93; "]"; } { 94; "^"; } { 95; "_"; } { 96; "`"; } { 97; "a"; } { 98; "b"; } { 99; "c"; } { 100; "d"; } { 101; "e"; } { 102; "f"; } { 103; "g"; } { 104; "h"; } { 105; "i"; } { 106; "j"; } { 107; "k"; } { 108; "l"; } { 109; "m"; } { 110; "n"; } { 111; "o"; } { 112; "p"; } { 113; "q"; } { 114; "r"; } { 115; "s"; } { 116; "t"; } { 117; "u"; } { 118; "v"; } { 119; "w"; } { 120; "x"; } { 121; "y"; } { 122; "z"; } { 123; "{"; } { 124; "|"; } { 125; "}"; } { 126; "~"; } } template build-loop( $index = 1 ) { ; if( $index < 10 ) { call build-loop( $index = $index + 1 ); } } template read-owner() { var $rpc = { { $owner-oid; } } var $result = jcs:execute( $connection, $rpc ); for-each( $result//self::xnm:error ) { expr jcs:syslog( "daemon.error", "Error writing owner to Utility MIB: ", message ); } expr $result/snmp-object/object-value; } template write-owner() { var $rpc = { { $owner-instance; "string"; $localtime-iso; } } var $result = jcs:execute( $connection, $rpc ); for-each( $result//self::xnm:error ) { expr jcs:syslog( "daemon.error", "Error writing owner to Utility MIB: ", message ); } }