Skip to content
Snippets Groups Projects
Commit 0a3f6377 authored by Erik Reid's avatar Erik Reid
Browse files

refactoring bgp neighbor parsing ... wip

parent cc2c2ba1
No related branches found
No related tags found
No related merge requests found
......@@ -112,55 +112,20 @@ UNIT_SCHEMA = """<?xml version="1.1" encoding="UTF-8" ?>
PEERING_LIST_SCHEMA = {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"top-level-peering": {
"type": "object",
"properties": {
"group": {"type": "string"},
"description": {"type": "string"},
"address": {"type": "string"},
"remote-asn": {"type": "integer"},
"local-asn": {"type": "integer"}
},
# lots of internal peerings - so maybe no explicit asn's
"required": ["group", "address"],
"additionalProperties": False
},
"instance-peering": {
"peering": {
"type": "object",
"properties": {
"instance": {"type": "string"},
"group": {"type": "string"},
"description": {"type": "string"},
"address": {"type": "string"},
"remote-asn": {"type": "integer"},
"local-asn": {"type": "integer"},
},
# description and-or local-asn is not always present,
# just based on empirical tests - not a problem
"required": ["instance", "group", "address", "remote-asn"],
"additionalProperties": False
},
"logical-system-peering": {
"type": "object",
"properties": {
"instance": {"type": "string"},
"logical-system": {"type": "string"},
"group": {"type": "string"},
"description": {"type": "string"},
"address": {"type": "string"},
"remote-asn": {"type": "integer"},
"local-asn": {"type": "integer"}
},
# local/remote-asn and/or description are not always present,
# just based on empirical tests - not a problem
"required": ["logical-system", "group", "address"],
# lots of internal peerings - so maybe no explicit asn's
"required": ["group", "address"],
"additionalProperties": False
},
"peering": {
"oneOf": [
{"$ref": "#/definitions/top-level-peering"},
{"$ref": "#/definitions/instance-peering"},
{"$ref": "#/definitions/logical-system-peering"}
]
}
},
"type": "array",
......@@ -287,7 +252,7 @@ def list_interfaces(netconf_config):
yield u
def all_bgp_peers(netconf_config):
def _system_bgp_peers(system_node):
def _peering_params(neighbor_node):
address = neighbor_node.find('name').text
......@@ -306,34 +271,39 @@ def all_bgp_peers(netconf_config):
info['description'] = description.text
return info
for group in netconf_config.xpath('//configuration/protocols/bgp/group'):
def _neighbors(group_node):
for neighbor in group_node.xpath('./neighbor'):
inactive = neighbor.get('inactive')
if inactive == 'inactive':
continue
yield _peering_params(neighbor)
for group in system_node.xpath('./protocols/bgp/group'):
group_name = group.find('name').text
for neighbor in group.xpath('./neighbor'):
peer = _peering_params(neighbor)
for peer in _neighbors(group):
peer['group'] = group_name
yield peer
for instance in netconf_config.xpath(
'//configuration/routing-instances/instance'):
for instance in system_node.xpath(
'./routing-instances/instance'):
instance_name = instance.find('name').text
for group in instance.xpath('./protocols/bgp/group'):
group_name = group.find('name').text
for neighbor in group.xpath('./neighbor'):
peer = _peering_params(neighbor)
peer['instance'] = instance_name
peer['group'] = group_name
yield peer
for peer in _system_bgp_peers(instance):
peer['instance'] = instance_name
yield peer
def all_bgp_peers(netconf_config):
for base_system in netconf_config.xpath('//configuration'):
# there should only be one
yield from _system_bgp_peers(base_system)
for logical_system in netconf_config.xpath(
'//configuration/logical-systems'):
logical_system_name = logical_system.find('name').text
for group in logical_system.xpath('./protocols/bgp/group'):
group_name = group.find('name').text
for neighbor in group.xpath('./neighbor'):
peer = _peering_params(neighbor)
peer['logical-system'] = logical_system_name
peer['group'] = group_name
yield peer
for peer in _system_bgp_peers(logical_system):
peer['logical-system'] = logical_system_name
yield peer
def interface_addresses(netconf_config):
......
......@@ -35,9 +35,22 @@ def test_interface_list(netconf_doc):
jsonschema.validate(interfaces, schema)
assert interfaces # at least shouldn't be empty
from lxml import etree
def test_bgp_peering_data(netconf_doc):
active_peers = set()
inactive_peers = set()
for neighbor in netconf_doc.xpath('//group/neighbor'):
address = neighbor.find('name').text
address = ipaddress.ip_address(address).exploded
inactive = neighbor.get('inactive')
if inactive == 'inactive':
inactive_peers.add(address)
else:
if address == '62.40.99.50':
print('here')
active_peers.add(address)
peerings = list(juniper.all_bgp_peers(netconf_doc))
jsonschema.validate(peerings, juniper.PEERING_LIST_SCHEMA)
assert peerings # there's always at least one
......@@ -47,6 +60,15 @@ def test_bgp_peering_data(netconf_doc):
canonical_address = ipaddress.ip_address(p['address']).exploded
assert p['address'] == canonical_address
# confirm we got all of the active peerings
returned_addresses = {p['address'] for p in peerings}
missing = active_peers - returned_addresses
if missing:
print('here')
assert returned_addresses == active_peers
# confirm that none of the inactive peerings were returned
assert not inactive_peers & returned_addresses
def test_snmp_community_string(mocked_netifaces, netconf_doc):
assert juniper.snmp_community_string(netconf_doc) == '0pBiFbD'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment