Refactor Panel class
A follow up patch will be adding better code coverage on Panels. Actually validating the values of our fields. To do that, we first need to split out the logic to be better consumed. Change-Id: I9e4ca5b90075b860788eed131eefd03c446a010b Signed-off-by: Paul Belanger <pabelanger@redhat.com>
This commit is contained in:
parent
984466022f
commit
7a84b4e064
@ -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
|
57
grafana_dashboards/schema/panel/__init__.py
Normal file
57
grafana_dashboards/schema/panel/__init__.py
Normal file
@ -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
|
32
grafana_dashboards/schema/panel/base.py
Normal file
32
grafana_dashboards/schema/panel/base.py
Normal file
@ -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)
|
30
grafana_dashboards/schema/panel/dashlist.py
Normal file
30
grafana_dashboards/schema/panel/dashlist.py
Normal file
@ -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)
|
38
grafana_dashboards/schema/panel/graph.py
Normal file
38
grafana_dashboards/schema/panel/graph.py
Normal file
@ -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)
|
68
grafana_dashboards/schema/panel/singlestat.py
Normal file
68
grafana_dashboards/schema/panel/singlestat.py
Normal file
@ -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)
|
30
grafana_dashboards/schema/panel/text.py
Normal file
30
grafana_dashboards/schema/panel/text.py
Normal file
@ -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)
|
Loading…
x
Reference in New Issue
Block a user