Skip to content

Commit

Permalink
Main improved dashboard links (#622)
Browse files Browse the repository at this point in the history
* Add missing options, functionality to DashboardLink

Includes the ability to create direct links or a list of dashboard links,
extra options like includeVars and targetBlank.

* Add docstring to DashboardLink, remove the unused `dashboard` param

Removing this parameter is a breaking change... It didn't actually
impact the generated link, other than acting as an alias to 'title'
in some cases. If preferred, I can restore it to retain that alias
behaviour, and perhaps add a warning log message?

* Update changelog

* Fix the DashboardLink type param in docstrings

* Fix the field name for URL in DashboardLinks

* Correct type annotations for py37, py38

* Fix flake8 warnigns in docstring for DashboardLink

* Add tests for DashboardLink

* Fix flake8 complaints in tests/test_core.py
  • Loading branch information
padraic-padraic authored Sep 29, 2023
1 parent f5da3c7 commit 6f36ce6
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 12 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ Changelog
0.x.x (?)
==================

* Extended DashboardLink to support links to dashboards and urls, as per the docs_

.. _`docs`: https://grafana.com/docs/grafana/latest/dashboards/build-dashboards/manage-dashboard-links/#dashboard-links

* Added ...
* Added Minimum option for Timeseries
* Added Maximum option for Timeseries
Expand Down
69 changes: 57 additions & 12 deletions grafanalib/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
encourage it by way of some defaults. Rather, they are ways of building
arbitrary Grafana JSON.
"""

from __future__ import annotations
import itertools
import math

import string
import warnings
from numbers import Number
from typing import Literal

import attr
from attr.validators import in_, instance_of
Expand Down Expand Up @@ -74,7 +75,7 @@ def to_json_data(self):
FLOT = 'flot'

ABSOLUTE_TYPE = 'absolute'
DASHBOARD_TYPE = 'dashboard'
DASHBOARD_TYPE = Literal['dashboards', 'link']
ROW_TYPE = 'row'
GRAPH_TYPE = 'graph'
DISCRETE_TYPE = 'natel-discrete-panel'
Expand Down Expand Up @@ -300,6 +301,9 @@ def to_json_data(self):
DEFAULT_AUTO_COUNT = 30
DEFAULT_MIN_AUTO_INTERVAL = '10s'

DASHBOARD_LINK_ICON = Literal['bolt', 'cloud', 'dashboard', 'doc',
'external link', 'info', 'question']


@attr.s
class Mapping(object):
Expand Down Expand Up @@ -875,24 +879,65 @@ def to_json_data(self):

@attr.s
class DashboardLink(object):
dashboard = attr.ib()
uri = attr.ib()
keepTime = attr.ib(
"""Create a link to other dashboards, or external resources.
Dashboard Links come in two flavours; a list of dashboards, or a direct
link to an arbitrary URL. These are controlled by the ``type`` parameter.
A dashboard list targets a given set of tags, whereas for a link you must
also provide the URL.
See `the documentation <https://grafana.com/docs/grafana/latest/dashboards/build-dashboards/manage-dashboard-links/#dashboard-links>`
for more information.
:param asDropdown: Controls if the list appears in a dropdown rather than
tiling across the dashboard. Affects 'dashboards' type only. Defaults
to False
:param icon: Set the icon, from a predefined list. See
``grafanalib.core.DASHBOARD_LINK_ICON`` for allowed values. Affects
the 'link' type only. Defaults to 'external link'
:param includeVars: Controls if data variables from the current dashboard
are passed as query parameters to the linked target. Defaults to False
:param keepTime: Controls if the current time range is passed as query
parameters to the linked target. Defaults to False
:param tags: A list of tags used to select dashboards for the link.
Affects the 'dashboards' type only. Defaults to an empty list
:param targetBlank: Controls if the link opens in a new tab. Defaults
to False
:param tooltip: Tooltip text that appears when hovering over the link.
Affects the 'link' type only. Defaults to an empty string
:param type: Controls the type of DashboardLink generated. Must be
one of 'dashboards' or 'link'.
:param uri: The url target of the external link. Affects the 'link'
type only.
"""
asDropdown: bool = attr.ib(default=False, validator=instance_of(bool))
icon: DASHBOARD_LINK_ICON = attr.ib(default='external link',
validator=in_(DASHBOARD_LINK_ICON.__args__))
includeVars: bool = attr.ib(default=False, validator=instance_of(bool))
keepTime: bool = attr.ib(
default=True,
validator=instance_of(bool),
)
title = attr.ib(default=None)
type = attr.ib(default=DASHBOARD_TYPE)
tags: list[str] = attr.ib(factory=list, validator=instance_of(list))
targetBlank: bool = attr.ib(default=False, validator=instance_of(bool))
title: str = attr.ib(default="")
tooltip: str = attr.ib(default="", validator=instance_of(str))
type: DASHBOARD_TYPE = attr.ib(default='dashboards',
validator=in_(DASHBOARD_TYPE.__args__))
uri: str = attr.ib(default="", validator=instance_of(str))

def to_json_data(self):
title = self.dashboard if self.title is None else self.title
return {
'dashUri': self.uri,
'dashboard': self.dashboard,
'asDropdown': self.asDropdown,
'icon': self.icon,
'includeVars': self.includeVars,
'keepTime': self.keepTime,
'title': title,
'tags': self.tags,
'targetBlank': self.targetBlank,
'title': self.title,
'tooltip': self.tooltip,
'type': self.type,
'url': self.uri,
'url': self.uri
}


Expand Down
34 changes: 34 additions & 0 deletions grafanalib/tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1190,3 +1190,37 @@ def test_sql_target_with_source_files():
assert t.to_json_data()["targets"][0].rawQuery is True
assert t.to_json_data()["targets"][0].rawSql == "SELECT example\nFROM test\nWHERE example='example' AND example_date BETWEEN '1970-01-01' AND '1971-01-01';\n"
print(t.to_json_data()["targets"][0])


class TestDashboardLink():

def test_validators(self):
with pytest.raises(ValueError):
G.DashboardLink(
type='dashboard',
)
with pytest.raises(ValueError):
G.DashboardLink(
icon='not an icon'
)

def test_initialisation(self):
dl = G.DashboardLink().to_json_data()
assert dl['asDropdown'] is False
assert dl['icon'] == 'external link'
assert dl['includeVars'] is False
assert dl['keepTime'] is True
assert not dl['tags']
assert dl['targetBlank'] is False
assert dl['title'] == ""
assert dl['tooltip'] == ""
assert dl['type'] == 'dashboards'
assert dl['url'] == ""

url = 'https://grafana.com'
dl = G.DashboardLink(
uri=url,
type='link'
).to_json_data()
assert dl['url'] == url
assert dl['type'] == 'link'

0 comments on commit 6f36ce6

Please sign in to comment.