From 0136eb042e9caf52a879cd8fe45f9544bf168905 Mon Sep 17 00:00:00 2001
From: Robert Latta <robert.latta@geant.org>
Date: Tue, 9 Mar 2021 17:30:25 +0000
Subject: [PATCH] switched poller route to use IMS data

---
 inventory_provider/routes/poller.py | 86 +++++++++++++++++++----------
 1 file changed, 58 insertions(+), 28 deletions(-)

diff --git a/inventory_provider/routes/poller.py b/inventory_provider/routes/poller.py
index 228ae0b7..85591b89 100644
--- a/inventory_provider/routes/poller.py
+++ b/inventory_provider/routes/poller.py
@@ -1,10 +1,12 @@
 import json
 import logging
 import re
+from distutils.util import strtobool
 
-from flask import Blueprint, Response, current_app
+from flask import Blueprint, Response, current_app, request
 from inventory_provider import juniper
 from inventory_provider.routes import common
+from inventory_provider.routes.classifier import get_ims_equipment_name
 
 logger = logging.getLogger(__name__)
 routes = Blueprint('poller-support-routes', __name__)
@@ -104,35 +106,56 @@ def _load_interface_bundles(hostname=None):
 
 
 def _load_services(hostname=None):
-    result = dict()
-    key_pattern = f'opsdb:interface_services:{hostname}:*' \
-        if hostname else 'opsdb:interface_services:*'
-
-    def _service_params(full_service_info):
-        return {
-            'id': full_service_info['id'],
-            'name': full_service_info['name'],
-            'type': full_service_info['service_type'],
-            'status': full_service_info['status']
-        }
+    if hostname:
+        hostname = get_ims_equipment_name(hostname)
+
+    key_pattern = f'ims:interface_port_ids:{hostname}:*' \
+        if hostname else 'ims:interface_port_ids:*'
+
+    port_id_interfaces = {}
+    interface_services = {}
+
+    def _get_port_id_services(s):
+        nonlocal port_id_interfaces
+        for d in s:
+            k = d['key']
+            v = d['value']
+            port_id_interfaces[v['port_id']] = k.split(':')[-2:]
+            yield f'ims:port_id_services:{v["port_id"]}'
+
+    def _filter_and_format_services(_services):
+        included_service_ids = set()
+        for s in _services:
+            if s['id'] in included_service_ids:
+                continue
+            if s['circuit_type'] == 'service':
+                included_service_ids.add(s['id'])
+                yield {
+                    'id': s['id'],
+                    'name': s['name'],
+                    'type': s['service_type'],
+                    'status': s['status']
+                }
 
-    for doc in common.load_json_docs(
+    if_ports = common.load_json_docs(
             config_params=current_app.config['INVENTORY_PROVIDER_CONFIG'],
             key_pattern=key_pattern,
-            num_threads=20):
-
-        m = re.match(r'^opsdb:interface_services:([^:]+):(.+)', doc['key'])
-        if not m:
-            logger.warning(f'can\'t parse redis service key {doc["key"]}')
-            # there are some weird records (dtn*, dp1*)
-            continue
+            num_threads=20)
 
-        router = m.group(1)
-        interface = m.group(2)
-        result.setdefault(router, dict())
-        result[router][interface] = [_service_params(s) for s in doc['value']]
+    for r in common.load_json_docs(
+            config_params=current_app.config['INVENTORY_PROVIDER_CONFIG'],
+            key_pattern=_get_port_id_services(if_ports),
+            num_threads=20):
+        services = r['value']
+        if services:
+            h, i = port_id_interfaces[services[0]['port_a_id']]
+            ifs_h = interface_services.get(h, {})
+            interface_services[h] = ifs_h
+            ifs_h_i = ifs_h.get(i, [])
+            ifs_h_i.extend(list(_filter_and_format_services(services)))
+            ifs_h[i] = ifs_h_i
 
-    return result
+    return interface_services
 
 
 def _load_interfaces(hostname):
@@ -159,7 +182,6 @@ def _load_interfaces(hostname):
 
 
 def _load_poller_interfaces(hostname=None):
-
     snmp_indexes = _load_snmp_indexes(hostname)
     bundles = _load_interface_bundles(hostname)
     services = _load_services(hostname)
@@ -207,10 +229,18 @@ def interfaces(hostname=None):
 
     cache_key = f'classifier-cache:poller-interfaces:{hostname}' \
         if hostname else 'classifier-cache:poller-interfaces:all'
-
     r = common.get_current_redis()
 
-    result = r.get(cache_key)
+    ignore_cache = request.args.get('ignore-cache', default='false', type=str)
+    try:
+        ignore_cache = strtobool(ignore_cache)
+    except ValueError:
+        ignore_cache = False
+    if ignore_cache:
+        result = False
+    else:
+        result = r.get(cache_key)
+
     if result:
         result = result.decode('utf-8')
     else:
-- 
GitLab