Showing posts with label commit script. Show all posts
Showing posts with label commit script. Show all posts

Wednesday, June 18, 2014

Op script - Interface auto-description based on lldp learned neighbors

A coworker said that Arista had this python PortAutoDescription script that auto populates the ports on a switch with it's neighbor description learned through lldp. He was wondering if Juniper had such an implementation. Well this is not built into Junos, but is really easy to do as a SLAX script.

Here it is in action:

{master:0}[edit]

jnpr@SW1# run show lldp neighbors

Local Interface    Parent Interface    Chassis Id          Port info          System Name

ge-0/0/47.0        -                   00:21:59:c7:09:40   ge-0/0/47.0        SW3b               

ge-0/0/44.0        -                   78:19:f7:9f:77:00   ge-0/0/44.0        SW2b               



{master:0}[edit]

jnpr@SW1# show interfaces

ge-0/0/44 {

    unit 0 {

        family ethernet-switching {

            port-mode trunk;

            vlan {

                members all;

            }

        }

    }

}

ge-0/0/47 {

    unit 0 {

        family ethernet-switching {

            port-mode access;

            vlan {

                members v100;

            }

        }

    }

}



{master:0}[edit]

jnpr@SW1# run op IntAutoDesc

lldp-local-interface ge-0/0/47.0 connected to lldp-remote-system-name SW3b

configuration check succeeds

commit complete

lldp-local-interface ge-0/0/44.0 connected to lldp-remote-system-name SW2b

configuration check succeeds

commit complete



{master:0}[edit]

jnpr@SW1# show interfaces

ge-0/0/44 {

    description to-SW2b;

    unit 0 {

        family ethernet-switching {

            port-mode trunk;

            vlan {

                members all;

            }

        }

    }

}

ge-0/0/47 {

    description to-SW3b;

    unit 0 {

        family ethernet-switching {

            port-mode access;

            vlan {

                members v100;

            }

        }

    }

}

SOURCE CODE
----------------------------------

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 /

{

    <event-op-results> {

        var $lldp-info = <command> "show lldp neighbor ";

        var $lldp-result = jcs:invoke($lldp-info);

        var $con = jcs:open();
        for-each($lldp-result/lldp-neighbor-information)

        {
                var $lldp-int = current()/lldp-local-interface;
                var $lldp-remote = current()/lldp-remote-system-name;
                <output>local-name($lldp-int) _ " " _ $lldp-int _ " connected to " _ local-name($lldp-remote) _ " " _ $lldp-remote;

        var $if = substring-before($lldp-int, ".");
        var $int = <configuration> {
           <interfaces> {
              <interface> {
                       <name> $if;
                       <description> "to-" _ $lldp-remote;
               }
             }
        }

        call jcs:load-configuration($connection = $con, $configuration = $int);


        }

        expr jcs:close($con);

      }

}

Thursday, March 27, 2014

Network Automation - Creating routing instances using a Juniper commit script

Juniper has a scripting language called slax. This language is based on XML. By using a commit script, a network administrator can automate creating Customer tenant vpls instances. If you have a predefined template of how you create your instances and want to simplify this with only 1 command you can do the following.

There is a hidden command called apply-macro. The apply-macro is a place holder for arguments to pass to a commit script. This commit script will create a vpls instance, using the router-id as part of the route distinguisher, the last octect will be used for the site-identifier and will automatically increment the routing-instance name VPLS_CUST_X by counting how many routing instances were previously built. To add a customer name use the argument name "cust" followed by the name in the apply-macro. The script will also use the system host-name to create the VPLS name of the site. After committing, the script will delete the apply-macro. There is also error checking to see if the router-id and AS number is present.

first put the script in your /var/db/scripts/commit directory on the router and then point to the script
---------

user@router# show system
scripts {
    commit {
        file vpls-add.slax;
    }
}
script in action
---------
user@router# set routing-instances apply-macro vpls-add ifl xe-3/2/0.513

[edit]
user@router# show routing-instances
apply-macro vpls-add {
    ifl xe-3/2/0.513;
}

[edit]
user@router# commit
warning: host-name is router
warning:                VPLS NAME is VPLS_CUST_1
                        router-id is 1.1.1.1
                        SID is 1
                        IFL is xe-3/2/0.513
                        RD is 513
                        COUNT is 0
[edit routing-instances apply-macro vpls-add data ifl]
  warning: Adding routing instance VPLS_CUST_1
[edit]
  warning: deleting apply-macro vpls-add
commit complete

[edit]
user@router# show interfaces xe-3/2/0
vlan-tagging;
encapsulation extended-vlan-vpls;
unit 513 {
    vlan-id 513;
    family vpls;
}

[edit]
user@router# show routing-instances
VPLS_CUST_1 {
    instance-type vpls;
    vlan-id 513;
    interface xe-3/2/0.513;
    route-distinguisher 1.1.1.1:513;
    vrf-target target:100:513;
    protocols {
        vpls {
            site router_513 {
                site-identifier 1;
                interface xe-3/2/0.513;
            }
        }
    }
}


