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


No comments:

Post a Comment