An intro into Juniper automation

Dan Lindow
Nov 4 · 3 min read

As a network engineer a lot of a lot of the role is around the ongoing operations of network devices. Historically we would hop onto devices, fire a few commands at them and hope the traffic drains. Would it not be better if you could do this from a simple script? Let me show!

Lab setup

The lab consists of 4 vMX routers in a box design. It’s leveraging OSPF on the links and loopbacks. the “Net” cloud connects me to the lab network.

The configuration does not matter a whole lot here beyond this magical block of configuration:

root@R3> show configuration groups
DRAIN {
protocols {
ospf {
area <*> {
interface <*> {
metric 65535;
}
}
}
}
}

This configuration on its own does not apply to any section of the configuration (yet) but it is prepped and ready for when we do want to apply it.

When this configuration is applied, these statements would kick in. Example

root@R3# set protocols ospf apply-groups DRAIN[edit]
root@R3# show protocols | display inheritance
ospf {
area 0.0.0.0 {
interface em2.0 {
##
## '65535' was inherited from group 'DRAIN'
##
metric 65535;
}
interface em3.0 {
##
## '65535' was inherited from group 'DRAIN'
##
metric 65535;
}
interface lo0.0 {
##
## '65535' was inherited from group 'DRAIN'
##
metric 65535;
}
}
}

What we can see here is that all the interfaces have had their OSPF metrics hiked. One line of configuration and we are set!

Let’s take this a step further.

Automation

We can leverage Python to handle this configuration for us and ensure that the device is drained correctly. A helpful library for this is the official Juniper PyEZ module. More reading on that here:

I’ve put a quick script together to handle the interactions for us:

We can now kick off our automation efforts with minimal thought:

drain:

python traffic_management.py --device R3 --operation drain
INFO:__main__:Going to begin draining traffic on R3
INFO:__main__:diff just prior to the commit: None
INFO:__main__:commit applied, waiting 30 seconds to confirm
INFO:__main__:Device drained!

and we can confirm on R1 that R3 did indeed get pulled out of the ECMP group:

root@R1> show route 4.4.4.4inet.0: 15 destinations, 15 routes (15 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
4.4.4.4/32 *[OSPF/10] 00:01:02, metric 2
> to 10.0.0.1 via em3.0
root@R1>

restore:

python traffic_management.py --device R3 --operation restore
INFO:__main__:Going to begin draining traffic on R3
INFO:__main__:diff just prior to the commit:
[edit protocols ospf]
- apply-groups DRAIN;
INFO:__main__:commit applied, waiting 30 seconds to confirm
INFO:__main__:Device restored!!

and the restoration of ECMP on R1:

root@R1> show route 4.4.4.4inet.0: 15 destinations, 15 routes (15 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
4.4.4.4/32 *[OSPF/10] 00:00:20, metric 2
> to 10.0.0.1 via em3.0
to 10.0.0.3 via em4.0

As an added bonus, you also get commit messages to ensure you know what happened and when:

root@R3> show system commit
0 2019-11-04 16:02:21 UTC by root via netconf
1 2019-11-04 16:01:51 UTC by root via netconf commit confirmed, rollback in 10mins
Restoring traffic
2 2019-11-04 16:01:40 UTC by root via netconf
3 2019-11-04 16:01:09 UTC by root via netconf commit confirmed, rollback in 10mins
Draining traffic
Dan Lindow

Written by

IT wizard, beer judge, race car driver, and SME of all things.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade