Skip to content
Snippets Groups Projects
nren_access.py 4.78 KiB
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