-
Bjarke Madsen authoredBjarke Madsen authored
nren_access.py 4.94 KiB
import json
import os
import jinja2
from concurrent.futures import ProcessPoolExecutor
from brian_dashboard_manager.templating.render import create_dropdown_panel, \
create_panel_target
from brian_dashboard_manager.templating.helpers import \
is_aggregate_interface, is_logical_interface, is_physical_interface, \
num_generator, gridPos_generator, letter_generator, \
get_panel_definitions, flatten
def get_nrens(interfaces):
result = {}
for interface in interfaces:
description = interface.get('description', '').strip()
nren_name = description.split(' ')[2].upper()
nren = result.get(
nren_name, {'AGGREGATES': [], 'SERVICES': [], 'PHYSICAL': []})
interface_name = interface.get('name')
host = interface.get('router', '')
router = host.replace('.geant.net', '')
panel_title = f"{router} - {{}} - {interface_name} - {description}"
if is_aggregate_interface(interface):
nren['AGGREGATES'].append({
'interface': interface_name,
'hostname': host,
'alias': f"{host.split('.')[1].upper()} - {nren_name}"
})
# link aggregates are also shown
# under the physical dropdown
nren['PHYSICAL'].append({
'title': panel_title,
'hostname': host,
'interface': interface_name
})
elif is_logical_interface(interface):
nren['SERVICES'].append({
'title': panel_title,
'hostname': host,
'interface': interface_name
})
elif is_physical_interface(interface):
nren['PHYSICAL'].append({
'title': panel_title,
'hostname': host,
'interface': interface_name
})
result[nren_name] = nren
return result
# start IDs from 3 since aggregate
# panels have hardcoded IDs (1, 2).
id_gen = num_generator(start=3)
# aggregate panels have y=0, start generating at 1*height
gridPos = gridPos_generator(id_gen, start=1)
# Aggregate panels have unique targets,
# handle those here.
def get_aggregate_targets(aggregates):
ingress = []
egress = []
# used to generate refIds
letters = letter_generator()
for target in aggregates:
ref_id = next(letters)
in_data = {
**target,
'alias': f"{target['alias']} - Ingress Traffic",
'refId': ref_id,
'select_field': 'ingress'
}
out_data = {
**target,
'alias': f"{target['alias']} - Egress Traffic",
'refId': ref_id,
'select_field': 'egress'
}
ingress_target = create_panel_target(in_data)
egress_target = create_panel_target(out_data)
ingress.append(ingress_target)
egress.append(egress_target)
return ingress, egress
def get_dashboard_data(interfaces, datasource):
with ProcessPoolExecutor(max_workers=4) as executor:
def get_panels(data):
for panel in data:
yield executor.submit(
get_panel_definitions,
{
**panel,
**next(gridPos)
},
datasource
)
nren_data = executor.submit(get_nrens, interfaces).result()
for nren, data in nren_data.items():
services_dropdown = create_dropdown_panel(
'Services', **next(gridPos))
services = get_panels(data['SERVICES'])
iface_dropdown = create_dropdown_panel(
'Interfaces', **next(gridPos))
physical = get_panels(data['PHYSICAL'])
agg_ingress, agg_egress = executor.submit(
get_aggregate_targets, data['AGGREGATES']).result()
yield {
'nren_name': nren,
'datasource': datasource,
'ingress_aggregate_targets': agg_ingress,
'egress_aggregate_targets': agg_egress,
'dropdown_groups': [
{
'dropdown': services_dropdown,
'panels': flatten([p.result() for p in services]),
},
{
'dropdown': iface_dropdown,
'panels': flatten([p.result() for p in physical]),
}
]
}
def generate_nrens(interfaces, datasource):
file = os.path.abspath(os.path.join(
os.path.dirname(__file__),
'templates',
'nren_access',
'nren-dashboard.json.j2'))
with open(file) as f:
template = jinja2.Template(f.read())
for dashboard in get_dashboard_data(interfaces, datasource):
rendered = template.render(dashboard)
rendered = json.loads(rendered)
rendered['uid'] = None
rendered['id'] = None
yield rendered