Fix DVR to service LBaaS VIP Ports
Currently, DVR router namespaces are created only when there is a valid VM port on the compute node, or for the gateway-port on the service node. But when an LBaaS VIP port is created the l3 agent does not create a DVR namespace to service the VIP port. This fix enables DVR namespaces to be created to service the LBaaS VIP port. Also, this fix enables L2 Agent running in DVR mode, to add-in OVS rules to enable packets to be routed to such LBaaS VIP Ports which are resident on DVR routed interfaces. Therefore, with this fix both East-West and North-South traffic will be serviced by DVR for LBaas VIP Ports. DocImpact Authored-by: Swaminathan Vasudevan <swaminathan.vasudevan@hp.com> Co-Authored-By: Vivekanandan Narasimhan <vivekanandan.narasimhan@hp.com> Change-Id: I698b971d50721fb0512a11569f7d3139d0d456f3 Closes-Bug: #1356464
This commit is contained in:
parent
07aed08413
commit
d60257b244
@ -40,9 +40,10 @@ class DVRServerRpcApiMixin(object):
|
|||||||
version=self.DVR_RPC_VERSION)
|
version=self.DVR_RPC_VERSION)
|
||||||
|
|
||||||
@log.log
|
@log.log
|
||||||
def get_compute_ports_on_host_by_subnet(self, context, host, subnet):
|
def get_ports_on_host_by_subnet(self, context, host, subnet):
|
||||||
return self.call(context,
|
return self.call(context,
|
||||||
self.make_msg('get_compute_ports_on_host_by_subnet',
|
self.make_msg(
|
||||||
|
'get_ports_on_host_by_subnet',
|
||||||
host=host,
|
host=host,
|
||||||
subnet=subnet),
|
subnet=subnet),
|
||||||
version=self.DVR_RPC_VERSION)
|
version=self.DVR_RPC_VERSION)
|
||||||
@ -70,10 +71,9 @@ class DVRServerRpcCallbackMixin(object):
|
|||||||
def get_dvr_mac_address_by_host(self, context, host):
|
def get_dvr_mac_address_by_host(self, context, host):
|
||||||
return self.plugin.get_dvr_mac_address_by_host(context, host)
|
return self.plugin.get_dvr_mac_address_by_host(context, host)
|
||||||
|
|
||||||
def get_compute_ports_on_host_by_subnet(self, context, host, subnet):
|
def get_ports_on_host_by_subnet(self, context, host, subnet):
|
||||||
return self.plugin.get_compute_ports_on_host_by_subnet(context,
|
return self.plugin.get_ports_on_host_by_subnet(context,
|
||||||
host,
|
host, subnet)
|
||||||
subnet)
|
|
||||||
|
|
||||||
def get_subnet_for_dvr(self, context, subnet):
|
def get_subnet_for_dvr(self, context, subnet):
|
||||||
return self.plugin.get_subnet_for_dvr(context, subnet)
|
return self.plugin.get_subnet_for_dvr(context, subnet)
|
||||||
|
@ -36,6 +36,7 @@ DEVICE_OWNER_DHCP = "network:dhcp"
|
|||||||
DEVICE_OWNER_DVR_INTERFACE = "network:router_interface_distributed"
|
DEVICE_OWNER_DVR_INTERFACE = "network:router_interface_distributed"
|
||||||
DEVICE_OWNER_AGENT_GW = "network:floatingip_agent_gateway"
|
DEVICE_OWNER_AGENT_GW = "network:floatingip_agent_gateway"
|
||||||
DEVICE_OWNER_ROUTER_SNAT = "network:router_centralized_snat"
|
DEVICE_OWNER_ROUTER_SNAT = "network:router_centralized_snat"
|
||||||
|
DEVICE_OWNER_LOADBALANCER = "neutron:LOADBALANCER"
|
||||||
|
|
||||||
DEVICE_ID_RESERVED_DHCP_PORT = "reserved_dhcp_port"
|
DEVICE_ID_RESERVED_DHCP_PORT = "reserved_dhcp_port"
|
||||||
|
|
||||||
|
@ -335,3 +335,16 @@ class exception_logger(object):
|
|||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
self.logger(e)
|
self.logger(e)
|
||||||
return call
|
return call
|
||||||
|
|
||||||
|
|
||||||
|
def is_dvr_serviced(device_owner):
|
||||||
|
"""Check if the port need to be serviced by DVR
|
||||||
|
|
||||||
|
Helper function to check the device owners of the
|
||||||
|
ports in the compute and service node to make sure
|
||||||
|
if they are required for DVR or any service directly or
|
||||||
|
indirectly associated with DVR.
|
||||||
|
"""
|
||||||
|
if (device_owner.startswith('compute:') or (
|
||||||
|
q_const.DEVICE_OWNER_LOADBALANCER == device_owner)):
|
||||||
|
return True
|
||||||
|
@ -22,6 +22,7 @@ from neutron.common import log
|
|||||||
from neutron.common import utils
|
from neutron.common import utils
|
||||||
from neutron.db import model_base
|
from neutron.db import model_base
|
||||||
from neutron.extensions import dvr as ext_dvr
|
from neutron.extensions import dvr as ext_dvr
|
||||||
|
from neutron.extensions import portbindings
|
||||||
from neutron import manager
|
from neutron import manager
|
||||||
from neutron.openstack.common import log as logging
|
from neutron.openstack.common import log as logging
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
@ -121,24 +122,35 @@ class DVRDbMixin(ext_dvr.DVRMacAddressPluginBase):
|
|||||||
'mac_address': dvr_mac_entry['mac_address']}
|
'mac_address': dvr_mac_entry['mac_address']}
|
||||||
|
|
||||||
@log.log
|
@log.log
|
||||||
def get_compute_ports_on_host_by_subnet(self, context, host, subnet):
|
def get_ports_on_host_by_subnet(self, context, host, subnet):
|
||||||
|
"""Returns ports of interest, on a given subnet in the input host
|
||||||
|
|
||||||
|
This method returns ports that need to be serviced by DVR.
|
||||||
|
:param context: rpc request context
|
||||||
|
:param host: host id to match and extract ports of interest
|
||||||
|
:param subnet: subnet id to match and extract ports of interest
|
||||||
|
:returns list -- Ports on the given subnet in the input host
|
||||||
|
"""
|
||||||
# FIXME(vivek, salv-orlando): improve this query by adding the
|
# FIXME(vivek, salv-orlando): improve this query by adding the
|
||||||
# capability of filtering by binding:host_id
|
# capability of filtering by binding:host_id
|
||||||
vm_ports_by_host = []
|
ports_by_host = []
|
||||||
filter = {'fixed_ips': {'subnet_id': [subnet]}}
|
filter = {'fixed_ips': {'subnet_id': [subnet]}}
|
||||||
ports = self.plugin.get_ports(context, filters=filter)
|
ports = self.plugin.get_ports(context, filters=filter)
|
||||||
LOG.debug("List of Ports on subnet %(subnet)s received as %(ports)s",
|
LOG.debug("List of Ports on subnet %(subnet)s at host %(host)s "
|
||||||
{'subnet': subnet, 'ports': ports})
|
"received as %(ports)s",
|
||||||
|
{'subnet': subnet, 'host': host, 'ports': ports})
|
||||||
for port in ports:
|
for port in ports:
|
||||||
if 'compute:' in port['device_owner']:
|
device_owner = port['device_owner']
|
||||||
if port['binding:host_id'] == host:
|
if (utils.is_dvr_serviced(device_owner)):
|
||||||
port_dict = self.plugin._make_port_dict(
|
if port[portbindings.HOST_ID] == host:
|
||||||
port, process_extensions=False)
|
port_dict = self.plugin._make_port_dict(port,
|
||||||
vm_ports_by_host.append(port_dict)
|
process_extensions=False)
|
||||||
LOG.debug("Returning list of VM Ports on host %(host)s for subnet "
|
ports_by_host.append(port_dict)
|
||||||
"%(subnet)s ports %(ports)s",
|
LOG.debug("Returning list of dvr serviced ports on host %(host)s"
|
||||||
{'host': host, 'subnet': subnet, 'ports': vm_ports_by_host})
|
" for subnet %(subnet)s ports %(ports)s",
|
||||||
return vm_ports_by_host
|
{'host': host, 'subnet': subnet,
|
||||||
|
'ports': ports_by_host})
|
||||||
|
return ports_by_host
|
||||||
|
|
||||||
@log.log
|
@log.log
|
||||||
def get_subnet_for_dvr(self, context, subnet):
|
def get_subnet_for_dvr(self, context, subnet):
|
||||||
|
@ -24,6 +24,7 @@ from sqlalchemy.orm import exc
|
|||||||
from sqlalchemy.orm import joinedload
|
from sqlalchemy.orm import joinedload
|
||||||
|
|
||||||
from neutron.common import constants
|
from neutron.common import constants
|
||||||
|
from neutron.common import utils as n_utils
|
||||||
from neutron import context as n_ctx
|
from neutron import context as n_ctx
|
||||||
from neutron.db import agents_db
|
from neutron.db import agents_db
|
||||||
from neutron.db import agentschedulers_db
|
from neutron.db import agentschedulers_db
|
||||||
@ -320,8 +321,12 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
|
|||||||
if agentschedulers_db.AgentSchedulerDbMixin.is_eligible_agent(
|
if agentschedulers_db.AgentSchedulerDbMixin.is_eligible_agent(
|
||||||
active, l3_agent)]
|
active, l3_agent)]
|
||||||
|
|
||||||
def check_vmexists_on_l3agent(self, context, l3_agent, router_id,
|
def check_ports_exist_on_l3agent(self, context, l3_agent, router_id,
|
||||||
subnet_id):
|
subnet_id):
|
||||||
|
"""
|
||||||
|
This function checks for existence of dvr serviceable
|
||||||
|
ports on the host, running the input l3agent.
|
||||||
|
"""
|
||||||
if not subnet_id:
|
if not subnet_id:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -329,7 +334,7 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
|
|||||||
filter = {'fixed_ips': {'subnet_id': [subnet_id]}}
|
filter = {'fixed_ips': {'subnet_id': [subnet_id]}}
|
||||||
ports = core_plugin.get_ports(context, filters=filter)
|
ports = core_plugin.get_ports(context, filters=filter)
|
||||||
for port in ports:
|
for port in ports:
|
||||||
if ("compute:" in port['device_owner'] and
|
if (n_utils.is_dvr_serviced(port['device_owner']) and
|
||||||
l3_agent['host'] == port['binding:host_id']):
|
l3_agent['host'] == port['binding:host_id']):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -397,7 +402,7 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
|
|||||||
not is_router_distributed):
|
not is_router_distributed):
|
||||||
candidates.append(l3_agent)
|
candidates.append(l3_agent)
|
||||||
elif is_router_distributed and agent_mode.startswith('dvr') and (
|
elif is_router_distributed and agent_mode.startswith('dvr') and (
|
||||||
self.check_vmexists_on_l3agent(
|
self.check_ports_exist_on_l3agent(
|
||||||
context, l3_agent, sync_router['id'], subnet_id)):
|
context, l3_agent, sync_router['id'], subnet_id)):
|
||||||
candidates.append(l3_agent)
|
candidates.append(l3_agent)
|
||||||
return candidates
|
return candidates
|
||||||
|
@ -17,6 +17,7 @@ from oslo.config import cfg
|
|||||||
from neutron.api.v2 import attributes
|
from neutron.api.v2 import attributes
|
||||||
from neutron.common import constants as l3_const
|
from neutron.common import constants as l3_const
|
||||||
from neutron.common import exceptions as n_exc
|
from neutron.common import exceptions as n_exc
|
||||||
|
from neutron.common import utils as n_utils
|
||||||
from neutron.db import l3_attrs_db
|
from neutron.db import l3_attrs_db
|
||||||
from neutron.db import l3_db
|
from neutron.db import l3_db
|
||||||
from neutron.db import l3_dvrscheduler_db as l3_dvrsched_db
|
from neutron.db import l3_dvrscheduler_db as l3_dvrsched_db
|
||||||
@ -333,10 +334,9 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
|
|||||||
def get_vm_port_hostid(self, context, port_id, port=None):
|
def get_vm_port_hostid(self, context, port_id, port=None):
|
||||||
"""Return the portbinding host_id."""
|
"""Return the portbinding host_id."""
|
||||||
vm_port_db = port or self._core_plugin.get_port(context, port_id)
|
vm_port_db = port or self._core_plugin.get_port(context, port_id)
|
||||||
allowed_device_owners = ("neutron:LOADBALANCER", DEVICE_OWNER_AGENT_GW)
|
|
||||||
device_owner = vm_port_db['device_owner'] if vm_port_db else ""
|
device_owner = vm_port_db['device_owner'] if vm_port_db else ""
|
||||||
if (device_owner in allowed_device_owners or
|
if (n_utils.is_dvr_serviced(device_owner) or
|
||||||
device_owner.startswith("compute:")):
|
device_owner == DEVICE_OWNER_AGENT_GW):
|
||||||
return vm_port_db[portbindings.HOST_ID]
|
return vm_port_db[portbindings.HOST_ID]
|
||||||
|
|
||||||
def get_agent_gw_ports_exist_for_network(
|
def get_agent_gw_ports_exist_for_network(
|
||||||
|
@ -20,6 +20,7 @@ from sqlalchemy import orm
|
|||||||
from sqlalchemy.orm import exc
|
from sqlalchemy.orm import exc
|
||||||
|
|
||||||
from neutron.common import constants as q_const
|
from neutron.common import constants as q_const
|
||||||
|
from neutron.common import utils as n_utils
|
||||||
from neutron.db import agents_db
|
from neutron.db import agents_db
|
||||||
from neutron.db import l3_agentschedulers_db as l3agent_sch_db
|
from neutron.db import l3_agentschedulers_db as l3agent_sch_db
|
||||||
from neutron.db import model_base
|
from neutron.db import model_base
|
||||||
@ -135,17 +136,18 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
|
|||||||
subnet_ids.add(int_subnet)
|
subnet_ids.add(int_subnet)
|
||||||
return subnet_ids
|
return subnet_ids
|
||||||
|
|
||||||
def check_vm_exists_on_subnet(self, context, host, port_id, subnet_id):
|
def check_ports_active_on_host_and_subnet(self, context, host,
|
||||||
"""Check if there is any vm exists on the subnet_id."""
|
port_id, subnet_id):
|
||||||
|
"""Check if there is any dvr serviceable port on the subnet_id."""
|
||||||
filter_sub = {'fixed_ips': {'subnet_id': [subnet_id]}}
|
filter_sub = {'fixed_ips': {'subnet_id': [subnet_id]}}
|
||||||
ports = self._core_plugin.get_ports(context, filters=filter_sub)
|
ports = self._core_plugin.get_ports(context, filters=filter_sub)
|
||||||
for port in ports:
|
for port in ports:
|
||||||
if ("compute:" in port['device_owner']
|
if (n_utils.is_dvr_serviced(port['device_owner'])
|
||||||
and port['status'] == 'ACTIVE'
|
and port['status'] == 'ACTIVE'
|
||||||
and port['binding:host_id'] == host
|
and port['binding:host_id'] == host
|
||||||
and port['id'] != port_id):
|
and port['id'] != port_id):
|
||||||
LOG.debug('DVR: VM exists for subnet %(subnet_id)s on host '
|
LOG.debug('DVR: Active port exists for subnet %(subnet_id)s '
|
||||||
'%(host)s', {'subnet_id': subnet_id,
|
'on host %(host)s', {'subnet_id': subnet_id,
|
||||||
'host': host})
|
'host': host})
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
@ -164,7 +166,7 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
|
|||||||
subnet_ids = self.get_subnet_ids_on_router(context, router_id)
|
subnet_ids = self.get_subnet_ids_on_router(context, router_id)
|
||||||
vm_exists_on_subnet = False
|
vm_exists_on_subnet = False
|
||||||
for subnet in subnet_ids:
|
for subnet in subnet_ids:
|
||||||
if self.check_vm_exists_on_subnet(context,
|
if self.check_ports_active_on_host_and_subnet(context,
|
||||||
port_host,
|
port_host,
|
||||||
port_id,
|
port_id,
|
||||||
subnet):
|
subnet):
|
||||||
|
@ -155,7 +155,10 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
binding.host != host):
|
binding.host != host):
|
||||||
binding.host = host
|
binding.host = host
|
||||||
changes = True
|
changes = True
|
||||||
if "compute:" in port['device_owner']:
|
# Whenever a DVR serviceable port comes up on a
|
||||||
|
# node, it has to be communicated to the L3 Plugin
|
||||||
|
# and agent for creating the respective namespaces.
|
||||||
|
if (utils.is_dvr_serviced(port['device_owner'])):
|
||||||
l3plugin = manager.NeutronManager.get_service_plugins().get(
|
l3plugin = manager.NeutronManager.get_service_plugins().get(
|
||||||
service_constants.L3_ROUTER_NAT)
|
service_constants.L3_ROUTER_NAT)
|
||||||
if (utils.is_extension_supported(
|
if (utils.is_extension_supported(
|
||||||
|
@ -207,11 +207,11 @@ class RpcCallbacks(n_rpc.RpcCallback,
|
|||||||
return super(RpcCallbacks, self).get_dvr_mac_address_by_host(
|
return super(RpcCallbacks, self).get_dvr_mac_address_by_host(
|
||||||
rpc_context, host)
|
rpc_context, host)
|
||||||
|
|
||||||
def get_compute_ports_on_host_by_subnet(self, rpc_context, **kwargs):
|
def get_ports_on_host_by_subnet(self, rpc_context, **kwargs):
|
||||||
host = kwargs.get('host')
|
host = kwargs.get('host')
|
||||||
subnet = kwargs.get('subnet')
|
subnet = kwargs.get('subnet')
|
||||||
LOG.debug("DVR Agent requests list of VM ports on host %s", host)
|
LOG.debug("DVR Agent requests list of VM ports on host %s", host)
|
||||||
return super(RpcCallbacks, self).get_compute_ports_on_host_by_subnet(
|
return super(RpcCallbacks, self).get_ports_on_host_by_subnet(
|
||||||
rpc_context, host, subnet)
|
rpc_context, host, subnet)
|
||||||
|
|
||||||
def get_subnet_for_dvr(self, rpc_context, **kwargs):
|
def get_subnet_for_dvr(self, rpc_context, **kwargs):
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
from neutron.api.rpc.handlers import dvr_rpc
|
from neutron.api.rpc.handlers import dvr_rpc
|
||||||
from neutron.common import constants as n_const
|
from neutron.common import constants as n_const
|
||||||
|
from neutron.common import utils as n_utils
|
||||||
from neutron.openstack.common import log as logging
|
from neutron.openstack.common import log as logging
|
||||||
from neutron.plugins.openvswitch.common import constants
|
from neutron.plugins.openvswitch.common import constants
|
||||||
|
|
||||||
@ -310,10 +311,10 @@ class OVSDVRNeutronAgent(dvr_rpc.DVRAgentRpcApiMixin):
|
|||||||
subnet_info = ldm.get_subnet_info()
|
subnet_info = ldm.get_subnet_info()
|
||||||
ip_subnet = subnet_info['cidr']
|
ip_subnet = subnet_info['cidr']
|
||||||
local_compute_ports = (
|
local_compute_ports = (
|
||||||
self.plugin_rpc.get_compute_ports_on_host_by_subnet(
|
self.plugin_rpc.get_ports_on_host_by_subnet(
|
||||||
self.context, self.host, subnet_uuid))
|
self.context, self.host, subnet_uuid))
|
||||||
LOG.debug("DVR: List of ports received from "
|
LOG.debug("DVR: List of ports received from "
|
||||||
"get_compute_ports_on_host_by_subnet %s",
|
"get_ports_on_host_by_subnet %s",
|
||||||
local_compute_ports)
|
local_compute_ports)
|
||||||
for prt in local_compute_ports:
|
for prt in local_compute_ports:
|
||||||
vif = self.int_br.get_vif_port_by_id(prt['id'])
|
vif = self.int_br.get_vif_port_by_id(prt['id'])
|
||||||
@ -389,7 +390,7 @@ class OVSDVRNeutronAgent(dvr_rpc.DVRAgentRpcApiMixin):
|
|||||||
ovsport.add_subnet(subnet_uuid)
|
ovsport.add_subnet(subnet_uuid)
|
||||||
self.local_ports[port.vif_id] = ovsport
|
self.local_ports[port.vif_id] = ovsport
|
||||||
|
|
||||||
def _bind_compute_port_on_dvr_subnet(self, port, fixed_ips,
|
def _bind_port_on_dvr_subnet(self, port, fixed_ips,
|
||||||
device_owner, local_vlan):
|
device_owner, local_vlan):
|
||||||
# Handle new compute port added use-case
|
# Handle new compute port added use-case
|
||||||
subnet_uuid = None
|
subnet_uuid = None
|
||||||
@ -517,8 +518,8 @@ class OVSDVRNeutronAgent(dvr_rpc.DVRAgentRpcApiMixin):
|
|||||||
device_owner,
|
device_owner,
|
||||||
local_vlan_id)
|
local_vlan_id)
|
||||||
|
|
||||||
if device_owner and device_owner.startswith('compute:'):
|
if device_owner and n_utils.is_dvr_serviced(device_owner):
|
||||||
self._bind_compute_port_on_dvr_subnet(port, fixed_ips,
|
self._bind_port_on_dvr_subnet(port, fixed_ips,
|
||||||
device_owner,
|
device_owner,
|
||||||
local_vlan_id)
|
local_vlan_id)
|
||||||
|
|
||||||
@ -593,7 +594,7 @@ class OVSDVRNeutronAgent(dvr_rpc.DVRAgentRpcApiMixin):
|
|||||||
# release port state
|
# release port state
|
||||||
self.local_ports.pop(port.vif_id, None)
|
self.local_ports.pop(port.vif_id, None)
|
||||||
|
|
||||||
def _unbind_compute_port_on_dvr_subnet(self, port, local_vlan):
|
def _unbind_port_on_dvr_subnet(self, port, local_vlan):
|
||||||
|
|
||||||
ovsport = self.local_ports[port.vif_id]
|
ovsport = self.local_ports[port.vif_id]
|
||||||
# This confirms that this compute port being removed belonged
|
# This confirms that this compute port being removed belonged
|
||||||
@ -710,9 +711,8 @@ class OVSDVRNeutronAgent(dvr_rpc.DVRAgentRpcApiMixin):
|
|||||||
self._unbind_distributed_router_interface_port(vif_port,
|
self._unbind_distributed_router_interface_port(vif_port,
|
||||||
local_vlan_id)
|
local_vlan_id)
|
||||||
|
|
||||||
if device_owner and device_owner.startswith('compute:'):
|
if device_owner and n_utils.is_dvr_serviced(device_owner):
|
||||||
self._unbind_compute_port_on_dvr_subnet(vif_port,
|
self._unbind_port_on_dvr_subnet(vif_port, local_vlan_id)
|
||||||
local_vlan_id)
|
|
||||||
|
|
||||||
if device_owner == n_const.DEVICE_OWNER_ROUTER_SNAT:
|
if device_owner == n_const.DEVICE_OWNER_ROUTER_SNAT:
|
||||||
self._unbind_centralized_snat_port_on_dvr_subnet(vif_port,
|
self._unbind_centralized_snat_port_on_dvr_subnet(vif_port,
|
||||||
|
@ -21,6 +21,7 @@ import webob
|
|||||||
|
|
||||||
from neutron.common import constants
|
from neutron.common import constants
|
||||||
from neutron.common import exceptions as exc
|
from neutron.common import exceptions as exc
|
||||||
|
from neutron.common import utils
|
||||||
from neutron import context
|
from neutron import context
|
||||||
from neutron.extensions import multiprovidernet as mpnet
|
from neutron.extensions import multiprovidernet as mpnet
|
||||||
from neutron.extensions import portbindings
|
from neutron.extensions import portbindings
|
||||||
@ -163,6 +164,17 @@ class TestMl2PortsV2(test_plugin.TestPortsV2, Ml2PluginV2TestCase):
|
|||||||
mock.call(ctx, disassociate_floatingips.return_value)
|
mock.call(ctx, disassociate_floatingips.return_value)
|
||||||
])
|
])
|
||||||
|
|
||||||
|
def test_check_if_compute_port_serviced_by_dvr(self):
|
||||||
|
self.assertTrue(utils.is_dvr_serviced('compute:None'))
|
||||||
|
|
||||||
|
def test_check_if_lbaas_vip_port_serviced_by_dvr(self):
|
||||||
|
self.assertTrue(utils.is_dvr_serviced(
|
||||||
|
constants.DEVICE_OWNER_LOADBALANCER))
|
||||||
|
|
||||||
|
def test_check_if_port_not_serviced_by_dvr(self):
|
||||||
|
self.assertFalse(utils.is_dvr_serviced(
|
||||||
|
constants.DEVICE_OWNER_ROUTER_INTF))
|
||||||
|
|
||||||
def test_disassociate_floatingips_do_notify_returns_nothing(self):
|
def test_disassociate_floatingips_do_notify_returns_nothing(self):
|
||||||
ctx = context.get_admin_context()
|
ctx = context.get_admin_context()
|
||||||
l3plugin = manager.NeutronManager.get_service_plugins().get(
|
l3plugin = manager.NeutronManager.get_service_plugins().get(
|
||||||
|
@ -223,7 +223,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||||||
'cidr': '1.1.1.0/24',
|
'cidr': '1.1.1.0/24',
|
||||||
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
||||||
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
||||||
'get_compute_ports_on_host_by_subnet',
|
'get_ports_on_host_by_subnet',
|
||||||
return_value=[]),
|
return_value=[]),
|
||||||
mock.patch.object(self.agent.dvr_agent.int_br,
|
mock.patch.object(self.agent.dvr_agent.int_br,
|
||||||
'get_vif_port_by_id',
|
'get_vif_port_by_id',
|
||||||
@ -243,7 +243,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||||||
self.assertTrue(add_flow_tun_fn.called)
|
self.assertTrue(add_flow_tun_fn.called)
|
||||||
self.assertTrue(delete_flows_int_fn.called)
|
self.assertTrue(delete_flows_int_fn.called)
|
||||||
|
|
||||||
def test_port_bound_for_dvr_with_compute_ports(self, ofport=10):
|
def _test_port_bound_for_dvr(self, device_owner):
|
||||||
self._setup_for_dvr_test()
|
self._setup_for_dvr_test()
|
||||||
with mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.'
|
with mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.'
|
||||||
'set_db_attribute',
|
'set_db_attribute',
|
||||||
@ -259,7 +259,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||||||
'cidr': '1.1.1.0/24',
|
'cidr': '1.1.1.0/24',
|
||||||
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
||||||
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
||||||
'get_compute_ports_on_host_by_subnet',
|
'get_ports_on_host_by_subnet',
|
||||||
return_value=[]),
|
return_value=[]),
|
||||||
mock.patch.object(self.agent.dvr_agent.int_br,
|
mock.patch.object(self.agent.dvr_agent.int_br,
|
||||||
'get_vif_port_by_id',
|
'get_vif_port_by_id',
|
||||||
@ -279,11 +279,18 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||||||
self.agent.port_bound(self._compute_port, self._net_uuid,
|
self.agent.port_bound(self._compute_port, self._net_uuid,
|
||||||
'vxlan', None, None,
|
'vxlan', None, None,
|
||||||
self._compute_fixed_ips,
|
self._compute_fixed_ips,
|
||||||
"compute:None", False)
|
device_owner, False)
|
||||||
self.assertTrue(add_flow_tun_fn.called)
|
self.assertTrue(add_flow_tun_fn.called)
|
||||||
self.assertTrue(add_flow_int_fn.called)
|
self.assertTrue(add_flow_int_fn.called)
|
||||||
self.assertTrue(delete_flows_int_fn.called)
|
self.assertTrue(delete_flows_int_fn.called)
|
||||||
|
|
||||||
|
def test_port_bound_for_dvr_with_compute_ports(self):
|
||||||
|
self._test_port_bound_for_dvr(device_owner="compute:None")
|
||||||
|
|
||||||
|
def test_port_bound_for_dvr_with_lbaas_vip_ports(self):
|
||||||
|
self._test_port_bound_for_dvr(
|
||||||
|
device_owner=n_const.DEVICE_OWNER_LOADBALANCER)
|
||||||
|
|
||||||
def test_port_bound_for_dvr_with_csnat_ports(self, ofport=10):
|
def test_port_bound_for_dvr_with_csnat_ports(self, ofport=10):
|
||||||
self._setup_for_dvr_test()
|
self._setup_for_dvr_test()
|
||||||
with mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.'
|
with mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.'
|
||||||
@ -299,7 +306,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||||||
'cidr': '1.1.1.0/24',
|
'cidr': '1.1.1.0/24',
|
||||||
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
||||||
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
||||||
'get_compute_ports_on_host_by_subnet',
|
'get_ports_on_host_by_subnet',
|
||||||
return_value=[]),
|
return_value=[]),
|
||||||
mock.patch.object(self.agent.dvr_agent.int_br,
|
mock.patch.object(self.agent.dvr_agent.int_br,
|
||||||
'get_vif_port_by_id',
|
'get_vif_port_by_id',
|
||||||
@ -334,7 +341,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||||||
'cidr': '1.1.1.0/24',
|
'cidr': '1.1.1.0/24',
|
||||||
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
||||||
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
||||||
'get_compute_ports_on_host_by_subnet',
|
'get_ports_on_host_by_subnet',
|
||||||
return_value=[]),
|
return_value=[]),
|
||||||
mock.patch.object(self.agent.dvr_agent.int_br,
|
mock.patch.object(self.agent.dvr_agent.int_br,
|
||||||
'get_vif_port_by_id',
|
'get_vif_port_by_id',
|
||||||
@ -368,7 +375,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||||||
self.assertTrue(delete_flows_int_fn.called)
|
self.assertTrue(delete_flows_int_fn.called)
|
||||||
self.assertTrue(delete_flows_tun_fn.called)
|
self.assertTrue(delete_flows_tun_fn.called)
|
||||||
|
|
||||||
def test_treat_devices_removed_for_dvr_with_compute_ports(self, ofport=10):
|
def _test_treat_devices_removed_for_dvr(self, device_owner):
|
||||||
self._setup_for_dvr_test()
|
self._setup_for_dvr_test()
|
||||||
with mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.'
|
with mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.'
|
||||||
'set_db_attribute',
|
'set_db_attribute',
|
||||||
@ -383,7 +390,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||||||
'cidr': '1.1.1.0/24',
|
'cidr': '1.1.1.0/24',
|
||||||
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
||||||
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
||||||
'get_compute_ports_on_host_by_subnet',
|
'get_ports_on_host_by_subnet',
|
||||||
return_value=[]),
|
return_value=[]),
|
||||||
mock.patch.object(self.agent.dvr_agent.int_br,
|
mock.patch.object(self.agent.dvr_agent.int_br,
|
||||||
'get_vif_port_by_id',
|
'get_vif_port_by_id',
|
||||||
@ -404,7 +411,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||||||
self._net_uuid, 'vxlan',
|
self._net_uuid, 'vxlan',
|
||||||
None, None,
|
None, None,
|
||||||
self._compute_fixed_ips,
|
self._compute_fixed_ips,
|
||||||
"compute:None", False)
|
device_owner, False)
|
||||||
self.assertTrue(add_flow_tun_fn.called)
|
self.assertTrue(add_flow_tun_fn.called)
|
||||||
self.assertTrue(add_flow_int_fn.called)
|
self.assertTrue(add_flow_int_fn.called)
|
||||||
self.assertTrue(delete_flows_int_fn.called)
|
self.assertTrue(delete_flows_int_fn.called)
|
||||||
@ -420,6 +427,13 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||||||
self.agent.treat_devices_removed([self._compute_port.vif_id])
|
self.agent.treat_devices_removed([self._compute_port.vif_id])
|
||||||
self.assertTrue(delete_flows_int_fn.called)
|
self.assertTrue(delete_flows_int_fn.called)
|
||||||
|
|
||||||
|
def test_treat_devices_removed_for_dvr_with_compute_ports(self):
|
||||||
|
self._test_treat_devices_removed_for_dvr(device_owner="compute:None")
|
||||||
|
|
||||||
|
def test_treat_devices_removed_for_dvr_with_lbaas_vip_ports(self):
|
||||||
|
self._test_treat_devices_removed_for_dvr(
|
||||||
|
device_owner=n_const.DEVICE_OWNER_LOADBALANCER)
|
||||||
|
|
||||||
def test_treat_devices_removed_for_dvr_csnat_port(self, ofport=10):
|
def test_treat_devices_removed_for_dvr_csnat_port(self, ofport=10):
|
||||||
self._setup_for_dvr_test()
|
self._setup_for_dvr_test()
|
||||||
with mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.'
|
with mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.'
|
||||||
@ -435,7 +449,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||||||
'cidr': '1.1.1.0/24',
|
'cidr': '1.1.1.0/24',
|
||||||
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
||||||
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
||||||
'get_compute_ports_on_host_by_subnet',
|
'get_ports_on_host_by_subnet',
|
||||||
return_value=[]),
|
return_value=[]),
|
||||||
mock.patch.object(self.agent.dvr_agent.int_br,
|
mock.patch.object(self.agent.dvr_agent.int_br,
|
||||||
'get_vif_port_by_id',
|
'get_vif_port_by_id',
|
||||||
|
@ -584,7 +584,7 @@ class L3DvrSchedulerTestCase(testlib_api.SqlTestCase,
|
|||||||
self.assertEqual(sub_ids.pop(),
|
self.assertEqual(sub_ids.pop(),
|
||||||
dvr_port.get('fixed_ips').pop(0).get('subnet_id'))
|
dvr_port.get('fixed_ips').pop(0).get('subnet_id'))
|
||||||
|
|
||||||
def test_check_vm_exists_on_subnet(self):
|
def test_check_ports_active_on_host_and_subnet(self):
|
||||||
dvr_port = {
|
dvr_port = {
|
||||||
'id': 'dvr_port1',
|
'id': 'dvr_port1',
|
||||||
'device_id': 'r1',
|
'device_id': 'r1',
|
||||||
@ -613,12 +613,40 @@ class L3DvrSchedulerTestCase(testlib_api.SqlTestCase,
|
|||||||
'.L3AgentNotifyAPI')):
|
'.L3AgentNotifyAPI')):
|
||||||
sub_ids = self.dut.get_subnet_ids_on_router(self.adminContext,
|
sub_ids = self.dut.get_subnet_ids_on_router(self.adminContext,
|
||||||
r1['id'])
|
r1['id'])
|
||||||
result = self.dut.check_vm_exists_on_subnet(
|
result = self.dut.check_ports_active_on_host_and_subnet(
|
||||||
self.adminContext,
|
self.adminContext,
|
||||||
'thisHost', 'dvr_port1',
|
'thisHost', 'dvr_port1',
|
||||||
sub_ids)
|
sub_ids)
|
||||||
self.assertFalse(result)
|
self.assertFalse(result)
|
||||||
|
|
||||||
|
def test_check_dvr_serviced_port_exists_on_subnet(self):
|
||||||
|
vip_port = {
|
||||||
|
'id': 'lbaas-vip-port1',
|
||||||
|
'device_id': 'vip-pool-id',
|
||||||
|
'status': 'ACTIVE',
|
||||||
|
'binding:host_id': 'thisHost',
|
||||||
|
'device_owner': constants.DEVICE_OWNER_LOADBALANCER,
|
||||||
|
'fixed_ips': [
|
||||||
|
{
|
||||||
|
'subnet_id': 'my-subnet-id',
|
||||||
|
'ip_address': '10.10.10.1'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
with contextlib.nested(
|
||||||
|
mock.patch('neutron.db.db_base_plugin_v2.NeutronDbPluginV2'
|
||||||
|
'.get_ports', return_value=[vip_port]),
|
||||||
|
mock.patch('neutron.common.utils.is_dvr_serviced',
|
||||||
|
return_value=True)) as (get_ports_fn, dvr_serv_fn):
|
||||||
|
result = self.dut.check_ports_active_on_host_and_subnet(
|
||||||
|
self.adminContext,
|
||||||
|
'thisHost',
|
||||||
|
'dvr1-intf-id',
|
||||||
|
'my-subnet-id')
|
||||||
|
self.assertTrue(result)
|
||||||
|
self.assertEqual(dvr_serv_fn.call_count, 1)
|
||||||
|
|
||||||
def test_schedule_snat_router_with_snat_candidates(self):
|
def test_schedule_snat_router_with_snat_candidates(self):
|
||||||
agent = agents_db.Agent()
|
agent = agents_db.Agent()
|
||||||
agent.admin_state_up = True
|
agent.admin_state_up = True
|
||||||
|
Loading…
Reference in New Issue
Block a user