Merge "Ensure gateway is set for prefix delegated subnets"
This commit is contained in:
commit
99345b714f
|
@ -1437,7 +1437,8 @@ class DeviceManager(object):
|
||||||
skip_subnet = (
|
skip_subnet = (
|
||||||
subnet.ip_version != ip_version or
|
subnet.ip_version != ip_version or
|
||||||
not subnet.enable_dhcp or
|
not subnet.enable_dhcp or
|
||||||
subnet.gateway_ip is None)
|
subnet.gateway_ip is None or
|
||||||
|
subnet.subnetpool_id == constants.IPV6_PD_POOL_ID)
|
||||||
|
|
||||||
if skip_subnet:
|
if skip_subnet:
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -160,7 +160,7 @@ class DbBasePluginCommon(object):
|
||||||
'standard_attr_id': standard_attr_id,
|
'standard_attr_id': standard_attr_id,
|
||||||
}
|
}
|
||||||
res['gateway_ip'] = str(
|
res['gateway_ip'] = str(
|
||||||
subnet['gateway_ip']) if subnet['gateway_ip'] else None
|
subnet['gateway_ip']) if subnet['gateway_ip'] is not None else None
|
||||||
# TODO(korzen) this method can get subnet as DB object or Subnet OVO,
|
# TODO(korzen) this method can get subnet as DB object or Subnet OVO,
|
||||||
# so temporary workaround will be to fill in the fields in separate
|
# so temporary workaround will be to fill in the fields in separate
|
||||||
# ways. After converting all code pieces to use Subnet OVO, the latter
|
# ways. After converting all code pieces to use Subnet OVO, the latter
|
||||||
|
|
|
@ -58,9 +58,6 @@ class IpamBackendMixin(db_base_plugin_common.DbBasePluginCommon):
|
||||||
if subnet.get('gateway_ip') is const.ATTR_NOT_SPECIFIED:
|
if subnet.get('gateway_ip') is const.ATTR_NOT_SPECIFIED:
|
||||||
if subnet.get('ip_version') == const.IP_VERSION_6:
|
if subnet.get('ip_version') == const.IP_VERSION_6:
|
||||||
gateway_ip = netaddr.IPNetwork(cidr_net).network
|
gateway_ip = netaddr.IPNetwork(cidr_net).network
|
||||||
pd_net = netaddr.IPNetwork(const.PROVISIONAL_IPV6_PD_PREFIX)
|
|
||||||
if gateway_ip == pd_net.network:
|
|
||||||
return
|
|
||||||
else:
|
else:
|
||||||
gateway_ip = netaddr.IPNetwork(cidr_net).network + 1
|
gateway_ip = netaddr.IPNetwork(cidr_net).network + 1
|
||||||
return str(gateway_ip)
|
return str(gateway_ip)
|
||||||
|
|
|
@ -88,7 +88,12 @@ class TestSubnet(base.BaseFullStackTestCase):
|
||||||
ipv6_ra_mode='slaac',
|
ipv6_ra_mode='slaac',
|
||||||
subnetpool_id='prefix_delegation')
|
subnetpool_id='prefix_delegation')
|
||||||
subnet = self._show_subnet(subnet['id'])
|
subnet = self._show_subnet(subnet['id'])
|
||||||
self.assertIsNone(subnet['subnet']['gateway_ip'])
|
cidr = subnet['subnet']['cidr']
|
||||||
|
self.assertEqual(subnet['subnet']['gateway_ip'],
|
||||||
|
str(netaddr.IPNetwork(cidr).network))
|
||||||
|
router = self.safe_client.create_router(self._project_id)
|
||||||
|
self.safe_client.add_router_interface(
|
||||||
|
router['id'], subnet['subnet']['id'])
|
||||||
|
|
||||||
def test_create_subnet_ipv4_with_subnetpool(self):
|
def test_create_subnet_ipv4_with_subnetpool(self):
|
||||||
subnetpool_cidr = self.useFixture(
|
subnetpool_cidr = self.useFixture(
|
||||||
|
|
|
@ -16,6 +16,7 @@ from unittest import mock
|
||||||
|
|
||||||
from neutron_lib import constants
|
from neutron_lib import constants
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
from oslo_utils import uuidutils
|
||||||
|
|
||||||
from neutron.agent.linux import dhcp
|
from neutron.agent.linux import dhcp
|
||||||
from neutron.agent.linux import ip_lib
|
from neutron.agent.linux import ip_lib
|
||||||
|
@ -47,6 +48,7 @@ class TestDhcp(functional_base.BaseSudoTestCase):
|
||||||
def test_cleanup_stale_devices(self):
|
def test_cleanup_stale_devices(self):
|
||||||
plugin = mock.MagicMock()
|
plugin = mock.MagicMock()
|
||||||
dev_mgr = dhcp.DeviceManager(self.conf, plugin)
|
dev_mgr = dhcp.DeviceManager(self.conf, plugin)
|
||||||
|
spool_id = uuidutils.generate_uuid()
|
||||||
network = {
|
network = {
|
||||||
'id': 'foo_id',
|
'id': 'foo_id',
|
||||||
'project_id': 'foo_project',
|
'project_id': 'foo_project',
|
||||||
|
@ -57,6 +59,7 @@ class TestDhcp(functional_base.BaseSudoTestCase):
|
||||||
'ipv6_address_mode': None,
|
'ipv6_address_mode': None,
|
||||||
'ipv6_ra_mode': None,
|
'ipv6_ra_mode': None,
|
||||||
'cidr': '10.0.0.0/24',
|
'cidr': '10.0.0.0/24',
|
||||||
|
'subnetpool_id': spool_id,
|
||||||
'ip_version':
|
'ip_version':
|
||||||
constants.IP_VERSION_4,
|
constants.IP_VERSION_4,
|
||||||
'gateway_ip': '10.0.0.1'})]}
|
'gateway_ip': '10.0.0.1'})]}
|
||||||
|
|
|
@ -108,6 +108,7 @@ class DHCPAgentOVSTestFramework(base.BaseSudoTestCase):
|
||||||
ip_version=lib_const.IP_VERSION_4,
|
ip_version=lib_const.IP_VERSION_4,
|
||||||
prefix_override=None):
|
prefix_override=None):
|
||||||
cidr = self._IP_ADDRS[ip_version]['cidr']
|
cidr = self._IP_ADDRS[ip_version]['cidr']
|
||||||
|
spool_id = uuidutils.generate_uuid()
|
||||||
if prefix_override is not None:
|
if prefix_override is not None:
|
||||||
cidr = '/'.join((cidr.split('/')[0], str(prefix_override)))
|
cidr = '/'.join((cidr.split('/')[0], str(prefix_override)))
|
||||||
sn_dict = dhcp.DictModel(
|
sn_dict = dhcp.DictModel(
|
||||||
|
@ -115,6 +116,7 @@ class DHCPAgentOVSTestFramework(base.BaseSudoTestCase):
|
||||||
network_id=net_id,
|
network_id=net_id,
|
||||||
ip_version=ip_version,
|
ip_version=ip_version,
|
||||||
cidr=cidr,
|
cidr=cidr,
|
||||||
|
subnetpool_id=spool_id,
|
||||||
gateway_ip=self._IP_ADDRS[ip_version]['gateway'],
|
gateway_ip=self._IP_ADDRS[ip_version]['gateway'],
|
||||||
enable_dhcp=dhcp_enabled,
|
enable_dhcp=dhcp_enabled,
|
||||||
dns_nameservers=[],
|
dns_nameservers=[],
|
||||||
|
|
|
@ -53,6 +53,8 @@ FAKE_NETWORK_UUID = '12345678-1234-5678-1234567890ab'
|
||||||
FAKE_NETWORK_DHCP_NS = "qdhcp-%s" % FAKE_NETWORK_UUID
|
FAKE_NETWORK_DHCP_NS = "qdhcp-%s" % FAKE_NETWORK_UUID
|
||||||
FAKE_PROJECT_ID = 'aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa'
|
FAKE_PROJECT_ID = 'aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa'
|
||||||
FAKE_PRIORITY = 6
|
FAKE_PRIORITY = 6
|
||||||
|
FAKE_V4_SUBNETPOOL_ID = 'kkkkkkkk-kkkk-kkkk-kkkk-kkkkkkkkkkkk'
|
||||||
|
FAKE_V6_SUBNETPOOL_ID = 'jjjjjjjj-jjjj-jjjj-jjjj-jjjjjjjjjjjj'
|
||||||
|
|
||||||
|
|
||||||
fake_subnet1_allocation_pools = dhcp.DictModel(id='', start='172.9.9.2',
|
fake_subnet1_allocation_pools = dhcp.DictModel(id='', start='172.9.9.2',
|
||||||
|
@ -64,6 +66,7 @@ fake_subnet1 = dhcp.DictModel(id='bbbbbbbb-bbbb-bbbb-bbbbbbbbbbbb',
|
||||||
gateway_ip='172.9.9.1', host_routes=[],
|
gateway_ip='172.9.9.1', host_routes=[],
|
||||||
dns_nameservers=[],
|
dns_nameservers=[],
|
||||||
ip_version=const.IP_VERSION_4,
|
ip_version=const.IP_VERSION_4,
|
||||||
|
subnetpool_id=FAKE_V4_SUBNETPOOL_ID,
|
||||||
ipv6_ra_mode=None, ipv6_address_mode=None,
|
ipv6_ra_mode=None, ipv6_address_mode=None,
|
||||||
allocation_pools=fake_subnet1_allocation_pools)
|
allocation_pools=fake_subnet1_allocation_pools)
|
||||||
|
|
||||||
|
@ -1785,6 +1788,7 @@ class FakeV4Subnet(object):
|
||||||
self.cidr = '192.168.0.0/24'
|
self.cidr = '192.168.0.0/24'
|
||||||
self.gateway_ip = '192.168.0.1'
|
self.gateway_ip = '192.168.0.1'
|
||||||
self.enable_dhcp = True
|
self.enable_dhcp = True
|
||||||
|
self.subnetpool_id = FAKE_V4_SUBNETPOOL_ID
|
||||||
|
|
||||||
|
|
||||||
class FakeV6Subnet(object):
|
class FakeV6Subnet(object):
|
||||||
|
@ -1794,6 +1798,7 @@ class FakeV6Subnet(object):
|
||||||
self.cidr = '2001:db8:0:1::/64'
|
self.cidr = '2001:db8:0:1::/64'
|
||||||
self.gateway_ip = '2001:db8:0:1::1'
|
self.gateway_ip = '2001:db8:0:1::1'
|
||||||
self.enable_dhcp = True
|
self.enable_dhcp = True
|
||||||
|
self.subnetpool_id = FAKE_V6_SUBNETPOOL_ID
|
||||||
|
|
||||||
|
|
||||||
class FakeV4SubnetOutsideGateway(FakeV4Subnet):
|
class FakeV4SubnetOutsideGateway(FakeV4Subnet):
|
||||||
|
|
|
@ -437,6 +437,7 @@ class FakeV4Subnet(Dictable):
|
||||||
self.enable_dhcp = True
|
self.enable_dhcp = True
|
||||||
self.host_routes = [FakeV4HostRoute()]
|
self.host_routes = [FakeV4HostRoute()]
|
||||||
self.dns_nameservers = ['8.8.8.8']
|
self.dns_nameservers = ['8.8.8.8']
|
||||||
|
self.subnetpool_id = 'kkkkkkkk-kkkk-kkkk-kkkk-kkkkkkkkkkkk'
|
||||||
|
|
||||||
|
|
||||||
class FakeV4Subnet2(FakeV4Subnet):
|
class FakeV4Subnet2(FakeV4Subnet):
|
||||||
|
@ -564,6 +565,7 @@ class FakeV6Subnet(object):
|
||||||
self.dns_nameservers = ['2001:0200:feed:7ac0::1']
|
self.dns_nameservers = ['2001:0200:feed:7ac0::1']
|
||||||
self.ipv6_ra_mode = None
|
self.ipv6_ra_mode = None
|
||||||
self.ipv6_address_mode = None
|
self.ipv6_address_mode = None
|
||||||
|
self.subnetpool_id = 'jjjjjjjj-jjjj-jjjj-jjjj-jjjjjjjjjjjj'
|
||||||
|
|
||||||
|
|
||||||
class FakeV4SubnetNoDHCP(object):
|
class FakeV4SubnetNoDHCP(object):
|
||||||
|
@ -588,6 +590,7 @@ class FakeV6SubnetDHCPStateful(Dictable):
|
||||||
self.dns_nameservers = ['2001:0200:feed:7ac0::1']
|
self.dns_nameservers = ['2001:0200:feed:7ac0::1']
|
||||||
self.ipv6_ra_mode = None
|
self.ipv6_ra_mode = None
|
||||||
self.ipv6_address_mode = constants.DHCPV6_STATEFUL
|
self.ipv6_address_mode = constants.DHCPV6_STATEFUL
|
||||||
|
self.subnetpool_id = 'mmmmmmmm-mmmm-mmmm-mmmm-mmmmmmmmmmmm'
|
||||||
|
|
||||||
|
|
||||||
class FakeV6SubnetSlaac(object):
|
class FakeV6SubnetSlaac(object):
|
||||||
|
|
|
@ -4041,8 +4041,9 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase):
|
||||||
ipv6_ra_mode=constants.DHCPV6_STATELESS,
|
ipv6_ra_mode=constants.DHCPV6_STATELESS,
|
||||||
ipv6_address_mode=constants.DHCPV6_STATELESS)
|
ipv6_address_mode=constants.DHCPV6_STATELESS)
|
||||||
# If gateway_ip is not specified and the subnet is using prefix
|
# If gateway_ip is not specified and the subnet is using prefix
|
||||||
# delegation, until the CIDR is assigned, this value should be "None"
|
# delegation, until the CIDR is assigned, this value should be first
|
||||||
expected = {'gateway_ip': None,
|
# IP from the subnet
|
||||||
|
expected = {'gateway_ip': str(netaddr.IPNetwork(cidr).network),
|
||||||
'cidr': cidr}
|
'cidr': cidr}
|
||||||
self._test_create_subnet(expected=expected,
|
self._test_create_subnet(expected=expected,
|
||||||
cidr=cidr, ip_version=constants.IP_VERSION_6,
|
cidr=cidr, ip_version=constants.IP_VERSION_6,
|
||||||
|
|
Loading…
Reference in New Issue