user@router# set routing-instances apply-macro vpls-add ifl xe-3/2/0.514

[edit]
user@router# set routing-instances apply-macro vpls-add cust JNPR_USER

[edit]
user@router# commit
warning: host-name is router
warning:                VPLS NAME is JNPR_USER
                        router-id is 1.1.1.1
                        SID is 1
                        IFL is xe-3/2/0.514
                        RD is 514
                        COUNT is 1
[edit routing-instances apply-macro vpls-add data ifl]
  warning: Adding routing instance JNPR_USER
[edit]
  warning: deleting apply-macro vpls-add
commit complete

[edit]
user@router# show routing-instances
JNPR_USER {
    instance-type vpls;
    vlan-id 514;
    interface xe-3/2/0.514;
    route-distinguisher 1.1.1.1:514;
    vrf-target target:100:514;
    protocols {
        vpls {
            site router_514 {
                site-identifier 1;
                interface xe-3/2/0.514;
            }
        }
    }
}

script
--------------------------------

version 1.0;


/*
* This script builds VPLS instances based on the following apply-macro layout
* config line: set routing-instances apply-macro vpls-add ifl xe-3/2/0.513
 */
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 {
    if (routing-instances/apply-macro[name == "vpls-add"]) {
        var $instance = routing-instances;
        var $count = count(routing-instances/instance);
        var $lo0 = routing-options/router-id;
        var $rid = normalize-space($lo0);
        
        if (not($lo0)) {
            <xnm:error> {
                <message> "\"no router-id, please configure router-id under routing-options\"";
            }
        }
        var $ASN = routing-options/autonomous-system;
        var $AS = normalize-space($ASN);
        if (not($ASN)) {
            <xnm:error> {
                <message> "\"no autonomous-system, please configure autonomous-system under routing-options\"";
            }
        }
        var $HOST = system/host-name;
        <xnm:warning> {
            <message> {
                expr "host-name is ";
                expr $HOST;
            }
        }
        var $site = substring-before($rid, ".");
        
        for-each ($instance/apply-macro/data[starts-with(name, "ifl")]) {
            var $ifname = ./value;
            var $if = normalize-space($ifname);
            var $rd = substring-after($ifname, ".");
            var $ifl = substring-before($ifname, ".");
            expr "\n\n* Check to see if there is a Customer name. If not then pre-assign one.\n";
            var $name = $instance/apply-macro/data[name == "cust"]/value;
            var $cust = {
                if (not($name)) {
                    expr "VPLS_CUST_";
                    expr $count + 1;
                
                } else {
                    expr $name;
                }
            }
            expr "\n\n* Check to see if there is a vlan id. If not then use the ifl.\n";
            var $vlan = $instance/apply-macro/data[name == "vlan"]/value;
            var $vid = {
                if (not($vlan)) {
                    expr $rd;
                
                } else {
                    expr $vlan;
                }
            }
            <xnm:warning> {
                <message> {
                    expr "\n                        VPLS NAME is ";
                    expr $cust;
                    expr "\n                        router-id is ";
                    expr $rid;
                    expr "\n                        SID is ";
                    expr $site;
                    expr "\n                    IFL is ";
                    expr $if;
                    expr "\n                    RD is ";
                    expr $vid;
                    expr "\n                        COUNT is ";
                    expr $count;
                }
            }
            expr "\n\n\n* ADD INTERFACE\n                ";
            <change> {
                <interfaces> {
                    <interface> {
                        <name> $ifl;
                        <vlan-tagging>;
                        <encapsulation> "extended-vlan-vpls";
                        <unit> {
                            <name> $rd;
                            <vlan-id> $vid;
                            <family> {
                                <vpls> ;
                            }
                        }
                    }
                }
            }
            expr "\n\n* ROUTING INSTANCE ADD\n                ";
            <change> {
                <routing-instances> {
                    <instance> {
                        <name> $cust;
                        <instance-type> "vpls";
                        <vlan-id> $vid;
                        <interface> {
                            <name> $if;
                        }
                        <route-distinguisher> {
                            <rd-type> {
                                expr $rid;
                                expr ":";
                                expr $rd;
                            }
                        }
                        <vrf-target> {
                            <community> {
                                expr "target:";
                                expr $AS;
                                expr ":";
                                expr $rd;
                            }
                        }
                        <protocols> {
                            <vpls> {
                                <site> {
                                    <name> $HOST _ "_" _ $rd;
                                    <site-identifier> $site;
                                    <interface> {
                                        <name> $if;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            call jcs:emit-change() {
                with $message = {
                    expr "Adding routing instance ";
                    expr $cust;
                 }
            }
        }
        expr "\n\n\n\n\n* DELETE THE APPLY-MARCO\n         ";
        var $macro = routing-instances/apply-macro[name == "vpls-add"];
        if ($macro) {
            <change> {
                <routing-instances> {
                    <apply-macro delete = "delete"> {
                        <name> "vpls-add";
                    }
                }
            }
            call jcs:emit-change() {
                with $message = {
                    expr "deleting apply-macro vpls-add";
                 }
            }
        }
    }
}