From 89e71ad53db30f672473ff934df1aa1c65ec37a0 Mon Sep 17 00:00:00 2001 From: akrzos Date: Thu, 8 Feb 2018 15:08:14 -0500 Subject: [PATCH] Add links to GrafYaml Allow dashboards with links to be created. Change-Id: Ie6e27808e465d98fd6694a60b31aa78b883e7ed3 --- grafana_dashboards/schema/dashboard.py | 4 ++ grafana_dashboards/schema/links.py | 77 +++++++++++++++++++++++ tests/schema/fixtures/dashboard-0026.json | 55 ++++++++++++++++ tests/schema/fixtures/dashboard-0026.yaml | 23 +++++++ 4 files changed, 159 insertions(+) create mode 100644 grafana_dashboards/schema/links.py create mode 100644 tests/schema/fixtures/dashboard-0026.json create mode 100644 tests/schema/fixtures/dashboard-0026.yaml diff --git a/grafana_dashboards/schema/dashboard.py b/grafana_dashboards/schema/dashboard.py index 2997056..ddffcda 100644 --- a/grafana_dashboards/schema/dashboard.py +++ b/grafana_dashboards/schema/dashboard.py @@ -14,6 +14,7 @@ import voluptuous as v +from grafana_dashboards.schema.links import Links from grafana_dashboards.schema.row import Row from grafana_dashboards.schema.template import Template @@ -21,6 +22,7 @@ from grafana_dashboards.schema.template import Template class Dashboard(object): def get_schema(self): + dashboard = { v.Required('timezone', default='utc'): v.Any('browser', 'utc'), v.Required('title'): v.All(str, v.Length(min=1)), @@ -31,6 +33,8 @@ class Dashboard(object): v.Required('to'): v.Any(v.Datetime(), str), }, } + links = Links().get_schema() + dashboard.update(links.schema) rows = Row().get_schema() dashboard.update(rows.schema) templating = Template().get_schema() diff --git a/grafana_dashboards/schema/links.py b/grafana_dashboards/schema/links.py new file mode 100644 index 0000000..74e7e57 --- /dev/null +++ b/grafana_dashboards/schema/links.py @@ -0,0 +1,77 @@ +# Copyright 2018 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import voluptuous as v + + +class Links(object): + icons = [ + 'bolt', + 'external link', + 'cloud', + 'dashboard', + 'doc', + 'info', + 'question', + ] + + link_base = { + v.Required('type'): v.Any('dashboards', 'link'), + v.Optional('asDropdown'): v.All(bool), + v.Optional('icon', default='external link'): v.Any(*icons), + v.Optional('includeVars', default=False): v.All(bool), + v.Optional('keepTime', default=False): v.All(bool), + v.Optional('tags'): v.All([str]), + v.Optional('targetBlank', default=False): v.All(bool), + v.Optional('title'): v.All(str), + } + + def _validate(self): + + def f(data): + res = [] + if not isinstance(data, list): + raise v.Invalid('Should be a list') + + for link in data: + validate = v.Schema(self.link_base, extra=True) + validate(link) + + if link['type'] == 'dashboards': + link_dashboards = { + v.Optional('asDropdown'): v.All(bool), + v.Optional('tags'): v.All([str]), + } + link_dashboards.update(self.link_base) + schema = v.Schema(link_dashboards) + elif link['type'] == 'link': + link_link = { + v.Optional('tooltip'): v.All(str), + v.Required('url'): v.All(str), + } + link_link.update(self.link_base) + schema = v.Schema(link_link) + + res.append(schema(link)) + + return res + + return f + + def get_schema(self): + schema = v.Schema({ + v.Optional('links'): v.All(self._validate()), + }) + + return schema diff --git a/tests/schema/fixtures/dashboard-0026.json b/tests/schema/fixtures/dashboard-0026.json new file mode 100644 index 0000000..0fceb8c --- /dev/null +++ b/tests/schema/fixtures/dashboard-0026.json @@ -0,0 +1,55 @@ +{ + "dashboard": { + "dashboard-with-links": { + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "test_tag" + ], + "targetBlank": true, + "title": "test_link_title", + "type": "dashboards" + }, + { + "icon": "cloud", + "includeVars": false, + "keepTime": false, + "targetBlank": false, + "title": "test_link_title", + "type": "link", + "url": "http://grafana.com" + } + ], + "rows": [ + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "content": "Some example text is required.", + "editable": true, + "error": false, + "mode": "markdown", + "span": 12, + "title": "no title (click here)", + "type": "text" + } + ], + "showTitle": false, + "title": "New row" + } + ], + "templating": { + "enabled": false, + "list": [] + }, + "timezone": "utc", + "title": "Dashboard with links" + } + } +} diff --git a/tests/schema/fixtures/dashboard-0026.yaml b/tests/schema/fixtures/dashboard-0026.yaml new file mode 100644 index 0000000..3ea2d8a --- /dev/null +++ b/tests/schema/fixtures/dashboard-0026.yaml @@ -0,0 +1,23 @@ +dashboard: + title: Dashboard with links + links: + - type: dashboards + title: test_link_title + asDropdown: true + tags: + - test_tag + includeVars: true + keepTime: true + targetBlank: true + - type: link + title: test_link_title + icon: cloud + url: http://grafana.com + rows: + - title: New row + height: 250px + panels: + - title: no title (click here) + type: text + mode: markdown + content: Some example text is required.