Merge "Encapsulate some port properties in the PortContext"

This commit is contained in:
Jenkins 2014-07-25 18:27:58 +00:00 committed by Gerrit Code Review
commit 01f1508d59
9 changed files with 143 additions and 55 deletions

View File

@ -149,21 +149,23 @@ class NetworkContext(object):
@abc.abstractproperty
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
NeutronPluginBaseV2.create_network and all extensions in the
ml2 plugin.
Return the network, as defined by NeutronPluginBaseV2.
create_network and all extensions in the ml2 plugin, with
all its properties 'current' at the time the context was
established.
"""
pass
@abc.abstractproperty
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
update_network. Method is only valid within calls to
update_network_precommit and update_network_postcommit.
Return the network, with all its properties set to their
original values prior to a call to update_network. Method is
only valid within calls to update_network_precommit and
update_network_postcommit.
"""
pass
@ -185,21 +187,23 @@ class SubnetContext(object):
@abc.abstractproperty
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
NeutronPluginBaseV2.create_subnet and all extensions in the
ml2 plugin.
Return the subnet, as defined by NeutronPluginBaseV2.
create_subnet and all extensions in the ml2 plugin, with
all its properties 'current' at the time the context was
established.
"""
pass
@abc.abstractproperty
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
update_subnet. Method is only valid within calls to
update_subnet_precommit and update_subnet_postcommit.
Return the subnet, with all its properties set to their
original values prior to a call to update_subnet. Method is
only valid within calls to update_subnet_precommit and
update_subnet_postcommit.
"""
pass
@ -216,21 +220,37 @@ class PortContext(object):
@abc.abstractproperty
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
NeutronPluginBaseV2.create_port and all extensions in the ml2
plugin.
Return the port, as defined by NeutronPluginBaseV2.
create_port and all extensions in the ml2 plugin, with
all its properties 'current' at the time the context was
established.
"""
pass
@abc.abstractproperty
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
update_port. Method is only valid within calls to
update_port_precommit and update_port_postcommit.
Return the port, with all its properties set to their
original values prior to a call to update_port. Method is
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
@ -254,6 +274,20 @@ class PortContext(object):
"""
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
def bound_driver(self):
"""Return the currently bound mechanism driver name."""

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from neutron.extensions import portbindings
from neutron.openstack.common import jsonutils
from neutron.plugins.ml2 import db
from neutron.plugins.ml2 import driver_api as api
@ -93,6 +94,14 @@ class PortContext(MechanismDriverContext, api.PortContext):
def original(self):
return self._original_port
@property
def status(self):
return self._port['status']
@property
def original_status(self):
return self._original_port['status']
@property
def network(self):
return self._network_context
@ -112,6 +121,14 @@ class PortContext(MechanismDriverContext, api.PortContext):
if segment[api.ID] == self._original_bound_segment_id:
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
def bound_driver(self):
return self._binding.driver

View File

@ -19,7 +19,6 @@ import jsonrpclib
from oslo.config import cfg
from neutron.common import constants as n_const
from neutron.extensions import portbindings
from neutron.openstack.common import log as logging
from neutron.plugins.ml2.common import exceptions as ml2_exc
from neutron.plugins.ml2 import driver_api
@ -801,7 +800,7 @@ class AristaDriver(driver_api.MechanismDriver):
port = context.current
device_id = port['device_id']
device_owner = port['device_owner']
host = port[portbindings.HOST_ID]
host = context.host
# device_id and device_owner are set on VM boot
is_vm_boot = device_id and device_owner
@ -822,7 +821,7 @@ class AristaDriver(driver_api.MechanismDriver):
port = context.current
device_id = port['device_id']
device_owner = port['device_owner']
host = port[portbindings.HOST_ID]
host = context.host
# device_id and device_owner are set on VM boot
is_vm_boot = device_id and device_owner
@ -885,7 +884,7 @@ class AristaDriver(driver_api.MechanismDriver):
device_id = port['device_id']
device_owner = port['device_owner']
host = port[portbindings.HOST_ID]
host = context.host
is_vm_boot = device_id and device_owner
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."""
port = context.current
host_id = port[portbindings.HOST_ID]
host_id = context.host
device_id = port['device_id']
tenant_id = port['tenant_id']
network_id = port['network_id']
@ -947,7 +946,7 @@ class AristaDriver(driver_api.MechanismDriver):
"""
port = context.current
device_id = port['device_id']
host = port[portbindings.HOST_ID]
host = context.host
port_id = port['id']
network_id = port['network_id']
tenant_id = port['tenant_id']

View File

