Merge "Support for AddressScopes as an API of what to expose"
This commit is contained in:
commit
b42a05ac30
@ -64,6 +64,10 @@ A driver implements the support for BGP capabilities. It ensures both VMs and
|
|||||||
LBs on providers networks or with Floating IPs associated can be
|
LBs on providers networks or with Floating IPs associated can be
|
||||||
exposed throug BGP. In addition, VMs on tenant networks can be also exposed
|
exposed throug BGP. In addition, VMs on tenant networks can be also exposed
|
||||||
if the ``expose_tenant_network`` configuration option is enabled.
|
if the ``expose_tenant_network`` configuration option is enabled.
|
||||||
|
To control what tenant networks are exposed another flag can be used:
|
||||||
|
``address_scopes``. If not set, all the tenant networks will be exposed, while
|
||||||
|
if it is configured with a (set of) address_scopes, only the tenant networks
|
||||||
|
whose address_scope matches will be exposed.
|
||||||
|
|
||||||
A common driver API is defined exposing the next methods:
|
A common driver API is defined exposing the next methods:
|
||||||
|
|
||||||
@ -217,7 +221,8 @@ VMs and LBs on provider networks or with FIPs can be reached through BGP
|
|||||||
VMs in tenant networks should be reachable too -- although instead of directly
|
VMs in tenant networks should be reachable too -- although instead of directly
|
||||||
in the node they are created, through one of the network gateway chassis nodes.
|
in the node they are created, through one of the network gateway chassis nodes.
|
||||||
The same happens with ``expose_ipv6_gua_tenant_networks`` but only for IPv6
|
The same happens with ``expose_ipv6_gua_tenant_networks`` but only for IPv6
|
||||||
GUA ranges.
|
GUA ranges. In addition, if the config option ``address_scopes`` is set only
|
||||||
|
the tenant networks with matching corresponding address_scope will be exposed.
|
||||||
|
|
||||||
To accomplish this, it needs to ensure that:
|
To accomplish this, it needs to ensure that:
|
||||||
|
|
||||||
@ -466,6 +471,7 @@ below:
|
|||||||
expose_tenant_networks=True
|
expose_tenant_networks=True
|
||||||
# expose_ipv6_gua_tenant_networks=True
|
# expose_ipv6_gua_tenant_networks=True
|
||||||
driver=osp_bgp_driver
|
driver=osp_bgp_driver
|
||||||
|
address_scopes=2237917c7b12489a84de4ef384a2bcae
|
||||||
|
|
||||||
$ sudo bgp-agent --config-dir bgp-agent.conf
|
$ sudo bgp-agent --config-dir bgp-agent.conf
|
||||||
Starting BGP Agent...
|
Starting BGP Agent...
|
||||||
@ -488,6 +494,13 @@ below:
|
|||||||
instead.
|
instead.
|
||||||
|
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
If you what to filter the tenant networks to be exposed by some specific
|
||||||
|
address scopes, add the list of address scopes to ``addresss_scope=XXX``
|
||||||
|
section. If no filtering should be applied, just remove the line.
|
||||||
|
|
||||||
|
|
||||||
Note that the OVN BGP Agent operates under the next assumptions:
|
Note that the OVN BGP Agent operates under the next assumptions:
|
||||||
|
|
||||||
- A dynamic routing solution, in this case FRR, is deployed and
|
- A dynamic routing solution, in this case FRR, is deployed and
|
||||||
@ -566,8 +579,9 @@ Limitations
|
|||||||
The following limitations apply:
|
The following limitations apply:
|
||||||
|
|
||||||
- There is no API to decide what to expose, all VMs/LBs on providers or with
|
- There is no API to decide what to expose, all VMs/LBs on providers or with
|
||||||
Floating IPs associated to them will get exposed. And all the VMs in tenant
|
Floating IPs associated to them will get exposed. For the VMs in the tenant
|
||||||
networks if the expose_tenant_network flag is enabled.
|
networks, the flag ``address_scopes`` should be used for filtering what
|
||||||
|
subnets to expose -- which should be also used to ensure no overlapping IPs.
|
||||||
|
|
||||||
- There is no support for overlapping CIDRs, so this must be avoided, e.g., by
|
- There is no support for overlapping CIDRs, so this must be avoided, e.g., by
|
||||||
using address scopes and subnet pools.
|
using address scopes and subnet pools.
|
||||||
|
@ -45,6 +45,7 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._expose_tenant_networks = (CONF.expose_tenant_networks or
|
self._expose_tenant_networks = (CONF.expose_tenant_networks or
|
||||||
CONF.expose_ipv6_gua_tenant_networks)
|
CONF.expose_ipv6_gua_tenant_networks)
|
||||||
|
self.allowed_address_scopes = set(CONF.address_scopes or [])
|
||||||
self.ovn_routing_tables = {} # {'br-ex': 200}
|
self.ovn_routing_tables = {} # {'br-ex': 200}
|
||||||
self.ovn_bridge_mappings = {} # {'public': 'br-ex'}
|
self.ovn_bridge_mappings = {} # {'public': 'br-ex'}
|
||||||
self.ovn_local_cr_lrps = {}
|
self.ovn_local_cr_lrps = {}
|
||||||
@ -91,6 +92,9 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
|
|||||||
linux_net.delete_routes_from_table(CONF.bgp_vrf_table_id)
|
linux_net.delete_routes_from_table(CONF.bgp_vrf_table_id)
|
||||||
|
|
||||||
LOG.info("VRF configuration for advertising routes completed")
|
LOG.info("VRF configuration for advertising routes completed")
|
||||||
|
if self._expose_tenant_networks and self.allowed_address_scopes:
|
||||||
|
LOG.info("Configured allowed address scopes: %s",
|
||||||
|
", ".join(self.allowed_address_scopes))
|
||||||
|
|
||||||
events = ()
|
events = ()
|
||||||
for event in self._get_events():
|
for event in self._get_events():
|
||||||
@ -621,20 +625,28 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
|
|||||||
return
|
return
|
||||||
if not CONF.expose_tenant_networks:
|
if not CONF.expose_tenant_networks:
|
||||||
# This means CONF.expose_ipv6_gua_tenant_networks is enabled
|
# This means CONF.expose_ipv6_gua_tenant_networks is enabled
|
||||||
ips_to_expose = []
|
gua_ips = []
|
||||||
for ip in ips:
|
for ip in ips:
|
||||||
if driver_utils.is_ipv6_gua(ip):
|
if driver_utils.is_ipv6_gua(ip):
|
||||||
|
gua_ips.append(ip)
|
||||||
|
if not gua_ips:
|
||||||
|
return
|
||||||
|
ips = gua_ips
|
||||||
|
|
||||||
|
ips_to_expose = []
|
||||||
|
for ip in ips:
|
||||||
|
if self._address_scope_allowed(ip, None, row):
|
||||||
ips_to_expose.append(ip)
|
ips_to_expose.append(ip)
|
||||||
if not ips_to_expose:
|
if not ips_to_expose:
|
||||||
return
|
return
|
||||||
ips = ips_to_expose
|
|
||||||
port_lrp = self.sb_idl.get_lrp_port_for_datapath(row.datapath)
|
port_lrp = self.sb_idl.get_lrp_port_for_datapath(row.datapath)
|
||||||
if port_lrp in self.ovn_local_lrps.keys():
|
if port_lrp in self.ovn_local_lrps.keys():
|
||||||
LOG.debug("Adding BGP route for tenant IP %s on chassis %s",
|
LOG.debug("Adding BGP route for tenant IP %s on chassis %s",
|
||||||
ips, self.chassis)
|
ips_to_expose, self.chassis)
|
||||||
linux_net.add_ips_to_dev(CONF.bgp_nic, ips)
|
linux_net.add_ips_to_dev(CONF.bgp_nic, ips_to_expose)
|
||||||
LOG.debug("Added BGP route for tenant IP %s on chassis %s",
|
LOG.debug("Added BGP route for tenant IP %s on chassis %s",
|
||||||
ips, self.chassis)
|
ips_to_expose, self.chassis)
|
||||||
|
|
||||||
@lockutils.synchronized('bgp')
|
@lockutils.synchronized('bgp')
|
||||||
def withdraw_remote_ip(self, ips, row, chassis=None):
|
def withdraw_remote_ip(self, ips, row, chassis=None):
|
||||||
@ -643,20 +655,27 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
|
|||||||
return
|
return
|
||||||
if not CONF.expose_tenant_networks:
|
if not CONF.expose_tenant_networks:
|
||||||
# This means CONF.expose_ipv6_gua_tenant_networks is enabled
|
# This means CONF.expose_ipv6_gua_tenant_networks is enabled
|
||||||
ips_to_withdraw = []
|
gua_ips = []
|
||||||
for ip in ips:
|
for ip in ips:
|
||||||
if driver_utils.is_ipv6_gua(ip):
|
if driver_utils.is_ipv6_gua(ip):
|
||||||
|
gua_ips.append(ip)
|
||||||
|
if not gua_ips:
|
||||||
|
return
|
||||||
|
ips = gua_ips
|
||||||
|
|
||||||
|
ips_to_withdraw = []
|
||||||
|
for ip in ips:
|
||||||
|
if self._address_scope_allowed(ip, None, row):
|
||||||
ips_to_withdraw.append(ip)
|
ips_to_withdraw.append(ip)
|
||||||
if not ips_to_withdraw:
|
if not ips_to_withdraw:
|
||||||
return
|
return
|
||||||
ips = ips_to_withdraw
|
|
||||||
port_lrp = self.sb_idl.get_lrp_port_for_datapath(row.datapath)
|
port_lrp = self.sb_idl.get_lrp_port_for_datapath(row.datapath)
|
||||||
if port_lrp in self.ovn_local_lrps.keys():
|
if port_lrp in self.ovn_local_lrps.keys():
|
||||||
LOG.debug("Deleting BGP route for tenant IP %s on chassis %s",
|
LOG.debug("Deleting BGP route for tenant IP %s on chassis %s",
|
||||||
ips, self.chassis)
|
ips_to_withdraw, self.chassis)
|
||||||
linux_net.del_ips_from_dev(CONF.bgp_nic, ips)
|
linux_net.del_ips_from_dev(CONF.bgp_nic, ips_to_withdraw)
|
||||||
LOG.debug("Deleted BGP route for tenant IP %s on chassis %s",
|
LOG.debug("Deleted BGP route for tenant IP %s on chassis %s",
|
||||||
ips, self.chassis)
|
ips_to_withdraw, self.chassis)
|
||||||
|
|
||||||
def _process_cr_lrp_port(self, cr_lrp_port_name, provider_datapath,
|
def _process_cr_lrp_port(self, cr_lrp_port_name, provider_datapath,
|
||||||
router_port):
|
router_port):
|
||||||
@ -697,6 +716,8 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
|
|||||||
# This should not happen: subnet without CIDR
|
# This should not happen: subnet without CIDR
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if not self._address_scope_allowed(lrp_ip, lrp.options['peer']):
|
||||||
|
return
|
||||||
subnet_datapath = self.sb_idl.get_port_datapath(
|
subnet_datapath = self.sb_idl.get_port_datapath(
|
||||||
lrp.options['peer'])
|
lrp.options['peer'])
|
||||||
self._expose_lrp_port(lrp_ip, lrp.logical_port,
|
self._expose_lrp_port(lrp_ip, lrp.logical_port,
|
||||||
@ -875,16 +896,21 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
|
|||||||
|
|
||||||
LOG.debug("Deleting IP Rules for network %s on chassis %s", ip,
|
LOG.debug("Deleting IP Rules for network %s on chassis %s", ip,
|
||||||
self.chassis)
|
self.chassis)
|
||||||
|
exposed_lrp = False
|
||||||
if lrp:
|
if lrp:
|
||||||
if lrp in self.ovn_local_lrps.keys():
|
if lrp in self.ovn_local_lrps.keys():
|
||||||
|
exposed_lrp = True
|
||||||
self.ovn_local_lrps.pop(lrp)
|
self.ovn_local_lrps.pop(lrp)
|
||||||
else:
|
else:
|
||||||
for subnet_lp in cr_lrp_info['subnets_datapath'].keys():
|
for subnet_lp in cr_lrp_info['subnets_datapath'].keys():
|
||||||
if subnet_lp in self.ovn_local_lrps.keys():
|
if subnet_lp in self.ovn_local_lrps.keys():
|
||||||
|
exposed_lrp = True
|
||||||
self.ovn_local_lrps.pop(subnet_lp)
|
self.ovn_local_lrps.pop(subnet_lp)
|
||||||
break
|
break
|
||||||
self.ovn_local_cr_lrps[associated_cr_lrp]['subnets_datapath'].pop(
|
self.ovn_local_cr_lrps[associated_cr_lrp]['subnets_datapath'].pop(
|
||||||
lrp, None)
|
lrp, None)
|
||||||
|
if not exposed_lrp:
|
||||||
|
return
|
||||||
|
|
||||||
cr_lrp_ips = [ip_address.split('/')[0]
|
cr_lrp_ips = [ip_address.split('/')[0]
|
||||||
for ip_address in cr_lrp_info.get('ips', [])]
|
for ip_address in cr_lrp_info.get('ips', [])]
|
||||||
@ -937,6 +963,9 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
|
|||||||
if not cr_lrp:
|
if not cr_lrp:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if not self._address_scope_allowed(ip, row.options['peer']):
|
||||||
|
return
|
||||||
|
|
||||||
self._expose_lrp_port(ip, row.logical_port, cr_lrp, subnet_datapath)
|
self._expose_lrp_port(ip, row.logical_port, cr_lrp, subnet_datapath)
|
||||||
|
|
||||||
@lockutils.synchronized('bgp')
|
@lockutils.synchronized('bgp')
|
||||||
@ -971,3 +1000,24 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
|
|||||||
return
|
return
|
||||||
|
|
||||||
self._withdraw_lrp_port(ip, row.logical_port, cr_lrp)
|
self._withdraw_lrp_port(ip, row.logical_port, cr_lrp)
|
||||||
|
|
||||||
|
def _address_scope_allowed(self, ip, port_name, sb_port=None):
|
||||||
|
if not self.allowed_address_scopes:
|
||||||
|
# No address scopes to filter on => announce everything
|
||||||
|
return True
|
||||||
|
|
||||||
|
if not sb_port:
|
||||||
|
sb_port = self.sb_idl.get_port_by_name(port_name)
|
||||||
|
if not sb_port:
|
||||||
|
LOG.error("Port %s missing, skipping.", port_name)
|
||||||
|
return False
|
||||||
|
address_scopes = driver_utils.get_addr_scopes(sb_port)
|
||||||
|
|
||||||
|
# if we should filter on address scopes and this port has no
|
||||||
|
# address scopes set we do not need to expose it
|
||||||
|
if not any(address_scopes.values()):
|
||||||
|
return False
|
||||||
|
# if address scope does not match, no need to expose it
|
||||||
|
ip_version = linux_net.get_ip_version(ip)
|
||||||
|
|
||||||
|
return address_scopes[ip_version] in self.allowed_address_scopes
|
||||||
|
@ -23,6 +23,7 @@ from oslo_log import log as logging
|
|||||||
|
|
||||||
from ovn_bgp_agent import constants
|
from ovn_bgp_agent import constants
|
||||||
from ovn_bgp_agent.drivers import driver_api
|
from ovn_bgp_agent.drivers import driver_api
|
||||||
|
from ovn_bgp_agent.drivers.openstack.utils import driver_utils
|
||||||
from ovn_bgp_agent.drivers.openstack.utils import frr
|
from ovn_bgp_agent.drivers.openstack.utils import frr
|
||||||
from ovn_bgp_agent.drivers.openstack.utils import ovn
|
from ovn_bgp_agent.drivers.openstack.utils import ovn
|
||||||
from ovn_bgp_agent.drivers.openstack.utils import ovs
|
from ovn_bgp_agent.drivers.openstack.utils import ovs
|
||||||
@ -220,16 +221,6 @@ class OVNBGPStretchedL2Driver(driver_api.AgentDriverBase):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _get_addr_scopes(self, port):
|
|
||||||
return {
|
|
||||||
constants.IP_VERSION_4: port.external_ids.get(
|
|
||||||
constants.SUBNET_POOL_ADDR_SCOPE4
|
|
||||||
),
|
|
||||||
constants.IP_VERSION_6: port.external_ids.get(
|
|
||||||
constants.SUBNET_POOL_ADDR_SCOPE6
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
@lockutils.synchronized("bgp")
|
@lockutils.synchronized("bgp")
|
||||||
def expose_subnet(self, ip, row):
|
def expose_subnet(self, ip, row):
|
||||||
cr_lrp = self.sb_idl.is_router_gateway_on_any_chassis(row.datapath)
|
cr_lrp = self.sb_idl.is_router_gateway_on_any_chassis(row.datapath)
|
||||||
@ -358,7 +349,7 @@ class OVNBGPStretchedL2Driver(driver_api.AgentDriverBase):
|
|||||||
LOG.error("Patchport %s for CR-LRP %s missing, skipping.",
|
LOG.error("Patchport %s for CR-LRP %s missing, skipping.",
|
||||||
patch_port, row.logical_port)
|
patch_port, row.logical_port)
|
||||||
return
|
return
|
||||||
address_scopes = self._get_addr_scopes(port)
|
address_scopes = driver_utils.get_addr_scopes(port)
|
||||||
self.ovn_local_cr_lrps[row.logical_port][
|
self.ovn_local_cr_lrps[row.logical_port][
|
||||||
"address_scopes"] = address_scopes
|
"address_scopes"] = address_scopes
|
||||||
if not any([
|
if not any([
|
||||||
@ -407,7 +398,7 @@ class OVNBGPStretchedL2Driver(driver_api.AgentDriverBase):
|
|||||||
LOG.error("Patchport %s for CR-LRP %s missing, skipping.",
|
LOG.error("Patchport %s for CR-LRP %s missing, skipping.",
|
||||||
patch_port, gateway_port)
|
patch_port, gateway_port)
|
||||||
return
|
return
|
||||||
address_scopes = self._get_addr_scopes(port)
|
address_scopes = driver_utils.get_addr_scopes(port)
|
||||||
# if we should filter on address scopes and this port has no
|
# if we should filter on address scopes and this port has no
|
||||||
# address scopes set we do not need to go further
|
# address scopes set we do not need to go further
|
||||||
if not any(address_scopes.values()):
|
if not any(address_scopes.values()):
|
||||||
@ -502,7 +493,7 @@ class OVNBGPStretchedL2Driver(driver_api.AgentDriverBase):
|
|||||||
LOG.error("Patchport %s for CR-LRP %s missing, skipping.",
|
LOG.error("Patchport %s for CR-LRP %s missing, skipping.",
|
||||||
patch_port, gateway_port)
|
patch_port, gateway_port)
|
||||||
return
|
return
|
||||||
address_scopes = self._get_addr_scopes(port)
|
address_scopes = driver_utils.get_addr_scopes(port)
|
||||||
# if we have address scopes configured and none of them matches
|
# if we have address scopes configured and none of them matches
|
||||||
# for this port, we can skip further processing
|
# for this port, we can skip further processing
|
||||||
if not any(address_scopes.values()):
|
if not any(address_scopes.values()):
|
||||||
|
@ -42,3 +42,12 @@ def is_ipv6_gua(ip):
|
|||||||
if ipv6.is_global:
|
if ipv6.is_global:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def get_addr_scopes(port):
|
||||||
|
return {
|
||||||
|
constants.IP_VERSION_4: port.external_ids.get(
|
||||||
|
constants.SUBNET_POOL_ADDR_SCOPE4),
|
||||||
|
constants.IP_VERSION_6: port.external_ids.get(
|
||||||
|
constants.SUBNET_POOL_ADDR_SCOPE6),
|
||||||
|
}
|
||||||
|
@ -768,6 +768,37 @@ class TestOVNBGPDriver(test_base.TestCase):
|
|||||||
# Assert that add_ip_route() was not called
|
# Assert that add_ip_route() was not called
|
||||||
mock_add_route.assert_not_called()
|
mock_add_route.assert_not_called()
|
||||||
|
|
||||||
|
@mock.patch.object(linux_net, 'add_ips_to_dev')
|
||||||
|
@mock.patch.object(linux_net, 'add_ip_route')
|
||||||
|
@mock.patch.object(linux_net, 'add_ip_rule')
|
||||||
|
def test__process_lrp_port_address_scopes(
|
||||||
|
self, mock_add_rule, mock_add_route, mock_add_ips_dev):
|
||||||
|
gateway = {}
|
||||||
|
gateway['ips'] = ['{}/32'.format(self.fip),
|
||||||
|
'2003::1234:abcd:ffff:c0a8:102/128']
|
||||||
|
gateway['provider_datapath'] = 'bc6780f4-9510-4270-b4d2-b8d5c6802713'
|
||||||
|
gateway['subnets_datapath'] = {}
|
||||||
|
gateway['subnets_cidr'] = []
|
||||||
|
gateway['bridge_device'] = self.bridge
|
||||||
|
gateway['bridge_vlan'] = 10
|
||||||
|
self.bgp_driver.ovn_local_cr_lrps = {'gateway_port': gateway}
|
||||||
|
mock_address_scope_allowed = mock.patch.object(
|
||||||
|
self.bgp_driver, '_address_scope_allowed').start()
|
||||||
|
mock_address_scope_allowed.return_value = False
|
||||||
|
|
||||||
|
router_port = fakes.create_object({
|
||||||
|
'chassis': [],
|
||||||
|
'mac': ['{} {}/32'.format(self.mac, self.ipv4)],
|
||||||
|
'logical_port': 'lrp-fake-logical-port',
|
||||||
|
'options': {'peer': 'fake-peer'}})
|
||||||
|
|
||||||
|
self.bgp_driver._process_lrp_port(router_port, 'gateway_port')
|
||||||
|
|
||||||
|
# Assert that the add methods were called
|
||||||
|
mock_add_rule.assert_not_called()
|
||||||
|
mock_add_route.assert_not_called()
|
||||||
|
mock_add_ips_dev.assert_not_called()
|
||||||
|
|
||||||
def test__get_bridge_for_datapath(self):
|
def test__get_bridge_for_datapath(self):
|
||||||
self.sb_idl.get_network_name_and_tag.return_value = (
|
self.sb_idl.get_network_name_and_tag.return_value = (
|
||||||
'fake-network', [10])
|
'fake-network', [10])
|
||||||
@ -1337,6 +1368,24 @@ class TestOVNBGPDriver(test_base.TestCase):
|
|||||||
|
|
||||||
mock_add_ip_dev.assert_not_called()
|
mock_add_ip_dev.assert_not_called()
|
||||||
|
|
||||||
|
@mock.patch.object(linux_net, 'add_ips_to_dev')
|
||||||
|
def test_expose_remote_ip_address_scope(self, mock_add_ip_dev):
|
||||||
|
self.sb_idl.is_provider_network.return_value = False
|
||||||
|
lrp = 'fake-lrp'
|
||||||
|
self.sb_idl.get_lrp_port_for_datapath.return_value = lrp
|
||||||
|
self.bgp_driver.ovn_local_lrps = {lrp: 'fake-cr-lrp'}
|
||||||
|
row = fakes.create_object({
|
||||||
|
'name': 'fake-row', 'datapath': 'fake-dp'})
|
||||||
|
|
||||||
|
mock_address_scope_allowed = mock.patch.object(
|
||||||
|
self.bgp_driver, '_address_scope_allowed').start()
|
||||||
|
mock_address_scope_allowed.side_effect = [False, True]
|
||||||
|
|
||||||
|
ips = [self.ipv4, self.ipv6]
|
||||||
|
self.bgp_driver.expose_remote_ip(ips, row)
|
||||||
|
|
||||||
|
mock_add_ip_dev.assert_called_once_with(CONF.bgp_nic, [self.ipv6])
|
||||||
|
|
||||||
@mock.patch.object(linux_net, 'del_ips_from_dev')
|
@mock.patch.object(linux_net, 'del_ips_from_dev')
|
||||||
def test_withdraw_remote_ip(self, mock_del_ip_dev):
|
def test_withdraw_remote_ip(self, mock_del_ip_dev):
|
||||||
self.sb_idl.is_provider_network.return_value = False
|
self.sb_idl.is_provider_network.return_value = False
|
||||||
@ -1416,6 +1465,24 @@ class TestOVNBGPDriver(test_base.TestCase):
|
|||||||
|
|
||||||
mock_del_ip_dev.assert_not_called()
|
mock_del_ip_dev.assert_not_called()
|
||||||
|
|
||||||
|
@mock.patch.object(linux_net, 'del_ips_from_dev')
|
||||||
|
def test_withdraw_remote_ip_address_scope(self, mock_del_ip_dev):
|
||||||
|
self.sb_idl.is_provider_network.return_value = False
|
||||||
|
lrp = 'fake-lrp'
|
||||||
|
self.sb_idl.get_lrp_port_for_datapath.return_value = lrp
|
||||||
|
self.bgp_driver.ovn_local_lrps = {lrp: 'fake-cr-lrp'}
|
||||||
|
row = fakes.create_object({
|
||||||
|
'name': 'fake-row', 'datapath': 'fake-dp'})
|
||||||
|
|
||||||
|
mock_address_scope_allowed = mock.patch.object(
|
||||||
|
self.bgp_driver, '_address_scope_allowed').start()
|
||||||
|
mock_address_scope_allowed.side_effect = [False, True]
|
||||||
|
|
||||||
|
ips = [self.ipv4, self.ipv6]
|
||||||
|
self.bgp_driver.withdraw_remote_ip(ips, row)
|
||||||
|
|
||||||
|
mock_del_ip_dev.assert_called_once_with(CONF.bgp_nic, [self.ipv6])
|
||||||
|
|
||||||
@mock.patch.object(linux_net, 'add_ndp_proxy')
|
@mock.patch.object(linux_net, 'add_ndp_proxy')
|
||||||
@mock.patch.object(linux_net, 'get_ip_version')
|
@mock.patch.object(linux_net, 'get_ip_version')
|
||||||
def test__expose_cr_lrp_port(self, mock_ip_version, mock_ndp_proxy):
|
def test__expose_cr_lrp_port(self, mock_ip_version, mock_ndp_proxy):
|
||||||
@ -1684,6 +1751,26 @@ class TestOVNBGPDriver(test_base.TestCase):
|
|||||||
|
|
||||||
mock_expose_lrp_port.assert_not_called()
|
mock_expose_lrp_port.assert_not_called()
|
||||||
|
|
||||||
|
def test_expose_subnet_address_scope(self):
|
||||||
|
self.sb_idl.is_router_gateway_on_chassis.return_value = self.cr_lrp0
|
||||||
|
self.sb_idl.get_port_datapath.return_value = 'fake-port-dp'
|
||||||
|
row = fakes.create_object({
|
||||||
|
'name': 'fake-row',
|
||||||
|
'logical_port': 'subnet_port',
|
||||||
|
'datapath': 'fake-dp',
|
||||||
|
'options': {'peer': 'fake-peer'}})
|
||||||
|
|
||||||
|
mock_expose_lrp_port = mock.patch.object(
|
||||||
|
self.bgp_driver, '_expose_lrp_port').start()
|
||||||
|
|
||||||
|
mock_address_scope_allowed = mock.patch.object(
|
||||||
|
self.bgp_driver, '_address_scope_allowed').start()
|
||||||
|
mock_address_scope_allowed.return_value = False
|
||||||
|
|
||||||
|
self.bgp_driver.expose_subnet('fake-ip', row)
|
||||||
|
|
||||||
|
mock_expose_lrp_port.assert_not_called()
|
||||||
|
|
||||||
def test_withdraw_subnet(self):
|
def test_withdraw_subnet(self):
|
||||||
row = fakes.create_object({
|
row = fakes.create_object({
|
||||||
'name': 'fake-row',
|
'name': 'fake-row',
|
||||||
@ -1799,3 +1886,77 @@ class TestOVNBGPDriver(test_base.TestCase):
|
|||||||
mock_del_rule.assert_not_called()
|
mock_del_rule.assert_not_called()
|
||||||
mock_del_route.assert_not_called()
|
mock_del_route.assert_not_called()
|
||||||
mock_del_exposed_ips.assert_not_called()
|
mock_del_exposed_ips.assert_not_called()
|
||||||
|
|
||||||
|
@mock.patch.object(driver_utils, 'get_addr_scopes')
|
||||||
|
def test__address_scope_allowed(self, m_addr_scopes):
|
||||||
|
self.bgp_driver.allowed_address_scopes = set(["fake_address_scope"])
|
||||||
|
port_ip = self.ipv4
|
||||||
|
port_name = "fake-port"
|
||||||
|
sb_port = "fake-sb-port"
|
||||||
|
self.sb_idl.get_port_by_name.return_value = sb_port
|
||||||
|
address_scopes = {
|
||||||
|
constants.IP_VERSION_4: "fake_address_scope",
|
||||||
|
constants.IP_VERSION_6: "fake_ipv6_address_scope"}
|
||||||
|
m_addr_scopes.return_value = address_scopes
|
||||||
|
|
||||||
|
ret = self.bgp_driver._address_scope_allowed(port_ip, port_name)
|
||||||
|
|
||||||
|
self.assertEqual(True, ret)
|
||||||
|
m_addr_scopes.assert_called_once_with(sb_port)
|
||||||
|
|
||||||
|
def test__address_scope_allowed_not_configured(self):
|
||||||
|
self.bgp_driver.allowed_address_scopes = set([])
|
||||||
|
port_ip = self.ipv4
|
||||||
|
port_name = "fake-port"
|
||||||
|
sb_port = "fake-sb-port"
|
||||||
|
|
||||||
|
ret = self.bgp_driver._address_scope_allowed(
|
||||||
|
port_ip, port_name, sb_port)
|
||||||
|
|
||||||
|
self.assertEqual(True, ret)
|
||||||
|
|
||||||
|
@mock.patch.object(driver_utils, 'get_addr_scopes')
|
||||||
|
def test__address_scope_allowed_no_match(self, m_addr_scopes):
|
||||||
|
self.bgp_driver.allowed_address_scopes = set(["fake_address_scope"])
|
||||||
|
port_ip = self.ipv4
|
||||||
|
port_name = "fake-port"
|
||||||
|
sb_port = "fake-sb-port"
|
||||||
|
self.sb_idl.get_port_by_name.return_value = sb_port
|
||||||
|
address_scopes = {
|
||||||
|
constants.IP_VERSION_4: "different_fake_address_scope",
|
||||||
|
constants.IP_VERSION_6: "fake_ipv6_address_scope"}
|
||||||
|
m_addr_scopes.return_value = address_scopes
|
||||||
|
|
||||||
|
ret = self.bgp_driver._address_scope_allowed(port_ip, port_name)
|
||||||
|
|
||||||
|
self.assertEqual(False, ret)
|
||||||
|
m_addr_scopes.assert_called_once_with(sb_port)
|
||||||
|
|
||||||
|
@mock.patch.object(driver_utils, 'get_addr_scopes')
|
||||||
|
def test__address_scope_allowed_no_port(self, m_addr_scopes):
|
||||||
|
self.bgp_driver.allowed_address_scopes = set(["fake_address_scope"])
|
||||||
|
port_ip = self.ipv4
|
||||||
|
port_name = "fake-port"
|
||||||
|
self.sb_idl.get_port_by_name.return_value = []
|
||||||
|
|
||||||
|
ret = self.bgp_driver._address_scope_allowed(port_ip, port_name)
|
||||||
|
|
||||||
|
self.assertEqual(False, ret)
|
||||||
|
m_addr_scopes.assert_not_called()
|
||||||
|
|
||||||
|
@mock.patch.object(driver_utils, 'get_addr_scopes')
|
||||||
|
def test__address_scope_allowed_no_address_scope(self, m_addr_scopes):
|
||||||
|
self.bgp_driver.allowed_address_scopes = set(["fake_address_scope"])
|
||||||
|
port_ip = self.ipv4
|
||||||
|
port_name = "fake-port"
|
||||||
|
sb_port = "fake-sb-port"
|
||||||
|
self.sb_idl.get_port_by_name.return_value = sb_port
|
||||||
|
address_scopes = {
|
||||||
|
constants.IP_VERSION_4: "",
|
||||||
|
constants.IP_VERSION_6: ""}
|
||||||
|
m_addr_scopes.return_value = address_scopes
|
||||||
|
|
||||||
|
ret = self.bgp_driver._address_scope_allowed(port_ip, port_name)
|
||||||
|
|
||||||
|
self.assertEqual(False, ret)
|
||||||
|
m_addr_scopes.assert_called_once_with(sb_port)
|
||||||
|
@ -20,6 +20,7 @@ from oslo_config import cfg
|
|||||||
from ovn_bgp_agent import config
|
from ovn_bgp_agent import config
|
||||||
from ovn_bgp_agent import constants
|
from ovn_bgp_agent import constants
|
||||||
from ovn_bgp_agent.drivers.openstack import ovn_stretched_l2_bgp_driver
|
from ovn_bgp_agent.drivers.openstack import ovn_stretched_l2_bgp_driver
|
||||||
|
from ovn_bgp_agent.drivers.openstack.utils import driver_utils
|
||||||
from ovn_bgp_agent.drivers.openstack.utils import frr
|
from ovn_bgp_agent.drivers.openstack.utils import frr
|
||||||
from ovn_bgp_agent.drivers.openstack.utils import ovn
|
from ovn_bgp_agent.drivers.openstack.utils import ovn
|
||||||
from ovn_bgp_agent.drivers.openstack.utils import ovs
|
from ovn_bgp_agent.drivers.openstack.utils import ovs
|
||||||
@ -226,10 +227,6 @@ class TestOVNBGPStretchedL2Driver(test_base.TestCase):
|
|||||||
|
|
||||||
self.assertTrue(test_route not in self.bgp_driver.vrf_routes)
|
self.assertTrue(test_route not in self.bgp_driver.vrf_routes)
|
||||||
|
|
||||||
def test__get_addr_scopes(self):
|
|
||||||
addr_scopes = self.bgp_driver._get_addr_scopes(self.lp0)
|
|
||||||
self.assertEqual(self.addr_scope, addr_scopes)
|
|
||||||
|
|
||||||
def test__address_scope_allowed(self):
|
def test__address_scope_allowed(self):
|
||||||
test_scope2 = {
|
test_scope2 = {
|
||||||
constants.IP_VERSION_4: self.addr_scopev4,
|
constants.IP_VERSION_4: self.addr_scopev4,
|
||||||
@ -773,14 +770,11 @@ class TestOVNBGPStretchedL2Driver(test_base.TestCase):
|
|||||||
{}
|
{}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@mock.patch.object(driver_utils, "get_addr_scopes")
|
||||||
@mock.patch.object(linux_net, "add_ip_route")
|
@mock.patch.object(linux_net, "add_ip_route")
|
||||||
def test__ensure_network_exposed_port_not_existing(
|
def test__ensure_network_exposed_port_not_existing(self,
|
||||||
self,
|
mock_add_ip_route,
|
||||||
mock_add_ip_route
|
mock_addr_scopes):
|
||||||
):
|
|
||||||
mock__get_addr_scopes = mock.patch.object(
|
|
||||||
self.bgp_driver, "_get_addr_scopes"
|
|
||||||
).start()
|
|
||||||
gateway = {}
|
gateway = {}
|
||||||
gateway["ips"] = [
|
gateway["ips"] = [
|
||||||
ipaddress.ip_interface(ip)
|
ipaddress.ip_interface(ip)
|
||||||
@ -793,7 +787,7 @@ class TestOVNBGPStretchedL2Driver(test_base.TestCase):
|
|||||||
self.bgp_driver._ensure_network_exposed(
|
self.bgp_driver._ensure_network_exposed(
|
||||||
self.router_port, "gateway_port"
|
self.router_port, "gateway_port"
|
||||||
)
|
)
|
||||||
mock__get_addr_scopes.assert_not_called()
|
mock_addr_scopes.assert_not_called()
|
||||||
mock_add_ip_route.assert_not_called()
|
mock_add_ip_route.assert_not_called()
|
||||||
self.assertDictEqual(
|
self.assertDictEqual(
|
||||||
self.bgp_driver.propagated_lrp_ports,
|
self.bgp_driver.propagated_lrp_ports,
|
||||||
@ -1208,17 +1202,15 @@ class TestOVNBGPStretchedL2Driver(test_base.TestCase):
|
|||||||
mock__ensure_network_exposed.assert_not_called()
|
mock__ensure_network_exposed.assert_not_called()
|
||||||
self.sb_idl.get_port_by_name.assert_called_once_with("fake-port")
|
self.sb_idl.get_port_by_name.assert_called_once_with("fake-port")
|
||||||
|
|
||||||
def test__expose_cr_lrp_no_addr_scope(self):
|
@mock.patch.object(driver_utils, "get_addr_scopes")
|
||||||
|
def test__expose_cr_lrp_no_addr_scope(self, mock_addr_scopes):
|
||||||
mock__ensure_network_exposed = mock.patch.object(
|
mock__ensure_network_exposed = mock.patch.object(
|
||||||
self.bgp_driver, "_ensure_network_exposed"
|
self.bgp_driver, "_ensure_network_exposed"
|
||||||
).start()
|
).start()
|
||||||
mock__get_addr_scopes = mock.patch.object(
|
|
||||||
self.bgp_driver, "_get_addr_scopes"
|
|
||||||
).start()
|
|
||||||
|
|
||||||
self.sb_idl.get_port_by_name.return_value = self.fake_patch_port
|
self.sb_idl.get_port_by_name.return_value = self.fake_patch_port
|
||||||
|
|
||||||
mock__get_addr_scopes.return_value = {
|
mock_addr_scopes.return_value = {
|
||||||
constants.IP_VERSION_4: "address_scope_v4",
|
constants.IP_VERSION_4: "address_scope_v4",
|
||||||
constants.IP_VERSION_6: "address_scope_v6",
|
constants.IP_VERSION_6: "address_scope_v6",
|
||||||
}
|
}
|
||||||
@ -1226,7 +1218,7 @@ class TestOVNBGPStretchedL2Driver(test_base.TestCase):
|
|||||||
self.bgp_driver._expose_cr_lrp([], self.cr_lrp0)
|
self.bgp_driver._expose_cr_lrp([], self.cr_lrp0)
|
||||||
|
|
||||||
self.sb_idl.get_port_by_name.assert_called_once_with("fake-port")
|
self.sb_idl.get_port_by_name.assert_called_once_with("fake-port")
|
||||||
mock__get_addr_scopes.assert_called_once_with(self.fake_patch_port)
|
mock_addr_scopes.assert_called_once_with(self.fake_patch_port)
|
||||||
self.sb_idl.get_lrp_ports_for_router.assert_not_called()
|
self.sb_idl.get_lrp_ports_for_router.assert_not_called()
|
||||||
mock__ensure_network_exposed.assert_not_called()
|
mock__ensure_network_exposed.assert_not_called()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user