Are annotations possible?

174 views
Skip to first unread message

Eric P

unread,
Apr 21, 2015, 6:13:37 PM4/21/15
to junos-p...@googlegroups.com
I'm working on a script to block abuser IPs- basically allows my NOC to block abuse IPs immediately rather than waiting for me to do it.  When I do it manually, I add an annotation with the date the IP was blocked. 

I'm not sure if this is possible with PyEZ- to do annotations in JunOS requires you to edit to the hierarchy you want to remark, then use the annotate command.  So for an example, logged into the device, I would typically do the following:

[edit firewall family inet filter inbound term abuse_ips from source-address]
1.2.3.4
annotate "blocked 21 April 2015 by username"


In PyEZ, to add a blocked IP I would do something like:

Config.load("set firewall family inet filter inbound term abuse_ips from source-address 1.2.3.4")


But I don't know how you would add an annotation to that since annotate is a hierarchy-specific command that you can't issue from the top level.  Anyone have any ideas?

Kurt Bales

unread,
Apr 21, 2015, 6:17:32 PM4/21/15
to Eric P, junos-p...@googlegroups.com
Completely untesteded but could you do something like:

'''set firewall family inet filter inbound term abuse_ips from source-address 1.2.3.4
edit firewall family inet filter inbound term abuse_ips from source-address
annotate "blocked 21 April 2015 by username"
top'''

Regards,

Kurt Bales
@networkjanitor JNCIE-ENT #368



--
You received this message because you are subscribed to the Google Groups "Junos Python EZ" group.
To unsubscribe from this group and stop receiving emails from it, send an email to junos-python-...@googlegroups.com.
Visit this group at http://groups.google.com/group/junos-python-ez.
To view this discussion on the web visit https://groups.google.com/d/msgid/junos-python-ez/c2305db4-5037-4abb-b4c6-8a5aa5857479%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Rick Sherman

unread,
Apr 22, 2015, 11:59:42 AM4/22/15
to junos-p...@googlegroups.com
Hi Eric,

The text configuration (Curly brace) is going to be your best bet.  You can turn this into a Jinja2 template and load it very easily with PyEZ.

firewall {
    family inet {
        filter inbound {
            term abuse_ips {
                from {
                    source-address {
                        /* blocked 21 April 2015 by username */
                        1.2.3.4/32;
                    }
                }
            }
        }
    }
}


Template:
firewall {
    family inet {
        filter inbound {
            term abuse_ips {
                from {
                    source-address {
                        /* blocked {{ date }} by {{ user}} */
                        {{ ip }};
                    }
                }
            }
        }
    }
}

Installing config:
import datetime
from jnpr.junos import Device
from jnpr.junos.utils.config import Config

dev = Device(host='192.168.74.31', user='rick', passwd='password123')
dev.open()

cu = Config(dev)

config_data = {
    'date': datetime.date.today().strftime("%d %B %Y"),
    'user': 'rsherman',
    'ip': '1.2.3.4/32'
}

cu.load(template_path='annotated.conf', template_vars=config_data, merge=True)

cu.commit()

dev.close()

Here are some links to more information:

-Rick

Eric P

unread,
Apr 22, 2015, 12:24:37 PM4/22/15
to junos-p...@googlegroups.com, e.j.p...@gmail.com
Kurt,

Firstly, thank you for your reply.

This was a good idea but unfortunately pyez doesn't recognize edit as a valid configuration format.  The relevant parts of the script I wrote (I'm still very new at this, be gentle!):

import sys

from jnpr.junos import Device
from jnpr.junos.utils.config import Config
from jnpr.junos.exception import *
from getpass import getpass
import socket
import time

#define credentials
userid = raw_input('username: ')
hidepass = getpass()

#define devices
devlist = ['router1', 'router2', 'router3']
dev = [Device(host, user=userid, password=hidepass) for host in devlist]
time = time.strftime("%d/%m/%Y")

# Open the device, handle exceptions
for d in dev:
    try:
        d.open()
    except Exception as err:
        print "Cannot connect to device:", err

#get abuse IP, check for validity
while True:
    badip = raw_input('enter abuse IP: ')
    try:
        socket.inet_aton(badip)
        break
    except socket.error:
        print "IP address is not valid, please enter valid IP address"
        continue

#push abuse IP to temp abuse ACL
for d in dev:
    print "device: {0}".format(d)
    d.bind( cu=Config )
    print "Loading configuration changes"
    d.cu.load("set firewall family inet filter TEST_FILTER term temp_abuse_ips from source-address {abuseip}".format(abuseip=badip))
    d.cu.load("edit firewall family inet filter TEST_FILTER term temp_abuse_ips from source-address {abuseip}".format(abuseip=badip))
    d.cu.load("annotate \"blocked time by userid\"").format(time=time, userid=userid)


Edit isn't recognized as a value for the load method

Traceback (most recent call last):
  File "filepath", line 42, in <module>
    d.cu.load("edit firewall family inet filter TEST_FILTER term temp_abuse_ips from source-address {abuseip}".format(abuseip=badip))
  File "/usr/lib/python2.6/site-packages/jnpr/junos/utils/config.py", line 338, in load
    "Not able to resolve the config format "
RuntimeError: Not able to resolve the config format You must define the format of the contents explicitly to the function. Ex: format='set'

Eric P

unread,
Apr 22, 2015, 12:27:13 PM4/22/15
to junos-p...@googlegroups.com
Rick,

Thanks for taking the time to reply.

I will try this out.  My problem with it is that I would really like this to be a self-service script- the idea being that our NOC identifies an abuse IP and the standard procedure is just to run this script which gathers the necessary information and then pushes the IP into the abuse filter.  Having to generate a new .conf file for each new IP and then change the script to point to the new file doesn't seem efficient.

Kurt Bales

unread,
Apr 22, 2015, 12:32:30 PM4/22/15
to Eric P, junos-p...@googlegroups.com
Rick can correct me if I'm wrong but "edit" is still a set format command, just like "delete" is a set format command.

You can also put all of those commands into a single string (or a template) and load then together.

For more options, visit https://groups.google.com/d/optout.


--

Rick Sherman

unread,
Apr 22, 2015, 12:33:11 PM4/22/15
to junos-p...@googlegroups.com
Hi Eric,

Please review the information provided.  Templates are a reusable version of the configuration that you can dynamically load information into.  (This is exactly what you're looking for).

config_data = {
    'date': time,
    'user': userid,
    'ip': badip
}


That configuration data is sourced from the script you provided and merged into the template at load time.

-Rick

Eric P

unread,
Apr 22, 2015, 12:42:34 PM4/22/15
to junos-p...@googlegroups.com
Rick,

Thanks again for the reply!

I am still really new to this and didn't really understand templating- I didn't realize the configuration data didn't have to be in a separate file.  Your answer makes sense now and I will try it out.
Reply all
Reply to author
Forward
0 new messages