/* * Change enabled interfaces for couple of vlans by events (up/down ospf or ping probe) * */ 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"; param $iface-primary; param $iface-protect; param $vlans; param $test-name; param $neighbor; param $localtime_iso; match / { var $our = { if (not(jcs:empty($neighbor))) { if (event-script-input/trigger-event/id == "RPD_OSPF_NBRUP" || event-script-input/trigger-event/id == "RPD_OSPF_NBRDOWN") { if (event-script-input/trigger-event/attribute-list/attribute[name="neighbor-address"]/value == $neighbor) { expr "yes"; } } } else if (not(jcs:empty($test-name))) { if (event-script-input/trigger-event/id == "PING_TEST_COMPLETED" || event-script-input/trigger-event/id == "PING_TEST_FAILED") { if (event-script-input/trigger-event/attribute-list/attribute[name="test-name"]/value == $test-name) { expr "yes"; } } } else { expr "yes"; } } if ($our == "yes") { expr jcs:syslog("external.debug", "event script backup iface-primary: ", $iface-primary, " iface-protect: ", $iface-protect, " vlans: ", $vlans, " event: ", event-script-input/trigger-event/id); /* if down disable specified vlans (subinterfaces) on $iface-primary, enable on $iface-protect */ /* if up disable specified vlans (subinterfaces) on $iface-protected, enable on $iface-primary */ if (event-script-input/trigger-event/id == "PING_TEST_COMPLETED" || event-script-input/trigger-event/id == "RPD_OSPF_NBRUP") { var $tag = $vlans _ "-up"; if (event-script-input/trigger-event/id == "PING_TEST_COMPLETED" && not(jcs:dampen($tag, 1, 1))) { expr jcs:syslog("external.notice", "Called too frequent"); } else { call change($iface-dis=$iface-protect, $iface-ena=$iface-primary, $vlans=$vlans); } } else if (event-script-input/trigger-event/id == "PING_TEST_FAILED" || event-script-input/trigger-event/id == "RPD_OSPF_NBRDOWN") { var $tag = $vlans _ "-down"; if (event-script-input/trigger-event/id == "PING_TEST_FAILED" && not(jcs:dampen($tag, 1, 1))) { expr jcs:syslog("external.notice", "Called too frequent"); } else { call change($iface-dis=$iface-primary, $iface-ena=$iface-protect, $vlans=$vlans); } } else { expr jcs:syslog("external.error", "Error: unknown event received: ", event-script-input/trigger-event/id); } expr jcs:syslog("external.debug", "event script backup finished iface-primary: ", $iface-primary, " iface-protect: ", $iface-protect, " vlans: ", $vlans, " event: ", event-script-input/trigger-event/id); } else { expr jcs:syslog("external.debug", "not our event ignored, our is '", $our, "'"); } } template change($iface-dis, $iface-ena, $vlans) { var $connection = jcs:open(); var $change = { call update-loop($iface-dis=$iface-dis, $iface-ena=$iface-ena, $vlans=$vlans, $connection=$connection); } if (jcs:regex("[a-z]", $change)) { call update-config($connection=$connection, $change=$change, $iface-dis=$iface-dis, $iface-ena=$iface-ena, $n="0"); } else { expr jcs:syslog("external.info", "No changes"); } /* expr jcs:execute($connection, "request-end-session"); */ expr jcs:close($connection); } template update-loop($iface-dis, $iface-ena, $vlans, $connection, $change) { expr jcs:syslog("external.debug", "update-loop, iface-dis: ", $iface-dis, " iface-ena: ", $iface-ena, " vlans: ", $vlans); var $v = jcs:regex("^,?([0-9]+)(,[0-9]+)*$", $vlans); if (jcs:empty($v[1])) { expr jcs:syslog("external.error", "Bad list of vlans"); } else { /* change vlan $v[2] */ call update-vlan($iface-dis=$iface-dis, $iface-ena=$iface-ena, $vlan=$v[2], $connection=$connection); /* recurse with rest of vlans */ if (not(jcs:empty($v[3]))) { call update-loop($iface-dis=$iface-dis, $iface-ena=$iface-ena, $vlans=$v[3], $connection=$connection); } } } template update-vlan($iface-dis, $iface-ena, $vlan, $connection) { expr jcs:syslog("external.debug", "update-vlan, iface-dis: ", $iface-dis, " iface-ena: ", $iface-ena, " vlan: ", $vlan); var $config-request1 = { { { { $iface-dis; { $vlan; } } } } } var $config1 = jcs:execute($connection, $config-request1)/interfaces/interface[name==$iface-dis]/unit[name==$vlan]; if ($config1/@inactive) { expr jcs:syslog("external.warning", "Warning: ", $iface-dis, ".", $vlan, " inactive"); } else if ($config1/encapsulation || $config1/family) { if ($config1/disable) { expr jcs:syslog("external.warning", "Warning: ", $iface-dis, ".", $vlan, " already disabled"); } else { var $config-request2 = { { { { $iface-ena; { $vlan; } } } } } var $config2 = jcs:execute($connection, $config-request2)/interfaces/interface[name==$iface-ena]/unit[name==$vlan]; if ($config2/@inactive) { expr jcs:syslog("external.warning", "Warning: ", $iface-ena, ".", $vlan, " inactive"); } else if ($config2/encapsulation || $config2/family) { if ($config2/disable) { /* all ok, change */ { $iface-ena; { $vlan; ; } } { $iface-dis; { $vlan; ; } } } else { expr jcs:syslog("external.warning", "Warning: ", $iface-ena, ".", $vlan, " already enabled"); } } else { expr jcs:syslog("external.warning", "Warning: ", $iface-ena, ".", $vlan, " not found"); } } } else { expr jcs:syslog("external.warning", "Warning: ", $iface-dis, ".", $vlan, " not found"); } } template update-config($connection, $change, $iface-dis, $iface-ena, $n) { expr jcs:syslog("external.debug", "update-config"); var $open-req = { ; } var $res-open = jcs:execute($connection, $open-req); if ($res-open//xnm:error) { for-each ($res-open//xnm:error) { expr jcs:syslog("external.error", "Error: Open configuration: ", message); } } else { var $change-req = { { { copy-of $change; } } } var $res-load = jcs:execute($connection, $change-req); if ($res-load//xnm:error) { expr jcs:execute($connection, "close-configuration"); for-each ($res-load//xnm:error) { expr jcs:syslog("external.error", "Error: Load configuration: ", message); } } else { var $res-commit = jcs:execute($connection, "commit-configuration"); expr jcs:execute($connection, "close-configuration"); if ($res-commit//xnm:error) { for-each ($res-commit//xnm:error) { expr jcs:syslog("external.error", "Error: Commit: ", message); } if (jcs:regex("configuration database locked by", $res-commit//xnm:error/message)) { if ($n <= 18) { /* trying 3 minutes */ expr jcs:syslog("Retry (try number ", $n+1, ")"); expr jcs:sleep(10); call update-config($connection=$connection, $change=$change, $iface-dis=$iface-dis, $iface-ena=$iface-ena, $n=$n+1); } } } else { expr jcs:syslog("external.notice", "Configuration updated successfully"); } } } }