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_panel_fields, create_aggregate_panel 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}" location = host.split('.')[1].upper() if is_aggregate_interface(interface): nren['AGGREGATES'].append({ 'interface': interface_name, 'hostname': host, 'alias': f"{location} - {nren_name} ({interface_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 id_gen = num_generator(start=1) # 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)) if errors: result.append(get_panel_fields( {**panel, **next(gridPos)}, 'errors', datasource)) return result def build_data(nren, data, datasource): global gridPos if len(data['AGGREGATES']) > 0: agg_panels = create_aggregate_panel( f'Aggregate - {nren}', gridPos_generator(id_gen, agg=True), data['AGGREGATES'], datasource) else: # if there's no aggregate panel(s), start other stuff at y=0. gridPos = gridPos_generator(id_gen, start=0) agg_panels = [] 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, 'aggregate_panels': agg_panels, '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