diff --git a/Changelog.md b/Changelog.md index 8f4afe18557ca5dd7698aa19760736586abb1196..98f8d93e44b2ee79b2ad0bc4e3fabb2c75fbeaed 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +## [0.55] - 2020-12-08 +- LGR-73: updated business logic for classifying LG routers public/internal + ## [0.54] - 2020-10-07 - DBOARD3-334: peer-info classifier performance improvement diff --git a/inventory_provider/db/opsdb.py b/inventory_provider/db/opsdb.py index 07a24e275ca2aa107ddcfc1199fee64292ac4745..cdf49bdc947cb282b5e86093dee0f5448d5708f7 100644 --- a/inventory_provider/db/opsdb.py +++ b/inventory_provider/db/opsdb.py @@ -400,27 +400,40 @@ SELECT g.longitude AS pop_longitude, p.country_code AS pop_country_code, g.country AS pop_country, - g.city AS pop_city + e.model AS equipment_model FROM opsdb.equipment e LEFT JOIN opsdb.pop p ON p.absid = e.PTR_pop LEFT JOIN opsdb.geocoding g ON g.absid = p.PTR_geocoding LEFT JOIN opsdb.organisation o ON o.absid = e.PTR_owner WHERE - e.model LIKE 'mx%' + e.manufacturer = 'Juniper' AND e.status = 'Operational' AND o.name = 'DANTE / GEANT' - AND NOT (e.name REGEXP 'vpn-proxy|vrr|taas') + AND NOT (e.name REGEXP 'vpn-proxy|vrr|taas|junosspace') """ + def _public(row): + # cf. LGR-73 + + if row['pop_name'] in INTERNAL_POP_NAMES: + return False + + router_name_lower = row['router_name'].lower() + if any(router_name_lower.startswith(prefix) + for prefix in ['srx', 'gts', 'sw', 'qfx']): + return False + + if row['pop_city'].lower() == 'slough' \ + and not row['equipment_model'].upper().startswith('MX'): + return False + + return True + def _row2rsp(row): - print(row) return { 'equipment name': row['router_name'], - 'type': - 'INTERNAL' - if row['pop_name'] in INTERNAL_POP_NAMES - else 'CORE', + 'type': 'CORE' if _public(row) else 'INTERNAL', 'pop': { 'name': row['pop_name'], 'city': row['pop_city'], diff --git a/inventory_provider/routes/lg.py b/inventory_provider/routes/lg.py index e8b72f6a0f312b4fb445a34f438a7d9bb168fab0..bcb528ccc8252f806c3ce5b8b6366dea7e8da0f8 100644 --- a/inventory_provider/routes/lg.py +++ b/inventory_provider/routes/lg.py @@ -1,6 +1,6 @@ import json -from flask import Blueprint, jsonify, Response +from flask import Blueprint, jsonify, Response, current_app from inventory_provider.routes import common @@ -25,29 +25,25 @@ def routers(access): status=404, mimetype='text/html') - redis = common.get_current_redis() - def _visible(router): if access == ACCESS_INTERNAL: return True return router['type'] == 'CORE' def _routers(): - i = 0 - for k in redis.scan_iter('opsdb:lg:*'): - rtr = redis.get(k.decode('utf-8')).decode('utf-8') - rtr = json.loads(rtr) - i += 1 - if _visible(rtr): - yield rtr + for doc in common.load_json_docs( + config_params=current_app.config['INVENTORY_PROVIDER_CONFIG'], + key_pattern='opsdb:lg:*'): + yield doc['value'] + redis = common.get_current_redis() cache_key = f'classifier-cache:lg:{access}' result = redis.get(cache_key) if result: result = json.loads(result.decode('utf-8')) else: - result = list(_routers()) + result = list(filter(_visible, _routers())) # cache this data for the next call redis.set(cache_key, json.dumps(result).encode('utf-8')) diff --git a/setup.py b/setup.py index e955ca263415521e8ff1272197bc0ccf51bfd351..cede0c37d6d0f10ac079969dc6f42a5e276fc2a7 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name='inventory-provider', - version="0.54", + version="0.55", author='GEANT', author_email='swd@geant.org', description='Dashboard inventory provider', diff --git a/test/test_opsdb_queries.py b/test/test_opsdb_queries.py index e3d0bc56176fa30551bab6011459ad9b19cf497e..da219e271fd717a46655b5b6721ffa027d3fbe01 100644 --- a/test/test_opsdb_queries.py +++ b/test/test_opsdb_queries.py @@ -281,6 +281,26 @@ def test_lookup_lg_routers(connection, cached_test_data): jsonschema.validate(routers, LG_ROUTERS_SCHEMA) assert routers # shouldn't be empty + # LGR-73 + assert any( + r['equipment name'].startswith('sw2.am.office') for r in routers) + assert any( + r['equipment name'].startswith('sw3.am.office') for r in routers) + + switches = filter( + lambda r: r['equipment name'].startswith('sw'), routers) + assert all(s['type'] == 'INTERNAL' for s in switches) + + assert not any( + r['equipment name'].lower().startswith('junosspace') for r in routers) + + internal_prefix_patterns = ['srx', 'gts', 'qfx'] + for prefix in internal_prefix_patterns: + filtered = filter( + lambda r: r['equipment name'].lower().startswith(prefix), routers) + assert all(r['type'] == 'INTERNAL' for r in filtered), \ + f'not all {prefix}* routers are INTERNAL' + CIRCUIT_INFO_SCHEMA = { "$schema": "http://json-schema.org/draft-07/schema#", diff --git a/tox.ini b/tox.ini index a4cd729f02609783ef037fa1c93cbcc492104d50..f08e8f1c3512dd36edca87ebb6b20de3a3212053 100644 --- a/tox.ini +++ b/tox.ini @@ -11,7 +11,7 @@ deps = commands = coverage erase - coverage run --source inventory_provider -m py.test {posargs} + coverage run --source inventory_provider --omit='inventory_provider/routes/ims*,inventory_provider/db/ims*,inventory_provider/tasks/ims*' -m py.test {posargs} coverage xml coverage html coverage report --fail-under 75