cloudkitty/cloudkitty/collector/ceilometer.py

140 lines
5.1 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
File: ceilometer.py
Author: Stephane Albert
Email: stephane.albert@objectif-libre.com
Github: http://github.com/objectiflibre
Description: CloudKitty, Ceilometer Collector
"""
from datetime import datetime
from ceilometerclient import client as cclient
from cloudkitty.collector.base import BaseCollector
class CeilometerCollector(BaseCollector):
def __init__(self, **kwargs):
super(CeilometerCollector, self).__init__(**kwargs)
self._resource_cache = {}
def _connect(self):
"""
Initialize connection to the Ceilometer endpoint.
"""
self._conn = cclient.get_client('2', os_username=self.user,
os_password=self.password,
os_auth_url=self.keystone_url,
os_tenant_name=self.tenant,
os_region_name=self.region)
def gen_filter(self, op='eq', **kwargs):
"""
Generate ceilometer filter from kwargs.
"""
q_filter = []
for kwarg in kwargs:
q_filter.append({'field': kwarg, 'op': op, 'value': kwargs[kwarg]})
return q_filter
def prepend_filter(self, prepend, **kwargs):
"""
Prepend the dict key with the prepend value, useful to compose filters.
"""
q_filter = {}
for kwarg in kwargs:
q_filter[prepend + kwarg] = kwargs[kwarg]
return q_filter
def user_metadata_filter(self, op='eq', **kwargs):
"""
Create user_metadata filter from kwargs.
"""
user_filter = {}
for kwarg in kwargs:
field = kwarg
# Auto replace of . to _ to match ceilometer behaviour
if '.' in field:
field = field.replace('.', '_')
user_filter[field] = kwargs[kwarg]
user_filter = self.prepend_filter('user_metadata.', **user_filter)
return self.metadata_filter(op, **user_filter)
def metadata_filter(self, op='eq', **kwargs):
"""
Create metadata filter from kwargs.
"""
meta_filter = self.prepend_filter('metadata.', **kwargs)
return self.gen_filter(op, **meta_filter)
def get_active_instances(self, start, end=None, project_id=None,
q_filter=None):
"""
Return the number of instance that were active during the
timespan.
"""
start_iso = datetime.fromtimestamp(start).isoformat()
req_filter = self.gen_filter(op='ge', timestamp=start_iso)
if project_id:
req_filter.extend(self.gen_filter(project=project_id))
if end:
end_iso = datetime.fromtimestamp(end).isoformat()
req_filter.extend(self.gen_filter(op='le', timestamp=end_iso))
if isinstance(q_filter, list):
req_filter.extend(q_filter)
elif q_filter:
req_filter.append(q_filter)
instance_stats = self._conn.statistics.list(meter_name='instance',
period=0, q=req_filter,
groupby=['resource_id'])
return [instance.groupby['resource_id'] for instance in instance_stats]
def get_compute(self, start, end=None, project_id=None, q_filter=None):
active_instances = self.get_active_instances(start, end, project_id,
q_filter)
compute_data = []
volume_data = {'unit': 'instance', 'qty': 1}
for instance in active_instances:
instance_data = {}
instance_data['desc'] = self.get_resource_detail(instance)
instance_data['desc']['instance_id'] = instance
instance_data['vol'] = volume_data
compute_data.append(instance_data)
data = {}
data['compute'] = compute_data
return data
def _strip_compute(self, data):
res_data = {}
res_data['name'] = data.metadata.get('display_name')
res_data['flavor'] = data.metadata.get('flavor.name')
res_data['vcpus'] = data.metadata.get('vcpus')
res_data['memory'] = data.metadata.get('memory_mb')
res_data['image_id'] = data.metadata.get('image.id')
res_data['availability_zone'] = \
data.metadata.get('OS-EXT-AZ.availability_zone')
res_data['project_id'] = data.project_id
res_data['user_id'] = data.user_id
res_data['metadata'] = {}
for field in data.metadata:
if field.startswith('user_metadata'):
res_data['metadata'][field[14:]] = data.metadata[field]
return res_data
def strip_resource_data(self, res_data, res_type='compute'):
if res_type == 'compute':
return self._strip_compute(res_data)
def get_resource_detail(self, resource_id):
if resource_id not in self._resource_cache:
resource = self._conn.resources.get(resource_id)
resource = self.strip_resource_data(resource)
self._resource_cache[resource_id] = resource
return self._resource_cache[resource_id]