OpenConfigBabelFish

Goal

OpenConfigBabelFish is TextFSM based tool to read and convert IP/MPLS Router configs. Whenever possible, the OpenConfig format will be used to store the data.

OpenConfig
Other formats
ConfigBabelFish Python Module
Traditional Vendors
OpenConfig YAML / JSON
user defined format
input parsing:
TextFSM template-library
templates per vendor and protocol element
OpenConfig mapping dictionaries
dics per protocol element
based on OpenConfig YANG defibnition
output rendering:
Jinja2 template-library
templates per protocol element
python yaml dump
python json dump
Cisco config or
Juniper config

First Focus is on Service Provider EGP and IGP Protocols e.G BGP (subsequently ISIS, … )

key element is the mapping of the textfsm record content to an python dict
Althouh this is complex and hard to describe in sentences, I have depecited below the mapping I used in my proof of concept file:

TextFSM parsing creates a list of records. The integer in the OpenConfigMappingDict defines the index in the TextFSM record for a specific placeholder.

e.g. The “as” is the first(:=0) field in the global-BGP output TextFSM record
       the “router-id” is the second (:=1) field in the global-BGP output TextFSM record

please note that the attributes are far beeing complete, I have just used two attributes for the PoC.

template name textfsm templates cisco OpenConfigMappingDict
CiscoBgpGlobalDefinition Value As (\S+)
Value RouterId (\S+)
Value description (.*)

Start
^router bgp ${As}
^ bgp router-id ${RouterId}
^ description ${description}
^!$ -> Record

EOF
‘bgp’: {
  ’global’: {
    ’as’: 0,
    ’router-id’:1,
    ’description’: 2
  }
}
CiscoBgpGrouplDefinition “Value Filldown As (\S+)
Value Required peerGroup (\S+)
Value description (.*)
Value remoteAs (\S+)

Start
^router bgp ${As}
^ neighbor-group ${peerGroup}
^  remote-as ${remoteAs}
^  description ${description}
^ !$ -> Record
“bgp”: {
  ”peer-groups”:{
    1 : {
      ”description” : 2,
      ”remote-as” : 3
    }
  }
}
CiscoBgpNeighborDefinition Value Filldown As (\S+)
Value Required neighbor (\S+)
Value peerGroup (\S+)
Value description (.*)

Start
^router bgp ${As}
^ neighbor ${neighbor}
^  use neighbor-group ${peerGroup}
^  description ${description}
^ !$ -> Record

EOF

‘bgp’: {
  ’neighbors’: {
    1: {
‘      use-group’: 2,
      ’description’: 3
    }
  }
}

Proof of Concept Example:

Input config snippet

outer isis 11
 is-type level-2-only
 net 49.0011.0011.0011.0011.00
 address-family ipv4 unicast
  metric-style wide
  metric 10000011
 !
 address-family ipv4 unicast
  metric-style wide
  metric 10000001
  maximum-paths 16
 !
 interface Loopback0
  passive
  address-family ipv4 unicast
  !
 !
 interface Loopback11
  passive
  address-family ipv4 unicast
  !
 !
 interface GigabitEthernet0/0/0/0
  circuit-type level-2-only
  point-to-point
  lsp-interval 10
  hello-padding disable
  address-family ipv4 unicast
   metric 27 level 2
   mpls ldp sync level 2
  !
 !
!
router bgp 1111
 nsr
 bgp router-id 11.111.111.1
 description "BGP-router-desription"
 address-family ipv4 unicast
  bgp dampening route-policy graded-flap-dampening
  maximum-paths ebgp 2
  maximum-paths ibgp 2
  redistribute static route-policy MARK-static-IBGP
 !
 address-family vpnv4 unicast
 !
 address-family ipv6 unicast
  maximum-paths ebgp 2
  maximum-paths ibgp 2
  network 1111::/19 route-policy MARK-1111-PA-AGGREGATE
 !
 neighbor-group GROUP1
  remote-as 2221
  description "BGP-group-description-1"
  update-source Loopback0
  address-family ipv4 unicast
   maximum-prefix 900000 90 restart 60
   route-policy IPV4_OUT out
   next-hop-self
   soft-reconfiguration inbound always
  !
 !
 neighbor-group GROUP2
  remote-as 2222
  description "BGP-group-description-2"
  update-source Loopback0
  address-family ipv4 unicast
   maximum-prefix 900000 90 restart 60
   route-policy IPV4_OUT out
   next-hop-self
   soft-reconfiguration inbound always
  !
 !
 neighbor 22.22.22.21
  use neighbor-group GROUP1
  description "BGP-neighbor-description-1"
 !
 neighbor 22.22.22.22
  use neighbor-group GROUP2
  description "BGP-neighbor-description-2"
 !
!

PoC python script

The script PoC.py extracts just the values, which ar epresent in the TextFSM templates and creates following output YAML dictionary:

please note the the script is far from perfect, it was created just to prrof the functionality.

Output YAML dict:

bgp:
  global:
    as: '1111'
    description: '"BGP-router-desription"'
    router-id: 11.111.111.1
  neighbors:
    22.22.22.21:
      description: '"BGP-neighbor-description-1"'
      use-group: GROUP1
    22.22.22.22:
      description: '"BGP-neighbor-description-2"'
      use-group: GROUP2
  peer-groups:
    GROUP1:
      description: '"BGP-group-description-1"'
      remote-as: '2221'
    GROUP2:
      description: '"BGP-group-description-2"'
      remote-as: '2222'

OpenConfig. Vendor-neutral, model-driven network management
Google TextFSM. (Python 2.x)
Jonathan Slenders jtextfsm. Fork of TextFSM, compatible with Python 3.x

Written with Haroopad.