From d3bb84faf725583d73c7a0a74dcc4bb24a3cd775 Mon Sep 17 00:00:00 2001
From: Erik Reid <erik.reid@geant.org>
Date: Wed, 11 Dec 2019 11:37:00 +0100
Subject: [PATCH] compute interface service tree in redis

---
 inventory_provider/tasks/worker.py | 71 ++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/inventory_provider/tasks/worker.py b/inventory_provider/tasks/worker.py
index 33709d1f..e6e9cbee 100644
--- a/inventory_provider/tasks/worker.py
+++ b/inventory_provider/tasks/worker.py
@@ -560,6 +560,7 @@ def refresh_finalizer(self, pending_task_ids_json):
 
         _wait_for_tasks(task_ids, update_callback=_update)
         _build_subnet_db(update_callback=_update)
+        _build_interface_services(update_callback=_update)
 
     except (jsonschema.ValidationError,
             json.JSONDecodeError,
@@ -573,6 +574,76 @@ def refresh_finalizer(self, pending_task_ids_json):
     logger.debug('<<< refresh_finalizer')
 
 
+def _build_interface_services(update_callback=lambda s: None):
+    logger.debug('>>> interface_services')
+
+    r = get_next_redis(InventoryTask.config)
+
+    def _interfaces():
+        for k in r.scan_iter('netconf-interfaces:*'):
+            k = k.decode('utf-8')
+            (_, router_name, ifc_name) = k.split(':')
+
+            info = r.get(k).decode('utf-8')
+            info = json.loads(info)
+
+            assert ifc_name == info['name']
+            yield {
+                'hostname': router_name,
+                'interface': info['name'],
+                'description': info['description']
+            }
+
+    def _classify(ifc):
+        if ifc['description'].startswith('SRV_MDVPN'):
+            return 'mdvpn'
+        if 'LHCONE' in ifc['description']:
+            return 'lhcone'
+        return None
+
+
+    r = get_next_redis(InventoryTask.config)
+    rp = r.pipeline()
+    for ifc in list(_interfaces()):
+        service_type = _classify(ifc)
+        if not service_type:
+            continue
+        rp.set(
+            f'{service_type}:interface-services'
+            f':{ifc["hostname"]}:{ifc["interface"]}',
+            json.dumps(ifc))
+
+    rp.execute()
+
+    logger.debug('<<< update_interfaces_to_services')
+
+
+    for ifc in _interfaces():
+            entry = subnets.setdefault(info['interface address'], [])
+            entry.append(info)
+
+        update_callback('saving {} subnets'.format(len(subnets)))
+
+    try:
+        task_ids = json.loads(pending_task_ids_json)
+        logger.debug('task_ids: %r' % task_ids)
+        jsonschema.validate(task_ids, input_schema)
+
+        _wait_for_tasks(task_ids, update_callback=_update)
+        _build_subnet_db(update_callback=_update)
+
+    except (jsonschema.ValidationError,
+            json.JSONDecodeError,
+            InventoryTaskError) as e:
+        update_latch_status(InventoryTask.config, failure=True)
+        raise e
+
+    latch_db(InventoryTask.config)
+    _update('latched current/next dbs')
+
+    logger.debug('<<< interface_services')
+
+
 def _build_subnet_db(update_callback=lambda s: None):
 
     r = get_next_redis(InventoryTask.config)
-- 
GitLab