summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2014-09-19 00:29:52 +0000
committerGerrit Code Review <review@openstack.org>2014-09-19 00:29:52 +0000
commit6e7cfdf514f283aa8b3fc938c78eb3afea8d59e0 (patch)
treef898465357f38c37fabbe46e94f9a7b251d80104
parent0ecad55d846a5aae9196b6be2f417bff918956c0 (diff)
parentd469733e59872a897737db6ed5fd92d57986aee4 (diff)
downloadnova-6e7cfdf514f283aa8b3fc938c78eb3afea8d59e0.tar.gz
Merge "Avoid re-adding iptables rules for instances that have disappeared" into stable/havana
-rw-r--r--nova/network/linux_net.py6
-rw-r--r--nova/tests/virt/libvirt/test_libvirt.py24
-rw-r--r--nova/virt/firewall.py7
3 files changed, 37 insertions, 0 deletions
diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py
index 3c5fc61615..39eb838597 100644
--- a/nova/network/linux_net.py
+++ b/nova/network/linux_net.py
@@ -185,6 +185,12 @@ class IptablesTable(object):
self.remove_chains = set()
self.dirty = True
+ def has_chain(self, name, wrap=True):
+ if wrap:
+ return name in self.chains
+ else:
+ return name in self.unwrapped_chains
+
def add_chain(self, name, wrap=True):
"""Adds a named chain to the table.
diff --git a/nova/tests/virt/libvirt/test_libvirt.py b/nova/tests/virt/libvirt/test_libvirt.py
index 4725612377..bc19d98785 100644
--- a/nova/tests/virt/libvirt/test_libvirt.py
+++ b/nova/tests/virt/libvirt/test_libvirt.py
@@ -6188,6 +6188,8 @@ class IptablesFirewallTestCase(test.TestCase):
self.mox.StubOutWithMock(self.fw,
'add_filters_for_instance',
use_mock_anything=True)
+ self.mox.StubOutWithMock(self.fw.iptables.ipv4['filter'],
+ 'has_chain')
self.fw.instance_rules(instance_ref,
mox.IgnoreArg()).AndReturn((None, None))
@@ -6195,6 +6197,8 @@ class IptablesFirewallTestCase(test.TestCase):
mox.IgnoreArg())
self.fw.instance_rules(instance_ref,
mox.IgnoreArg()).AndReturn((None, None))
+ self.fw.iptables.ipv4['filter'].has_chain(mox.IgnoreArg()
+ ).AndReturn(True)
self.fw.add_filters_for_instance(instance_ref, mox.IgnoreArg(),
mox.IgnoreArg())
self.mox.ReplayAll()
@@ -6203,6 +6207,26 @@ class IptablesFirewallTestCase(test.TestCase):
self.fw.instances[instance_ref['id']] = instance_ref
self.fw.do_refresh_security_group_rules("fake")
+ def test_do_refresh_security_group_rules_instance_disappeared(self):
+ instance1 = {'id': 0, 'uuid': 'fake-uuid1'}
+ instance2 = {'id': 1, 'uuid': 'fake-uuid2'}
+ self.fw.instances = {0: instance1, 1: instance2}
+ self.fw.network_infos = _fake_network_info(self.stubs, 2)
+ mock_filter = mock.MagicMock()
+ with mock.patch.dict(self.fw.iptables.ipv4, {'filter': mock_filter}):
+ mock_filter.has_chain.return_value = False
+ with mock.patch.object(self.fw, 'instance_rules') as mock_ir:
+ mock_ir.return_value = (None, None)
+ self.fw.do_refresh_security_group_rules('secgroup')
+ self.assertEqual(2, mock_ir.call_count)
+ # NOTE(danms): Make sure that it is checking has_chain each time,
+ # continuing to process all the instances, and never adding the
+ # new chains back if has_chain() is False
+ mock_filter.has_chain.assert_has_calls([mock.call('inst-0'),
+ mock.call('inst-1')],
+ any_order=True)
+ self.assertEqual(0, mock_filter.add_chain.call_count)
+
def test_unfilter_instance_undefines_nwfilter(self):
admin_ctxt = context.get_admin_context()
diff --git a/nova/virt/firewall.py b/nova/virt/firewall.py
index 1c1cd0aab1..f4929c3d50 100644
--- a/nova/virt/firewall.py
+++ b/nova/virt/firewall.py
@@ -441,6 +441,13 @@ class IptablesFirewallDriver(FirewallDriver):
@utils.synchronized('iptables', external=True)
def _inner_do_refresh_rules(self, instance, ipv4_rules,
ipv6_rules):
+ chain_name = self._instance_chain_name(instance)
+ if not self.iptables.ipv4['filter'].has_chain(chain_name):
+ LOG.info(
+ _('instance chain %s disappeared during refresh, '
+ 'skipping') % chain_name,
+ instance=instance)
+ return
self.remove_filters_for_instance(instance)
self.add_filters_for_instance(instance, ipv4_rules, ipv6_rules)