import json import os import jinja2 from concurrent.futures import ProcessPoolExecutor from brian_dashboard_manager.templating.render import create_dropdown_panel from brian_dashboard_manager.templating.helpers import \ is_aggregate_interface, is_logical_interface, is_physical_interface, \ num_generator, gridPos_generator, get_aggregate_targets, \ get_panel_fields 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) def get_panel_definitions(panels, datasource, errors=False): result = [] for panel in panels: result.append(get_panel_fields( {**panel, **next(gridPos)}, 'traffic', datasource)) if panel.get('has_v6', False): result.append(get_panel_fields( {**panel, **next(gridPos)}, 'IPv6', datasource)) result.append(get_panel_fields( {**panel, **next(gridPos)}, 'multicast', datasource)) if errors: result.append(get_panel_fields( {**panel, **next(gridPos)}, 'errors', datasource)) return result def build_data(nren, data, datasource): agg_ingress, agg_egress = get_aggregate_targets(data['AGGREGATES']) services_dropdown = create_dropdown_panel('Services', **next(gridPos)) service_panels = get_panel_definitions(data['SERVICES'], datasource) iface_dropdown = create_dropdown_panel('Interfaces', **next(gridPos)) phys_panels = get_panel_definitions(data['PHYSICAL'], datasource, True) return { 'nren_name': nren, 'datasource': datasource, 'ingress_aggregate_targets': agg_ingress, 'egress_aggregate_targets': agg_egress, 'dropdown_groups': [ { 'dropdown': services_dropdown, 'panels': service_panels, }, { 'dropdown': iface_dropdown, 'panels': phys_panels, } ] } def get_dashboard_data(interfaces, datasource): nren_data = get_nrens(interfaces) result = [] with ProcessPoolExecutor(max_workers=4) as executor: for nren, data in nren_data.items(): result.append(executor.submit(build_data, nren, data, datasource)) return [r.result() for r in result] 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