Automation & Programmability
Automation & Programmability
Python for Non-Programmers (Part 4)
01.20.15

AUTOMATION IS NOT ALWAYS ABOUT ABSTRACTIONS

 

I'll used the term unstructured changes to mean making changes where the content of the change comes from text (file or string), rather than an abstraction like the Resource described in Part 3 of this series.  You might find using unstructured changes far more useful in your efforts.  They lend themselves very well to common and repetitive tasks such as bulk changes, or standing up new equipment. 

 

WHAT ARE THE OPTIONS?

 

The Junos CLI allows you to display configuration in one of three formats: "text", "set" and "xml". 

 

The "text" format, or what some folks refer to a curly-brace format:

 

[edit]
jeremy@switch# show vlans 
Blue {
    vlan-id 100;
}
Green {
    vlan-id 300;
}
Red {
    vlan-id 200;
}

 

The "set" format:

[edit]
jeremy@switch# show vlans | display set 
set vlans Blue vlan-id 100
set vlans Green vlan-id 300
set vlans Red vlan-id 200

 

The "xml" format (edited):

 

[edit]
jeremy@switch# show vlans | display xml    
<rpc-reply>
    <configuration>
            <vlans>
                <vlan>
                    <name>Blue</name>
                    <vlan-id>100</vlan-id>
                </vlan>
                <vlan>
                    <name>Green</name>
                    <vlan-id>300</vlan-id>
                </vlan>
                <vlan>
                    <name>Red</name>
                    <vlan-id>200</vlan-id>
                </vlan>
            </vlans>
    </configuration>
</rpc-reply>

 

In the context of the Junos EZ library, all of these formats are considered "unstructured" since we're talking about using the text to make changes, rather than Resource definitions. (even though XML is structured-text-data).

 

You can use any of these formats with the Junos EZ library, though I'd expect you'd either use the "text" or the "set" format.

 NOTE:  If you are planning on using the "set" format, you must be running Junos 11.3R1 or later.

 

THE JUNOS-EZ CONFIG UTILITY

 

The Junos EZ library includes a toolbox of routines for managing Junos configuration.  You can use them doing the following at the Python shell: (assume dev is an open Device variable):

 

>>> from jnpr.junos.utils.config import Config
>>> cu = Config(dev)
>>> cu
jnpr.junos.utils.Config(jnpr-dc-fw)

 

You can then get extensive help on using the Config utility by doing "help(cu)" at the Python shell, but I'll leave that as an exercise for the reader.

 

You will want to use the load() routine to loading unstructured changes.  The content of the change can come from either a string variable or from a file.  

 

To load changes from a file you would do something like this:

 

>>> cu.load(path="config-example.conf")

 

The Junos EZ library will use the file extension (by default) to determine the format of the content.  If the file ends in ".conf" it assumes (text/curly).  You can override this behavior (see the help for details).

 

You can see the diff of this change by using the "print diff" routine:


>>> cu.pdiff()

[edit system]
-  host-name jnpr-dc-fw;
+  host-name jeremy;
-  domain-name wfs.com;
+  domain-name jeremy.com;

 

The load command only loads the changes, it does not comit them.  You would use the commit_check() and commit() routines for this purpose.  If you need to make exclusive changes you can use the lock() and unlock() routines.


TEMPLATE BASED CONFIGURATION

 

The Config load() can also be used to make template based configuration changes.  Templates are simply unstructured text that have variables, and you provide the variables at runtime.  This would be a common task for initial device setup, for example.

 

The Junos EZ library uses the standard Python templating library called "Jinja2".  It is extremely powerful and well documented, with tons of blogs about it.  

 

Let's take a look at a simple Junos "text" jinja2 template.  The variables are denoted between the double-curly braces:

 

system {
  host-name {{ host_name }};
  domain-name {{ domain_name }};
}

 

The Junos EZ library attempts to make the templating process very simple.  Here is the way we would use this template from the Python shell.  Assume the template is in a file called "mytemplate.conf".

 

# setup the template variables

>>> myvars = {}
>>> myvars['host_name'] = 'myhost-name'
>>> myvars['domain_name'] = 'myhost-domainname'

# load the template with the vars

>>> cu.load(template_path='mytemplate.conf', template_vars=myvars)

# now display the diff

>>> cu.pdiff()

[edit system]
-  host-name jnpr-dc-fw;
+  host-name myhost-name;
-  domain-name wfs.com;
+  domain-name myhost-domainname;


 

THE POSSIBILITIES ARE WIDE OPEN

 

Once you start to get comfortable with jinja2 templates, you'll find that you can do just about any kind of unstructured configuration change.  Jinja2 supports loops, conditionals, and all sorts of extensions that you might find useful.  I plan to write a series of "cookbook" articles covering this topic as well.

 

FURTHER READING

 

 

 

 

 

 

01.20.15
ericrochow

Is there a way using Junos EZ to view the VLAN members on a particular interface (basically the equivalent of "show configuration interfaces ge-0/0/0.0 family ethernet-switching vlan members")? As far as I can tell, I can only do the equivalent of "show vlans", which tells me the oposite of what I'm looking for.

Top Kudoed Authors
User Kudos Count
1
1