Refresh network info cache for secgroups

Before updating security group rules, we need to make sure that
the info cache is up-to-date. Without this source groups are not
updated properly. This was a regression introduced in commit
85aac04704 which fixed a potential
DOS using source groups.

Fixes bug 1216720

Change-Id: I6b5115df53f2e159ea506ef966cd49cedd35f83d
This commit is contained in:
Vishvananda Ishaya 2013-09-04 12:41:26 -07:00
parent 8d900dacc6
commit 8679b2c8e7
3 changed files with 44 additions and 31 deletions

View File

@ -63,6 +63,8 @@ from nova.network import floating_ips
from nova.network import model as network_model
from nova.network import rpcapi as network_rpcapi
from nova.network.security_group import openstack_driver
from nova.objects import instance as instance_obj
from nova.objects import instance_info_cache as info_cache_obj
from nova.openstack.common import excutils
from nova.openstack.common.gettextutils import _
from nova.openstack.common import importutils
@ -369,14 +371,25 @@ class NetworkManager(manager.Manager):
# NOTE(francois.charlier): the instance may have been deleted already
# thus enabling `read_deleted`
admin_context = context.get_admin_context(read_deleted='yes')
if uuidutils.is_uuid_like(instance_id):
instance_ref = self.db.instance_get_by_uuid(admin_context,
instance_id)
else:
instance_ref = self.db.instance_get(admin_context, instance_id)
instance = instance_obj.Instance.get_by_uuid(admin_context,
instance_id)
groups = instance_ref['security_groups']
group_ids = [group['id'] for group in groups]
try:
# NOTE(vish): We need to make sure the instance info cache has been
# updated with new ip info before we trigger the
# security group refresh. This is somewhat ineffecient
# but avoids doing some dangerous refactoring for a
# bug fix.
nw_info = self.get_instance_nw_info(admin_context, instance_id,
None, None)
ic = info_cache_obj.InstanceInfoCache.new(admin_context,
instance_id)
ic.network_info = nw_info
ic.save(update_cells=False)
except exception.InstanceInfoCacheNotFound:
pass
groups = instance.security_groups
group_ids = [group.id for group in groups]
self.security_group_api.trigger_members_refresh(admin_context,
group_ids)
@ -834,13 +847,13 @@ class NetworkManager(manager.Manager):
else:
address = self.db.fixed_ip_associate_pool(
context.elevated(), network['id'], instance_id)
self._do_trigger_security_group_members_refresh_for_instance(
instance_id)
get_vif = self.db.virtual_interface_get_by_instance_and_network
vif = get_vif(context, instance_id, network['id'])
values = {'allocated': True,
'virtual_interface_id': vif['id']}
self.db.fixed_ip_update(context, address, values)
self._do_trigger_security_group_members_refresh_for_instance(
instance_id)
# NOTE(vish) This db query could be removed if we pass az and name
# (or the whole instance object).
@ -1709,8 +1722,6 @@ class VlanManager(RPCAllocateFixedIP, floating_ips.FloatingIP, NetworkManager):
address = self.db.fixed_ip_associate_pool(context,
network['id'],
instance_id)
self._do_trigger_security_group_members_refresh_for_instance(
instance_id)
vif = self.db.virtual_interface_get_by_instance_and_network(
context, instance_id, network['id'])
@ -1718,6 +1729,10 @@ class VlanManager(RPCAllocateFixedIP, floating_ips.FloatingIP, NetworkManager):
'virtual_interface_id': vif['id']}
self.db.fixed_ip_update(context, address, values)
if not kwargs.get('vpn', None):
self._do_trigger_security_group_members_refresh_for_instance(
instance_id)
# NOTE(vish) This db query could be removed if we pass az and name
# (or the whole instance object).
instance = self.db.instance_get_by_uuid(context, instance_id)

View File

