Files
watcher/watcher/decision_engine/datasources/grafana_translator/base.py
Dantali0n 433eabb8d1 Move datasources folder into decision_engine
The datasources are only used by the decision_engine, however, they
are placed in a directory one level higher. This patch moves the
datasources code into the decision_engine folder.

Change-Id: Ia54531fb899b79a59bb77adea079ff27c0d518fa
2019-07-12 08:54:09 +02:00

126 lines
4.4 KiB
Python

# -*- encoding: utf-8 -*-
# Copyright (c) 2019 European Organization for Nuclear Research (CERN)
#
# Authors: Corne Lukken <info@dantalion.nl>
#
# 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 abc
from watcher._i18n import _
from watcher.common import exception
from watcher.decision_engine.datasources import base
class BaseGrafanaTranslator(object):
"""Grafana translator baseclass to use with grafana for different databases
Specific databasses that are proxied through grafana require some
alterations depending on the database.
"""
"""
data {
metric: name of the metric as found in DataSourceBase.METRIC_MAP,
db: database specified for this metric in grafana_client config
options,
attribute: the piece of information that will be selected from the
resource object to build the query.
query: the unformatted query from the configuration for this metric,
resource: the object from the OpenStackClient
resource_type: the type of the resource
['compute_node','instance', 'bare_metal', 'storage'],
period: the period of time to collect metrics for in seconds,
aggregate: the aggregation can be any from ['mean', 'max', 'min',
'count'],
granularity: interval between datapoints in seconds (optional),
}
"""
"""Every grafana translator should have a uniquely identifying name"""
NAME = ''
RESOURCE_TYPES = base.DataSourceBase.RESOURCE_TYPES
AGGREGATES = base.DataSourceBase.AGGREGATES
def __init__(self, data):
self._data = data
self._validate_data()
def _validate_data(self):
"""iterate through the supplied data and verify attributes"""
optionals = ['granularity']
reference_data = {
'metric': None,
'db': None,
'attribute': None,
'query': None,
'resource': None,
'resource_type': None,
'period': None,
'aggregate': None,
'granularity': None
}
reference_data.update(self._data)
for key, value in reference_data.items():
if value is None and key not in optionals:
raise exception.InvalidParameter(
message=(_("The value %(value)s for parameter "
"%(parameter)s is invalid") % {'value': None,
'parameter': key}
)
)
if reference_data['resource_type'] not in self.RESOURCE_TYPES:
raise exception.InvalidParameter(parameter='resource_type',
parameter_type='RESOURCE_TYPES')
if reference_data['aggregate'] not in self.AGGREGATES:
raise exception.InvalidParameter(parameter='aggregate',
parameter_type='AGGREGATES')
@staticmethod
def _extract_attribute(resource, attribute):
"""Retrieve the desired attribute from the resource
:param resource: The resource object to extract the attribute from.
:param attribute: The name of the attribute to subtract as string.
:return: The extracted attribute or None
"""
try:
return getattr(resource, attribute)
except AttributeError:
raise
@staticmethod
def _query_format(query, aggregate, resource, period,
granularity, translator_specific):
return query.format(aggregate, resource, period, granularity,
translator_specific)
@abc.abstractmethod
def build_params(self):
"""Build the set of parameters to send with the request"""
raise NotImplementedError()
@abc.abstractmethod
def extract_result(self, raw_results):
"""Extrapolate the metric from the raw results of the request"""
raise NotImplementedError()