import json import os import jinja2 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_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) # 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_panel_definitions(panels, datasource, errors=False): result = [] for panel in panels: result.append(get_panel_fields( {**panel, **next(gridPos)}, 'traffic', datasource)) 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 get_dashboard_data(interfaces, datasource): nren_data = get_nrens(interfaces) for nren, data in nren_data.items(): 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) yield { '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 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