Skip to content
Snippets Groups Projects
render.py 9.13 KiB
def create_dropdown_panel(title, id, y, **kwargs):
    """
    Creates a dropdown panel from the given data.

    :param title: title of the dropdown panel
    :param id: id of the dropdown panel
    :param y: y of the dropdown panel
    :param kwargs: data to be used in the template

    :return: rendered dropdown panel JSON
    """
    return {
        "aliasColors": {},
        "collapsed": False,
        "datasource": None,
        "fill": None,
        "fillGradient": None,
        "gridPos": {"h": 1, "w": 24, "x": 0, "y": y},
        "id": id,
        "legend": None,
        "lines": None,
        "linewidth": None,
        "search": None,
        "stack": None,
        "tags": None,
        "targets": None,
        "title": title,
        "type": "row",
        "xaxis": None,
        "yaxes": None,
        "yaxis": None,
    }


def create_yaxes(type):
    """
    Creates the yaxes JSON for the given type, used in the panel template.

    :param type: type of yaxes to create (bits/s or errors/s)

    :return: rendered yaxes JSON
    """
    if type == "errors":
        return [
            {
                "format": "none",
                "label": "errors and discards per second",
                "logBase": 1,
                "max": None,
                "min": 0,
                "show": True,
            },
            {
                "format": "none",
                "label": "errors and discards per second",
                "logBase": 1,
                "max": None,
                "min": 0,
                "show": True,
            },
        ]
    else:
        return [
            {
                "format": "bps",
                "label": "bits per second",
                "logBase": 1,
                "max": None,
                "min": "",
                "show": True,
            },
            {
                "format": "bps",
                "label": "bits per second",
                "logBase": 1,
                "max": None,
                "min": "",
                "show": True,
            },
        ]


def create_panel_target(
    alias,
    select_field,
    refId,
    percentile=False,
    measurement="interface_rates",
    errors=False,
    isp=None,
    subscription=None,
    scid=None,
    interface_tag=None,
    nren=None,
    hostname=None,
    interface=None,
    **_
):
    """
    Creates a panel target from the given data.
    A panel target defines how to query data for a single timeseries.

    :param data: data to be used in the template

    :return: rendered panel target JSON
    """
    select = [{"params": [select_field], "type": "field"}]
    select.append(
        {"params": [95], "type": "percentile"}
        if percentile
        else {"params": [], "type": "max"}
    )
    if not errors:
        select.append({"params": ["*8"], "type": "math"})
    if isp:
        tags = [
            {"condition": None, "key": "tag", "operator": "=", "value": interface_tag},
            {"condition": "AND", "key": "isp", "operator": "=", "value": isp},
            {"condition": "AND", "key": "nren", "operator": "=", "value": nren},
        ]
    elif subscription:
        tags = [
            {"condition": None, "key": "hostname", "operator": "=", "value": hostname},
            {
                "condition": "AND",
                "key": "subscription",
                "operator": "=",
                "value": subscription,
            },
        ]
    elif scid:
        tags = [{"condition": None, "key": "scid", "operator": "=", "value": scid}]
    else:
        tags = [
            {
                "condition": None,
                "key": "hostname",
                "operator": "=",
                "value": hostname,
            },
            {
                "condition": "AND",
                "key": "interface_name",
                "operator": "=",
                "value": interface,
            },
        ]
    result = {
        "alias": alias,
        "groupBy": (
            []
            if percentile
            else [
                {"params": ["$__interval"], "type": "time"},
                {"params": ["null"], "type": "fill"},
            ]
        ),
        "measurement": measurement,
        "orderByTime": None,
        "policy": None,
        "refId": refId,
        "resultFormat": "time_series",
        "select": [select],
        "tags": tags,
    }
    return result


