Fix FloatingIP.save() passing FixedIP object to sqlalchemy
This prevents the FloatingIP.save() method from passing the
calculated FixedIP object to the sqlalchemy floating_ip_update()
function, which would expect it to be an SA object. It also
aborts any attempt to save the object with a modified fixed_ip_id
linkage, as associate/disassociate should be used for that.
This also fixes a bug where FloatingIP expects the result of
floating_ip_update() to be a FloatingIp SA object.
Added missing import to allow tests to work in stable/icehouse.
Change-Id: I065caedf4d81c8583a3b390934a1d403cf2e87bd
Closes-bug: #1334164
(cherry picked from commit 48de2895b9
)
This commit is contained in:
parent
1408081296
commit
526853ea20
@ -1026,6 +1026,7 @@ def floating_ip_update(context, address, values):
|
||||
float_ip_ref.save(session=session)
|
||||
except db_exc.DBDuplicateEntry:
|
||||
raise exception.FloatingIpExists(address=values['address'])
|
||||
return float_ip_ref
|
||||
|
||||
|
||||
def _dnsdomain_get(context, session, fqdomain):
|
||||
|
@ -124,6 +124,14 @@ class FloatingIP(obj_base.NovaPersistentObject, obj_base.NovaObject):
|
||||
if 'address' in updates:
|
||||
raise exception.ObjectActionError(action='save',
|
||||
reason='address is not mutable')
|
||||
if 'fixed_ip_id' in updates:
|
||||
reason = 'fixed_ip_id is not mutable'
|
||||
raise exception.ObjectActionError(action='save', reason=reason)
|
||||
|
||||
# NOTE(danms): Make sure we don't pass the calculated fixed_ip
|
||||
# relationship to the DB update method
|
||||
updates.pop('fixed_ip', None)
|
||||
|
||||
db_floatingip = db.floating_ip_update(context, str(self.address),
|
||||
updates)
|
||||
self._from_db_object(context, self, db_floatingip)
|
||||
|
@ -4075,7 +4075,9 @@ class FloatingIpTestCase(test.TestCase, ModelsObjectComparatorMixin):
|
||||
'interface': 'some_interface',
|
||||
'pool': 'some_pool'
|
||||
}
|
||||
db.floating_ip_update(self.ctxt, float_ip['address'], values)
|
||||
floating_ref = db.floating_ip_update(self.ctxt, float_ip['address'],
|
||||
values)
|
||||
self.assertIsNot(floating_ref, None)
|
||||
updated_float_ip = db.floating_ip_get(self.ctxt, float_ip['id'])
|
||||
self._assertEqualObjects(updated_float_ip, values,
|
||||
ignored_keys=['id', 'address', 'updated_at',
|
||||
|
@ -16,6 +16,7 @@ import mock
|
||||
import netaddr
|
||||
|
||||
from nova import exception
|
||||
from nova.objects import fixed_ip
|
||||
from nova.objects import floating_ip
|
||||
from nova.tests.objects import test_fixed_ip
|
||||
from nova.tests.objects import test_network
|
||||
@ -129,13 +130,32 @@ class _TestFloatingIPObject(object):
|
||||
floatingip = floating_ip.FloatingIP(context=self.context,
|
||||
id=123, address='1.2.3.4',
|
||||
host='foo')
|
||||
self.assertRaises(exception.ObjectActionError, floatingip.save)
|
||||
floatingip.obj_reset_changes(['address', 'id'])
|
||||
floatingip.save()
|
||||
self.assertEqual(set(), floatingip.obj_what_changed())
|
||||
update.assert_called_with(self.context, '1.2.3.4',
|
||||
{'host': 'foo'})
|
||||
|
||||
def test_save_errors(self):
|
||||
floatingip = floating_ip.FloatingIP(context=self.context,
|
||||
id=123, host='foo')
|
||||
floatingip.obj_reset_changes()
|
||||
floating_ip.address = '1.2.3.4'
|
||||
self.assertRaises(exception.ObjectActionError, floatingip.save)
|
||||
|
||||
floatingip.obj_reset_changes()
|
||||
floatingip.fixed_ip_id = 1
|
||||
self.assertRaises(exception.ObjectActionError, floatingip.save)
|
||||
|
||||
@mock.patch('nova.db.floating_ip_update')
|
||||
def test_save_no_fixedip(self, update):
|
||||
update.return_value = fake_floating_ip
|
||||
floatingip = floating_ip.FloatingIP(context=self.context,
|
||||
id=123)
|
||||
floatingip.fixed_ip = fixed_ip.FixedIP(context=self.context,
|
||||
id=456)
|
||||
self.assertNotIn('fixed_ip', update.calls[1])
|
||||
|
||||
@mock.patch('nova.db.floating_ip_get_all')
|
||||
def test_get_all(self, get):
|
||||
get.return_value = [fake_floating_ip]
|
||||
|
Loading…
Reference in New Issue
Block a user