distil/distil/helpers.py

166 lines
5.9 KiB
Python

# Copyright (C) 2014 Catalyst IT Ltd
#
# 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 novaclient import client as nova_client
from cinderclient.v2 import client as cinderclient
from glanceclient import client as glanceclient
from keystoneclient.v2_0 import client as keystoneclient
from decimal import Decimal
from distil import config
import math
import logging as log
cache = {}
def reset_cache():
global cache
log.info("flavors/volume_types cache reset")
cache = {'flavors': {}, 'volume_types': []}
def flavor_name(f_id):
"""Grabs the correct flavor name from Nova given the correct ID."""
if f_id not in cache['flavors']:
try:
_client_class = nova_client.get_client_class(2)
nova = _client_class(
config.auth['username'],
config.auth['password'],
config.auth['default_tenant'],
config.auth['end_point'],
region_name=config.main['region'],
insecure=config.auth['insecure'])
except:
nova = nova_client.Client('2',
username=config.auth['username'],
api_key=config.auth['password'],
password=config.auth['password'],
project_id=config.auth['default_tenant'],
auth_url=config.auth['end_point'],
region_name=config.main['region'],
insecure=config.auth['insecure'])
cache['flavors'][f_id] = nova.flavors.get(f_id).name
return cache['flavors'][f_id]
def volume_type(volume_type):
if not cache['volume_types']:
cinder = cinderclient.Client(
config.auth['username'],
config.auth['password'],
config.auth['default_tenant'],
config.auth['end_point'],
region=config.main['region'],
insecure=config.auth['insecure'])
for vtype in cinder.volume_types.list():
cache['volume_types'].append({'id': vtype.id,
'name': vtype.name})
for vtype in cache['volume_types']:
# check name first, as that will be more common
if vtype['name'] == volume_type:
return volume_type
elif vtype['id'] == volume_type:
return vtype['name']
return False
def get_image(image_id):
try:
keystone = keystoneclient.Client(username=config.auth['username'],
password=config.auth['password'],
tenant_name=config.auth['default_tenant'],
auth_url=config.auth['end_point'],
region_name=config.main['region'],
insecure=config.auth['insecure'])
client_kwargs = {
'token': keystone.auth_token,
'insecure': config.auth['insecure']
}
endpoint_kwargs = {
'service_type': 'image',
'endpoint_type': 'publicURL',
}
endpoint = keystone.service_catalog.url_for(**endpoint_kwargs)
glance = glanceclient.Client('2', endpoint, **client_kwargs)
return glance.images.get(image_id)
except Exception:
return
def get_volume(instance_id):
try:
try:
_client_class = nova_client.get_client_class(2)
nova = _client_class(
config.auth['username'],
config.auth['password'],
config.auth['default_tenant'],
config.auth['end_point'],
region_name=config.main['region'],
insecure=config.auth['insecure'])
except:
nova = nova_client.Client('2',
username=config.auth['username'],
api_key=config.auth['password'],
password=config.auth['password'],
project_id=config.auth['default_tenant'],
auth_url=config.auth['end_point'],
region_name=config.main['region'],
insecure=config.auth['insecure'])
instance = nova.servers.get(instance_id)
# Assume first volume is the root disk
volume_id = getattr(instance, 'os-extended-volumes:volumes_attached')[0]['id']
if not volume_id:
return None
cinder = cinderclient.Client(
config.auth['username'],
config.auth['password'],
config.auth['default_tenant'],
config.auth['end_point'],
region=config.main['region'],
insecure=config.auth['insecure'])
return cinder.volumes.get(volume_id)
except Exception:
return
def to_gigabytes_from_bytes(value):
"""From Bytes, unrounded."""
return ((value / Decimal(1024)) / Decimal(1024)) / Decimal(1024)
def to_hours_from_seconds(value):
"""From seconds to rounded hours"""
return Decimal(math.ceil((value / Decimal(60)) / Decimal(60)))
conversions = {'byte': {'gigabyte': to_gigabytes_from_bytes},
'second': {'hour': to_hours_from_seconds}}
def convert_to(value, from_unit, to_unit):
"""Converts a given value to the given unit.
Assumes that the value is in the lowest unit form,
of the given unit (seconds or bytes).
e.g. if the unit is gigabyte we assume the value is in bytes"""
if from_unit == to_unit:
return value
return conversions[from_unit][to_unit](value)