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
Branches
Tags
No related merge requests found
...@@ -112,55 +112,20 @@ UNIT_SCHEMA = """<?xml version="1.1" encoding="UTF-8" ?> ...@@ -112,55 +112,20 @@ UNIT_SCHEMA = """<?xml version="1.1" encoding="UTF-8" ?>
PEERING_LIST_SCHEMA = { PEERING_LIST_SCHEMA = {
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"definitions": { "definitions": {
"top-level-peering": { "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": {
"type": "object", "type": "object",
"properties": { "properties": {
"instance": {"type": "string"},
"group": {"type": "string"}, "group": {"type": "string"},
"description": {"type": "string"}, "description": {"type": "string"},
"address": {"type": "string"}, "address": {"type": "string"},
"remote-asn": {"type": "integer"}, "remote-asn": {"type": "integer"},
"local-asn": {"type": "integer"}, "local-asn": {"type": "integer"},
}, "instance": {"type": "string"},
# 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": {
"logical-system": {"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, # lots of internal peerings - so maybe no explicit asn's
# just based on empirical tests - not a problem "required": ["group", "address"],
"required": ["logical-system", "group", "address"],
"additionalProperties": False "additionalProperties": False
},
"peering": {
"oneOf": [
{"$ref": "#/definitions/top-level-peering"},
{"$ref": "#/definitions/instance-peering"},
{"$ref": "#/definitions/logical-system-peering"}
]
} }
}, },
"type": "array", "type": "array",
...@@ -287,7 +252,7 @@ def list_interfaces(netconf_config): ...@@ -287,7 +252,7 @@ def list_interfaces(netconf_config):
yield u yield u
def all_bgp_peers(netconf_config): def _system_bgp_peers(system_node):
def _peering_params(neighbor_node): def _peering_params(neighbor_node):
address = neighbor_node.find('name').text address = neighbor_node.find('name').text
...@@ -306,34 +271,39 @@ def all_bgp_peers(netconf_config): ...@@ -306,34 +271,39 @@ def all_bgp_peers(netconf_config):
info['description'] = description.text info['description'] = description.text
return info 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 group_name = group.find('name').text
for neighbor in group.xpath('./neighbor'): for peer in _neighbors(group):
peer = _peering_params(neighbor)
peer['group'] = group_name peer['group'] = group_name
yield peer yield peer
for instance in netconf_config.xpath( for instance in system_node.xpath(
'//configuration/routing-instances/instance'): './routing-instances/instance'):
instance_name = instance.find('name').text instance_name = instance.find('name').text
for group in instance.xpath('./protocols/bgp/group'): for peer in _system_bgp_peers(instance):
group_name = group.find('name').text peer['instance'] = instance_name
for neighbor in group.xpath('./neighbor'): yield peer
peer = _peering_params(neighbor)
peer['instance'] = instance_name
peer['group'] = group_name def all_bgp_peers(netconf_config):
yield peer
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( for logical_system in netconf_config.xpath(
'//configuration/logical-systems'): '//configuration/logical-systems'):
logical_system_name = logical_system.find('name').text logical_system_name = logical_system.find('name').text
for group in logical_system.xpath('./protocols/bgp/group'): for peer in _system_bgp_peers(logical_system):
group_name = group.find('name').text peer['logical-system'] = logical_system_name
for neighbor in group.xpath('./neighbor'): yield peer
peer = _peering_params(neighbor)
peer['logical-system'] = logical_system_name
peer['group'] = group_name
yield peer
def interface_addresses(netconf_config): def interface_addresses(netconf_config):
......
...@@ -35,9 +35,22 @@ def test_interface_list(netconf_doc): ...@@ -35,9 +35,22 @@ def test_interface_list(netconf_doc):
jsonschema.validate(interfaces, schema) jsonschema.validate(interfaces, schema)
assert interfaces # at least shouldn't be empty assert interfaces # at least shouldn't be empty
from lxml import etree
def test_bgp_peering_data(netconf_doc): 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)) peerings = list(juniper.all_bgp_peers(netconf_doc))
jsonschema.validate(peerings, juniper.PEERING_LIST_SCHEMA) jsonschema.validate(peerings, juniper.PEERING_LIST_SCHEMA)
assert peerings # there's always at least one assert peerings # there's always at least one
...@@ -47,6 +60,15 @@ def test_bgp_peering_data(netconf_doc): ...@@ -47,6 +60,15 @@ def test_bgp_peering_data(netconf_doc):
canonical_address = ipaddress.ip_address(p['address']).exploded canonical_address = ipaddress.ip_address(p['address']).exploded
assert p['address'] == canonical_address 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): def test_snmp_community_string(mocked_netifaces, netconf_doc):
assert juniper.snmp_community_string(netconf_doc) == '0pBiFbD' assert juniper.snmp_community_string(netconf_doc) == '0pBiFbD'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment