Introduce trusted ports to firewall driver API

Currently trusted ports (DHCP & router ports) are considered trusted
ports based on theirs owner. Trusted ports are not passed to the
firewall driver and hence the driver doesn't have any way how to deal
with such ports.

This change introduces two new methods to firewall driver API:
 - process_trusted_ports
 - remove_trusted_ports

These methods will give firewall driver a chance to process traffic
coming from the trusted ports in case its needed.

For specific case, see patch depending on this one.

Change-Id: I0be64483515e45f98ffffce8346a6bff06bc0fd1
Related-bug: #1626010
This commit is contained in:
Jakub Libosvar 2017-06-13 12:03:31 +00:00 committed by Jakub Libosvar
parent d559cd53e8
commit e9e8f5dccb
3 changed files with 59 additions and 10 deletions

View File

@ -162,6 +162,13 @@ class FirewallDriver(object):
"""
raise NotImplementedError()
def process_trusted_ports(self, port_ids):
"""Process ports that are trusted and shouldn't be filtered."""
pass
def remove_trusted_ports(self, port_ids):
pass
class NoopFirewallDriver(FirewallDriver):
"""Noop Firewall Driver.

View File

@ -128,6 +128,7 @@ class SecurityGroupAgentRpc(object):
else:
devices = self.plugin_rpc.security_group_rules_for_devices(
self.context, list(device_ids))
trusted_devices = list(set(device_ids) - set(devices.keys()))
with self.firewall.defer_apply():
if self.use_enhanced_rpc:
@ -142,6 +143,7 @@ class SecurityGroupAgentRpc(object):
else:
LOG.debug("Prepare port filter for %s", device['device'])
self.firewall.prepare_port_filter(device)
self.firewall.process_trusted_ports(trusted_devices)
def _update_security_group_info(self, security_groups,
security_group_member_ips):
@ -213,9 +215,10 @@ class SecurityGroupAgentRpc(object):
with self.firewall.defer_apply():
for device_id in device_ids:
device = self.firewall.ports.get(device_id)
if not device:
continue
self.firewall.remove_port_filter(device)
if device:
self.firewall.remove_port_filter(device)
else:
self.firewall.remove_trusted_ports([device_id])
@skip_if_noopfirewall_or_firewall_disabled
def refresh_firewall(self, device_ids=None):

View File

@ -871,6 +871,7 @@ class SecurityGroupAgentRpcTestCase(BaseSecurityGroupAgentRpcTestCase):
self.firewall.assert_has_calls([mock.call.defer_apply(),
mock.call.prepare_port_filter(
self.fake_device),
mock.call.process_trusted_ports([]),
mock.call.defer_apply(),
mock.call.remove_port_filter(
self.fake_device),
@ -896,6 +897,35 @@ class SecurityGroupAgentRpcTestCase(BaseSecurityGroupAgentRpcTestCase):
self.assertFalse(self.agent.plugin_rpc.
security_group_rules_for_devices.called)
def test_prepare_devices_filter_with_trusted_ports(self):
devices_to_filter = {k: {'device': k} for k in range(4, 8)}
all_devices = range(10)
expected_devices = [0, 1, 2, 3, 8, 9]
self.agent._use_enhanced_rpc = True
with mock.patch.object(
self.agent.plugin_rpc,
'security_group_info_for_devices',
return_value={
'devices': devices_to_filter,
'security_groups': {},
'sg_member_ips': {}}):
with mock.patch.object(
self.agent.firewall, 'process_trusted_ports') as m_process:
self.agent.prepare_devices_filter(all_devices)
m_process.assert_called_once_with(expected_devices)
def test_remove_devices_filter_with_trusted_ports(self):
all_devices = range(10)
firewall_managed_ports = {k: k for k in range(4, 8)}
trusted_port_ids = [0, 1, 2, 3, 8, 9]
with mock.patch.object(self.agent, 'firewall') as mock_firewall:
mock_firewall.ports = firewall_managed_ports
self.agent.remove_devices_filter(all_devices)
mock_firewall.remove_port_filter.assert_has_calls(
[mock.call(i) for i in firewall_managed_ports.keys()])
mock_firewall.remove_trusted_ports(
[mock.call([i]) for i in trusted_port_ids])
def test_security_groups_rule_updated(self):
self.agent.refresh_firewall = mock.Mock()
self.agent.prepare_devices_filter(['fake_port_id'])
@ -937,17 +967,21 @@ class SecurityGroupAgentRpcTestCase(BaseSecurityGroupAgentRpcTestCase):
self.agent.refresh_firewall()
calls = [mock.call.defer_apply(),
mock.call.prepare_port_filter(self.fake_device),
mock.call.process_trusted_ports(['fake_port_id']),
mock.call.defer_apply(),
mock.call.update_port_filter(self.fake_device)]
mock.call.update_port_filter(self.fake_device),
mock.call.process_trusted_ports([])]
self.firewall.assert_has_calls(calls)
def test_refresh_firewall_devices(self):
self.agent.prepare_devices_filter(['fake_port_id'])
self.agent.refresh_firewall([self.fake_device])
self.agent.refresh_firewall([self.fake_device['device']])
calls = [mock.call.defer_apply(),
mock.call.prepare_port_filter(self.fake_device),
mock.call.process_trusted_ports(['fake_port_id']),
mock.call.defer_apply(),
mock.call.update_port_filter(self.fake_device)]
mock.call.update_port_filter(self.fake_device),
mock.call.process_trusted_ports([])]
self.firewall.assert_has_calls(calls)
def test_refresh_firewall_none(self):
@ -959,7 +993,7 @@ class SecurityGroupAgentRpcTestCase(BaseSecurityGroupAgentRpcTestCase):
self.agent.plugin_rpc.security_group_info_for_devices = mock.Mock()
self.agent.plugin_rpc.security_group_rules_for_devices = mock.Mock()
self.agent.firewall.defer_apply = mock.Mock()
self.agent.refresh_firewall([self.fake_device])
self.agent.refresh_firewall([self.fake_device['device']])
self.assertFalse(self.agent.plugin_rpc.
security_group_info_for_devices.called)
self.assertFalse(self.agent.plugin_rpc.
@ -1010,6 +1044,7 @@ class SecurityGroupAgentEnhancedRpcTestCase(
tmp_mock2,
mock.call.prepare_port_filter(
self.fake_device),
mock.call.process_trusted_ports([]),
mock.call.defer_apply(),
mock.call.remove_port_filter(
self.fake_device),
@ -1066,19 +1101,21 @@ class SecurityGroupAgentEnhancedRpcTestCase(
mock.call.update_security_group_members(
'fake_sgid2', {'IPv4': [], 'IPv6': []}),
mock.call.prepare_port_filter(self.fake_device),
mock.call.process_trusted_ports(['fake_port_id']),
mock.call.defer_apply(),
mock.call.update_security_group_rules('fake_sgid2', []),
mock.call.update_security_group_rules(
'fake_sgid1', [{'remote_group_id': 'fake_sgid2'}]),
mock.call.update_security_group_members(
'fake_sgid2', {'IPv4': [], 'IPv6': []}),
mock.call.update_port_filter(self.fake_device)]
mock.call.update_port_filter(self.fake_device),
mock.call.process_trusted_ports([])]
self.firewall.assert_has_calls(calls)
def test_refresh_firewall_devices_enhanced_rpc(self):
self.agent.prepare_devices_filter(['fake_device'])
self.agent.refresh_firewall([self.fake_device])
self.agent.refresh_firewall([self.fake_device['device']])
calls = [mock.call.defer_apply(),
mock.call.update_security_group_rules('fake_sgid2', []),
mock.call.update_security_group_rules('fake_sgid1', [
@ -1087,13 +1124,15 @@ class SecurityGroupAgentEnhancedRpcTestCase(
'IPv4': [], 'IPv6': []
}),
mock.call.prepare_port_filter(self.fake_device),
mock.call.process_trusted_ports([]),
mock.call.defer_apply(),
mock.call.update_security_group_rules('fake_sgid2', []),
mock.call.update_security_group_rules('fake_sgid1', [
{'remote_group_id': 'fake_sgid2'}]),
mock.call.update_security_group_members('fake_sgid2', {
'IPv4': [], 'IPv6': []}),
mock.call.update_port_filter(self.fake_device)
mock.call.update_port_filter(self.fake_device),
mock.call.process_trusted_ports([]),
]
self.firewall.assert_has_calls(calls)