]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Fix metering agent failure when chain missing
authorFei Long Wang <flwang@catalyst.net.nz>
Mon, 16 Feb 2015 11:58:45 +0000 (00:58 +1300)
committerFei Long Wang <flwang@catalyst.net.nz>
Wed, 18 Mar 2015 21:03:47 +0000 (10:03 +1300)
The metering agent will fail if one of the iptables chains
is missing, which will cause errors extracting data from
all the other chains. Add a simple try/except to let the
loop continue.

Closes-Bug: #1421037

Change-Id: I370ee0e2cc58ca7e1c5ef9bf4dbcce5abf7545a1

neutron/services/metering/drivers/iptables/iptables_driver.py
neutron/tests/unit/services/metering/drivers/test_iptables_driver.py

index 8bdec808c73d14b110043455ebf46988a2d0eabc..0e828f096f89f54567c1372a6e373cf8dc374967 100644 (file)
@@ -23,7 +23,7 @@ from neutron.agent.linux import iptables_manager
 from neutron.common import constants as constants
 from neutron.common import ipv6_utils
 from neutron.common import log
-from neutron.i18n import _LI
+from neutron.i18n import _LE, _LI
 from neutron.services.metering.drivers import abstract_driver
 
 
@@ -266,11 +266,18 @@ class IptablesMeteringDriver(abstract_driver.MeteringAbstractDriver):
                 continue
 
             for label_id, label in rm.metering_labels.items():
-                chain = iptables_manager.get_chain_name(WRAP_NAME + LABEL +
-                                                        label_id, wrap=False)
+                try:
+                    chain = iptables_manager.get_chain_name(WRAP_NAME +
+                                                            LABEL +
+                                                            label_id,
+                                                            wrap=False)
 
-                chain_acc = rm.iptables_manager.get_traffic_counters(
-                    chain, wrap=False, zero=True)
+                    chain_acc = rm.iptables_manager.get_traffic_counters(
+                        chain, wrap=False, zero=True)
+                except RuntimeError:
+                    LOG.exception(_LE('Failed to get traffic counters, '
+                                      'router: %s'), router)
+                    continue
 
                 if not chain_acc:
                     continue
index 292a7983963ce3b587a8fef1d831e772a560f542..45dd320272128119258507fafb87ec8a685f4ace 100644 (file)
@@ -360,3 +360,19 @@ class IptablesDriverTestCase(base.BaseTestCase):
                                         wrap=False)]
 
         self.v4filter_inst.assert_has_calls(calls)
+
+    def test_get_traffic_counters_with_missing_chain(self):
+        for r in TEST_ROUTERS:
+            rm = iptables_driver.RouterWithMetering(self.metering.conf, r)
+            rm.metering_labels = {r['_metering_labels'][0]['id']: 'fake'}
+            self.metering.routers[r['id']] = rm
+
+        mocked_method = self.iptables_cls.return_value.get_traffic_counters
+        mocked_method.side_effect = [{'pkts': 1, 'bytes': 8},
+                                     RuntimeError('Failed to find the chain')]
+
+        counters = self.metering.get_traffic_counters(None, TEST_ROUTERS)
+        expected_label_id = TEST_ROUTERS[0]['_metering_labels'][0]['id']
+        self.assertIn(expected_label_id, counters)
+        self.assertEqual(1, counters[expected_label_id]['pkts'])
+        self.assertEqual(8, counters[expected_label_id]['bytes'])