From 2fadfd2928df34f5954e787a11dcb1d99401b0e2 Mon Sep 17 00:00:00 2001 From: Andreas Motl Date: Thu, 25 Apr 2024 04:22:10 +0200 Subject: [PATCH] Dashboard Builder: Add capability to use Grafonnet --- HISTORY.md | 4 ++- README.md | 60 +++++++++++++++++++++++++++++++++++++++--- docs/backlog.md | 9 ++++++- grafana_import/util.py | 5 ++++ 4 files changed, 72 insertions(+), 6 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 658c020..f6e118a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -9,7 +9,9 @@ * Fix exit codes in failure situations. * Fix exception handling and propagation in failure situations. * Add feature to support dashboard builders, in the spirit of - dashboard-as-code. + dashboard-as-code. Supports Grafonnet, grafana-dashboard, grafanalib, + and any other kind of executable program generating Grafana Dashboard + JSON. * Add watchdog feature, monitoring the input dashboard for changes on disk, and re-uploading it, when changed. diff --git a/README.md b/README.md index 6f3d832..5e31fee 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@ _Export and import Grafana dashboards using the [Grafana HTTP API] and - Export dashboards into JSON format. - Import dashboards into Grafana, both in native JSON format, or emitted by dashboard builders, supporting dashboard-as-code workflows. - - The import action preserves the version history of dashboards. - - Supported builders are [grafana-dashboard], [grafanalib], and - any other executable program which emits Grafana Dashboard JSON + - Supported builders are [Grafonnet], [grafana-dashboard], [grafanalib], + and any other executable program which emits Grafana Dashboard JSON on STDOUT. + - The import action preserves the version history of dashboards. - Watchdog: For a maximum of authoring and editing efficiency, the watchdog monitors the input dashboard for changes on disk, and re-uploads it to the Grafana API, when changed. @@ -22,7 +22,7 @@ _Export and import Grafana dashboards using the [Grafana HTTP API] and ## Installation ```shell -pip install --upgrade 'grafana-import[builder] git+https://github.com/grafana-toolbox/grafana-import.git' +pip install --upgrade 'grafana-import[builder] @ git+https://github.com/grafana-toolbox/grafana-import.git' ``` Currently, there is no up-to-date version on PyPI, so we recommend to @@ -169,6 +169,53 @@ using a configuration file, use the `GRAFANA_TOKEN` environment variable. [grafana-client authentication variants]: https://github.com/panodata/grafana-client/#authentication +## Builders + +grafana-import provides support for dashboard-as-code builders. + +To get inspired what you can do, by reading more examples, please also visit +[grafonnet examples], [grafana-dashboard examples], and [grafanalib examples]. + +### Grafonnet + +[Grafonnet] is a [Jsonnet] library for generating Grafana dashboards. + +The library is generated from JSON Schemas generated by Grok. In turn, +these schemas are generated directly from the Grafana repository, in +order to ensure Grafonnet is always synchronized with the development +of Grafana without much friction. + +#### Install +Install Jsonnet, and its jsonnet-bundler package manager. +```shell +brew install go-jsonnet jsonnet-bundler +``` +Install Grafonnet into a Jsonnet project. +```shell +git clone https://github.com/grafana-toolbox/grafana-snippets +cd grafana-snippets/dashboard/grafonnet-simple +jb install github.com/grafana/grafonnet/gen/grafonnet-latest@main +``` + +#### Usage +Render dashboard defined in [Grafonnet]/[Jsonnet]. +```shell +grafana-import import --overwrite -i /path/to/faro.jsonnet +``` + +### grafana-dashboard +Render dashboard defined using [grafana-dashboard]. +```shell +grafana-import import --overwrite -i /path/to/gd-dashboard.py +``` + +### grafanalib +Render dashboard defined using [grafanalib]. +```shell +grafana-import import --overwrite -i /path/to/gl-dashboard.py +``` + + ## Help `grafana-import --help` @@ -238,4 +285,9 @@ learn how to set up a [development sandbox]. [Grafana HTTP API]: https://grafana.com/docs/grafana/latest/http_api/ [grafana-client]: https://github.com/panodata/grafana-client [grafana-dashboard]: https://github.com/fzyzcjy/grafana_dashboard_python +[grafana-dashboard examples]: https://github.com/fzyzcjy/grafana_dashboard_python/tree/master/examples [grafanalib]: https://github.com/weaveworks/grafanalib +[grafanalib examples]: https://github.com/weaveworks/grafanalib/tree/main/grafanalib/tests/examples +[Grafonnet]: https://github.com/grafana/grafonnet +[grafonnet examples]: https://github.com/grafana/grafonnet/tree/main/examples +[Jsonnet]: https://github.com/google/go-jsonnet diff --git a/docs/backlog.md b/docs/backlog.md index 54915eb..59f136d 100644 --- a/docs/backlog.md +++ b/docs/backlog.md @@ -6,4 +6,11 @@ back to Python code. It should be used on the `export` subsystem, to provide an alternative output format. https://github.com/fzyzcjy/grafana_dashboard_python/tree/master/examples/json_to_python -- Provide support for the Grafana `cog` builder +- Builder: Support grafanalib + - https://community.panodata.org/t/grafanalib-is-a-python-library-for-building-grafana-dashboards/102 +- Builder: Support Grafonnet + - https://github.com/grafana/grafonnet/ + - https://community.panodata.org/t/grafonnet-a-jsonnet-library-for-generating-grafana-dashboards/158 +- Builder: Support Grafana `cog` + - https://github.com/grafana/cog +- Slogan: Import and export Grafana dashboards .... diff --git a/grafana_import/util.py b/grafana_import/util.py index 00ef7dd..3fe75fc 100644 --- a/grafana_import/util.py +++ b/grafana_import/util.py @@ -119,6 +119,11 @@ def read_dashboard_file(path: t.Union[str, Path]) -> t.Dict[str, t.Any]: except OSError as ex: raise IOError(f"Reading file failed: {path}. Reason: {ex.strerror}") from ex + elif path.suffix == ".jsonnet": + # jsonnet --jpath vendor faro.jsonnet + command = f"jsonnet --jpath {path.parent / 'vendor'} {path}" + payload = subprocess.check_output(shlex.split(command), encoding="utf-8") # noqa: S603 + elif path.suffix == ".py": command = f"{sys.executable} {path}" payload = subprocess.check_output(shlex.split(command), encoding="utf-8") # noqa: S603