@ -93,7 +93,7 @@ class APICMechanismDriver(api.MechanismDriver):
# Not a compute port, return
return
host = port.get(portbindings.HOST_ID)
host = context.host
# Check host that the dhcp agent is running on
filters = {'device_owner': 'network:dhcp',
'network_id': network}

View File

@ -155,8 +155,7 @@ class CiscoNexusMechanismDriver(api.MechanismDriver):
def _is_vm_migration(self, context):
if not context.bound_segment and context.original_bound_segment:
return (context.current.get(portbindings.HOST_ID) !=
context.original.get(portbindings.HOST_ID))
return context.host != context.original_host
def _port_action(self, port, segment, func):
"""Verify configuration and then process event."""

View File

@ -48,7 +48,8 @@ class L2populationMechanismDriver(api.MechanismDriver,
ip['ip_address']] for ip in port['fixed_ips']]
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:
self.L2populationAgentNotify.remove_fdb_entries(
self.rpc_ctx, fanout_msg)
@ -67,7 +68,8 @@ class L2populationMechanismDriver(api.MechanismDriver,
def _fixed_ips_changed(self, context, orig, port, 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:
return
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)
if diff_ips:
self._fixed_ips_changed(context, orig, port, diff_ips)
if (port['binding:host_id'] != orig['binding:host_id']
and port['status'] == const.PORT_STATUS_ACTIVE
if (context.host != context.original_host
and context.status == const.PORT_STATUS_ACTIVE
and not self.migrated_ports.get(orig['id'])):
# The port has been migrated. We have to store the original
# binding to send appropriate fdb once the port will be set
# on the destination host
self.migrated_ports[orig['id']] = orig
elif port['status'] != orig['status']:
if port['status'] == const.PORT_STATUS_ACTIVE:
self.migrated_ports[orig['id']] = (
(orig, context.original_host))
elif context.status != context.original_status:
if context.status == const.PORT_STATUS_ACTIVE:
self._update_port_up(context)
elif port['status'] == const.PORT_STATUS_DOWN:
fdb_entries = self._update_port_down(context, port)
elif context.status == const.PORT_STATUS_DOWN:
fdb_entries = self._update_port_down(
context, port, context.host)
self.L2populationAgentNotify.remove_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)
if orig:
# this port has been migrated : remove its entries from fdb
fdb_entries = self._update_port_down(context, orig)
original_port = orig[0]
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.rpc_ctx, fdb_entries)
def _get_port_infos(self, context, port):
agent_host = port['binding:host_id']
def _get_port_infos(self, context, port, agent_host):
if not agent_host:
return
@ -150,14 +156,14 @@ class L2populationMechanismDriver(api.MechanismDriver,
return agent, agent_ip, segment, fdb_entries
def _update_port_up(self, context):
port_context = context.current
port_infos = self._get_port_infos(context, port_context)
port = context.current
agent_host = context.host
port_infos = self._get_port_infos(context, port, agent_host)
if not port_infos:
return
agent, agent_ip, segment, port_fdb_entries = port_infos
agent_host = port_context['binding:host_id']
network_id = port_context['network_id']
network_id = port['network_id']
session = db_api.get_session()
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,
other_fdb_entries)
def _update_port_down(self, context, port_context):
port_infos = self._get_port_infos(context, port_context)
def _update_port_down(self, context, port, agent_host):
port_infos = self._get_port_infos(context, port, agent_host)
if not port_infos:
return
agent, agent_ip, segment, port_fdb_entries = port_infos
agent_host = port_context['binding:host_id']
network_id = port_context['network_id']
network_id = port['network_id']
session = db_api.get_session()
agent_active_ports = self.get_agent_network_active_port_count(

View File

@ -59,6 +59,14 @@ class FakePortContext(api.PortContext):
def original(self):
return None
@property
def status(self):
return 'DOWN'
@property
def original_status(self):
return None
@property
def network(self):
return self._network_context
@ -74,6 +82,14 @@ class FakePortContext(api.PortContext):
def original_bound_segment(self):
return None
@property
def host(self):
return ''
@property
def original_host(self):
return None
@property
def bound_driver(self):
return None

View File

@ -18,6 +18,7 @@ from oslo.config import cfg
from neutron.common import constants as n_const
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 exceptions as arista_exc
from neutron.plugins.ml2.drivers.arista import mechanism_arista as arista
@ -723,3 +724,11 @@ class FakePortContext(object):
@property
def network(self):
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)

View File

@ -19,6 +19,7 @@ import mock
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 import type_vlan # noqa
from neutron.tests import base
@ -224,3 +225,11 @@ class FakePortContext(object):
def set_binding(self, segment_id, vif_type, cap_port_filter):
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)