Trigger provider security group update for RA

For IPv6 subnets, router RA rule is added to compute node
to allow VM to accept RA from router interface on network node.
However, currently this is only done when router port which
sends RA is created *before* VM port is created.

This fix triggers provider security group rule update for IPv6 subnet
when router interface port is created or updated.

Change-Id: I7d950f12909a0c2a82b129279e6249b9fac80112
Closes-Bug: 1290252
This commit is contained in:
Xuhan Peng 2014-03-17 16:38:51 +08:00
parent fc832a0cd7
commit b4e318e4b6
3 changed files with 106 additions and 2 deletions

View File

@ -118,6 +118,12 @@ class SecurityGroupServerRpcMixin(sg_db.SecurityGroupDbMixin):
"""
if port['device_owner'] == q_const.DEVICE_OWNER_DHCP:
self.notifier.security_groups_provider_updated(context)
# For IPv6, provider rule need to be updated in case router
# interface is created or updated after VM port is created.
elif port['device_owner'] == q_const.DEVICE_OWNER_ROUTER_INTF:
if any(netaddr.IPAddress(fixed_ip['ip_address']).version == 6
for fixed_ip in port['fixed_ips']):
self.notifier.security_groups_provider_updated(context)
else:
self.notifier.security_groups_member_updated(
context, port.get(ext_sg.SECURITYGROUPS))
@ -246,8 +252,6 @@ class SecurityGroupServerRpcCallbackMixin(object):
gateway_ip = subnet['gateway_ip']
if subnet['ip_version'] != 6 or not gateway_ip:
continue
# TODO(xuhanp): Figure out how to call the following code
# each time router is created or updated.
if not netaddr.IPAddress(gateway_ip).is_link_local():
if subnet['ipv6_ra_mode']:
gateway_ip = self._get_lla_gateway_ip_for_subnet(context,

View File

@ -87,6 +87,12 @@ class TestOneConvergenceSGServerRpcCallBack(
def test_security_group_rule_for_device_ipv6_multi_router_interfaces(self):
self.skipTest("NVSD Plugin does not support IPV6.")
def test_notify_security_group_ipv6_gateway_port_added(self):
self.skipTest("NVSD Plugin does not support IPV6.")
def test_notify_security_group_ipv6_normal_port_added(self):
self.skipTest("NVSD Plugin does not support IPV6.")
class TestOneConvergenceSGServerRpcCallBackXML(
OneConvergenceSecurityGroupsTestCase,
@ -112,6 +118,12 @@ class TestOneConvergenceSGServerRpcCallBackXML(
def test_security_group_rule_for_device_ipv6_multi_router_interfaces(self):
self.skipTest("NVSD Plugin does not support IPV6.")
def test_notify_security_group_ipv6_gateway_port_added(self):
self.skipTest("NVSD Plugin does not support IPV6.")
def test_notify_security_group_ipv6_normal_port_added(self):
self.skipTest("NVSD Plugin does not support IPV6.")
class TestOneConvergenceSecurityGroups(OneConvergenceSecurityGroupsTestCase,
test_sg.TestSecurityGroups,

View File

@ -66,6 +66,94 @@ class SGServerRpcCallBackMixinTestCase(test_sg.SecurityGroupDBTestCase):
super(SGServerRpcCallBackMixinTestCase, self).setUp(plugin)
self.rpc = FakeSGCallback()
def _test_security_group_port(self, device_owner, gw_ip,
cidr, ip_version, ip_address):
with self.network() as net:
with self.subnet(net,
gateway_ip=gw_ip,
cidr=cidr,
ip_version=ip_version) as subnet:
with mock.patch.object(
self.notifier,
'security_groups_provider_updated') as mock_notifier:
kwargs = {
'fixed_ips': [{'subnet_id': subnet['subnet']['id'],
'ip_address': ip_address}]}
if device_owner:
kwargs['device_owner'] = device_owner
res = self._create_port(
self.fmt, net['network']['id'], **kwargs)
res = self.deserialize(self.fmt, res)
port_id = res['port']['id']
if device_owner == const.DEVICE_OWNER_ROUTER_INTF:
data = {'port': {'fixed_ips': []}}
req = self.new_update_request('ports', data, port_id)
res = self.deserialize(self.fmt,
req.get_response(self.api))
self._delete('ports', port_id)
return mock_notifier
def test_notify_security_group_ipv6_gateway_port_added(self):
if getattr(self, "notifier", None) is None:
self.skipTest("Notifier mock is not set so security group "
"RPC calls can't be tested")
mock_notifier = self._test_security_group_port(
const.DEVICE_OWNER_ROUTER_INTF,
'2001:0db8::1',
'2001:0db8::/64',
6,
'2001:0db8::1')
self.assertTrue(mock_notifier.called)
def test_notify_security_group_ipv6_normal_port_added(self):
if getattr(self, "notifier", None) is None:
self.skipTest("Notifier mock is not set so security group "
"RPC calls can't be tested")
mock_notifier = self._test_security_group_port(
None,
'2001:0db8::1',
'2001:0db8::/64',
6,
'2001:0db8::3')
self.assertFalse(mock_notifier.called)
def test_notify_security_group_ipv4_dhcp_port_added(self):
if getattr(self, "notifier", None) is None:
self.skipTest("Notifier mock is not set so security group "
"RPC calls can't be tested")
mock_notifier = self._test_security_group_port(
const.DEVICE_OWNER_DHCP,
'192.168.1.1',
'192.168.1.0/24',
4,
'192.168.1.2')
self.assertTrue(mock_notifier.called)
def test_notify_security_group_ipv4_gateway_port_added(self):
if getattr(self, "notifier", None) is None:
self.skipTest("Notifier mock is not set so security group "
"RPC calls can't be tested")
mock_notifier = self._test_security_group_port(
const.DEVICE_OWNER_ROUTER_INTF,
'192.168.1.1',
'192.168.1.0/24',
4,
'192.168.1.1')
self.assertFalse(mock_notifier.called)
def test_notify_security_group_ipv4_normal_port_added(self):
if getattr(self, "notifier", None) is None:
self.skipTest("Notifier mock is not set so security group "
"RPC calls can't be tested")
mock_notifier = self._test_security_group_port(
None,
'192.168.1.1',
'192.168.1.0/24',
4,
'192.168.1.3')
self.assertFalse(mock_notifier.called)
def test_security_group_rules_for_devices_ipv4_ingress(self):
fake_prefix = FAKE_PREFIX[const.IPv4]
with self.network() as n: