ec2: Remove unused functions from 'ec2utils'
Remove a large number of util functions from the aforementioned modules. These were identified by searching for matches to functions bottom up, removing those with new matches, then repeating until no matches were found. Most of what's left is used by the metadata API and could be moved there in the future. An exception that is no longer used is removed. There are some unused objects also, but these will be removed in a follow-up as their removal is significantly more involved. Change-Id: I852648a975745d0327378ffc30f1469a7ce82ca7 Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
This commit is contained in:
parent
de31466fdb
commit
5660202ed6
|
@ -15,22 +15,15 @@
|
|||
# under the License.
|
||||
|
||||
import functools
|
||||
import re
|
||||
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import timeutils
|
||||
from oslo_utils import uuidutils
|
||||
import six
|
||||
|
||||
from nova import cache_utils
|
||||
from nova import context
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
from nova.network import model as network_model
|
||||
from nova import objects
|
||||
from nova.objects import base as obj_base
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
# NOTE(vish): cache mapping for one week
|
||||
_CACHE_TIME = 7 * 24 * 60 * 60
|
||||
_CACHE = None
|
||||
|
@ -52,11 +45,6 @@ def memoize(func):
|
|||
return memoizer
|
||||
|
||||
|
||||
def reset_cache():
|
||||
global _CACHE
|
||||
_CACHE = None
|
||||
|
||||
|
||||
def image_type(image_type):
|
||||
"""Converts to a three letter image type.
|
||||
|
||||
|
@ -74,37 +62,6 @@ def image_type(image_type):
|
|||
return image_type
|
||||
|
||||
|
||||
def resource_type_from_id(context, resource_id):
|
||||
"""Get resource type by ID
|
||||
|
||||
Returns a string representation of the Amazon resource type, if known.
|
||||
Returns None on failure.
|
||||
|
||||
:param context: context under which the method is called
|
||||
:param resource_id: resource_id to evaluate
|
||||
"""
|
||||
|
||||
known_types = {
|
||||
'i': 'instance',
|
||||
'r': 'reservation',
|
||||
'vol': 'volume',
|
||||
'snap': 'snapshot',
|
||||
'ami': 'image',
|
||||
'aki': 'image',
|
||||
'ari': 'image'
|
||||
}
|
||||
|
||||
type_marker = resource_id.split('-')[0]
|
||||
|
||||
return known_types.get(type_marker)
|
||||
|
||||
|
||||
@memoize
|
||||
def id_to_glance_id(context, image_id):
|
||||
"""Convert an internal (db) id to a glance id."""
|
||||
return objects.S3ImageMapping.get_by_id(context, image_id).uuid
|
||||
|
||||
|
||||
@memoize
|
||||
def glance_id_to_id(context, glance_id):
|
||||
"""Convert a glance id to an internal (db) id."""
|
||||
|
@ -118,11 +75,6 @@ def glance_id_to_id(context, glance_id):
|
|||
return s3imap.id
|
||||
|
||||
|
||||
def ec2_id_to_glance_id(context, ec2_id):
|
||||
image_id = ec2_id_to_id(ec2_id)
|
||||
return id_to_glance_id(context, image_id)
|
||||
|
||||
|
||||
def glance_id_to_ec2_id(context, glance_id, image_type='ami'):
|
||||
image_id = glance_id_to_id(context, glance_id)
|
||||
if image_id is None:
|
||||
|
@ -130,14 +82,6 @@ def glance_id_to_ec2_id(context, glance_id, image_type='ami'):
|
|||
return image_ec2_id(image_id, image_type=image_type)
|
||||
|
||||
|
||||
def ec2_id_to_id(ec2_id):
|
||||
"""Convert an ec2 ID (i-[base 16 number]) to an instance id (int)."""
|
||||
try:
|
||||
return int(ec2_id.split('-')[-1], 16)
|
||||
except ValueError:
|
||||
raise exception.InvalidEc2Id(ec2_id=ec2_id)
|
||||
|
||||
|
||||
def image_ec2_id(image_id, image_type='ami'):
|
||||
"""Returns image ec2_id using id and three letter type."""
|
||||
template = image_type + '-%08x'
|
||||
|
@ -159,21 +103,6 @@ def get_ip_info_for_instance_from_nw_info(nw_info):
|
|||
return ip_info
|
||||
|
||||
|
||||
def get_ip_info_for_instance(context, instance):
|
||||
"""Return a dictionary of IP information for an instance."""
|
||||
|
||||
if isinstance(instance, obj_base.NovaObject):
|
||||
nw_info = instance.info_cache.network_info
|
||||
else:
|
||||
# FIXME(comstud): Temporary as we transition to objects.
|
||||
info_cache = instance.info_cache or {}
|
||||
nw_info = info_cache.get('network_info')
|
||||
# Make sure empty response is turned into the model
|
||||
if not nw_info:
|
||||
nw_info = []
|
||||
return get_ip_info_for_instance_from_nw_info(nw_info)
|
||||
|
||||
|
||||
def id_to_ec2_id(instance_id, template='i-%08x'):
|
||||
"""Convert an instance ID (int) to an ec2 ID (i-[base 16 number])."""
|
||||
return template % int(instance_id)
|
||||
|
@ -191,107 +120,6 @@ def id_to_ec2_inst_id(instance_id):
|
|||
return id_to_ec2_id(instance_id)
|
||||
|
||||
|
||||
def ec2_inst_id_to_uuid(context, ec2_id):
|
||||
""""Convert an instance id to uuid."""
|
||||
int_id = ec2_id_to_id(ec2_id)
|
||||
return get_instance_uuid_from_int_id(context, int_id)
|
||||
|
||||
|
||||
@memoize
|
||||
def get_instance_uuid_from_int_id(context, int_id):
|
||||
imap = objects.EC2InstanceMapping.get_by_id(context, int_id)
|
||||
return imap.uuid
|
||||
|
||||
|
||||
def id_to_ec2_snap_id(snapshot_id):
|
||||
"""Get or create an ec2 volume ID (vol-[base 16 number]) from uuid."""
|
||||
if uuidutils.is_uuid_like(snapshot_id):
|
||||
ctxt = context.get_admin_context()
|
||||
int_id = get_int_id_from_snapshot_uuid(ctxt, snapshot_id)
|
||||
return id_to_ec2_id(int_id, 'snap-%08x')
|
||||
else:
|
||||
return id_to_ec2_id(snapshot_id, 'snap-%08x')
|
||||
|
||||
|
||||
def id_to_ec2_vol_id(volume_id):
|
||||
"""Get or create an ec2 volume ID (vol-[base 16 number]) from uuid."""
|
||||
if uuidutils.is_uuid_like(volume_id):
|
||||
ctxt = context.get_admin_context()
|
||||
int_id = get_int_id_from_volume_uuid(ctxt, volume_id)
|
||||
return id_to_ec2_id(int_id, 'vol-%08x')
|
||||
else:
|
||||
return id_to_ec2_id(volume_id, 'vol-%08x')
|
||||
|
||||
|
||||
def ec2_vol_id_to_uuid(ec2_id):
|
||||
"""Get the corresponding UUID for the given ec2-id."""
|
||||
ctxt = context.get_admin_context()
|
||||
|
||||
# NOTE(jgriffith) first strip prefix to get just the numeric
|
||||
int_id = ec2_id_to_id(ec2_id)
|
||||
return get_volume_uuid_from_int_id(ctxt, int_id)
|
||||
|
||||
|
||||
_ms_time_regex = re.compile(r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3,6}Z$')
|
||||
|
||||
|
||||
def status_to_ec2_attach_status(volume):
|
||||
"""Get the corresponding EC2 attachment state.
|
||||
|
||||
According to EC2 API, the valid attachment status in response is:
|
||||
attaching | attached | detaching | detached
|
||||
"""
|
||||
volume_status = volume.get('status')
|
||||
attach_status = volume.get('attach_status')
|
||||
if volume_status in ('attaching', 'detaching'):
|
||||
ec2_attach_status = volume_status
|
||||
elif attach_status in ('attached', 'detached'):
|
||||
ec2_attach_status = attach_status
|
||||
else:
|
||||
msg = _("Unacceptable attach status:%s for ec2 API.") % attach_status
|
||||
raise exception.Invalid(msg)
|
||||
return ec2_attach_status
|
||||
|
||||
|
||||
def is_ec2_timestamp_expired(request, expires=None):
|
||||
"""Checks the timestamp or expiry time included in an EC2 request
|
||||
and returns true if the request is expired
|
||||
"""
|
||||
timestamp = request.get('Timestamp')
|
||||
expiry_time = request.get('Expires')
|
||||
|
||||
def parse_strtime(strtime):
|
||||
if _ms_time_regex.match(strtime):
|
||||
# NOTE(MotoKen): time format for aws-sdk-java contains millisecond
|
||||
time_format = "%Y-%m-%dT%H:%M:%S.%fZ"
|
||||
else:
|
||||
time_format = "%Y-%m-%dT%H:%M:%SZ"
|
||||
return timeutils.parse_strtime(strtime, time_format)
|
||||
|
||||
try:
|
||||
if timestamp and expiry_time:
|
||||
msg = _("Request must include either Timestamp or Expires,"
|
||||
" but cannot contain both")
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidRequest(msg)
|
||||
elif expiry_time:
|
||||
query_time = parse_strtime(expiry_time)
|
||||
return timeutils.is_older_than(query_time, -1)
|
||||
elif timestamp:
|
||||
query_time = parse_strtime(timestamp)
|
||||
|
||||
# Check if the difference between the timestamp in the request
|
||||
# and the time on our servers is larger than 5 minutes, the
|
||||
# request is too old (or too new).
|
||||
if query_time and expires:
|
||||
return timeutils.is_older_than(query_time, expires) or \
|
||||
timeutils.is_newer_than(query_time, expires)
|
||||
return False
|
||||
except ValueError:
|
||||
LOG.info("Timestamp is invalid.")
|
||||
return True
|
||||
|
||||
|
||||
@memoize
|
||||
def get_int_id_from_instance_uuid(context, instance_uuid):
|
||||
if instance_uuid is None:
|
||||
|
@ -304,162 +132,3 @@ def get_int_id_from_instance_uuid(context, instance_uuid):
|
|||
imap.uuid = instance_uuid
|
||||
imap.create()
|
||||
return imap.id
|
||||
|
||||
|
||||
@memoize
|
||||
def get_int_id_from_volume_uuid(context, volume_uuid):
|
||||
if volume_uuid is None:
|
||||
return
|
||||
try:
|
||||
vmap = objects.EC2VolumeMapping.get_by_uuid(context, volume_uuid)
|
||||
return vmap.id
|
||||
except exception.NotFound:
|
||||
vmap = objects.EC2VolumeMapping(context)
|
||||
vmap.uuid = volume_uuid
|
||||
vmap.create()
|
||||
return vmap.id
|
||||
|
||||
|
||||
@memoize
|
||||
def get_volume_uuid_from_int_id(context, int_id):
|
||||
vmap = objects.EC2VolumeMapping.get_by_id(context, int_id)
|
||||
return vmap.uuid
|
||||
|
||||
|
||||
def ec2_snap_id_to_uuid(ec2_id):
|
||||
"""Get the corresponding UUID for the given ec2-id."""
|
||||
ctxt = context.get_admin_context()
|
||||
|
||||
# NOTE(jgriffith) first strip prefix to get just the numeric
|
||||
int_id = ec2_id_to_id(ec2_id)
|
||||
return get_snapshot_uuid_from_int_id(ctxt, int_id)
|
||||
|
||||
|
||||
@memoize
|
||||
def get_int_id_from_snapshot_uuid(context, snapshot_uuid):
|
||||
if snapshot_uuid is None:
|
||||
return
|
||||
try:
|
||||
smap = objects.EC2SnapshotMapping.get_by_uuid(context, snapshot_uuid)
|
||||
return smap.id
|
||||
except exception.NotFound:
|
||||
smap = objects.EC2SnapshotMapping(context, uuid=snapshot_uuid)
|
||||
smap.create()
|
||||
return smap.id
|
||||
|
||||
|
||||
@memoize
|
||||
def get_snapshot_uuid_from_int_id(context, int_id):
|
||||
smap = objects.EC2SnapshotMapping.get_by_id(context, int_id)
|
||||
return smap.uuid
|
||||
|
||||
|
||||
_c2u = re.compile('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))')
|
||||
|
||||
|
||||
def camelcase_to_underscore(str):
|
||||
return _c2u.sub(r'_\1', str).lower().strip('_')
|
||||
|
||||
|
||||
def _try_convert(value):
|
||||
"""Return a non-string from a string or unicode, if possible.
|
||||
|
||||
============= =====================================================
|
||||
When value is returns
|
||||
============= =====================================================
|
||||
zero-length ''
|
||||
'None' None
|
||||
'True' True case insensitive
|
||||
'False' False case insensitive
|
||||
'0', '-0' 0
|
||||
0xN, -0xN int from hex (positive) (N is any number)
|
||||
0bN, -0bN int from binary (positive) (N is any number)
|
||||
* try conversion to int, float, complex, fallback value
|
||||
|
||||
"""
|
||||
def _negative_zero(value):
|
||||
epsilon = 1e-7
|
||||
return 0 if abs(value) < epsilon else value
|
||||
|
||||
if len(value) == 0:
|
||||
return ''
|
||||
if value == 'None':
|
||||
return None
|
||||
lowered_value = value.lower()
|
||||
if lowered_value == 'true':
|
||||
return True
|
||||
if lowered_value == 'false':
|
||||
return False
|
||||
for prefix, base in [('0x', 16), ('0b', 2), ('0', 8), ('', 10)]:
|
||||
try:
|
||||
if lowered_value.startswith((prefix, "-" + prefix)):
|
||||
return int(lowered_value, base)
|
||||
except ValueError:
|
||||
pass
|
||||
try:
|
||||
return _negative_zero(float(value))
|
||||
except ValueError:
|
||||
return value
|
||||
|
||||
|
||||
def dict_from_dotted_str(items):
|
||||
"""parse multi dot-separated argument into dict.
|
||||
EBS boot uses multi dot-separated arguments like
|
||||
BlockDeviceMapping.1.DeviceName=snap-id
|
||||
Convert the above into
|
||||
{'block_device_mapping': {'1': {'device_name': snap-id}}}
|
||||
"""
|
||||
args = {}
|
||||
for key, value in items:
|
||||
parts = key.split(".")
|
||||
key = str(camelcase_to_underscore(parts[0]))
|
||||
if isinstance(value, six.string_types):
|
||||
# NOTE(vish): Automatically convert strings back
|
||||
# into their respective values
|
||||
value = _try_convert(value)
|
||||
|
||||
if len(parts) > 1:
|
||||
d = args.get(key, {})
|
||||
args[key] = d
|
||||
for k in parts[1:-1]:
|
||||
k = camelcase_to_underscore(k)
|
||||
v = d.get(k, {})
|
||||
d[k] = v
|
||||
d = v
|
||||
d[camelcase_to_underscore(parts[-1])] = value
|
||||
else:
|
||||
args[key] = value
|
||||
|
||||
return args
|
||||
|
||||
|
||||
def search_opts_from_filters(filters):
|
||||
return {f['name'].replace('-', '_'): f['value']['1']
|
||||
for f in filters if f['value']['1']} if filters else {}
|
||||
|
||||
|
||||
def regex_from_ec2_regex(ec2_re):
|
||||
"""Converts an EC2-style regex to a python regex.
|
||||
Approach is based on python fnmatch.
|
||||
"""
|
||||
|
||||
iter_ec2_re = iter(ec2_re)
|
||||
|
||||
py_re = ''
|
||||
for char in iter_ec2_re:
|
||||
if char == '*':
|
||||
py_re += '.*'
|
||||
elif char == '?':
|
||||
py_re += '.'
|
||||
elif char == '\\':
|
||||
try:
|
||||
next_char = next(iter_ec2_re)
|
||||
except StopIteration:
|
||||
next_char = ''
|
||||
if next_char == '*' or next_char == '?':
|
||||
py_re += '[%s]' % next_char
|
||||
else:
|
||||
py_re += '\\\\' + next_char
|
||||
else:
|
||||
py_re += re.escape(char)
|
||||
return r'(?s)\A%s\Z' % py_re
|
||||
|
|
|
@ -613,10 +613,6 @@ class InstanceUnacceptable(Invalid):
|
|||
msg_fmt = _("Instance %(instance_id)s is unacceptable: %(reason)s")
|
||||
|
||||
|
||||
class InvalidEc2Id(Invalid):
|
||||
msg_fmt = _("Ec2 id %(ec2_id)s is unacceptable.")
|
||||
|
||||
|
||||
class InvalidUUID(Invalid):
|
||||
msg_fmt = _("Expected a uuid but received %(uuid)s.")
|
||||
|
||||
|
|
Loading…
Reference in New Issue