Merge "Caches Security Group Rule ACLs"

This commit is contained in:
Jenkins 2016-02-25 10:29:32 +00:00 committed by Gerrit Code Review
commit d39e537ae6
2 changed files with 61 additions and 2 deletions

View File

@ -503,6 +503,8 @@ class NetworkUtilsTestCase(base.BaseTestCase):
mock.sentinel.FAKE_WEIGHT)
mock_add_features = self.netutils._jobutils.add_multiple_virt_features
mock_add_features.assert_called_once_with([m_acl], m_port)
self.assertEqual([m_acl, fake_rule],
self.netutils._sg_acl_sds[m_port.ElementName])
@mock.patch.object(networkutils.NetworkUtils, '_get_new_weights')
@mock.patch.object(networkutils.NetworkUtils, '_filter_security_acls')
@ -517,9 +519,32 @@ class NetworkUtilsTestCase(base.BaseTestCase):
self.netutils._bind_security_rules(m_port, [fake_rule])
mock_filtered_acls.assert_called_once_with(fake_rule, [m_acl])
mock_get_weights.assert_called_once_with([fake_rule], [m_acl])
self.assertEqual([m_acl],
self.netutils._sg_acl_sds[m_port.ElementName])
def test_get_port_security_acls_cached(self):
mock_port = mock.MagicMock(ElementName=mock.sentinel.port_name)
self.netutils._sg_acl_sds = {
mock.sentinel.port_name: [mock.sentinel.fake_acl]}
acls = self.netutils._get_port_security_acls(mock_port)
self.assertEqual([mock.sentinel.fake_acl], acls)
def test_get_port_security_acls(self):
mock_port = mock.MagicMock()
mock_port.associators.return_value = [mock.sentinel.fake_acl]
acls = self.netutils._get_port_security_acls(mock_port)
self.assertEqual([mock.sentinel.fake_acl], acls)
self.assertEqual({mock_port.ElementName: [mock.sentinel.fake_acl]},
self.netutils._sg_acl_sds)
@mock.patch.object(networkutils.NetworkUtils, '_filter_security_acls')
def test_remove_security_rules(self, mock_filter):
mock_port, mock_acl = self._setup_security_rule_test()
mock_port.associators.return_value.append(mock.sentinel.fake_acl)
mock_acl = self._setup_security_rule_test()[1]
fake_rule = mock.MagicMock()
mock_filter.return_value = [mock_acl]
@ -531,6 +556,10 @@ class NetworkUtilsTestCase(base.BaseTestCase):
mock_remove_features.assert_called_once_with([mock_acl])
def test_remove_all_security_rules(self):
mock_port, mock_acl = self._setup_security_rule_test()
self.netutils._sg_acl_sds[mock_port.ElementName] = [
mock.sentinel.fake_acl]
mock_acl = self._setup_security_rule_test()[1]
self.netutils.remove_all_security_rules(self._FAKE_PORT_NAME)
mock_remove_features = (

View File

@ -85,6 +85,7 @@ class NetworkUtils(object):
self._switch_ports = {}
self._vlan_sds = {}
self._vsid_sds = {}
self._sg_acl_sds = {}
if sys.platform == 'win32':
self._conn = wmi.WMI(moniker='//./root/virtualization/v2')
@ -460,6 +461,10 @@ class NetworkUtils(object):
if remove_acls:
self._jobutils.remove_multiple_virt_features(remove_acls)
# remove the old ACLs from the cache.
new_acls = [a for a in acls if a not in remove_acls]
self._sg_acl_sds[port.ElementName] = new_acls
def remove_all_security_rules(self, switch_port_name):
port, found = self._get_switch_port_allocation(switch_port_name, False)
if not found:
@ -473,11 +478,15 @@ class NetworkUtils(object):
if filtered_acls:
self._jobutils.remove_multiple_virt_features(filtered_acls)
# clear the cache.
self._sg_acl_sds[port.ElementName] = []
def _bind_security_rules(self, port, sg_rules):
acls = port.associators(wmi_result_class=self._PORT_EXT_ACL_SET_DATA)
acls = self._get_port_security_acls(port)
# Add the ACL only if it don't already exist.
add_acls = []
processed_sg_rules = []
weights = self._get_new_weights(sg_rules, acls)
index = 0
@ -493,7 +502,7 @@ class NetworkUtils(object):
# append sg_rule the acls list, to make sure that the same rule
# is not processed twice.
acls.append(sg_rule)
processed_sg_rules.append(sg_rule)
# yielding to other threads that must run (like state reporting)
greenthread.sleep()
@ -501,6 +510,26 @@ class NetworkUtils(object):
if add_acls:
self._jobutils.add_multiple_virt_features(add_acls, port)
# caching the Security Group Rules that have been processed and
# added to the port. The list should only be used to check the
# existence of rules, nothing else.
acls.extend(processed_sg_rules)
def _get_port_security_acls(self, port):
"""Returns a mutable list of Security Group Rule objects.
Returns the list of Security Group Rule objects from the cache,
otherwise it fetches and caches from the port's associators.
"""
if port.ElementName in self._sg_acl_sds:
return self._sg_acl_sds[port.ElementName]
acls = port.associators(wmi_result_class=self._PORT_EXT_ACL_SET_DATA)
self._sg_acl_sds[port.ElementName] = acls
return acls
def _create_acl(self, direction, acl_type, action):
acl = self._create_default_setting_data(self._PORT_ALLOC_ACL_SET_DATA)
acl.set(Direction=direction,
@ -548,6 +577,7 @@ class NetworkUtilsR2(NetworkUtils):
acl = super(NetworkUtilsR2, self)._create_security_acl(sg_rule,
weight)
acl.Weight = weight
sg_rule.Weight = weight
return acl
def _get_new_weights(self, sg_rules, existent_acls):