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

Finished feature reverse-interface-address-lookups.

parents 2a78a62b 395dabff
No related branches found
No related tags found
No related merge requests found
......@@ -744,3 +744,55 @@ Any non-empty responses are JSON formatted messages.
"additionalProperties": False
}
```
* `reverse_interface_addresses/<address>`
* key examples
* `reverse_interface_addresses:193.203.0.203`
* `reverse_interface_addresses:2001:07f8:00a0:0000:0000:5926:0000:0002`
* valid values:
```json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"v4a": {
"type": "string",
"pattern": r'^(\d+\.){3}\d+$'
},
"v6a": {
"type": "string",
"pattern": r'^([a-f\d]{4}:){7}[a-f\d]{4}$'
},
"v4i": {
"type": "string",
"pattern": r'^(\d+\.){3}\d+/\d+$'
},
"v6i": {
"type": "string",
"pattern": r'^[a-f\d:]+/\d+$'
}
},
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"oneOf": [
{"$ref": "#/definitions/v4a"},
{"$ref": "#/definitions/v6a"}
]
},
"interface address": {
"oneOf": [
{"$ref": "#/definitions/v4i"},
{"$ref": "#/definitions/v6i"}
]
},
"interface name": {"type": "string"},
},
"required": ["name", "interface address", "interface name"],
"additionalProperties": False
}
}
```
......@@ -292,6 +292,22 @@ def vpn_rr_peers(netconf_config):
neighbor['peer-as'] = int(r.find('peer-as').text)
yield neighbor
def interface_addresses(netconf_config):
"""
yields a list of all distinct interface addresses
:param netconf_config:
:return:
"""
for ifc in list_interfaces(netconf_config):
for address in ifc['ipv4'] + ifc['ipv6']:
yield {
"name": ipaddress.ip_interface(address).ip.exploded,
"interface address": address,
"interface name": ifc['name']
}
# note for enabling vrr data parsing ...
# def fetch_vrr_config(hostname, ssh_params):
#
......
......@@ -249,7 +249,7 @@ def load_netconf_data(hostname):
r = get_redis(InventoryTask.config)
netconf = r.get('netconf:' + hostname)
if not netconf:
return None
raise InventoryTaskError('no netconf data found for %r' % hostname)
return etree.fromstring(netconf.decode('utf-8'))
......@@ -298,6 +298,13 @@ def refresh_vpn_rr_peers(hostname, netconf):
juniper.vpn_rr_peers(netconf))
def refresh_interface_address_lookups(hostname, netconf):
_refresh_peers(
hostname,
'reverse_interface_addresses',
juniper.interface_addresses(netconf))
@app.task(base=InventoryTask, bind=True)
def reload_router_config(self, hostname):
logger = logging.getLogger(__name__)
......@@ -313,20 +320,19 @@ def reload_router_config(self, hostname):
# get the timestamp for the current netconf data
current_netconf_timestamp = None
netconf_doc = load_netconf_data(hostname)
if netconf_doc:
try:
netconf_doc = load_netconf_data(hostname)
current_netconf_timestamp \
= juniper.netconf_changed_timestamp(netconf_doc)
logger.debug(
'current netconf timestamp: %r' % current_netconf_timestamp)
except InventoryTaskError:
pass # ok at this point if not found
# load new netconf data
netconf_refresh_config.apply(args=[hostname])
netconf_doc = load_netconf_data(hostname)
if netconf_doc is None:
raise InventoryTaskError(
'failure loading netconf data for %r' % hostname)
# return if new timestamp is the same as the original timestamp
new_netconf_timestamp = juniper.netconf_changed_timestamp(netconf_doc)
......@@ -352,6 +358,7 @@ def reload_router_config(self, hostname):
})
refresh_ix_public_peers(hostname, netconf_doc)
refresh_vpn_rr_peers(hostname, netconf_doc)
refresh_interface_address_lookups(hostname, netconf_doc)
clear_cached_classifier_responses(hostname)
# load snmp indexes
......
......@@ -102,3 +102,53 @@ def test_bgp_list(netconf_doc):
def test_snmp_community_string(mocked_netifaces, netconf_doc):
assert juniper.snmp_community_string(netconf_doc) == '0pBiFbD'
def test_interface_addresses_list(netconf_doc):
schema = {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"v4a": {
"type": "string",
"pattern": r'^(\d+\.){3}\d+$'
},
"v6a": {
"type": "string",
"pattern": r'^([a-f\d]{4}:){7}[a-f\d]{4}$'
},
"v4i": {
"type": "string",
"pattern": r'^(\d+\.){3}\d+/\d+$'
},
"v6i": {
"type": "string",
"pattern": r'^[a-f\d:]+/\d+$'
}
},
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"oneOf": [
{"$ref": "#/definitions/v4a"},
{"$ref": "#/definitions/v6a"}
]
},
"interface address": {
"oneOf": [
{"$ref": "#/definitions/v4i"},
{"$ref": "#/definitions/v6i"}
]
},
"interface name": {"type": "string"},
},
"required": ["name", "interface address", "interface name"],
"additionalProperties": False
}
}
addresses = list(juniper.interface_addresses(netconf_doc))
jsonschema.validate(addresses, schema)
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