Merge "Encapsulate some port properties in the PortContext"
This commit is contained in:
commit
d4ccddc3ef
@ -149,21 +149,23 @@ class NetworkContext(object):
|
|||||||
|
|
||||||
@abc.abstractproperty
|
@abc.abstractproperty
|
||||||
def current(self):
|
def current(self):
|
||||||
"""Return the current state of the network.
|
"""Return the network in its current configuration.
|
||||||
|
|
||||||
Return the current state of the network, as defined by
|
Return the network, as defined by NeutronPluginBaseV2.
|
||||||
NeutronPluginBaseV2.create_network and all extensions in the
|
create_network and all extensions in the ml2 plugin, with
|
||||||
ml2 plugin.
|
all its properties 'current' at the time the context was
|
||||||
|
established.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abc.abstractproperty
|
@abc.abstractproperty
|
||||||
def original(self):
|
def original(self):
|
||||||
"""Return the original state of the network.
|
"""Return the network in its original configuration.
|
||||||
|
|
||||||
Return the original state of the network, prior to a call to
|
Return the network, with all its properties set to their
|
||||||
update_network. Method is only valid within calls to
|
original values prior to a call to update_network. Method is
|
||||||
update_network_precommit and update_network_postcommit.
|
only valid within calls to update_network_precommit and
|
||||||
|
update_network_postcommit.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -185,21 +187,23 @@ class SubnetContext(object):
|
|||||||
|
|
||||||
@abc.abstractproperty
|
@abc.abstractproperty
|
||||||
def current(self):
|
def current(self):
|
||||||
"""Return the current state of the subnet.
|
"""Return the subnet in its current configuration.
|
||||||
|
|
||||||
Return the current state of the subnet, as defined by
|
Return the subnet, as defined by NeutronPluginBaseV2.
|
||||||
NeutronPluginBaseV2.create_subnet and all extensions in the
|
create_subnet and all extensions in the ml2 plugin, with
|
||||||
ml2 plugin.
|
all its properties 'current' at the time the context was
|
||||||
|
established.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abc.abstractproperty
|
@abc.abstractproperty
|
||||||
def original(self):
|
def original(self):
|
||||||
"""Return the original state of the subnet.
|
"""Return the subnet in its original configuration.
|
||||||
|
|
||||||
Return the original state of the subnet, prior to a call to
|
Return the subnet, with all its properties set to their
|
||||||
update_subnet. Method is only valid within calls to
|
original values prior to a call to update_subnet. Method is
|
||||||
update_subnet_precommit and update_subnet_postcommit.
|
only valid within calls to update_subnet_precommit and
|
||||||
|
update_subnet_postcommit.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -216,21 +220,37 @@ class PortContext(object):
|
|||||||
|
|
||||||
@abc.abstractproperty
|
@abc.abstractproperty
|
||||||
def current(self):
|
def current(self):
|
||||||
"""Return the current state of the port.
|
"""Return the port in its current configuration.
|
||||||
|
|
||||||
Return the current state of the port, as defined by
|
Return the port, as defined by NeutronPluginBaseV2.
|
||||||
NeutronPluginBaseV2.create_port and all extensions in the ml2
|
create_port and all extensions in the ml2 plugin, with
|
||||||
plugin.
|
all its properties 'current' at the time the context was
|
||||||
|
established.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abc.abstractproperty
|
@abc.abstractproperty
|
||||||
def original(self):
|
def original(self):
|
||||||
"""Return the original state of the port.
|
"""Return the port in its original configuration.
|
||||||
|
|
||||||
Return the original state of the port, prior to a call to
|
Return the port, with all its properties set to their
|
||||||
update_port. Method is only valid within calls to
|
original values prior to a call to update_port. Method is
|
||||||
update_port_precommit and update_port_postcommit.
|
only valid within calls to update_port_precommit and
|
||||||
|
update_port_postcommit.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abc.abstractproperty
|
||||||
|
def status(self):
|
||||||
|
"""Return the status of the current port."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abc.abstractproperty
|
||||||
|
def original_status(self):
|
||||||
|
"""Return the status of the original port.
|
||||||
|
|
||||||
|
The method is only valid within calls to update_port_precommit and
|
||||||
|
update_port_postcommit.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -254,6 +274,20 @@ class PortContext(object):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@abc.abstractproperty
|
||||||
|
def host(self):
|
||||||
|
"""Return the host associated with the 'current' port."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abc.abstractproperty
|
||||||
|
def original_host(self):
|
||||||
|
"""Return the host associated with the 'original' port.
|
||||||
|
|
||||||
|
Method is only valid within calls to update_port_precommit
|
||||||
|
and update_port_postcommit.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
@abc.abstractproperty
|
@abc.abstractproperty
|
||||||
def bound_driver(self):
|
def bound_driver(self):
|
||||||
"""Return the currently bound mechanism driver name."""
|
"""Return the currently bound mechanism driver name."""
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from neutron.extensions import portbindings
|
||||||
from neutron.openstack.common import jsonutils
|
from neutron.openstack.common import jsonutils
|
||||||
from neutron.plugins.ml2 import db
|
from neutron.plugins.ml2 import db
|
||||||
from neutron.plugins.ml2 import driver_api as api
|
from neutron.plugins.ml2 import driver_api as api
|
||||||
@ -93,6 +94,14 @@ class PortContext(MechanismDriverContext, api.PortContext):
|
|||||||
def original(self):
|
def original(self):
|
||||||
return self._original_port
|
return self._original_port
|
||||||
|
|
||||||
|
@property
|
||||||
|
def status(self):
|
||||||
|
return self._port['status']
|
||||||
|
|
||||||
|
@property
|
||||||
|
def original_status(self):
|
||||||
|
return self._original_port['status']
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def network(self):
|
def network(self):
|
||||||
return self._network_context
|
return self._network_context
|
||||||
@ -112,6 +121,14 @@ class PortContext(MechanismDriverContext, api.PortContext):
|
|||||||
if segment[api.ID] == self._original_bound_segment_id:
|
if segment[api.ID] == self._original_bound_segment_id:
|
||||||
return segment
|
return segment
|
||||||
|
|
||||||
|
@property
|
||||||
|
def host(self):
|
||||||
|
return self._port.get(portbindings.HOST_ID)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def original_host(self):
|
||||||
|
return self._original_port.get(portbindings.HOST_ID)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bound_driver(self):
|
def bound_driver(self):
|
||||||
return self._binding.driver
|
return self._binding.driver
|
||||||
|
@ -19,7 +19,6 @@ import jsonrpclib
|
|||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
|
|
||||||
from neutron.common import constants as n_const
|
from neutron.common import constants as n_const
|
||||||
from neutron.extensions import portbindings
|
|
||||||
from neutron.openstack.common import log as logging
|
from neutron.openstack.common import log as logging
|
||||||
from neutron.plugins.ml2.common import exceptions as ml2_exc
|
from neutron.plugins.ml2.common import exceptions as ml2_exc
|
||||||
from neutron.plugins.ml2 import driver_api
|
from neutron.plugins.ml2 import driver_api
|
||||||
@ -801,7 +800,7 @@ class AristaDriver(driver_api.MechanismDriver):
|
|||||||
port = context.current
|
port = context.current
|
||||||
device_id = port['device_id']
|
device_id = port['device_id']
|
||||||
device_owner = port['device_owner']
|
device_owner = port['device_owner']
|
||||||
host = port[portbindings.HOST_ID]
|
host = context.host
|
||||||
|
|
||||||
# device_id and device_owner are set on VM boot
|
# device_id and device_owner are set on VM boot
|
||||||
is_vm_boot = device_id and device_owner
|
is_vm_boot = device_id and device_owner
|
||||||
@ -822,7 +821,7 @@ class AristaDriver(driver_api.MechanismDriver):
|
|||||||
port = context.current
|
port = context.current
|
||||||
device_id = port['device_id']
|
device_id = port['device_id']
|
||||||
device_owner = port['device_owner']
|
device_owner = port['device_owner']
|
||||||
host = port[portbindings.HOST_ID]
|
host = context.host
|
||||||
|
|
||||||
# device_id and device_owner are set on VM boot
|
# device_id and device_owner are set on VM boot
|
||||||
is_vm_boot = device_id and device_owner
|
is_vm_boot = device_id and device_owner
|
||||||
@ -885,7 +884,7 @@ class AristaDriver(driver_api.MechanismDriver):
|
|||||||
|
|
||||||
device_id = port['device_id']
|
device_id = port['device_id']
|
||||||
device_owner = port['device_owner']
|
device_owner = port['device_owner']
|
||||||
host = port[portbindings.HOST_ID]
|
host = context.host
|
||||||
is_vm_boot = device_id and device_owner
|
is_vm_boot = device_id and device_owner
|
||||||
|
|
||||||
if host and is_vm_boot:
|
if host and is_vm_boot:
|
||||||
@ -926,7 +925,7 @@ class AristaDriver(driver_api.MechanismDriver):
|
|||||||
"""Delete information about a VM and host from the DB."""
|
"""Delete information about a VM and host from the DB."""
|
||||||
port = context.current
|
port = context.current
|
||||||
|
|
||||||
host_id = port[portbindings.HOST_ID]
|
host_id = context.host
|
||||||
device_id = port['device_id']
|
device_id = port['device_id']
|
||||||
tenant_id = port['tenant_id']
|
tenant_id = port['tenant_id']
|
||||||
network_id = port['network_id']
|
network_id = port['network_id']
|
||||||
@ -947,7 +946,7 @@ class AristaDriver(driver_api.MechanismDriver):
|
|||||||
"""
|
"""
|
||||||
port = context.current
|
port = context.current
|
||||||
device_id = port['device_id']
|
device_id = port['device_id']
|
||||||
host = port[portbindings.HOST_ID]
|
host = context.host
|
||||||
port_id = port['id']
|
port_id = port['id']
|
||||||
network_id = port['network_id']
|
network_id = port['network_id']
|
||||||
tenant_id = port['tenant_id']
|
tenant_id = port['tenant_id']
|
||||||
|
@ -93,7 +93,7 @@ class APICMechanismDriver(api.MechanismDriver):
|
|||||||
# Not a compute port, return
|
# Not a compute port, return
|
||||||
return
|
return
|
||||||
|
|
||||||
host = port.get(portbindings.HOST_ID)
|
host = context.host
|
||||||
# Check host that the dhcp agent is running on
|
# Check host that the dhcp agent is running on
|
||||||
filters = {'device_owner': 'network:dhcp',
|
filters = {'device_owner': 'network:dhcp',
|
||||||
'network_id': network}
|
'network_id': network}
|
||||||
|
@ -155,8 +155,7 @@ class CiscoNexusMechanismDriver(api.MechanismDriver):
|
|||||||
|
|
||||||
def _is_vm_migration(self, context):
|
def _is_vm_migration(self, context):
|
||||||
if not context.bound_segment and context.original_bound_segment:
|
if not context.bound_segment and context.original_bound_segment:
|
||||||
return (context.current.get(portbindings.HOST_ID) !=
|
return context.host != context.original_host
|
||||||
context.original.get(portbindings.HOST_ID))
|
|
||||||
|
|
||||||
def _port_action(self, port, segment, func):
|
def _port_action(self, port, segment, func):
|
||||||
"""Verify configuration and then process event."""
|
"""Verify configuration and then process event."""
|
||||||
|
@ -48,7 +48,8 @@ class L2populationMechanismDriver(api.MechanismDriver,
|
|||||||
ip['ip_address']] for ip in port['fixed_ips']]
|
ip['ip_address']] for ip in port['fixed_ips']]
|
||||||
|
|
||||||
def delete_port_postcommit(self, context):
|
def delete_port_postcommit(self, context):
|
||||||
fanout_msg = self._update_port_down(context, context.current)
|
fanout_msg = self._update_port_down(
|
||||||
|
context, context.current, context.host)
|
||||||
if fanout_msg:
|
if fanout_msg:
|
||||||
self.L2populationAgentNotify.remove_fdb_entries(
|
self.L2populationAgentNotify.remove_fdb_entries(
|
||||||
self.rpc_ctx, fanout_msg)
|
self.rpc_ctx, fanout_msg)
|
||||||
@ -67,7 +68,8 @@ class L2populationMechanismDriver(api.MechanismDriver,
|
|||||||
def _fixed_ips_changed(self, context, orig, port, diff_ips):
|
def _fixed_ips_changed(self, context, orig, port, diff_ips):
|
||||||
orig_ips, port_ips = diff_ips
|
orig_ips, port_ips = diff_ips
|
||||||
|
|
||||||
port_infos = self._get_port_infos(context, orig)
|
port_infos = self._get_port_infos(
|
||||||
|
context, orig, context.original_host)
|
||||||
if not port_infos:
|
if not port_infos:
|
||||||
return
|
return
|
||||||
agent, agent_ip, segment, port_fdb_entries = port_infos
|
agent, agent_ip, segment, port_fdb_entries = port_infos
|
||||||
@ -96,30 +98,34 @@ class L2populationMechanismDriver(api.MechanismDriver,
|
|||||||
diff_ips = self._get_diff_ips(orig, port)
|
diff_ips = self._get_diff_ips(orig, port)
|
||||||
if diff_ips:
|
if diff_ips:
|
||||||
self._fixed_ips_changed(context, orig, port, diff_ips)
|
self._fixed_ips_changed(context, orig, port, diff_ips)
|
||||||
if (port['binding:host_id'] != orig['binding:host_id']
|
if (context.host != context.original_host
|
||||||
and port['status'] == const.PORT_STATUS_ACTIVE
|
and context.status == const.PORT_STATUS_ACTIVE
|
||||||
and not self.migrated_ports.get(orig['id'])):
|
and not self.migrated_ports.get(orig['id'])):
|
||||||
# The port has been migrated. We have to store the original
|
# The port has been migrated. We have to store the original
|
||||||
# binding to send appropriate fdb once the port will be set
|
# binding to send appropriate fdb once the port will be set
|
||||||
# on the destination host
|
# on the destination host
|
||||||
self.migrated_ports[orig['id']] = orig
|
self.migrated_ports[orig['id']] = (
|
||||||
elif port['status'] != orig['status']:
|
(orig, context.original_host))
|
||||||
if port['status'] == const.PORT_STATUS_ACTIVE:
|
elif context.status != context.original_status:
|
||||||
|
if context.status == const.PORT_STATUS_ACTIVE:
|
||||||
self._update_port_up(context)
|
self._update_port_up(context)
|
||||||
elif port['status'] == const.PORT_STATUS_DOWN:
|
elif context.status == const.PORT_STATUS_DOWN:
|
||||||
fdb_entries = self._update_port_down(context, port)
|
fdb_entries = self._update_port_down(
|
||||||
|
context, port, context.host)
|
||||||
self.L2populationAgentNotify.remove_fdb_entries(
|
self.L2populationAgentNotify.remove_fdb_entries(
|
||||||
self.rpc_ctx, fdb_entries)
|
self.rpc_ctx, fdb_entries)
|
||||||
elif port['status'] == const.PORT_STATUS_BUILD:
|
elif context.status == const.PORT_STATUS_BUILD:
|
||||||
orig = self.migrated_ports.pop(port['id'], None)
|
orig = self.migrated_ports.pop(port['id'], None)
|
||||||
if orig:
|
if orig:
|
||||||
# this port has been migrated : remove its entries from fdb
|
original_port = orig[0]
|
||||||
fdb_entries = self._update_port_down(context, orig)
|
original_host = orig[1]
|
||||||
|
# this port has been migrated: remove its entries from fdb
|
||||||
|
fdb_entries = self._update_port_down(
|
||||||
|
context, original_port, original_host)
|
||||||
self.L2populationAgentNotify.remove_fdb_entries(
|
self.L2populationAgentNotify.remove_fdb_entries(
|
||||||
self.rpc_ctx, fdb_entries)
|
self.rpc_ctx, fdb_entries)
|
||||||
|
|
||||||
def _get_port_infos(self, context, port):
|
def _get_port_infos(self, context, port, agent_host):
|
||||||
agent_host = port['binding:host_id']
|
|
||||||
if not agent_host:
|
if not agent_host:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -150,14 +156,14 @@ class L2populationMechanismDriver(api.MechanismDriver,
|
|||||||
return agent, agent_ip, segment, fdb_entries
|
return agent, agent_ip, segment, fdb_entries
|
||||||
|
|
||||||
def _update_port_up(self, context):
|
def _update_port_up(self, context):
|
||||||
port_context = context.current
|
port = context.current
|
||||||
port_infos = self._get_port_infos(context, port_context)
|
agent_host = context.host
|
||||||
|
port_infos = self._get_port_infos(context, port, agent_host)
|
||||||
if not port_infos:
|
if not port_infos:
|
||||||
return
|
return
|
||||||
agent, agent_ip, segment, port_fdb_entries = port_infos
|
agent, agent_ip, segment, port_fdb_entries = port_infos
|
||||||
|
|
||||||
agent_host = port_context['binding:host_id']
|
network_id = port['network_id']
|
||||||
network_id = port_context['network_id']
|
|
||||||
|
|
||||||
session = db_api.get_session()
|
session = db_api.get_session()
|
||||||
agent_active_ports = self.get_agent_network_active_port_count(
|
agent_active_ports = self.get_agent_network_active_port_count(
|
||||||
@ -209,14 +215,13 @@ class L2populationMechanismDriver(api.MechanismDriver,
|
|||||||
self.L2populationAgentNotify.add_fdb_entries(self.rpc_ctx,
|
self.L2populationAgentNotify.add_fdb_entries(self.rpc_ctx,
|
||||||
other_fdb_entries)
|
other_fdb_entries)
|
||||||
|
|
||||||
def _update_port_down(self, context, port_context):
|
def _update_port_down(self, context, port, agent_host):
|
||||||
port_infos = self._get_port_infos(context, port_context)
|
port_infos = self._get_port_infos(context, port, agent_host)
|
||||||
if not port_infos:
|
if not port_infos:
|
||||||
return
|
return
|
||||||
agent, agent_ip, segment, port_fdb_entries = port_infos
|
agent, agent_ip, segment, port_fdb_entries = port_infos
|
||||||
|
|
||||||
agent_host = port_context['binding:host_id']
|
network_id = port['network_id']
|
||||||
network_id = port_context['network_id']
|
|
||||||
|
|
||||||
session = db_api.get_session()
|
session = db_api.get_session()
|
||||||
agent_active_ports = self.get_agent_network_active_port_count(
|
agent_active_ports = self.get_agent_network_active_port_count(
|
||||||
|
@ -59,6 +59,14 @@ class FakePortContext(api.PortContext):
|
|||||||
def original(self):
|
def original(self):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def status(self):
|
||||||
|
return 'DOWN'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def original_status(self):
|
||||||
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def network(self):
|
def network(self):
|
||||||
return self._network_context
|
return self._network_context
|
||||||
@ -74,6 +82,14 @@ class FakePortContext(api.PortContext):
|
|||||||
def original_bound_segment(self):
|
def original_bound_segment(self):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def host(self):
|
||||||
|
return ''
|
||||||
|
|
||||||
|
@property
|
||||||
|
def original_host(self):
|
||||||
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bound_driver(self):
|
def bound_driver(self):
|
||||||
return None
|
return None
|
||||||
|
@ -18,6 +18,7 @@ from oslo.config import cfg
|
|||||||
|
|
||||||
from neutron.common import constants as n_const
|
from neutron.common import constants as n_const
|
||||||
import neutron.db.api as ndb
|
import neutron.db.api as ndb
|
||||||
|
from neutron.extensions import portbindings
|
||||||
from neutron.plugins.ml2.drivers.arista import db
|
from neutron.plugins.ml2.drivers.arista import db
|
||||||
from neutron.plugins.ml2.drivers.arista import exceptions as arista_exc
|
from neutron.plugins.ml2.drivers.arista import exceptions as arista_exc
|
||||||
from neutron.plugins.ml2.drivers.arista import mechanism_arista as arista
|
from neutron.plugins.ml2.drivers.arista import mechanism_arista as arista
|
||||||
@ -723,3 +724,11 @@ class FakePortContext(object):
|
|||||||
@property
|
@property
|
||||||
def network(self):
|
def network(self):
|
||||||
return self._network_context
|
return self._network_context
|
||||||
|
|
||||||
|
@property
|
||||||
|
def host(self):
|
||||||
|
return self._port.get(portbindings.HOST_ID)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def original_host(self):
|
||||||
|
return self._original_port.get(portbindings.HOST_ID)
|
||||||
|
@ -19,6 +19,7 @@ import mock
|
|||||||
|
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
|
|
||||||
|
from neutron.extensions import portbindings
|
||||||
from neutron.plugins.ml2.drivers.cisco.apic import mechanism_apic as md
|
from neutron.plugins.ml2.drivers.cisco.apic import mechanism_apic as md
|
||||||
from neutron.plugins.ml2.drivers import type_vlan # noqa
|
from neutron.plugins.ml2.drivers import type_vlan # noqa
|
||||||
from neutron.tests import base
|
from neutron.tests import base
|
||||||
@ -224,3 +225,11 @@ class FakePortContext(object):
|
|||||||
|
|
||||||
def set_binding(self, segment_id, vif_type, cap_port_filter):
|
def set_binding(self, segment_id, vif_type, cap_port_filter):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def host(self):
|
||||||
|
return self._port.get(portbindings.HOST_ID)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def original_host(self):
|
||||||
|
return self._original_port.get(portbindings.HOST_ID)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user