diff --git a/inventory_provider/routes/classifier.py b/inventory_provider/routes/classifier.py index dde5fa03c85456a91903a11d9571df9a0e00a73b..a39f7a0de0dc8ab1c1bdc5c109289a5568260509 100644 --- a/inventory_provider/routes/classifier.py +++ b/inventory_provider/routes/classifier.py @@ -1,7 +1,7 @@ import ipaddress import json -from flask import Blueprint, Response, jsonify +from flask import Blueprint, Response from inventory_provider.routes import common @@ -92,40 +92,50 @@ def find_interfaces(address): @common.require_accepts_json def peer_info(address): - try: - address_obj = ipaddress.ip_address(address) - except ValueError: - return Response( - response='unable to parse %r as an ip address' % address, - status=422, - mimetype="text/html") - r = common.get_redis() - result = {} - - info = r.get('ix_public_peer:%s' % address) - if info: - info = info.decode('utf-8') - result['ix-public-peer-info'] = json.loads(info) - description = result['ix-public-peer-info']['description'] - assert description is not None # sanity - result['ix-public-peer-group'] = list( - ix_peering_group(address_obj, description)) - - info = r.get('vpn_rr_peer:%s' % address) - if info: - info = info.decode('utf-8') - result['vpn-rr-peer-info'] = json.loads(info) - - interfaces = list(find_interfaces(address_obj)) - if interfaces: - result['interfaces'] = interfaces - - if not result: - return Response( - response='no peering info found for %s' % address, - status=404, - mimetype="text/html") - - return jsonify(result) + cache_key = 'classifier:peer-cache:%s' % address + + result = r.get(cache_key) + if result: + result = result.decode('utf-8') + else: + try: + address_obj = ipaddress.ip_address(address) + except ValueError: + return Response( + response='unable to parse %r as an ip address' % address, + status=422, + mimetype="text/html") + + result = {} + + info = r.get('ix_public_peer:%s' % address) + if info: + info = info.decode('utf-8') + result['ix-public-peer-info'] = json.loads(info) + description = result['ix-public-peer-info']['description'] + assert description is not None # sanity + result['ix-public-peer-group'] = list( + ix_peering_group(address_obj, description)) + + info = r.get('vpn_rr_peer:%s' % address) + if info: + info = info.decode('utf-8') + result['vpn-rr-peer-info'] = json.loads(info) + + interfaces = list(find_interfaces(address_obj)) + if interfaces: + result['interfaces'] = interfaces + + if not result: + return Response( + response='no peering info found for %s' % address, + status=404, + mimetype="text/html") + + result = json.dumps(result) + # cache this data for the next call + r.set(cache_key, result.encode('utf-8')) + + return Response(result, mimetype="application/json") diff --git a/inventory_provider/tasks/worker.py b/inventory_provider/tasks/worker.py index 1830053b8a54223e955028718d742c5c73bb8477..59eb170da64012382d7224bda778d00db2fe6399 100644 --- a/inventory_provider/tasks/worker.py +++ b/inventory_provider/tasks/worker.py @@ -260,6 +260,7 @@ def clear_cached_classifier_responses(hostname): r = get_redis(InventoryTask.config) for k in r.keys('classifier:cache:%s:*' % hostname): r.delete(k) + # TODO: remove peer-cache (after adding hostname to query) def _refresh_peers(hostname, key_base, peers):