Coverage for watcher/decision_engine/datasources/grafana_translator/base.py: 85%
33 statements
« prev ^ index » next coverage.py v7.8.2, created at 2025-06-17 12:22 +0000
« prev ^ index » next coverage.py v7.8.2, created at 2025-06-17 12:22 +0000
1# -*- encoding: utf-8 -*-
2# Copyright (c) 2019 European Organization for Nuclear Research (CERN)
3#
4# Authors: Corne Lukken <info@dantalion.nl>
5#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15# implied.
16# See the License for the specific language governing permissions and
17# limitations under the License.
19import abc
21from watcher._i18n import _
22from watcher.common import exception
23from watcher.decision_engine.datasources import base
26class BaseGrafanaTranslator(object):
27 """Grafana translator baseclass to use with grafana for different databases
29 Specific databasses that are proxied through grafana require some
30 alterations depending on the database.
31 """
33 """
34 data {
35 metric: name of the metric as found in DataSourceBase.METRIC_MAP,
36 db: database specified for this metric in grafana_client config
37 options,
38 attribute: the piece of information that will be selected from the
39 resource object to build the query.
40 query: the unformatted query from the configuration for this metric,
41 resource: the object from the OpenStackClient
42 resource_type: the type of the resource
43 ['compute_node','instance', 'bare_metal', 'storage'],
44 period: the period of time to collect metrics for in seconds,
45 aggregate: the aggregation can be any from ['mean', 'max', 'min',
46 'count'],
47 granularity: interval between datapoints in seconds (optional),
48 }
49 """
51 """Every grafana translator should have a uniquely identifying name"""
52 NAME = ''
54 RESOURCE_TYPES = base.DataSourceBase.RESOURCE_TYPES
56 AGGREGATES = base.DataSourceBase.AGGREGATES
58 def __init__(self, data):
59 self._data = data
60 self._validate_data()
62 def _validate_data(self):
63 """iterate through the supplied data and verify attributes"""
65 optionals = ['granularity']
67 reference_data = {
68 'metric': None,
69 'db': None,
70 'attribute': None,
71 'query': None,
72 'resource': None,
73 'resource_type': None,
74 'period': None,
75 'aggregate': None,
76 'granularity': None
77 }
78 reference_data.update(self._data)
80 for key, value in reference_data.items():
81 if value is None and key not in optionals:
82 raise exception.InvalidParameter(
83 message=(_("The value %(value)s for parameter "
84 "%(parameter)s is invalid") % {'value': None,
85 'parameter': key}
86 )
87 )
89 if reference_data['resource_type'] not in self.RESOURCE_TYPES: 89 ↛ 90line 89 didn't jump to line 90 because the condition on line 89 was never true
90 raise exception.InvalidParameter(parameter='resource_type',
91 parameter_type='RESOURCE_TYPES')
93 if reference_data['aggregate'] not in self.AGGREGATES: 93 ↛ 94line 93 didn't jump to line 94 because the condition on line 93 was never true
94 raise exception.InvalidParameter(parameter='aggregate',
95 parameter_type='AGGREGATES')
97 @staticmethod
98 def _extract_attribute(resource, attribute):
99 """Retrieve the desired attribute from the resource
101 :param resource: The resource object to extract the attribute from.
102 :param attribute: The name of the attribute to subtract as string.
103 :return: The extracted attribute or None
104 """
106 try:
107 return getattr(resource, attribute)
108 except AttributeError:
109 raise
111 @staticmethod
112 def _query_format(query, aggregate, resource, period,
113 granularity, translator_specific):
114 return query.format(aggregate, resource, period, granularity,
115 translator_specific)
117 @abc.abstractmethod
118 def build_params(self):
119 """Build the set of parameters to send with the request"""
120 raise NotImplementedError()
122 @abc.abstractmethod
123 def extract_result(self, raw_results):
124 """Extrapolate the metric from the raw results of the request"""
125 raise NotImplementedError()