Remove transformers from the codebase
Since data frames are now handled as objects, transformers are no longer required. This simplifies the global codebase. Story: 2005890 Task: 36075 Change-Id: I76d9117bd95d80e51ca95804c999f145e65c3a2d
This commit is contained in:
parent
c841ee8c29
commit
492ec063a7
|
@ -31,7 +31,6 @@ from voluptuous import Optional
|
||||||
from voluptuous import Required
|
from voluptuous import Required
|
||||||
from voluptuous import Schema
|
from voluptuous import Schema
|
||||||
|
|
||||||
from cloudkitty import transformer
|
|
||||||
from cloudkitty import utils as ck_utils
|
from cloudkitty import utils as ck_utils
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,15 +100,12 @@ METRIC_BASE_SCHEMA = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_collector(transformers=None):
|
def get_collector():
|
||||||
metrics_conf = ck_utils.load_conf(CONF.collect.metrics_conf)
|
metrics_conf = ck_utils.load_conf(CONF.collect.metrics_conf)
|
||||||
if not transformers:
|
|
||||||
transformers = transformer.get_transformers()
|
|
||||||
collector_args = {
|
collector_args = {
|
||||||
'period': CONF.collect.period,
|
'period': CONF.collect.period,
|
||||||
'transformers': transformers,
|
'conf': metrics_conf,
|
||||||
}
|
}
|
||||||
collector_args.update({'conf': metrics_conf})
|
|
||||||
return driver.DriverManager(
|
return driver.DriverManager(
|
||||||
COLLECTORS_NAMESPACE,
|
COLLECTORS_NAMESPACE,
|
||||||
CONF.collect.collector,
|
CONF.collect.collector,
|
||||||
|
@ -132,7 +128,6 @@ def get_metrics_based_collector_metadata():
|
||||||
Results are based on enabled collector and metrics in CONF.
|
Results are based on enabled collector and metrics in CONF.
|
||||||
"""
|
"""
|
||||||
metrics_conf = ck_utils.load_conf(CONF.collect.metrics_conf)
|
metrics_conf = ck_utils.load_conf(CONF.collect.metrics_conf)
|
||||||
transformers = transformer.get_transformers()
|
|
||||||
collector = get_collector_without_invoke()
|
collector = get_collector_without_invoke()
|
||||||
metadata = {}
|
metadata = {}
|
||||||
if 'metrics' in metrics_conf:
|
if 'metrics' in metrics_conf:
|
||||||
|
@ -140,23 +135,11 @@ def get_metrics_based_collector_metadata():
|
||||||
alt_name = metric.get('alt_name', metric_name)
|
alt_name = metric.get('alt_name', metric_name)
|
||||||
metadata[alt_name] = collector.get_metadata(
|
metadata[alt_name] = collector.get_metadata(
|
||||||
metric_name,
|
metric_name,
|
||||||
transformers,
|
|
||||||
metrics_conf,
|
metrics_conf,
|
||||||
)
|
)
|
||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
|
|
||||||
class TransformerDependencyError(Exception):
|
|
||||||
"""Raised when a collector can't find a mandatory transformer."""
|
|
||||||
|
|
||||||
def __init__(self, collector, transformer):
|
|
||||||
super(TransformerDependencyError, self).__init__(
|
|
||||||
"Transformer '%s' not found, but required by %s" % (transformer,
|
|
||||||
collector))
|
|
||||||
self.collector = collector
|
|
||||||
self.transformer = transformer
|
|
||||||
|
|
||||||
|
|
||||||
class NoDataCollected(Exception):
|
class NoDataCollected(Exception):
|
||||||
"""Raised when the collection returned no data.
|
"""Raised when the collection returned no data.
|
||||||
|
|
||||||
|
@ -173,11 +156,9 @@ class NoDataCollected(Exception):
|
||||||
@six.add_metaclass(abc.ABCMeta)
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
class BaseCollector(object):
|
class BaseCollector(object):
|
||||||
collector_name = None
|
collector_name = None
|
||||||
dependencies = ['CloudKittyFormatTransformer']
|
|
||||||
|
|
||||||
def __init__(self, transformers, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
try:
|
try:
|
||||||
self.transformers = transformers
|
|
||||||
self.period = kwargs['period']
|
self.period = kwargs['period']
|
||||||
self.conf = self.check_configuration(kwargs['conf'])
|
self.conf = self.check_configuration(kwargs['conf'])
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
|
@ -188,18 +169,6 @@ class BaseCollector(object):
|
||||||
LOG.error('Problem while checking configurations.', v)
|
LOG.error('Problem while checking configurations.', v)
|
||||||
raise v
|
raise v
|
||||||
|
|
||||||
self._check_transformers()
|
|
||||||
self.t_cloudkitty = self.transformers['CloudKittyFormatTransformer']
|
|
||||||
|
|
||||||
def _check_transformers(self):
|
|
||||||
"""Check for transformer prerequisites
|
|
||||||
|
|
||||||
"""
|
|
||||||
for dependency in self.dependencies:
|
|
||||||
if dependency not in self.transformers:
|
|
||||||
raise TransformerDependencyError(self.collector_name,
|
|
||||||
dependency)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_configuration(conf):
|
def check_configuration(conf):
|
||||||
"""Checks and validates metric configuration.
|
"""Checks and validates metric configuration.
|
||||||
|
@ -229,7 +198,7 @@ class BaseCollector(object):
|
||||||
return trans_resource
|
return trans_resource
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_metadata(cls, resource_name, transformers):
|
def get_metadata(cls, resource_name):
|
||||||
"""Return metadata about collected resource as a dict.
|
"""Return metadata about collected resource as a dict.
|
||||||
|
|
||||||
Dict object should contain:
|
Dict object should contain:
|
||||||
|
@ -247,8 +216,7 @@ class BaseCollector(object):
|
||||||
provided in the metric conf at initialization.
|
provided in the metric conf at initialization.
|
||||||
(Available in ``self.conf['groupby']`` and ``self.conf['metadata']``).
|
(Available in ``self.conf['groupby']`` and ``self.conf['metadata']``).
|
||||||
|
|
||||||
Returns a list of items formatted with
|
Returns a list of cloudkitty.dataframe.DataPoint objects.
|
||||||
``CloudKittyFormatTransformer.format_item``.
|
|
||||||
|
|
||||||
:param metric_name: Name of the metric to fetch
|
:param metric_name: Name of the metric to fetch
|
||||||
:type metric_name: str
|
:type metric_name: str
|
||||||
|
|
|
@ -29,6 +29,7 @@ from voluptuous import Required
|
||||||
from voluptuous import Schema
|
from voluptuous import Schema
|
||||||
|
|
||||||
from cloudkitty import collector
|
from cloudkitty import collector
|
||||||
|
from cloudkitty import dataframe
|
||||||
from cloudkitty import utils as ck_utils
|
from cloudkitty import utils as ck_utils
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,8 +117,8 @@ class GnocchiCollector(collector.BaseCollector):
|
||||||
|
|
||||||
collector_name = 'gnocchi'
|
collector_name = 'gnocchi'
|
||||||
|
|
||||||
def __init__(self, transformers, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(GnocchiCollector, self).__init__(transformers, **kwargs)
|
super(GnocchiCollector, self).__init__(**kwargs)
|
||||||
|
|
||||||
adapter_options = {'connect_retries': 3}
|
adapter_options = {'connect_retries': 3}
|
||||||
if CONF.collector_gnocchi.gnocchi_auth_type == 'keystone':
|
if CONF.collector_gnocchi.gnocchi_auth_type == 'keystone':
|
||||||
|
@ -164,9 +165,8 @@ class GnocchiCollector(collector.BaseCollector):
|
||||||
return output
|
return output
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_metadata(cls, resource_name, transformers, conf):
|
def get_metadata(cls, resource_name, conf):
|
||||||
info = super(GnocchiCollector, cls).get_metadata(resource_name,
|
info = super(GnocchiCollector, cls).get_metadata(resource_name)
|
||||||
transformers)
|
|
||||||
try:
|
try:
|
||||||
info["metadata"].extend(
|
info["metadata"].extend(
|
||||||
conf[resource_name]['groupby']
|
conf[resource_name]['groupby']
|
||||||
|
@ -392,11 +392,11 @@ class GnocchiCollector(collector.BaseCollector):
|
||||||
project_id, start, end, e),
|
project_id, start, end, e),
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
data = self.t_cloudkitty.format_item(
|
formated_resources.append(dataframe.DataPoint(
|
||||||
|
met['unit'],
|
||||||
|
qty,
|
||||||
|
0,
|
||||||
groupby,
|
groupby,
|
||||||
metadata,
|
metadata,
|
||||||
met['unit'],
|
))
|
||||||
qty=qty,
|
|
||||||
)
|
|
||||||
formated_resources.append(data)
|
|
||||||
return formated_resources
|
return formated_resources
|
||||||
|
|
|
@ -25,7 +25,7 @@ from voluptuous import Required
|
||||||
from voluptuous import Schema
|
from voluptuous import Schema
|
||||||
|
|
||||||
from cloudkitty import collector
|
from cloudkitty import collector
|
||||||
from cloudkitty import transformer
|
from cloudkitty import dataframe
|
||||||
from cloudkitty import utils as ck_utils
|
from cloudkitty import utils as ck_utils
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,8 +94,8 @@ class MonascaCollector(collector.BaseCollector):
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def __init__(self, transformers, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(MonascaCollector, self).__init__(transformers, **kwargs)
|
super(MonascaCollector, self).__init__(**kwargs)
|
||||||
|
|
||||||
self.auth = ks_loading.load_auth_from_conf_options(
|
self.auth = ks_loading.load_auth_from_conf_options(
|
||||||
CONF,
|
CONF,
|
||||||
|
@ -129,7 +129,7 @@ class MonascaCollector(collector.BaseCollector):
|
||||||
return endpoint.url
|
return endpoint.url
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _get_metadata(self, metric_name, transformers, conf):
|
def _get_metadata(self, metric_name, conf):
|
||||||
info = {}
|
info = {}
|
||||||
info['unit'] = conf['metrics'][metric_name]['unit']
|
info['unit'] = conf['metrics'][metric_name]['unit']
|
||||||
|
|
||||||
|
@ -141,12 +141,9 @@ class MonascaCollector(collector.BaseCollector):
|
||||||
# NOTE(lukapeschke) if anyone sees a better way to do this,
|
# NOTE(lukapeschke) if anyone sees a better way to do this,
|
||||||
# please make a patch
|
# please make a patch
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_metadata(cls, resource_type, transformers, conf):
|
def get_metadata(cls, resource_type, conf):
|
||||||
args = {
|
tmp = cls(period=conf['period'])
|
||||||
'transformers': transformer.get_transformers(),
|
return tmp._get_metadata(resource_type, conf)
|
||||||
'period': conf['period']}
|
|
||||||
tmp = cls(**args)
|
|
||||||
return tmp._get_metadata(resource_type, transformers, conf)
|
|
||||||
|
|
||||||
def _get_dimensions(self, metric_name, project_id, q_filter):
|
def _get_dimensions(self, metric_name, project_id, q_filter):
|
||||||
dimensions = {}
|
dimensions = {}
|
||||||
|
@ -267,11 +264,11 @@ class MonascaCollector(collector.BaseCollector):
|
||||||
if len(d['statistics']):
|
if len(d['statistics']):
|
||||||
metadata, groupby, qty = self._format_data(
|
metadata, groupby, qty = self._format_data(
|
||||||
met, d, resources_info)
|
met, d, resources_info)
|
||||||
data = self.t_cloudkitty.format_item(
|
formated_resources.append(dataframe.DataPoint(
|
||||||
|
met['unit'],
|
||||||
|
qty,
|
||||||
|
0,
|
||||||
groupby,
|
groupby,
|
||||||
metadata,
|
metadata,
|
||||||
met['unit'],
|
))
|
||||||
qty=qty,
|
|
||||||
)
|
|
||||||
formated_resources.append(data)
|
|
||||||
return formated_resources
|
return formated_resources
|
||||||
|
|
|
@ -26,6 +26,7 @@ from cloudkitty import collector
|
||||||
from cloudkitty.collector.exceptions import CollectError
|
from cloudkitty.collector.exceptions import CollectError
|
||||||
from cloudkitty.common.prometheus_client import PrometheusClient
|
from cloudkitty.common.prometheus_client import PrometheusClient
|
||||||
from cloudkitty.common.prometheus_client import PrometheusResponseError
|
from cloudkitty.common.prometheus_client import PrometheusResponseError
|
||||||
|
from cloudkitty import dataframe
|
||||||
from cloudkitty import utils as ck_utils
|
from cloudkitty import utils as ck_utils
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,8 +77,8 @@ PROMETHEUS_EXTRA_SCHEMA = {
|
||||||
class PrometheusCollector(collector.BaseCollector):
|
class PrometheusCollector(collector.BaseCollector):
|
||||||
collector_name = 'prometheus'
|
collector_name = 'prometheus'
|
||||||
|
|
||||||
def __init__(self, transformers, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(PrometheusCollector, self).__init__(transformers, **kwargs)
|
super(PrometheusCollector, self).__init__(**kwargs)
|
||||||
url = CONF.collector_prometheus.prometheus_url
|
url = CONF.collector_prometheus.prometheus_url
|
||||||
|
|
||||||
user = CONF.collector_prometheus.prometheus_user
|
user = CONF.collector_prometheus.prometheus_user
|
||||||
|
@ -176,13 +177,12 @@ class PrometheusCollector(collector.BaseCollector):
|
||||||
item,
|
item,
|
||||||
)
|
)
|
||||||
|
|
||||||
item = self.t_cloudkitty.format_item(
|
formatted_resources.append(dataframe.DataPoint(
|
||||||
|
self.conf[metric_name]['unit'],
|
||||||
|
qty,
|
||||||
|
0,
|
||||||
groupby,
|
groupby,
|
||||||
metadata,
|
metadata,
|
||||||
self.conf[metric_name]['unit'],
|
))
|
||||||
qty=qty,
|
|
||||||
)
|
|
||||||
|
|
||||||
formatted_resources.append(item)
|
|
||||||
|
|
||||||
return formatted_resources
|
return formatted_resources
|
||||||
|
|
|
@ -39,7 +39,6 @@ from cloudkitty import extension_manager
|
||||||
from cloudkitty import messaging
|
from cloudkitty import messaging
|
||||||
from cloudkitty import storage
|
from cloudkitty import storage
|
||||||
from cloudkitty import storage_state as state
|
from cloudkitty import storage_state as state
|
||||||
from cloudkitty import transformer
|
|
||||||
from cloudkitty import tzutils
|
from cloudkitty import tzutils
|
||||||
from cloudkitty import utils as ck_utils
|
from cloudkitty import utils as ck_utils
|
||||||
|
|
||||||
|
@ -334,8 +333,7 @@ class Orchestrator(cotyledon.Service):
|
||||||
invoke_on_load=True,
|
invoke_on_load=True,
|
||||||
).driver
|
).driver
|
||||||
|
|
||||||
transformers = transformer.get_transformers()
|
self.collector = collector.get_collector()
|
||||||
self.collector = collector.get_collector(transformers)
|
|
||||||
self.storage = storage.get_storage()
|
self.storage = storage.get_storage()
|
||||||
self._state = state.StateManager()
|
self._state = state.StateManager()
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
from cloudkitty.collector import gnocchi
|
from cloudkitty.collector import gnocchi
|
||||||
from cloudkitty import tests
|
from cloudkitty import tests
|
||||||
from cloudkitty.tests import samples
|
from cloudkitty.tests import samples
|
||||||
from cloudkitty import transformer
|
|
||||||
|
|
||||||
|
|
||||||
class GnocchiCollectorTest(tests.TestCase):
|
class GnocchiCollectorTest(tests.TestCase):
|
||||||
|
@ -29,7 +28,6 @@ class GnocchiCollectorTest(tests.TestCase):
|
||||||
'gnocchi_auth_type', 'basic', 'collector_gnocchi')
|
'gnocchi_auth_type', 'basic', 'collector_gnocchi')
|
||||||
|
|
||||||
self.collector = gnocchi.GnocchiCollector(
|
self.collector = gnocchi.GnocchiCollector(
|
||||||
transformer.get_transformers(),
|
|
||||||
period=3600,
|
period=3600,
|
||||||
conf=samples.DEFAULT_METRICS_CONF,
|
conf=samples.DEFAULT_METRICS_CONF,
|
||||||
)
|
)
|
||||||
|
|
|
@ -18,7 +18,6 @@ import mock
|
||||||
|
|
||||||
from cloudkitty.collector import monasca as mon_collector
|
from cloudkitty.collector import monasca as mon_collector
|
||||||
from cloudkitty import tests
|
from cloudkitty import tests
|
||||||
from cloudkitty import transformer
|
|
||||||
|
|
||||||
|
|
||||||
class MonascaCollectorTest(tests.TestCase):
|
class MonascaCollectorTest(tests.TestCase):
|
||||||
|
@ -50,7 +49,6 @@ class MonascaCollectorTest(tests.TestCase):
|
||||||
'MonascaCollector._get_monasca_endpoint',
|
'MonascaCollector._get_monasca_endpoint',
|
||||||
return_value='http://noop'):
|
return_value='http://noop'):
|
||||||
self.collector = mon_collector.MonascaCollector(
|
self.collector = mon_collector.MonascaCollector(
|
||||||
transformer.get_transformers(),
|
|
||||||
period=3600,
|
period=3600,
|
||||||
conf=conf,
|
conf=conf,
|
||||||
)
|
)
|
||||||
|
|
|
@ -24,7 +24,6 @@ from cloudkitty.common.prometheus_client import PrometheusResponseError
|
||||||
from cloudkitty import dataframe
|
from cloudkitty import dataframe
|
||||||
from cloudkitty import tests
|
from cloudkitty import tests
|
||||||
from cloudkitty.tests import samples
|
from cloudkitty.tests import samples
|
||||||
from cloudkitty import transformer
|
|
||||||
|
|
||||||
|
|
||||||
class PrometheusCollectorTest(tests.TestCase):
|
class PrometheusCollectorTest(tests.TestCase):
|
||||||
|
@ -53,8 +52,7 @@ class PrometheusCollectorTest(tests.TestCase):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
transformers = transformer.get_transformers()
|
self.collector = prometheus.PrometheusCollector(**args)
|
||||||
self.collector = prometheus.PrometheusCollector(transformers, **args)
|
|
||||||
|
|
||||||
def test_fetch_all_build_query(self):
|
def test_fetch_all_build_query(self):
|
||||||
query = (
|
query = (
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright 2016 Objectif Libre
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
from cloudkitty.tests import samples
|
|
||||||
from cloudkitty import transformer
|
|
||||||
|
|
||||||
|
|
||||||
class Transformer(transformer.BaseTransformer):
|
|
||||||
compute_map = {
|
|
||||||
'name': ['name', 'display_name'],
|
|
||||||
'flavor': ['flavor', 'flavor.name', 'instance_type'],
|
|
||||||
'vcpus': ['vcpus'],
|
|
||||||
'memory': ['memory', 'memory_mb'],
|
|
||||||
'image_id': ['image_id', 'image.id', 'image_meta.base_image_ref'],
|
|
||||||
'availability_zone': [
|
|
||||||
'availability_zone',
|
|
||||||
'OS-EXT-AZ.availability_zone'],
|
|
||||||
}
|
|
||||||
volume_map = {
|
|
||||||
'volume_id': ['volume_id'],
|
|
||||||
'name': ['display_name'],
|
|
||||||
'availability_zone': ['availability_zone'],
|
|
||||||
'size': ['size'],
|
|
||||||
}
|
|
||||||
test_map = {'test': lambda x, y: 'ok'}
|
|
||||||
|
|
||||||
def _strip_network(self, res_metadata):
|
|
||||||
return {'test': 'ok'}
|
|
||||||
|
|
||||||
|
|
||||||
class TransformerMeta(Transformer):
|
|
||||||
metadata_item = 'metadata'
|
|
||||||
|
|
||||||
|
|
||||||
class EmptyClass(object):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ClassWithAttr(object):
|
|
||||||
def __init__(self, items=samples.COMPUTE_METADATA):
|
|
||||||
for key, val in items.items():
|
|
||||||
setattr(self, key, val)
|
|
|
@ -1,68 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright 2016 Objectif Libre
|
|
||||||
#
|
|
||||||
# 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 copy
|
|
||||||
|
|
||||||
from cloudkitty import tests
|
|
||||||
from cloudkitty.tests import samples
|
|
||||||
from cloudkitty.tests import transformers as t_transformers
|
|
||||||
|
|
||||||
TRANS_METADATA = {
|
|
||||||
'availability_zone': 'nova',
|
|
||||||
'flavor': 'm1.nano',
|
|
||||||
'image_id': 'f5600101-8fa2-4864-899e-ebcb7ed6b568',
|
|
||||||
'memory': '64',
|
|
||||||
'name': 'prod1',
|
|
||||||
'vcpus': '1'}
|
|
||||||
|
|
||||||
|
|
||||||
class TransformerBaseTest(tests.TestCase):
|
|
||||||
def test_strip_resource_on_dict(self):
|
|
||||||
metadata = copy.deepcopy(samples.COMPUTE_METADATA)
|
|
||||||
t_test = t_transformers.Transformer()
|
|
||||||
result = t_test.strip_resource_data('compute', metadata)
|
|
||||||
self.assertEqual(TRANS_METADATA, result)
|
|
||||||
|
|
||||||
def test_strip_resource_with_no_rules(self):
|
|
||||||
metadata = copy.deepcopy(samples.COMPUTE_METADATA)
|
|
||||||
t_test = t_transformers.Transformer()
|
|
||||||
result = t_test.strip_resource_data('unknown', metadata)
|
|
||||||
self.assertEqual(samples.COMPUTE_METADATA, result)
|
|
||||||
|
|
||||||
def test_strip_resource_with_func(self):
|
|
||||||
metadata = {'test': 'dummy'}
|
|
||||||
t_test = t_transformers.Transformer()
|
|
||||||
result = t_test.strip_resource_data('test', metadata)
|
|
||||||
self.assertEqual({'test': 'ok'}, result)
|
|
||||||
|
|
||||||
def test_strip_resource_with_stripping_function(self):
|
|
||||||
metadata = {}
|
|
||||||
t_test = t_transformers.Transformer()
|
|
||||||
result = t_test.strip_resource_data('network', metadata)
|
|
||||||
self.assertEqual({'test': 'ok'}, result)
|
|
||||||
|
|
||||||
def test_strip_resource_with_subitem(self):
|
|
||||||
test_obj = t_transformers.EmptyClass()
|
|
||||||
test_obj.metadata = copy.deepcopy(samples.COMPUTE_METADATA)
|
|
||||||
t_test = t_transformers.TransformerMeta()
|
|
||||||
result = t_test.strip_resource_data('compute', test_obj)
|
|
||||||
self.assertEqual(TRANS_METADATA, result)
|
|
||||||
|
|
||||||
def test_strip_resource_with_attributes(self):
|
|
||||||
test_obj = t_transformers.EmptyClass()
|
|
||||||
test_obj.metadata = t_transformers.ClassWithAttr()
|
|
||||||
t_test = t_transformers.TransformerMeta()
|
|
||||||
result = t_test.strip_resource_data('compute', test_obj)
|
|
||||||
self.assertEqual(TRANS_METADATA, result)
|
|
|
@ -1,69 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright 2014 Objectif Libre
|
|
||||||
#
|
|
||||||
# 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
|
|
||||||
|
|
||||||
import six
|
|
||||||
from stevedore import extension
|
|
||||||
|
|
||||||
TRANSFORMERS_NAMESPACE = 'cloudkitty.transformers'
|
|
||||||
|
|
||||||
|
|
||||||
def get_transformers():
|
|
||||||
transformers = {}
|
|
||||||
transformer_exts = extension.ExtensionManager(
|
|
||||||
TRANSFORMERS_NAMESPACE,
|
|
||||||
invoke_on_load=True)
|
|
||||||
for transformer in transformer_exts:
|
|
||||||
t_name = transformer.name
|
|
||||||
t_obj = transformer.obj
|
|
||||||
transformers[t_name] = t_obj
|
|
||||||
return transformers
|
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(abc.ABCMeta)
|
|
||||||
class BaseTransformer(object):
|
|
||||||
metadata_item = ''
|
|
||||||
|
|
||||||
def generic_strip(self, datatype, data):
|
|
||||||
metadata = getattr(data, self.metadata_item, data)
|
|
||||||
mappings = getattr(self, datatype + '_map', {})
|
|
||||||
result = {}
|
|
||||||
for key, transform in mappings.items():
|
|
||||||
if isinstance(transform, list):
|
|
||||||
for meta_key in transform:
|
|
||||||
if key not in result or result[key] is None:
|
|
||||||
try:
|
|
||||||
data = getattr(metadata, meta_key)
|
|
||||||
except AttributeError:
|
|
||||||
data = metadata.get(meta_key)
|
|
||||||
result[key] = data
|
|
||||||
else:
|
|
||||||
trans_data = transform(self, metadata)
|
|
||||||
if trans_data:
|
|
||||||
result[key] = trans_data
|
|
||||||
return result
|
|
||||||
|
|
||||||
def strip_resource_data(self, res_type, res_data):
|
|
||||||
res_type = res_type.replace('.', '_')
|
|
||||||
strip_func = getattr(self, '_strip_' + res_type, None)
|
|
||||||
if strip_func:
|
|
||||||
return strip_func(res_data)
|
|
||||||
return self.generic_strip(res_type, res_data) or res_data
|
|
||||||
|
|
||||||
def get_metadata(self, res_type):
|
|
||||||
"""Return list of metadata available for given resource type."""
|
|
||||||
|
|
||||||
return []
|
|
|
@ -1,43 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright 2014 Objectif Libre
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
from oslo_log import log
|
|
||||||
|
|
||||||
from cloudkitty import dataframe
|
|
||||||
from cloudkitty import transformer
|
|
||||||
|
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class CloudKittyFormatTransformer(transformer.BaseTransformer):
|
|
||||||
def format_item(self, groupby, metadata, unit, qty=1.0):
|
|
||||||
# data = {}
|
|
||||||
# data['groupby'] = groupby
|
|
||||||
# data['metadata'] = metadata
|
|
||||||
# # For backward compatibility.
|
|
||||||
# data['desc'] = data['groupby'].copy()
|
|
||||||
# data['desc'].update(data['metadata'])
|
|
||||||
# data['vol'] = {'unit': unit, 'qty': qty}
|
|
||||||
|
|
||||||
return dataframe.DataPoint(unit, qty, 0, groupby, metadata)
|
|
||||||
# return data
|
|
||||||
|
|
||||||
def format_service(self, service, items):
|
|
||||||
data = {}
|
|
||||||
data[service] = items
|
|
||||||
|
|
||||||
return data
|
|
|
@ -61,8 +61,8 @@ following prototype:
|
||||||
.. autoclass:: cloudkitty.collector.BaseCollector
|
.. autoclass:: cloudkitty.collector.BaseCollector
|
||||||
:members: fetch_all
|
:members: fetch_all
|
||||||
|
|
||||||
This method is supposed to return a list of objects formatted by
|
This method is supposed to return a list of
|
||||||
``CloudKittyFormatTransformer``.
|
``cloudkitty.dataframe.DataPoint`` objects.
|
||||||
|
|
||||||
Example code of a basic collector:
|
Example code of a basic collector:
|
||||||
|
|
||||||
|
@ -79,11 +79,12 @@ Example code of a basic collector:
|
||||||
data = []
|
data = []
|
||||||
for CONDITION:
|
for CONDITION:
|
||||||
# do stuff
|
# do stuff
|
||||||
data.append(self.t_cloudkitty.format_item(
|
data.append(dataframe.DataPoint(
|
||||||
|
unit,
|
||||||
|
qty, # int, float, decimal.Decimal or str
|
||||||
|
0, # price
|
||||||
groupby, # dict
|
groupby, # dict
|
||||||
metadata, # dict
|
metadata, # dict
|
||||||
unit, # str
|
|
||||||
qty=qty, # int / float
|
|
||||||
))
|
))
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
other:
|
||||||
|
- |
|
||||||
|
Since data frames are now represented as objects internally, transformers
|
||||||
|
are not used anymore and have been completely removed from the codebase.
|
|
@ -57,9 +57,6 @@ cloudkitty.fetchers =
|
||||||
gnocchi = cloudkitty.fetcher.gnocchi:GnocchiFetcher
|
gnocchi = cloudkitty.fetcher.gnocchi:GnocchiFetcher
|
||||||
prometheus = cloudkitty.fetcher.prometheus:PrometheusFetcher
|
prometheus = cloudkitty.fetcher.prometheus:PrometheusFetcher
|
||||||
|
|
||||||
cloudkitty.transformers =
|
|
||||||
CloudKittyFormatTransformer = cloudkitty.transformer.format:CloudKittyFormatTransformer
|
|
||||||
|
|
||||||
cloudkitty.rating.processors =
|
cloudkitty.rating.processors =
|
||||||
noop = cloudkitty.rating.noop:Noop
|
noop = cloudkitty.rating.noop:Noop
|
||||||
hashmap = cloudkitty.rating.hash:HashMap
|
hashmap = cloudkitty.rating.hash:HashMap
|
||||||
|
|
Loading…
Reference in New Issue