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:
Stephen Finucane 2019-05-31 15:43:46 +01:00
parent de31466fdb
commit 5660202ed6
2 changed files with 0 additions and 335 deletions

View File

@ -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

View File

@ -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.")