Uncategorized

JUNOScript – First attempt

So, there are many things that make Junos very robust and flexible.  One of the more rarely used, and more powerful is the built in scripting capabilities.  We’ve found a couple of situations where a script would come in very handy.

  1. By default, Juniper routers have all interfaces in an admin up state.  This is great, except for the fact that our NMS alarms on any interface that is admin up, but down, so this kicks off all kinds of alarms
  2. Every GigE port in our network has a single vlan that is used for management, and must be ‘bridged’ together.  Its really common to forget to add a newly configured interface to the bridge-group.

Interface-disable.slax

We’ve got this great script we’ve been using that transitively disables any unconfigured interface.  While I think its excellent to admin up interfaces by default, most NMS’s assume there is a problem with an interface in up/down status, so in order to avoid alarms, we’ve been using this script:

/*
 * This script transiently disables all unconfigured ge interfaces.
 */

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";

match configuration {

    /* Get the current interface list  */
    var $interfaces = jcs:invoke( "get-interface-information" );

    /* Only ge and xe interfaces */
    var $ge-interfaces = $interfaces/physical-interface[starts-with(name, "ge-") or starts-with(name, "xe-")];

    var $interface-hierarchy = interfaces;

    /* Go through each ge interface, if it isn't within the configuration than transiently disable it */
    for-each( $ge-interfaces ) {

        if( jcs:empty( $interface-hierarchy/interface[name == current()/name ] ) ) {
            <transient-change> {
                <interfaces> {
                    <interface> {
                        <name> name;
                        <disable>;
                    }
                }
            }
        }
    }
}

This works really well, with one exception.  After a power failure, the transient change is lost, and all unconfigured interfaces are in up/down status until someone logs in and does a commit.  While I enjoy the clean looking config the transitive solution offers, we’ve had a need to ensure this initial alarming doesn’t happen, which means we need to change the config non-transitively.

Below is the config I will apply (I use the group so during configuration later, all child units are also disabled, which has more to do with our internal processes than anything technical) to each interface.

interfaces {
    <*> {
        disable;
        unit <*> {
            disable;
        }
    }
}

interfaces {

    ge-0/0/0 {

        apply-groups DISABLEIF;

    }

}

Here is the non-transitive script to use that will apply the DISABLEIF group to each interface:

/*
 * This script disables all unconfigured ge interfaces.
 */

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";

match configuration {

    /* Get the current interface list  */
    var $interfaces = jcs:invoke( "get-interface-information" );

    /* Only ge and xe interfaces */
    var $ge-interfaces = $interfaces/physical-interface[starts-with(name, "ge-") or starts-with(name, "xe-")];

    var $interface-hierarchy = interfaces;

    /* Go through each ge interface, if it isn't within the configuration than apply-group DISABLEIF */
    for-each( $ge-interfaces ) {

        if( jcs:empty( $interface-hierarchy/interface[name == current()/name ] ) ) {
	     <xnm:warning> {
		<message> "Disabling unconfigured interface: " _ name;
	     }
	     <change> {
                <interfaces> {
                    <interface> {
                        <name> name;
                        <apply-groups> "DISABLEIF";
                    }
                }
	     }
        }
    }

}

You’ll have to store this file on the router’s hard drive in /var/db/scripts/commit/

Of course, you must tell your router to run this script on each commit:

set system script commit file "interface-disable.slax"

I’ll cover the bridge-domain update in another post!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s