@ -327,6 +327,9 @@ class FlatNetworkTestCase(test.TestCase):
self.network.validate_networks(self.context, requested_networks)
def test_add_fixed_ip_instance_using_id_without_vpn(self):
self.stubs.Set(self.network,
'_do_trigger_security_group_members_refresh_for_instance',
lambda *a, **kw: None)
self.mox.StubOutWithMock(db, 'network_get')
self.mox.StubOutWithMock(db, 'network_update')
self.mox.StubOutWithMock(db, 'fixed_ip_associate_pool')
@ -341,10 +344,6 @@ class FlatNetworkTestCase(test.TestCase):
mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn('192.168.0.101')
db.instance_get_by_uuid(mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn({'security_groups':
[{'id': 0, 'name': 'test'}]})
db.virtual_interface_get_by_instance_and_network(mox.IgnoreArg(),
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn({'id': 0})
@ -371,6 +370,9 @@ class FlatNetworkTestCase(test.TestCase):
networks[0]['id'])
def test_add_fixed_ip_instance_using_uuid_without_vpn(self):
self.stubs.Set(self.network,
'_do_trigger_security_group_members_refresh_for_instance',
lambda *a, **kw: None)
self.mox.StubOutWithMock(db, 'network_get_by_uuid')
self.mox.StubOutWithMock(db, 'network_update')
self.mox.StubOutWithMock(db, 'fixed_ip_associate_pool')
@ -385,10 +387,6 @@ class FlatNetworkTestCase(test.TestCase):
mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn('192.168.0.101')
db.instance_get_by_uuid(mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn({'security_groups':
[{'id': 0, 'name': 'test'}]})
db.virtual_interface_get_by_instance_and_network(mox.IgnoreArg(),
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn({'id': 0})
@ -458,6 +456,9 @@ class FlatNetworkTestCase(test.TestCase):
self.assertEqual(len(addresses), 0)
def test_instance_dns(self):
self.stubs.Set(self.network,
'_do_trigger_security_group_members_refresh_for_instance',
lambda *a, **kw: None)
fixedip = '192.168.0.101'
self.mox.StubOutWithMock(db, 'network_get_by_uuid')
self.mox.StubOutWithMock(db, 'network_update')
@ -473,10 +474,6 @@ class FlatNetworkTestCase(test.TestCase):
mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn(fixedip)
db.instance_get_by_uuid(mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn({'security_groups':
[{'id': 0, 'name': 'test'}]})
db.virtual_interface_get_by_instance_and_network(mox.IgnoreArg(),
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn({'id': 0})
@ -595,16 +592,15 @@ class VlanNetworkTestCase(test.TestCase):
vpn=True)
def test_allocate_fixed_ip(self):
self.stubs.Set(self.network,
'_do_trigger_security_group_members_refresh_for_instance',
lambda *a, **kw: None)
self.mox.StubOutWithMock(db, 'fixed_ip_associate_pool')
self.mox.StubOutWithMock(db, 'fixed_ip_update')
self.mox.StubOutWithMock(db,
'virtual_interface_get_by_instance_and_network')
self.mox.StubOutWithMock(db, 'instance_get_by_uuid')
db.instance_get_by_uuid(mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn({'security_groups':
[{'id': 0}]})
db.fixed_ip_associate_pool(mox.IgnoreArg(),
mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn('192.168.0.1')
@ -1102,6 +1098,9 @@ class VlanNetworkTestCase(test.TestCase):
mox.IgnoreArg())
def test_add_fixed_ip_instance_without_vpn_requested_networks(self):
self.stubs.Set(self.network,
'_do_trigger_security_group_members_refresh_for_instance',
lambda *a, **kw: None)
self.mox.StubOutWithMock(db, 'network_get')
self.mox.StubOutWithMock(db, 'fixed_ip_associate_pool')
self.mox.StubOutWithMock(db,
@ -1116,10 +1115,6 @@ class VlanNetworkTestCase(test.TestCase):
db.virtual_interface_get_by_instance_and_network(mox.IgnoreArg(),
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn({'id': 0})
db.instance_get_by_uuid(mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn({'security_groups': [{'id': 0}],
'availability_zone': '',
'uuid': FAKEUUID})
db.fixed_ip_associate_pool(mox.IgnoreArg(),
mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn('192.168.0.101')

View File

@ -401,6 +401,9 @@ class IptablesFirewallDriver(FirewallDriver):
else:
if rule['grantee_group']:
for instance in rule['grantee_group']['instances']:
if instance['info_cache']['deleted']:
LOG.debug('ignoring deleted cache')
continue
nw_info = compute_utils.get_nw_info_for_instance(
instance)