def create_panel(
    title,
    height,
    width,
    linewidth,
    y,
    id,
    datasource,
    x=0,
    alias_colors=None,
    disable_legend=False,
    stack=False,
    y_axis_type="bits",
    targets=None,
    panel_targets=None,
    **_
):
    """
    Creates a panel from the given data. Constructs the yaxes and panel targets
    and renders the panel template using these.

    :param data: data to be used in the template

    :return: rendered panel JSON
    """
    yaxes = create_yaxes(y_axis_type)

    result = {
        "aliasColors": alias_colors or {},
        "bars": False,
        "collapsed": None,
        "dashLength": 10,
        "dashes": False,
        "datasource": datasource,
        "decimals": 2,
        "fieldConfig": {"defaults": {"custom": {}}, "overrides": []},
        "fill": 1,
        "fillGradient": 10,
        "gridPos": {"h": height, "w": width, "x": x, "y": y},
        "hiddenSeries": False,
        "id": id,
        "lines": True,
        "linewidth": linewidth,
        "nullPointMode": "null",
        "options": {"alertThreshold": True},
        "percentage": False,
        "pointradius": 2,
        "points": False,
        "renderer": "flot",
        "search": None,
        "seriesOverrides": [],
        "spaceLength": 10,
        "stack": stack,
        "steppedLine": False,
        "tags": None,
        "thresholds": [],
        "timeFrom": None,
        "timeRegions": [],
        "timeShift": None,
        "title": title,
        "tooltip": {"shared": True, "sort": 0, "value_type": "individual"},
        "type": "graph",
        "xaxis": {
            "buckets": None,
            "mode": "time",
            "name": None,
            "show": True,
            "values": None,
        },
        "yaxes": yaxes,
        "yaxis": {"align": False, "alignLevel": None},
        "targets": [],
    }
    if not disable_legend:
        result["legend"] = {
            "alignAsTable": True,
            "avg": True,
            "current": True,
            "max": True,
            "min": False,
            "rightSide": None,
            "show": True,
            "total": False,
            "values": True,
        }

    targets = targets or []
    for target in panel_targets or []:
        targets.append(create_panel_target(**target))
    result["targets"] = targets
    return result


def create_infobox():
    return {
        "datasource": None,
        "gridPos": {"h": 1, "w": 24, "x": 0, "y": 0},
        "id": 1,
        "options": {"content": "", "mode": "html"},
        "pluginVersion": "8.2.5",
        "title": "INFO: The average values displayed are only mean values for timescales of 2 days or less",
        "type": "text",
    }


def render_with_aggregate_dashboard(
    nren_name, aggregate_panels, dropdown_groups, tag=None, tags=None, **_
):
    assert tag or tags
    panels = [create_infobox()]
    panels.extend(aggregate_panels)
    for group in dropdown_groups:
        panels.append(group["dropdown"])
        panels.extend(group["panels"])

    return {
        "id": None,
        "uid": None,
        "annotations": {
            "list": [
                {
                    "builtIn": 1,
                    "datasource": "-- Grafana --",
                    "enable": True,
                    "hide": True,
                    "iconColor": "rgba(0, 211, 255, 1)",
                    "name": "Annotations & Alerts",
                    "type": "dashboard",
                }
            ]
        },
        "editable": False,
        "gnetId": None,
        "graphTooltip": 0,
        "schemaVersion": 27,
        "style": "dark",
        "tags": tags or [tag],
        "templating": {"list": []},
        "time": {"from": "now-24h", "to": "now"},
        "timepicker": {},
        "timezone": "",
        "title": nren_name,
        "version": 1,
        "links": [],
        "panels": panels,
    }


def render_simple_dashboard(title, tag=None, tags=None, panels=None, **_):
    assert tag or tags
    return {
        "id": None,
        "uid": None,
        "annotations": {
            "list": [
                {
                    "builtIn": 1,
                    "datasource": "-- Grafana --",
                    "enable": True,
                    "hide": True,
                    "iconColor": "rgba(0, 211, 255, 1)",
                    "name": "Annotations & Alerts",
                    "type": "dashboard",
                }
            ]
        },
        "editable": False,
        "gnetId": None,
        "graphTooltip": 0,
        "schemaVersion": 27,
        "style": "dark",
        "tags": tags or [tag],
        "templating": {"list": []},
        "time": {"from": "now-24h", "to": "now"},
        "timepicker": {},
        "timezone": "",
        "title": title,
        "version": 1,
        "links": [],
        "panels": [
            create_infobox(),
            *(panels or []),
        ],
    }