Getting Started with Juniper and Batfish
Batfish and Juniper#
Batfish and pybatfish are great tools to analyse a network and store the evolution of a network over time.
Batfish is a java based application that does the configuration mangling and storage, while pybatfish
is the interface to upload config and ask questions about the configuration from the batfish server.
Batfish is most often (only?) deployed as a docker container.
Then you would use pybatfish
to interface with it.
Batfish uses static configuration dumps only from your networking devices and does not connect directly to the devices.
Batfish knows about the concept of a network and a snapshot.
- A network is a logical grouping of devices
- A snapshot is a state of the network at a given time. A network contains many snapshots allowing you to view the evolution of your network.
Batfish supports the following devices
How to use it with Juniper Devices#
You need to package and upload snapshot data.
Configuration files are uploaded based on a folder structure:
config/
: Configuration of network devices (router1.cfg, router2.cfg)hosts/
: Host configurations eg. pointers to their iptables files (host1.json, host2.json)iptables/
: iptables configuration files (host1.iptables, host2.iptables)batfish/
: supplemental information (isp_config.json)
When packaging the snapshot
top level folder should be part of the archive.
Getting the Juniper Configuration#
So how do we get the configuration dumps?
I use junos pyez
to connect to a list of inventory devices and write the config to files.
The rpc
I use is:
text_config = dev.rpc.get_config(options={
'database': 'committed',
'format': 'text'
})
- Using junos pyez to connect to devices
- Info on pyez retrieving configuration
- List of default pyez Remote Proceddure Calls
You could of course do it by manually sshing into the machines - but that isn’t nice is it:
ssh user@ip
show configuration | display text | save config_10_10_2020.txt
scp user@ip:/var/home/remote/config_10_10_2020.txt .
At this point you will have the configuration files. Make sure to move them into a directory like:
networks/<network_name>/config/
Running Batfish#
Run the batfish docker container:
docker pull batfish/allinone
docker run --name batfish -v $(pwd)/data:/data -p 8888:8888 -p 9997:9997 -p 9996:9996 batfish/allinone -d
Uploading the configuration to batfish#
Now everything is setup, create a script called upload.py
:
from pybatfish.client.commands import (
bf_session, bf_set_network, bf_init_snapshot
)
# Connect to batfish server running locally
bf_session.host = 'localhost'
# Set the network you are working with
bf_set_network('<network_name>')
# Intialise a snapshot
SNAPSHOT_DIR = 'networks/<network_name>'
bf_init_snapshot(SNAPSHOT_DIR, name='snapshot-2020-10-10', overwrite=True)
Then run the file:
python upload.py
This should start the process of importing the config into batfish, example output:
status: ASSIGNED
.... 2020-10-15 09:10:31.629000+02:00 Parse network configs 8 / 74. (00:00:24 elapsed)
status: ASSIGNED
.... 2020-10-15 09:10:31.629000+02:00 Parse network configs 8 / 74. (00:00:25 elapsed)
status: CHECKINGSTATUS
.... 2020-10-15 09:10:31.629000+02:00 Parse network configs 8 / 74. (00:00:26 elapsed)
status: ASSIGNED
.... 2020-10-15 09:10:31.629000+02:00 Parse network configs 8 / 74. (00:00:27 elapsed)
What now?#
Now you can get data, check configuration and run tests on the snapshot.
You do this by asking questions.
Interacting with a batfish service:
bfq.<question_name>()
Creates a question (with parameters, if applicable).bfq.<question_name>().answer()
sends a query to Batfish service and returns the results of executing the questionbfq.<question_name>().answer().frame()
converts the answer into a Pandas dataframe for easy data manipulation
The best way to interact with batfish is in a data science way…which means getting familiar with jupyter notebooks and pandas
Installing Jupyter locally#
pip install jupyter
pip install pandas
Then start the notebook:
jupyter notbook
Interacting with batfish#
You need to import some packages, set the network and snapshot - then start asking questions:
import pandas as pd
from pybatfish.client.commands import *
from pybatfish.datamodel import *
from pybatfish.datamodel.answer import *
from pybatfish.datamodel.flow import *
from pybatfish.question import *
from pybatfish.question import bfq
bf_set_network('<network_name>')
bf_set_snapshot('snapshot-2020-10-10')
load_questions()
The you can ask any questions you need to.
They provide some ideas from their public notebooks
Get a list of all possible questions#
>>> dir(bfq)
[...,
'aaaAuthenticationLogin',
'bgpEdges',
'bgpPeerConfiguration',
'bgpProcessConfiguration',
'bgpSessionCompatibility',
'bgpSessionStatus',
'bidirectionalReachability',
'bidirectionalTraceroute',
'compareFilters',
'definedStructures',
'detectLoops',
'differentialReachability',
'edges',
'eigrpEdges',
'evpnL3VniProperties',
'f5BigipVipConfiguration',
'fileParseStatus',
'filterLineReachability',
'filterTable',
'findMatchingFilterLines',
'initIssues',
'interfaceMtu',
'interfaceProperties',
'ipOwners',
'ipsecEdges',
'ipsecSessionStatus',
'isisEdges',
'layer1Edges',
'layer3Edges',
'loopbackMultipathConsistency',
'lpmRoutes',
'mlagProperties',
'multipathConsistency',
'namedStructures',
'nodeProperties',
'ospfAreaConfiguration',
'ospfEdges',
'ospfInterfaceConfiguration',
'ospfProcessConfiguration',
'ospfSessionCompatibility',
'parseWarning',
'prefixTracer',
'reachability',
'referencedStructures',
'resolveFilterSpecifier',
'resolveInterfaceSpecifier',
'resolveIpSpecifier',
'resolveIpsOfLocationSpecifier',
'resolveLocationSpecifier',
'resolveNodeSpecifier',
'routes',
'searchFilters',
'searchRoutePolicies',
'subnetMultipathConsistency',
'switchedVlanProperties',
'testFilters',
'testRoutePolicies',
'traceroute',
'undefinedReferences',
'unusedStructures',
'viConversionStatus',
'viConversionWarning',
'viModel',
'vxlanEdges',
'vxlanVniProperties']