166 lines
5.9 KiB
Python
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)
|