Pull out instance object handling for use by create also

The instance_create() function needs the same type handling
logic to tolerate object-initiated creates as does instance_update().
This pulls that logic out to a common function and makes both of
them use it.

Related to blueprint compute-api-objects

Change-Id: Ie8612ffb225b95bf7eab3c462441665095ed19bc
This commit is contained in:
Dan Smith 2013-07-26 16:09:07 -07:00
parent 5c5ddbcb40
commit 6d0c17e133
2 changed files with 59 additions and 15 deletions

View File

@ -1472,6 +1472,27 @@ def _validate_unique_server_name(context, session, name):
raise exception.InstanceExists(name=lowername)
def _handle_objects_related_type_conversions(values):
"""Make sure that certain things in values (which may have come from
an objects.instance.Instance object) are in suitable form for the
database.
"""
# NOTE(danms): Make sure IP addresses are passed as strings to
# the database engine
for key in ('access_ip_v4', 'access_ip_v6'):
if key in values and values[key] is not None:
values[key] = str(values[key])
# NOTE(danms): Strip UTC timezones from datetimes, since they're
# stored that way in the database
for key in ('created_at', 'deleted_at', 'updated_at',
'launched_at', 'terminated_at', 'scheduled_at'):
if key in values and values[key]:
if isinstance(values[key], basestring):
values[key] = timeutils.parse_strtime(values[key])
values[key] = values[key].replace(tzinfo=None)
@require_context
def instance_create(context, values):
"""Create a new Instance record in the database.
@ -1485,6 +1506,7 @@ def instance_create(context, values):
values['system_metadata'] = _metadata_refs(
values.get('system_metadata'), models.InstanceSystemMetadata)
_handle_objects_related_type_conversions(values)
instance_ref = models.Instance()
if not values.get('uuid'):
@ -2133,21 +2155,7 @@ def _instance_update(context, instance_uuid, values, copy_old_instance=False):
values.pop('system_metadata'),
session)
# NOTE(danms): Make sure IP addresses are passed as strings to
# the database engine
for key in ('access_ip_v4', 'access_ip_v6'):
if key in values and values[key] is not None:
values[key] = str(values[key])
# NOTE(danms): Strip UTC timezones from datetimes, since they're
# stored that way in the database
for key in ('created_at', 'deleted_at', 'updated_at',
'launched_at', 'terminated_at', 'scheduled_at'):
if key in values and values[key]:
if isinstance(values[key], basestring):
values[key] = timeutils.parse_strtime(values[key])
values[key] = values[key].replace(tzinfo=None)
_handle_objects_related_type_conversions(values)
instance_ref.update(values)
instance_ref.save(session=session)

View File

@ -21,6 +21,7 @@
import copy
import datetime
import iso8601
import types
import uuid as stdlib_uuid
@ -1272,6 +1273,41 @@ class InstanceTestCase(test.TestCase, ModelsObjectComparatorMixin):
instance = self.create_instance_with_args()
self.assertTrue(uuidutils.is_uuid_like(instance['uuid']))
def test_instance_create_with_object_values(self):
values = {
'access_ip_v4': netaddr.IPAddress('1.2.3.4'),
'access_ip_v6': netaddr.IPAddress('::1'),
}
dt_keys = ('created_at', 'deleted_at', 'updated_at',
'launched_at', 'terminated_at', 'scheduled_at')
dt = timeutils.utcnow()
dt_utc = dt.replace(tzinfo=iso8601.iso8601.Utc())
for key in dt_keys:
values[key] = dt_utc
inst = db.instance_create(self.ctxt, values)
self.assertEqual(inst['access_ip_v4'], '1.2.3.4')
self.assertEqual(inst['access_ip_v6'], '::1')
for key in dt_keys:
self.assertEqual(inst[key], dt)
def test_instance_update_with_object_values(self):
values = {
'access_ip_v4': netaddr.IPAddress('1.2.3.4'),
'access_ip_v6': netaddr.IPAddress('::1'),
}
dt_keys = ('created_at', 'deleted_at', 'updated_at',
'launched_at', 'terminated_at', 'scheduled_at')
dt = timeutils.utcnow()
dt_utc = dt.replace(tzinfo=iso8601.iso8601.Utc())
for key in dt_keys:
values[key] = dt_utc
inst = db.instance_create(self.ctxt, {})
inst = db.instance_update(self.ctxt, inst['uuid'], values)
self.assertEqual(inst['access_ip_v4'], '1.2.3.4')
self.assertEqual(inst['access_ip_v6'], '::1')
for key in dt_keys:
self.assertEqual(inst[key], dt)
def test_instance_get_all_with_meta(self):
inst = self.create_instance_with_args()
for inst in db.instance_get_all(self.ctxt):