diff --git a/grafana_dashboards/schema/panel.py b/grafana_dashboards/schema/panel.py deleted file mode 100644 index c66c310..0000000 --- a/grafana_dashboards/schema/panel.py +++ /dev/null @@ -1,140 +0,0 @@ -# Copyright 2015 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 Panel(object): - - def __init__(self): - self.base = { - v.Required('editable', default=True): v.All(bool), - v.Required('error', default=False): v.All(bool), - v.Required('span', default=12): v.All(int, v.Range(min=0, max=12)), - v.Required('title'): v.All(str, v.Length(min=1)), - v.Required('type'): v.Any( - 'dashlist', 'graph', 'singlestat', 'text'), - v.Optional('id'): int, - } - - self.dashlist = { - v.Required('limit', default=10): v.All(int), - v.Required('mode', default='starred'): v.Any('search', 'starred'), - v.Required('tag', default=''): v.All(str), - v.Required('query', default=''): v.All(str), - } - self.dashlist.update(self.base) - - self.graph = { - v.Required('bars', default=False): v.All(bool), - v.Required('fill', default=1): v.All(int), - v.Required('lines', default=True): v.All(bool), - v.Required('linewidth', default=2): v.All(int), - v.Required('percentage', default=False): v.All(bool), - v.Required('pointradius', default=5): v.All(int), - v.Required('points', default=False): v.All(bool), - v.Required('stack', default=False): v.All(bool), - v.Required('steppedLine', default=False): v.All(bool), - v.Required('targets', default=[]): v.All(list), - v.Required('x-axis', default=True): v.All(bool), - v.Required('y-axis', default=True): v.All(bool), - } - self.graph.update(self.base) - - # TODO(pabelanger): This is pretty ugly, there much be a better way to - # set default values. - sparkline_defaults = { - 'fillColor': 'rgba(31, 118, 189, 0.18)', - 'full': False, - 'lineColor': 'rgb(31, 120, 193)', - 'show': False, - } - sparkline = { - v.Required( - 'fillColor', default=sparkline_defaults['fillColor'] - ): v.All(str), - v.Required('full', default=False): v.All(bool), - v.Required( - 'lineColor', default=sparkline_defaults['lineColor'] - ): v.All(str), - v.Required('show', default=False): v.All(bool), - } - - self.singlestat = { - v.Required('colorBackground', default=False): v.All(bool), - v.Required('colorValue', default=False): v.All(bool), - v.Required('maxDataPoints', default=100): v.All(int), - v.Required('postfix', default=''): v.All(str), - # Support 0% to 200% by 10 - v.Required( - 'postfixFontSize', default='50%'): v.All( - v.Match(r'^[1-9]?[0]{1}%$|^1[0-9]?[0]{1}%$|^200%$')), - v.Required('prefix', default=''): v.All(str), - # Support 0% to 200% by 10 - v.Required( - 'prefixFontSize', default='50%'): v.All( - v.Match(r'^[1-9]?[0]{1}%$|^1[0-9]?[0]{1}%$|^200%$')), - v.Required('sparkline', default=sparkline_defaults): sparkline, - v.Required('targets', default=[]): v.All(list), - v.Required('thresholds', default=''): v.All(str), - # Support 0% to 200% by 10 - v.Required( - 'valueFontSize', default='80%'): v.All( - v.Match(r'^[1-9]?[0]{1}%$|^1[0-9]?[0]{1}%$|^200%$')), - v.Required('valueName', default='avg'): v.All( - 'avg', 'current', 'max', 'min', 'total'), - v.Optional('decimals'): v.All(int, v.Range(min=0, max=12)), - } - self.singlestat.update(self.base) - - self.text = { - v.Required('content'): v.All(str), - v.Required('mode', default='markdown'): v.Any( - 'html', 'markdown', 'text'), - v.Optional('style'): dict(), - } - self.text.update(self.base) - - def _validate(self): - - def f(data): - res = [] - if not isinstance(data, list): - raise v.Invalid('Should be a list') - - for panel in data: - validate = v.Schema(self.base, extra=True) - validate(panel) - - if panel['type'] == 'dashlist': - schema = v.Schema(self.dashlist) - elif panel['type'] == 'graph': - schema = v.Schema(self.graph) - elif panel['type'] == 'singlestat': - schema = v.Schema(self.singlestat) - elif panel['type'] == 'text': - schema = v.Schema(self.text) - - res.append(schema(panel)) - - return res - - return f - - def get_schema(self): - schema = v.Schema({ - v.Required('panels', default=[]): v.All(self._validate()), - }) - - return schema diff --git a/grafana_dashboards/schema/panel/__init__.py b/grafana_dashboards/schema/panel/__init__.py new file mode 100644 index 0000000..ab103eb --- /dev/null +++ b/grafana_dashboards/schema/panel/__init__.py @@ -0,0 +1,57 @@ +# Copyright 2015 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 + +from grafana_dashboards.schema.panel.base import Base +from grafana_dashboards.schema.panel.dashlist import Dashlist +from grafana_dashboards.schema.panel.graph import Graph +from grafana_dashboards.schema.panel.singlestat import Singlestat +from grafana_dashboards.schema.panel.text import Text + + +class Panel(object): + + def _validate(self): + + def f(data): + res = [] + if not isinstance(data, list): + raise v.Invalid('Should be a list') + + for panel in data: + validate = Base().get_schema() + validate(panel) + + if panel['type'] == 'dashlist': + schema = Dashlist().get_schema() + elif panel['type'] == 'graph': + schema = Graph().get_schema() + elif panel['type'] == 'singlestat': + schema = Singlestat().get_schema() + elif panel['type'] == 'text': + schema = Text().get_schema() + + res.append(schema(panel)) + + return res + + return f + + def get_schema(self): + schema = v.Schema({ + v.Required('panels', default=[]): v.All(self._validate()), + }) + + return schema diff --git a/grafana_dashboards/schema/panel/base.py b/grafana_dashboards/schema/panel/base.py new file mode 100644 index 0000000..25c72e3 --- /dev/null +++ b/grafana_dashboards/schema/panel/base.py @@ -0,0 +1,32 @@ +# Copyright 2015 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 Base(object): + + def __init__(self): + self.base = { + v.Required('editable', default=True): v.All(bool), + v.Required('error', default=False): v.All(bool), + v.Required('span', default=12): v.All(int, v.Range(min=0, max=12)), + v.Required('title'): v.All(str, v.Length(min=1)), + v.Required('type'): v.Any( + 'dashlist', 'graph', 'singlestat', 'text'), + v.Optional('id'): int, + } + + def get_schema(self): + return v.Schema(self.base, extra=True) diff --git a/grafana_dashboards/schema/panel/dashlist.py b/grafana_dashboards/schema/panel/dashlist.py new file mode 100644 index 0000000..532946f --- /dev/null +++ b/grafana_dashboards/schema/panel/dashlist.py @@ -0,0 +1,30 @@ +# Copyright 2015 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 + +from grafana_dashboards.schema.panel.base import Base + + +class Dashlist(Base): + + def get_schema(self): + dashlist = { + v.Required('limit', default=10): v.All(int), + v.Required('mode', default='starred'): v.Any('search', 'starred'), + v.Required('tag', default=''): v.All(str), + v.Required('query', default=''): v.All(str), + } + dashlist.update(self.base) + return v.Schema(dashlist) diff --git a/grafana_dashboards/schema/panel/graph.py b/grafana_dashboards/schema/panel/graph.py new file mode 100644 index 0000000..20b1dab --- /dev/null +++ b/grafana_dashboards/schema/panel/graph.py @@ -0,0 +1,38 @@ +# Copyright 2015 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 + +from grafana_dashboards.schema.panel.base import Base + + +class Graph(Base): + + def get_schema(self): + graph = { + v.Required('bars', default=False): v.All(bool), + v.Required('fill', default=1): v.All(int), + v.Required('lines', default=True): v.All(bool), + v.Required('linewidth', default=2): v.All(int), + v.Required('percentage', default=False): v.All(bool), + v.Required('pointradius', default=5): v.All(int), + v.Required('points', default=False): v.All(bool), + v.Required('stack', default=False): v.All(bool), + v.Required('steppedLine', default=False): v.All(bool), + v.Required('targets', default=[]): v.All(list), + v.Required('x-axis', default=True): v.All(bool), + v.Required('y-axis', default=True): v.All(bool), + } + graph.update(self.base) + return v.Schema(graph) diff --git a/grafana_dashboards/schema/panel/singlestat.py b/grafana_dashboards/schema/panel/singlestat.py new file mode 100644 index 0000000..cd0e202 --- /dev/null +++ b/grafana_dashboards/schema/panel/singlestat.py @@ -0,0 +1,68 @@ +# Copyright 2015 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 + +from grafana_dashboards.schema.panel.base import Base + + +class Singlestat(Base): + + def get_schema(self): + # TODO(pabelanger): This is pretty ugly, there much be a better way to + # set default values. + sparkline_defaults = { + 'fillColor': 'rgba(31, 118, 189, 0.18)', + 'full': False, + 'lineColor': 'rgb(31, 120, 193)', + 'show': False, + } + sparkline = { + v.Required( + 'fillColor', default=sparkline_defaults['fillColor'] + ): v.All(str), + v.Required('full', default=False): v.All(bool), + v.Required( + 'lineColor', default=sparkline_defaults['lineColor'] + ): v.All(str), + v.Required('show', default=False): v.All(bool), + } + + singlestat = { + v.Required('colorBackground', default=False): v.All(bool), + v.Required('colorValue', default=False): v.All(bool), + v.Required('maxDataPoints', default=100): v.All(int), + v.Required('postfix', default=''): v.All(str), + # Support 0% to 200% by 10 + v.Required( + 'postfixFontSize', default='50%'): v.All( + v.Match(r'^[1-9]?[0]{1}%$|^1[0-9]?[0]{1}%$|^200%$')), + v.Required('prefix', default=''): v.All(str), + # Support 0% to 200% by 10 + v.Required( + 'prefixFontSize', default='50%'): v.All( + v.Match(r'^[1-9]?[0]{1}%$|^1[0-9]?[0]{1}%$|^200%$')), + v.Required('sparkline', default=sparkline_defaults): sparkline, + v.Required('targets', default=[]): v.All(list), + v.Required('thresholds', default=''): v.All(str), + # Support 0% to 200% by 10 + v.Required( + 'valueFontSize', default='80%'): v.All( + v.Match(r'^[1-9]?[0]{1}%$|^1[0-9]?[0]{1}%$|^200%$')), + v.Required('valueName', default='avg'): v.All( + 'avg', 'current', 'max', 'min', 'total'), + v.Optional('decimals'): v.All(int, v.Range(min=0, max=12)), + } + singlestat.update(self.base) + return v.Schema(singlestat) diff --git a/grafana_dashboards/schema/panel/text.py b/grafana_dashboards/schema/panel/text.py new file mode 100644 index 0000000..8eeb495 --- /dev/null +++ b/grafana_dashboards/schema/panel/text.py @@ -0,0 +1,30 @@ +# Copyright 2015 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 + +from grafana_dashboards.schema.panel.base import Base + + +class Text(Base): + + def get_schema(self): + text = { + v.Required('content'): v.All(str), + v.Required('mode', default='markdown'): v.Any( + 'html', 'markdown', 'text'), + v.Optional('style'): dict(), + } + text.update(self.base) + return v.Schema(text)