diff --git a/neutron/db/migration/migrate_to_ml2.py b/neutron/db/migration/migrate_to_ml2.py index 9c854582f..97a187015 100755 --- a/neutron/db/migration/migrate_to_ml2.py +++ b/neutron/db/migration/migrate_to_ml2.py @@ -75,9 +75,10 @@ OPENVSWITCH = 'openvswitch' # Releases ICEHOUSE = 'icehouse' +JUNO = 'juno' -SUPPORTED_SCHEMA_VERSIONS = [ICEHOUSE] +SUPPORTED_SCHEMA_VERSIONS = [ICEHOUSE, JUNO] def check_db_schema_version(engine, metadata): @@ -115,7 +116,7 @@ def interpret_vlan_id(vlan_id): return (p_const.TYPE_VLAN, vlan_id) -class BaseMigrateToMl2_Icehouse(object): +class BaseMigrateToMl2(object): def __init__(self, vif_type, driver_type, segment_table_name, vlan_allocation_table_name, old_tables): @@ -210,6 +211,13 @@ class BaseMigrateToMl2_Icehouse(object): ml2_port_bindings = metadata.tables['ml2_port_bindings'] engine.execute(ml2_port_bindings.insert(), ml2_bindings) + +class BaseMigrateToMl2_IcehouseMixin(object): + """A mixin to ensure ml2 database schema state for Icehouse. + + This classes the missing tables for Icehouse schema revisions. In Juno, + the schema state has been healed, so we do not need to run these. + """ def drop_old_tables(self, engine, save_tables=False): if save_tables: return @@ -351,10 +359,10 @@ class BaseMigrateToMl2_Icehouse(object): ) -class MigrateLinuxBridgeToMl2_Icehouse(BaseMigrateToMl2_Icehouse): +class MigrateLinuxBridgeToMl2_Juno(BaseMigrateToMl2): def __init__(self): - super(MigrateLinuxBridgeToMl2_Icehouse, self).__init__( + super(MigrateLinuxBridgeToMl2_Juno, self).__init__( vif_type=portbindings.VIF_TYPE_BRIDGE, driver_type=LINUXBRIDGE, segment_table_name='network_bindings', @@ -362,7 +370,7 @@ class MigrateLinuxBridgeToMl2_Icehouse(BaseMigrateToMl2_Icehouse): old_tables=['portbindingports']) def migrate_segment_dict(self, binding): - super(MigrateLinuxBridgeToMl2_Icehouse, self).migrate_segment_dict( + super(MigrateLinuxBridgeToMl2_Juno, self).migrate_segment_dict( binding) vlan_id = binding.pop('vlan_id') network_type, segmentation_id = interpret_vlan_id(vlan_id) @@ -370,10 +378,10 @@ class MigrateLinuxBridgeToMl2_Icehouse(BaseMigrateToMl2_Icehouse): binding['segmentation_id'] = segmentation_id -class MigrateOpenvswitchToMl2_Icehouse(BaseMigrateToMl2_Icehouse): +class MigrateOpenvswitchToMl2_Juno(BaseMigrateToMl2): def __init__(self): - super(MigrateOpenvswitchToMl2_Icehouse, self).__init__( + super(MigrateOpenvswitchToMl2_Juno, self).__init__( vif_type=portbindings.VIF_TYPE_OVS, driver_type=OPENVSWITCH, segment_table_name='ovs_network_bindings', @@ -415,11 +423,25 @@ class MigrateOpenvswitchToMl2_Icehouse(BaseMigrateToMl2_Icehouse): raise ValueError(_('Unknown tunnel type: %s') % tunnel_type) +class MigrateLinuxBridgeToMl2_Icehouse(MigrateLinuxBridgeToMl2_Juno, + BaseMigrateToMl2_IcehouseMixin): + pass + + +class MigrateOpenvswitchToMl2_Icehouse(MigrateOpenvswitchToMl2_Juno, + BaseMigrateToMl2_IcehouseMixin): + pass + + migrate_map = { ICEHOUSE: { OPENVSWITCH: MigrateOpenvswitchToMl2_Icehouse, LINUXBRIDGE: MigrateLinuxBridgeToMl2_Icehouse, }, + JUNO: { + OPENVSWITCH: MigrateOpenvswitchToMl2_Juno, + LINUXBRIDGE: MigrateLinuxBridgeToMl2_Juno, + }, } @@ -436,7 +458,7 @@ def main(): OPENVSWITCH) parser.add_argument('--vxlan-udp-port', default=None, type=int, help=_('The UDP port to use for VXLAN tunnels.')) - parser.add_argument('--release', default=ICEHOUSE, choices=[ICEHOUSE]) + parser.add_argument('--release', default=JUNO, choices=[ICEHOUSE, JUNO]) parser.add_argument('--save-tables', default=False, action='store_true', help=_("Retain the old plugin's tables")) #TODO(marun) Provide a verbose option diff --git a/neutron/plugins/linuxbridge/README b/neutron/plugins/linuxbridge/README index 9f7f5d7c5..89eb5ece6 100644 --- a/neutron/plugins/linuxbridge/README +++ b/neutron/plugins/linuxbridge/README @@ -1,128 +1,7 @@ # -- Background -The Neutron Linux Bridge plugin is a plugin that allows you to manage -connectivity between VMs on hosts that are capable of running a Linux Bridge. - -The Neutron Linux Bridge plugin consists of three components: - -1) The plugin itself: The plugin uses a database backend (mysql for - now) to store configuration and mappings that are used by the - agent. The mysql server runs on a central server (often the same - host as nova itself). - -2) The neutron service host which will be running neutron. This can - be run on the server running nova. - -3) An agent which runs on the host and communicates with the host operating - system. The agent gathers the configuration and mappings from - the mysql database running on the neutron host. - -The sections below describe how to configure and run the neutron -service with the Linux Bridge plugin. - -# -- Python library dependencies - - Make sure you have the following package(s) installed on neutron server - host as well as any hosts which run the agent: - bridge-utils - python-mysqldb - sqlite3 - -# -- Nova configuration (controller node) - -1) Ensure that the neutron network manager is configured in the - nova.conf on the node that will be running nova-network. - -network_manager=nova.network.neutron.manager.NeutronManager - -# -- Nova configuration (compute node(s)) - -1) Configure the vif driver, and libvirt/vif type - -connection_type=libvirt -libvirt_type=qemu -libvirt_vif_type=ethernet -libvirt_vif_driver=nova.virt.libvirt.vif.NeutronLinuxBridgeVIFDriver -linuxnet_interface_driver=nova.network.linux_net.NeutronLinuxBridgeInterfaceDriver - -2) If you want a DHCP server to be run for the VMs to acquire IPs, - add the following flag to your nova.conf file: - -neutron_use_dhcp=true - -(Note: For more details on how to work with Neutron using Nova, i.e. how to create networks and such, - please refer to the top level Neutron README which points to the relevant documentation.) - -# -- Neutron configuration - -Make the Linux Bridge plugin the current neutron plugin - -- edit neutron.conf and change the core_plugin - -core_plugin = neutron.plugins.linuxbridge.lb_neutron_plugin.LinuxBridgePluginV2 - -# -- Database config. - -(Note: The plugin ships with a default SQLite in-memory database configuration, - and can be used to run tests without performing the suggested DB config below.) - -The Linux Bridge neutron plugin requires access to a mysql database in order -to store configuration and mappings that will be used by the agent. Here is -how to set up the database on the host that you will be running the neutron -service on. - -MySQL should be installed on the host, and all plugins and clients -must be configured with access to the database. - -To prep mysql, run: - -$ mysql -u root -p -e "create database neutron_linux_bridge" - -# log in to mysql service -$ mysql -u root -p -# The Linux Bridge Neutron agent running on each compute node must be able to -# make a mysql connection back to the main database server. -mysql> GRANT USAGE ON *.* to root@'yourremotehost' IDENTIFIED BY 'newpassword'; -# force update of authorization changes -mysql> FLUSH PRIVILEGES; - -(Note: If the remote connection fails to MySQL, you might need to add the IP address, - and/or fully-qualified hostname, and/or unqualified hostname in the above GRANT sql - command. Also, you might need to specify "ALL" instead of "USAGE".) - -# -- Plugin configuration - -- Edit the configuration file: - etc/neutron/plugins/linuxbridge/linuxbridge_conf.ini - Make sure it matches your mysql configuration. This file must be updated - with the addresses and credentials to access the database. - - Note: debug and logging information should be updated in etc/neutron.conf - - Note: When running the tests, set the connection type to sqlite, and when - actually running the server set it to mysql. At any given time, only one - of these should be active in the conf file (you can comment out the other). - -- On the neutron server, network_vlan_ranges must be configured in - linuxbridge_conf.ini to specify the names of the physical networks - managed by the linuxbridge plugin, along with the ranges of VLAN IDs - available on each physical network for allocation to virtual - networks. An entry of the form - "::" specifies a VLAN range on - the named physical network. An entry of the form - "" specifies a named network without making a - range of VLANs available for allocation. Networks specified using - either form are available for adminstrators to create provider flat - networks and provider VLANs. Multiple VLAN ranges can be specified - for the same physical network. - - The following example linuxbridge_conf.ini entry shows three - physical networks that can be used to create provider networks, with - ranges of VLANs available for allocation on two of them: - - [VLANS] - network_vlan_ranges = physnet1:1000:2999,physnet1:3000:3999,physnet2,physnet3:1:4094 - +The Neutron Linux Bridge plugin has removed from the tree in Juno. You must +migrate to ML2 using the script in: neutron/db/migration/migrate_to_ml2.py # -- Agent configuration diff --git a/neutron/plugins/linuxbridge/db/l2network_db_v2.py b/neutron/plugins/linuxbridge/db/l2network_db_v2.py deleted file mode 100644 index 416bd2f59..000000000 --- a/neutron/plugins/linuxbridge/db/l2network_db_v2.py +++ /dev/null @@ -1,238 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from six import moves -from sqlalchemy.orm import exc - -from neutron.common import exceptions as n_exc -import neutron.db.api as db -from neutron.db import models_v2 -from neutron.db import securitygroups_db as sg_db -from neutron import manager -from neutron.openstack.common import log as logging -from neutron.plugins.linuxbridge.common import config # noqa -from neutron.plugins.linuxbridge.common import constants -from neutron.plugins.linuxbridge.db import l2network_models_v2 - -LOG = logging.getLogger(__name__) - - -def sync_network_states(network_vlan_ranges): - """Synchronize network_states table with current configured VLAN ranges.""" - - session = db.get_session() - with session.begin(): - # get existing allocations for all physical networks - allocations = dict() - states = (session.query(l2network_models_v2.NetworkState). - all()) - for state in states: - if state.physical_network not in allocations: - allocations[state.physical_network] = set() - allocations[state.physical_network].add(state) - - # process vlan ranges for each configured physical network - for physical_network, vlan_ranges in network_vlan_ranges.iteritems(): - # determine current configured allocatable vlans for this - # physical network - vlan_ids = set() - for vlan_range in vlan_ranges: - vlan_ids |= set(moves.xrange(vlan_range[0], vlan_range[1] + 1)) - - # remove from table unallocated vlans not currently allocatable - if physical_network in allocations: - for state in allocations[physical_network]: - try: - # see if vlan is allocatable - vlan_ids.remove(state.vlan_id) - except KeyError: - # it's not allocatable, so check if its allocated - if not state.allocated: - # it's not, so remove it from table - LOG.debug(_("Removing vlan %(vlan_id)s on " - "physical network %(physical_network)s" - " from pool"), - {'vlan_id': state.vlan_id, - 'physical_network': physical_network}) - session.delete(state) - del allocations[physical_network] - - # add missing allocatable vlans to table - for vlan_id in sorted(vlan_ids): - state = l2network_models_v2.NetworkState(physical_network, - vlan_id) - session.add(state) - - # remove from table unallocated vlans for any unconfigured physical - # networks - for states in allocations.itervalues(): - for state in states: - if not state.allocated: - LOG.debug(_("Removing vlan %(vlan_id)s on physical " - "network %(physical_network)s" - " from pool"), - {'vlan_id': state.vlan_id, - 'physical_network': state.physical_network}) - session.delete(state) - - -def get_network_state(physical_network, vlan_id): - """Get state of specified network.""" - - session = db.get_session() - try: - state = (session.query(l2network_models_v2.NetworkState). - filter_by(physical_network=physical_network, - vlan_id=vlan_id). - one()) - return state - except exc.NoResultFound: - return None - - -def reserve_network(session): - with session.begin(subtransactions=True): - state = (session.query(l2network_models_v2.NetworkState). - filter_by(allocated=False). - with_lockmode('update'). - first()) - if not state: - raise n_exc.NoNetworkAvailable() - LOG.debug(_("Reserving vlan %(vlan_id)s on physical network " - "%(physical_network)s from pool"), - {'vlan_id': state.vlan_id, - 'physical_network': state.physical_network}) - state.allocated = True - return (state.physical_network, state.vlan_id) - - -def reserve_specific_network(session, physical_network, vlan_id): - with session.begin(subtransactions=True): - try: - state = (session.query(l2network_models_v2.NetworkState). - filter_by(physical_network=physical_network, - vlan_id=vlan_id). - with_lockmode('update'). - one()) - if state.allocated: - if vlan_id == constants.FLAT_VLAN_ID: - raise n_exc.FlatNetworkInUse( - physical_network=physical_network) - else: - raise n_exc.VlanIdInUse(vlan_id=vlan_id, - physical_network=physical_network) - LOG.debug(_("Reserving specific vlan %(vlan_id)s on physical " - "network %(physical_network)s from pool"), - {'vlan_id': vlan_id, - 'physical_network': physical_network}) - state.allocated = True - except exc.NoResultFound: - LOG.debug(_("Reserving specific vlan %(vlan_id)s on physical " - "network %(physical_network)s outside pool"), - {'vlan_id': vlan_id, - 'physical_network': physical_network}) - state = l2network_models_v2.NetworkState(physical_network, vlan_id) - state.allocated = True - session.add(state) - - -def release_network(session, physical_network, vlan_id, network_vlan_ranges): - with session.begin(subtransactions=True): - try: - state = (session.query(l2network_models_v2.NetworkState). - filter_by(physical_network=physical_network, - vlan_id=vlan_id). - with_lockmode('update'). - one()) - state.allocated = False - inside = False - for vlan_range in network_vlan_ranges.get(physical_network, []): - if vlan_id >= vlan_range[0] and vlan_id <= vlan_range[1]: - inside = True - break - if inside: - LOG.debug(_("Releasing vlan %(vlan_id)s on physical network " - "%(physical_network)s to pool"), - {'vlan_id': vlan_id, - 'physical_network': physical_network}) - else: - LOG.debug(_("Releasing vlan %(vlan_id)s on physical network " - "%(physical_network)s outside pool"), - {'vlan_id': vlan_id, - 'physical_network': physical_network}) - session.delete(state) - except exc.NoResultFound: - LOG.warning(_("vlan_id %(vlan_id)s on physical network " - "%(physical_network)s not found"), - {'vlan_id': vlan_id, - 'physical_network': physical_network}) - - -def add_network_binding(session, network_id, physical_network, vlan_id): - with session.begin(subtransactions=True): - binding = l2network_models_v2.NetworkBinding(network_id, - physical_network, vlan_id) - session.add(binding) - - -def get_network_binding(session, network_id): - try: - binding = (session.query(l2network_models_v2.NetworkBinding). - filter_by(network_id=network_id). - one()) - return binding - except exc.NoResultFound: - return - - -def get_port_from_device(device): - """Get port from database.""" - LOG.debug(_("get_port_from_device() called")) - session = db.get_session() - sg_binding_port = sg_db.SecurityGroupPortBinding.port_id - - query = session.query(models_v2.Port, - sg_db.SecurityGroupPortBinding.security_group_id) - query = query.outerjoin(sg_db.SecurityGroupPortBinding, - models_v2.Port.id == sg_binding_port) - query = query.filter(models_v2.Port.id.startswith(device)) - port_and_sgs = query.all() - if not port_and_sgs: - return - port = port_and_sgs[0][0] - plugin = manager.NeutronManager.get_plugin() - port_dict = plugin._make_port_dict(port) - port_dict['security_groups'] = [] - for port_in_db, sg_id in port_and_sgs: - if sg_id: - port_dict['security_groups'].append(sg_id) - port_dict['security_group_rules'] = [] - port_dict['security_group_source_groups'] = [] - port_dict['fixed_ips'] = [ip['ip_address'] - for ip in port['fixed_ips']] - return port_dict - - -def set_port_status(port_id, status): - """Set the port status.""" - LOG.debug(_("set_port_status as %s called"), status) - session = db.get_session() - try: - port = session.query(models_v2.Port).filter_by(id=port_id).one() - port['status'] = status - session.merge(port) - session.flush() - except exc.NoResultFound: - raise n_exc.PortNotFound(port_id=port_id) diff --git a/neutron/plugins/linuxbridge/lb_neutron_plugin.py b/neutron/plugins/linuxbridge/lb_neutron_plugin.py deleted file mode 100644 index a692bbcfb..000000000 --- a/neutron/plugins/linuxbridge/lb_neutron_plugin.py +++ /dev/null @@ -1,544 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import sys - -from oslo.config import cfg - -from neutron.agent import securitygroups_rpc as sg_rpc -from neutron.api.rpc.agentnotifiers import dhcp_rpc_agent_api -from neutron.api.rpc.agentnotifiers import l3_rpc_agent_api -from neutron.api.rpc.handlers import dhcp_rpc -from neutron.api.rpc.handlers import l3_rpc -from neutron.api.rpc.handlers import securitygroups_rpc -from neutron.api.v2 import attributes -from neutron.common import constants as q_const -from neutron.common import exceptions as n_exc -from neutron.common import rpc as n_rpc -from neutron.common import topics -from neutron.common import utils -from neutron.db import agents_db -from neutron.db import agentschedulers_db -from neutron.db import api as db_api -from neutron.db import db_base_plugin_v2 -from neutron.db import external_net_db -from neutron.db import extraroute_db -from neutron.db import l3_agentschedulers_db -from neutron.db import l3_gwmode_db -from neutron.db import portbindings_db -from neutron.db import quota_db # noqa -from neutron.db import securitygroups_rpc_base as sg_db_rpc -from neutron.extensions import portbindings -from neutron.extensions import providernet as provider -from neutron import manager -from neutron.openstack.common import importutils -from neutron.openstack.common import log as logging -from neutron.plugins.common import constants as svc_constants -from neutron.plugins.common import utils as plugin_utils -from neutron.plugins.linuxbridge.common import constants -from neutron.plugins.linuxbridge.db import l2network_db_v2 as db - - -LOG = logging.getLogger(__name__) - - -class LinuxBridgeRpcCallbacks(n_rpc.RpcCallback): - - # Device names start with "tap" - # history - # 1.1 Support Security Group RPC - # 1.2 Support get_devices_details_list - RPC_API_VERSION = '1.2' - - def get_device_details(self, rpc_context, **kwargs): - """Agent requests device details.""" - agent_id = kwargs.get('agent_id') - device = kwargs.get('device') - LOG.debug(_("Device %(device)s details requested from %(agent_id)s"), - {'device': device, 'agent_id': agent_id}) - plugin = manager.NeutronManager.get_plugin() - port = plugin.get_port_from_device(device) - if port: - binding = db.get_network_binding(db_api.get_session(), - port['network_id']) - (network_type, - segmentation_id) = constants.interpret_vlan_id(binding.vlan_id) - entry = {'device': device, - 'network_type': network_type, - 'physical_network': binding.physical_network, - 'segmentation_id': segmentation_id, - 'network_id': port['network_id'], - 'port_id': port['id'], - 'admin_state_up': port['admin_state_up']} - if cfg.CONF.AGENT.rpc_support_old_agents: - entry['vlan_id'] = binding.vlan_id - new_status = (q_const.PORT_STATUS_ACTIVE if port['admin_state_up'] - else q_const.PORT_STATUS_DOWN) - if port['status'] != new_status: - db.set_port_status(port['id'], new_status) - else: - entry = {'device': device} - LOG.debug(_("%s can not be found in database"), device) - return entry - - def get_devices_details_list(self, rpc_context, **kwargs): - return [ - self.get_device_details( - rpc_context, - device=device, - **kwargs - ) - for device in kwargs.pop('devices', []) - ] - - def update_device_down(self, rpc_context, **kwargs): - """Device no longer exists on agent.""" - # TODO(garyk) - live migration and port status - agent_id = kwargs.get('agent_id') - device = kwargs.get('device') - host = kwargs.get('host') - LOG.debug(_("Device %(device)s no longer exists on %(agent_id)s"), - {'device': device, 'agent_id': agent_id}) - plugin = manager.NeutronManager.get_plugin() - port = plugin.get_port_from_device(device) - if port: - entry = {'device': device, - 'exists': True} - if (host and not - plugin.get_port_host(rpc_context, port['id']) == host): - LOG.debug(_("Device %(device)s not bound to the" - " agent host %(host)s"), - {'device': device, 'host': host}) - elif port['status'] != q_const.PORT_STATUS_DOWN: - # Set port status to DOWN - db.set_port_status(port['id'], q_const.PORT_STATUS_DOWN) - else: - entry = {'device': device, - 'exists': False} - LOG.debug(_("%s can not be found in database"), device) - return entry - - def update_device_up(self, rpc_context, **kwargs): - """Device is up on agent.""" - agent_id = kwargs.get('agent_id') - device = kwargs.get('device') - host = kwargs.get('host') - LOG.debug(_("Device %(device)s up on %(agent_id)s"), - {'device': device, 'agent_id': agent_id}) - plugin = manager.NeutronManager.get_plugin() - port = plugin.get_port_from_device(device) - if port: - if (host and - not plugin.get_port_host(rpc_context, port['id']) == host): - LOG.debug(_("Device %(device)s not bound to the" - " agent host %(host)s"), - {'device': device, 'host': host}) - return - elif port['status'] != q_const.PORT_STATUS_ACTIVE: - db.set_port_status(port['id'], - q_const.PORT_STATUS_ACTIVE) - else: - LOG.debug(_("%s can not be found in database"), device) - - -class AgentNotifierApi(n_rpc.RpcProxy, - sg_rpc.SecurityGroupAgentRpcApiMixin): - '''Agent side of the linux bridge rpc API. - - API version history: - 1.0 - Initial version. - 1.1 - Added get_active_networks_info, create_dhcp_port, - and update_dhcp_port methods. - - - ''' - - BASE_RPC_API_VERSION = '1.1' - - def __init__(self, topic): - super(AgentNotifierApi, self).__init__( - topic=topic, default_version=self.BASE_RPC_API_VERSION) - self.topic = topic - self.topic_network_delete = topics.get_topic_name(topic, - topics.NETWORK, - topics.DELETE) - self.topic_port_update = topics.get_topic_name(topic, - topics.PORT, - topics.UPDATE) - - def network_delete(self, context, network_id): - self.fanout_cast(context, - self.make_msg('network_delete', - network_id=network_id), - topic=self.topic_network_delete) - - def port_update(self, context, port, physical_network, vlan_id): - network_type, segmentation_id = constants.interpret_vlan_id(vlan_id) - kwargs = {'port': port, - 'network_type': network_type, - 'physical_network': physical_network, - 'segmentation_id': segmentation_id} - if cfg.CONF.AGENT.rpc_support_old_agents: - kwargs['vlan_id'] = vlan_id - msg = self.make_msg('port_update', **kwargs) - self.fanout_cast(context, msg, - topic=self.topic_port_update) - - -class LinuxBridgePluginV2(db_base_plugin_v2.NeutronDbPluginV2, - external_net_db.External_net_db_mixin, - extraroute_db.ExtraRoute_db_mixin, - l3_gwmode_db.L3_NAT_db_mixin, - sg_db_rpc.SecurityGroupServerRpcMixin, - l3_agentschedulers_db.L3AgentSchedulerDbMixin, - agentschedulers_db.DhcpAgentSchedulerDbMixin, - portbindings_db.PortBindingMixin): - """Implement the Neutron abstractions using Linux bridging. - - A new VLAN is created for each network. An agent is relied upon - to perform the actual Linux bridge configuration on each host. - - The provider extension is also supported. As discussed in - https://bugs.launchpad.net/neutron/+bug/1023156, this class could - be simplified, and filtering on extended attributes could be - handled, by adding support for extended attributes to the - NeutronDbPluginV2 base class. When that occurs, this class should - be updated to take advantage of it. - - The port binding extension enables an external application relay - information to and from the plugin. - """ - - # This attribute specifies whether the plugin supports or not - # bulk/pagination/sorting operations. Name mangling is used in - # order to ensure it is qualified by class - __native_bulk_support = True - __native_pagination_support = True - __native_sorting_support = True - - _supported_extension_aliases = ["provider", "external-net", "router", - "ext-gw-mode", "binding", "quotas", - "security-group", "agent", "extraroute", - "l3_agent_scheduler", - "dhcp_agent_scheduler"] - - @property - def supported_extension_aliases(self): - if not hasattr(self, '_aliases'): - aliases = self._supported_extension_aliases[:] - sg_rpc.disable_security_group_extension_by_config(aliases) - self._aliases = aliases - return self._aliases - - def __init__(self): - super(LinuxBridgePluginV2, self).__init__() - self.base_binding_dict = { - portbindings.VIF_TYPE: portbindings.VIF_TYPE_BRIDGE, - portbindings.VIF_DETAILS: { - # TODO(rkukura): Replace with new VIF security details - portbindings.CAP_PORT_FILTER: - 'security-group' in self.supported_extension_aliases}} - self._parse_network_vlan_ranges() - db.sync_network_states(self.network_vlan_ranges) - self.tenant_network_type = cfg.CONF.VLANS.tenant_network_type - if self.tenant_network_type not in [svc_constants.TYPE_LOCAL, - svc_constants.TYPE_VLAN, - svc_constants.TYPE_NONE]: - LOG.error(_("Invalid tenant_network_type: %s. " - "Service terminated!"), - self.tenant_network_type) - sys.exit(1) - self._setup_rpc() - self.network_scheduler = importutils.import_object( - cfg.CONF.network_scheduler_driver - ) - self.router_scheduler = importutils.import_object( - cfg.CONF.router_scheduler_driver - ) - LOG.debug(_("Linux Bridge Plugin initialization complete")) - - def _setup_rpc(self): - # RPC support - self.service_topics = {svc_constants.CORE: topics.PLUGIN, - svc_constants.L3_ROUTER_NAT: topics.L3PLUGIN} - self.conn = n_rpc.create_connection(new=True) - self.endpoints = [LinuxBridgeRpcCallbacks(), - securitygroups_rpc.SecurityGroupServerRpcCallback(), - dhcp_rpc.DhcpRpcCallback(), - l3_rpc.L3RpcCallback(), - agents_db.AgentExtRpcCallback()] - for svc_topic in self.service_topics.values(): - self.conn.create_consumer(svc_topic, self.endpoints, fanout=False) - # Consume from all consumers in threads - self.conn.consume_in_threads() - self.notifier = AgentNotifierApi(topics.AGENT) - self.agent_notifiers[q_const.AGENT_TYPE_DHCP] = ( - dhcp_rpc_agent_api.DhcpAgentNotifyAPI() - ) - self.agent_notifiers[q_const.AGENT_TYPE_L3] = ( - l3_rpc_agent_api.L3AgentNotifyAPI() - ) - - def _parse_network_vlan_ranges(self): - try: - self.network_vlan_ranges = plugin_utils.parse_network_vlan_ranges( - cfg.CONF.VLANS.network_vlan_ranges) - except Exception as ex: - LOG.error(_("%s. Agent terminated!"), ex) - sys.exit(1) - LOG.info(_("Network VLAN ranges: %s"), self.network_vlan_ranges) - - def _add_network_vlan_range(self, physical_network, vlan_min, vlan_max): - self._add_network(physical_network) - self.network_vlan_ranges[physical_network].append((vlan_min, vlan_max)) - - def _add_network(self, physical_network): - if physical_network not in self.network_vlan_ranges: - self.network_vlan_ranges[physical_network] = [] - - def _extend_network_dict_provider(self, context, network): - binding = db.get_network_binding(context.session, network['id']) - if binding.vlan_id == constants.FLAT_VLAN_ID: - network[provider.NETWORK_TYPE] = svc_constants.TYPE_FLAT - network[provider.PHYSICAL_NETWORK] = binding.physical_network - network[provider.SEGMENTATION_ID] = None - elif binding.vlan_id == constants.LOCAL_VLAN_ID: - network[provider.NETWORK_TYPE] = svc_constants.TYPE_LOCAL - network[provider.PHYSICAL_NETWORK] = None - network[provider.SEGMENTATION_ID] = None - else: - network[provider.NETWORK_TYPE] = svc_constants.TYPE_VLAN - network[provider.PHYSICAL_NETWORK] = binding.physical_network - network[provider.SEGMENTATION_ID] = binding.vlan_id - - def _process_provider_create(self, context, attrs): - network_type = attrs.get(provider.NETWORK_TYPE) - physical_network = attrs.get(provider.PHYSICAL_NETWORK) - segmentation_id = attrs.get(provider.SEGMENTATION_ID) - - network_type_set = attributes.is_attr_set(network_type) - physical_network_set = attributes.is_attr_set(physical_network) - segmentation_id_set = attributes.is_attr_set(segmentation_id) - - if not (network_type_set or physical_network_set or - segmentation_id_set): - return (None, None, None) - - if not network_type_set: - msg = _("provider:network_type required") - raise n_exc.InvalidInput(error_message=msg) - elif network_type == svc_constants.TYPE_FLAT: - if segmentation_id_set: - msg = _("provider:segmentation_id specified for flat network") - raise n_exc.InvalidInput(error_message=msg) - else: - segmentation_id = constants.FLAT_VLAN_ID - elif network_type == svc_constants.TYPE_VLAN: - if not segmentation_id_set: - msg = _("provider:segmentation_id required") - raise n_exc.InvalidInput(error_message=msg) - if not utils.is_valid_vlan_tag(segmentation_id): - msg = (_("provider:segmentation_id out of range " - "(%(min_id)s through %(max_id)s)") % - {'min_id': q_const.MIN_VLAN_TAG, - 'max_id': q_const.MAX_VLAN_TAG}) - raise n_exc.InvalidInput(error_message=msg) - elif network_type == svc_constants.TYPE_LOCAL: - if physical_network_set: - msg = _("provider:physical_network specified for local " - "network") - raise n_exc.InvalidInput(error_message=msg) - else: - physical_network = None - if segmentation_id_set: - msg = _("provider:segmentation_id specified for local " - "network") - raise n_exc.InvalidInput(error_message=msg) - else: - segmentation_id = constants.LOCAL_VLAN_ID - else: - msg = _("provider:network_type %s not supported") % network_type - raise n_exc.InvalidInput(error_message=msg) - - if network_type in [svc_constants.TYPE_VLAN, svc_constants.TYPE_FLAT]: - if physical_network_set: - if physical_network not in self.network_vlan_ranges: - msg = (_("Unknown provider:physical_network %s") % - physical_network) - raise n_exc.InvalidInput(error_message=msg) - elif 'default' in self.network_vlan_ranges: - physical_network = 'default' - else: - msg = _("provider:physical_network required") - raise n_exc.InvalidInput(error_message=msg) - - return (network_type, physical_network, segmentation_id) - - def create_network(self, context, network): - (network_type, physical_network, - vlan_id) = self._process_provider_create(context, - network['network']) - - session = context.session - with session.begin(subtransactions=True): - #set up default security groups - tenant_id = self._get_tenant_id_for_create( - context, network['network']) - self._ensure_default_security_group(context, tenant_id) - - if not network_type: - # tenant network - network_type = self.tenant_network_type - if network_type == svc_constants.TYPE_NONE: - raise n_exc.TenantNetworksDisabled() - elif network_type == svc_constants.TYPE_VLAN: - physical_network, vlan_id = db.reserve_network(session) - else: # TYPE_LOCAL - vlan_id = constants.LOCAL_VLAN_ID - else: - # provider network - if network_type in [svc_constants.TYPE_VLAN, - svc_constants.TYPE_FLAT]: - db.reserve_specific_network(session, physical_network, - vlan_id) - # no reservation needed for TYPE_LOCAL - net = super(LinuxBridgePluginV2, self).create_network(context, - network) - db.add_network_binding(session, net['id'], - physical_network, vlan_id) - self._process_l3_create(context, net, network['network']) - self._extend_network_dict_provider(context, net) - # note - exception will rollback entire transaction - return net - - def update_network(self, context, id, network): - provider._raise_if_updates_provider_attributes(network['network']) - - session = context.session - with session.begin(subtransactions=True): - net = super(LinuxBridgePluginV2, self).update_network(context, id, - network) - self._process_l3_update(context, net, network['network']) - self._extend_network_dict_provider(context, net) - return net - - def delete_network(self, context, id): - session = context.session - with session.begin(subtransactions=True): - binding = db.get_network_binding(session, id) - self._process_l3_delete(context, id) - super(LinuxBridgePluginV2, self).delete_network(context, id) - if binding.vlan_id != constants.LOCAL_VLAN_ID: - db.release_network(session, binding.physical_network, - binding.vlan_id, self.network_vlan_ranges) - # the network_binding record is deleted via cascade from - # the network record, so explicit removal is not necessary - self.notifier.network_delete(context, id) - - def get_network(self, context, id, fields=None): - session = context.session - with session.begin(subtransactions=True): - net = super(LinuxBridgePluginV2, self).get_network(context, - id, None) - self._extend_network_dict_provider(context, net) - return self._fields(net, fields) - - def get_networks(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, page_reverse=False): - session = context.session - with session.begin(subtransactions=True): - nets = super(LinuxBridgePluginV2, - self).get_networks(context, filters, None, sorts, - limit, marker, page_reverse) - for net in nets: - self._extend_network_dict_provider(context, net) - - return [self._fields(net, fields) for net in nets] - - def create_port(self, context, port): - session = context.session - port_data = port['port'] - with session.begin(subtransactions=True): - self._ensure_default_security_group_on_port(context, port) - sgids = self._get_security_groups_on_port(context, port) - # Set port status as 'DOWN'. This will be updated by agent - port['port']['status'] = q_const.PORT_STATUS_DOWN - - port = super(LinuxBridgePluginV2, - self).create_port(context, port) - self._process_portbindings_create_and_update(context, - port_data, - port) - self._process_port_create_security_group( - context, port, sgids) - self.notify_security_groups_member_updated(context, port) - return port - - def update_port(self, context, id, port): - original_port = self.get_port(context, id) - session = context.session - need_port_update_notify = False - - with session.begin(subtransactions=True): - updated_port = super(LinuxBridgePluginV2, self).update_port( - context, id, port) - self._process_portbindings_create_and_update(context, - port['port'], - updated_port) - need_port_update_notify = self.update_security_group_on_port( - context, id, port, original_port, updated_port) - - need_port_update_notify |= self.is_security_group_member_updated( - context, original_port, updated_port) - - if original_port['admin_state_up'] != updated_port['admin_state_up']: - need_port_update_notify = True - - if need_port_update_notify: - self._notify_port_updated(context, updated_port) - return updated_port - - def delete_port(self, context, id, l3_port_check=True): - - # if needed, check to see if this is a port owned by - # and l3-router. If so, we should prevent deletion. - if l3_port_check: - self.prevent_l3_port_deletion(context, id) - - session = context.session - with session.begin(subtransactions=True): - router_ids = self.disassociate_floatingips( - context, id, do_notify=False) - port = self.get_port(context, id) - self._delete_port_security_group_bindings(context, id) - super(LinuxBridgePluginV2, self).delete_port(context, id) - - # now that we've left db transaction, we are safe to notify - self.notify_routers_updated(context, router_ids) - self.notify_security_groups_member_updated(context, port) - - def _notify_port_updated(self, context, port): - binding = db.get_network_binding(context.session, - port['network_id']) - self.notifier.port_update(context, port, - binding.physical_network, - binding.vlan_id) - - @classmethod - def get_port_from_device(cls, device): - port = db.get_port_from_device(device[len(q_const.TAP_DEVICE_PREFIX):]) - if port: - port['device'] = device - return port diff --git a/neutron/tests/unit/linuxbridge/test_agent_scheduler.py b/neutron/tests/unit/linuxbridge/test_agent_scheduler.py deleted file mode 100644 index 397baaf5c..000000000 --- a/neutron/tests/unit/linuxbridge/test_agent_scheduler.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from neutron.tests.unit.linuxbridge import test_linuxbridge_plugin -from neutron.tests.unit.openvswitch import test_agent_scheduler - - -class LbAgentSchedulerTestCase( - test_agent_scheduler.OvsAgentSchedulerTestCase): - plugin_str = test_linuxbridge_plugin.PLUGIN_NAME - l3_plugin = None - - -class LbL3AgentNotifierTestCase( - test_agent_scheduler.OvsL3AgentNotifierTestCase): - plugin_str = test_linuxbridge_plugin.PLUGIN_NAME - l3_plugin = None - - -class LbDhcpAgentNotifierTestCase( - test_agent_scheduler.OvsDhcpAgentNotifierTestCase): - plugin_str = test_linuxbridge_plugin.PLUGIN_NAME diff --git a/neutron/tests/unit/linuxbridge/test_lb_db.py b/neutron/tests/unit/linuxbridge/test_lb_db.py deleted file mode 100644 index f43248210..000000000 --- a/neutron/tests/unit/linuxbridge/test_lb_db.py +++ /dev/null @@ -1,169 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from oslo.config import cfg -from six import moves -import testtools -from testtools import matchers - -from neutron.common import exceptions as n_exc -from neutron.db import api as db -from neutron.plugins.linuxbridge.db import l2network_db_v2 as lb_db -from neutron.tests.unit import test_db_plugin as test_plugin -from neutron.tests.unit import testlib_api - -PHYS_NET = 'physnet1' -PHYS_NET_2 = 'physnet2' -VLAN_MIN = 10 -VLAN_MAX = 19 -VLAN_RANGES = {PHYS_NET: [(VLAN_MIN, VLAN_MAX)]} -UPDATED_VLAN_RANGES = {PHYS_NET: [(VLAN_MIN + 5, VLAN_MAX + 5)], - PHYS_NET_2: [(VLAN_MIN + 20, VLAN_MAX + 20)]} - -PLUGIN_NAME = ('neutron.plugins.linuxbridge.' - 'lb_neutron_plugin.LinuxBridgePluginV2') - - -class NetworkStatesTest(testlib_api.SqlTestCase): - def setUp(self): - super(NetworkStatesTest, self).setUp() - lb_db.sync_network_states(VLAN_RANGES) - self.session = db.get_session() - - def test_sync_network_states(self): - self.assertIsNone(lb_db.get_network_state(PHYS_NET, - VLAN_MIN - 1)) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MIN).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MIN + 1).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MAX - 1).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MAX).allocated) - self.assertIsNone(lb_db.get_network_state(PHYS_NET, - VLAN_MAX + 1)) - - lb_db.sync_network_states(UPDATED_VLAN_RANGES) - - self.assertIsNone(lb_db.get_network_state(PHYS_NET, - VLAN_MIN + 5 - 1)) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MIN + 5).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MIN + 5 + 1).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MAX + 5 - 1).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MAX + 5).allocated) - self.assertIsNone(lb_db.get_network_state(PHYS_NET, - VLAN_MAX + 5 + 1)) - - self.assertIsNone(lb_db.get_network_state(PHYS_NET_2, - VLAN_MIN + 20 - 1)) - self.assertFalse(lb_db.get_network_state(PHYS_NET_2, - VLAN_MIN + 20).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET_2, - VLAN_MIN + 20 + 1).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET_2, - VLAN_MAX + 20 - 1).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET_2, - VLAN_MAX + 20).allocated) - self.assertIsNone(lb_db.get_network_state(PHYS_NET_2, - VLAN_MAX + 20 + 1)) - - lb_db.sync_network_states(VLAN_RANGES) - - self.assertIsNone(lb_db.get_network_state(PHYS_NET, - VLAN_MIN - 1)) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MIN).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MIN + 1).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MAX - 1).allocated) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - VLAN_MAX).allocated) - self.assertIsNone(lb_db.get_network_state(PHYS_NET, - VLAN_MAX + 1)) - - self.assertIsNone(lb_db.get_network_state(PHYS_NET_2, - VLAN_MIN + 20)) - self.assertIsNone(lb_db.get_network_state(PHYS_NET_2, - VLAN_MAX + 20)) - - def test_network_pool(self): - vlan_ids = set() - for x in moves.xrange(VLAN_MIN, VLAN_MAX + 1): - physical_network, vlan_id = lb_db.reserve_network(self.session) - self.assertEqual(physical_network, PHYS_NET) - self.assertThat(vlan_id, matchers.GreaterThan(VLAN_MIN - 1)) - self.assertThat(vlan_id, matchers.LessThan(VLAN_MAX + 1)) - vlan_ids.add(vlan_id) - - with testtools.ExpectedException(n_exc.NoNetworkAvailable): - physical_network, vlan_id = lb_db.reserve_network(self.session) - - for vlan_id in vlan_ids: - lb_db.release_network(self.session, PHYS_NET, vlan_id, VLAN_RANGES) - - def test_specific_network_inside_pool(self): - vlan_id = VLAN_MIN + 5 - self.assertFalse(lb_db.get_network_state(PHYS_NET, - vlan_id).allocated) - lb_db.reserve_specific_network(self.session, PHYS_NET, vlan_id) - self.assertTrue(lb_db.get_network_state(PHYS_NET, - vlan_id).allocated) - - with testtools.ExpectedException(n_exc.VlanIdInUse): - lb_db.reserve_specific_network(self.session, PHYS_NET, vlan_id) - - lb_db.release_network(self.session, PHYS_NET, vlan_id, VLAN_RANGES) - self.assertFalse(lb_db.get_network_state(PHYS_NET, - vlan_id).allocated) - - def test_specific_network_outside_pool(self): - vlan_id = VLAN_MAX + 5 - self.assertIsNone(lb_db.get_network_state(PHYS_NET, vlan_id)) - lb_db.reserve_specific_network(self.session, PHYS_NET, vlan_id) - self.assertTrue(lb_db.get_network_state(PHYS_NET, - vlan_id).allocated) - - with testtools.ExpectedException(n_exc.VlanIdInUse): - lb_db.reserve_specific_network(self.session, PHYS_NET, vlan_id) - - lb_db.release_network(self.session, PHYS_NET, vlan_id, VLAN_RANGES) - self.assertIsNone(lb_db.get_network_state(PHYS_NET, vlan_id)) - - -class NetworkBindingsTest(test_plugin.NeutronDbPluginV2TestCase): - def setUp(self): - cfg.CONF.set_override('network_vlan_ranges', ['physnet1:1000:2999'], - group='VLANS') - super(NetworkBindingsTest, self).setUp(plugin=PLUGIN_NAME) - self.session = db.get_session() - - def test_add_network_binding(self): - params = {'provider:network_type': 'vlan', - 'provider:physical_network': PHYS_NET, - 'provider:segmentation_id': 1234} - params['arg_list'] = tuple(params.keys()) - with self.network(**params) as network: - TEST_NETWORK_ID = network['network']['id'] - binding = lb_db.get_network_binding(self.session, TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.physical_network, PHYS_NET) - self.assertEqual(binding.vlan_id, 1234) diff --git a/neutron/tests/unit/linuxbridge/test_lb_security_group.py b/neutron/tests/unit/linuxbridge/test_lb_security_group.py deleted file mode 100644 index e930092db..000000000 --- a/neutron/tests/unit/linuxbridge/test_lb_security_group.py +++ /dev/null @@ -1,97 +0,0 @@ -# Copyright 2012, Nachi Ueno, NTT MCL, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import mock - -from neutron.api.v2 import attributes -from neutron.extensions import securitygroup as ext_sg -from neutron.plugins.linuxbridge.db import l2network_db_v2 as lb_db -from neutron.tests.unit import test_extension_security_group as test_sg -from neutron.tests.unit import test_security_groups_rpc as test_sg_rpc - - -PLUGIN_NAME = ('neutron.plugins.linuxbridge.' - 'lb_neutron_plugin.LinuxBridgePluginV2') -NOTIFIER = ('neutron.plugins.linuxbridge.' - 'lb_neutron_plugin.AgentNotifierApi') - - -class LinuxBridgeSecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase): - _plugin_name = PLUGIN_NAME - - def setUp(self, plugin=None): - test_sg_rpc.set_firewall_driver(test_sg_rpc.FIREWALL_IPTABLES_DRIVER) - notifier_p = mock.patch(NOTIFIER) - notifier_cls = notifier_p.start() - self.notifier = mock.Mock() - notifier_cls.return_value = self.notifier - self._attribute_map_bk_ = {} - for item in attributes.RESOURCE_ATTRIBUTE_MAP: - self._attribute_map_bk_[item] = (attributes. - RESOURCE_ATTRIBUTE_MAP[item]. - copy()) - super(LinuxBridgeSecurityGroupsTestCase, self).setUp(PLUGIN_NAME) - - def tearDown(self): - attributes.RESOURCE_ATTRIBUTE_MAP = self._attribute_map_bk_ - super(LinuxBridgeSecurityGroupsTestCase, self).tearDown() - - -class TestLinuxBridgeSecurityGroups(LinuxBridgeSecurityGroupsTestCase, - test_sg.TestSecurityGroups, - test_sg_rpc.SGNotificationTestMixin): - pass - - -class TestLinuxBridgeSecurityGroupsXML(TestLinuxBridgeSecurityGroups): - fmt = 'xml' - - -class TestLinuxBridgeSecurityGroupsDB(LinuxBridgeSecurityGroupsTestCase): - def test_security_group_get_port_from_device(self): - with self.network() as n: - with self.subnet(n): - with self.security_group() as sg: - security_group_id = sg['security_group']['id'] - res = self._create_port(self.fmt, n['network']['id']) - port = self.deserialize(self.fmt, res) - fixed_ips = port['port']['fixed_ips'] - data = {'port': {'fixed_ips': fixed_ips, - 'name': port['port']['name'], - ext_sg.SECURITYGROUPS: - [security_group_id]}} - - req = self.new_update_request('ports', data, - port['port']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.api)) - port_id = res['port']['id'] - device_id = port_id[:8] - port_dict = lb_db.get_port_from_device(device_id) - self.assertEqual(port_id, port_dict['id']) - self.assertEqual([security_group_id], - port_dict[ext_sg.SECURITYGROUPS]) - self.assertEqual([], port_dict['security_group_rules']) - self.assertEqual([fixed_ips[0]['ip_address']], - port_dict['fixed_ips']) - self._delete('ports', port['port']['id']) - - def test_security_group_get_port_from_device_with_no_port(self): - port_dict = lb_db.get_port_from_device('bad_device_id') - self.assertIsNone(port_dict) - - -class TestLinuxBridgeSecurityGroupsDBXML(TestLinuxBridgeSecurityGroupsDB): - fmt = 'xml' diff --git a/neutron/tests/unit/linuxbridge/test_linuxbridge_plugin.py b/neutron/tests/unit/linuxbridge/test_linuxbridge_plugin.py deleted file mode 100644 index 0572336af..000000000 --- a/neutron/tests/unit/linuxbridge/test_linuxbridge_plugin.py +++ /dev/null @@ -1,127 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import mock -from oslo.config import cfg - -from neutron.common import constants as q_const -from neutron.extensions import portbindings -from neutron import manager -from neutron.plugins.linuxbridge import lb_neutron_plugin -from neutron.tests.unit import _test_extension_portbindings as test_bindings -from neutron.tests.unit import test_db_plugin as test_plugin -from neutron.tests.unit import test_security_groups_rpc as test_sg_rpc - -PLUGIN_NAME = ('neutron.plugins.linuxbridge.' - 'lb_neutron_plugin.LinuxBridgePluginV2') - - -class LinuxBridgePluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): - _plugin_name = PLUGIN_NAME - - def setUp(self): - super(LinuxBridgePluginV2TestCase, self).setUp(PLUGIN_NAME) - self.port_create_status = 'DOWN' - - -class TestLinuxBridgeBasicGet(test_plugin.TestBasicGet, - LinuxBridgePluginV2TestCase): - pass - - -class TestLinuxBridgeV2HTTPResponse(test_plugin.TestV2HTTPResponse, - LinuxBridgePluginV2TestCase): - pass - - -class TestLinuxBridgeNetworksV2(test_plugin.TestNetworksV2, - LinuxBridgePluginV2TestCase): - pass - - -class TestLinuxBridgePortsV2(test_plugin.TestPortsV2, - LinuxBridgePluginV2TestCase): - - def test_update_port_status_build(self): - with self.port() as port: - self.assertEqual(port['port']['status'], 'DOWN') - self.assertEqual(self.port_create_status, 'DOWN') - - -class TestLinuxBridgePortBinding(LinuxBridgePluginV2TestCase, - test_bindings.PortBindingsTestCase): - VIF_TYPE = portbindings.VIF_TYPE_BRIDGE - HAS_PORT_FILTER = True - ENABLE_SG = True - FIREWALL_DRIVER = test_sg_rpc.FIREWALL_IPTABLES_DRIVER - - def setUp(self): - test_sg_rpc.set_firewall_driver(self.FIREWALL_DRIVER) - cfg.CONF.set_override( - 'enable_security_group', self.ENABLE_SG, - group='SECURITYGROUP') - super(TestLinuxBridgePortBinding, self).setUp() - - -class TestLinuxBridgePortBindingNoSG(TestLinuxBridgePortBinding): - HAS_PORT_FILTER = False - ENABLE_SG = False - FIREWALL_DRIVER = test_sg_rpc.FIREWALL_NOOP_DRIVER - - -class TestLinuxBridgePortBindingHost( - LinuxBridgePluginV2TestCase, - test_bindings.PortBindingsHostTestCaseMixin): - pass - - -class TestLinuxBridgePluginRpcCallbacks(test_plugin.NeutronDbPluginV2TestCase): - def setUp(self): - super(TestLinuxBridgePluginRpcCallbacks, self).setUp(PLUGIN_NAME) - self.callbacks = lb_neutron_plugin.LinuxBridgeRpcCallbacks() - - def test_update_device_down(self): - with mock.patch.object(manager.NeutronManager, "get_plugin") as gp: - plugin = gp.return_value - plugin.get_port_from_device.return_value = None - self.assertEqual( - self.callbacks.update_device_down("fake_context", - agent_id="123", - device="device", - host="host"), - {'device': 'device', 'exists': False} - ) - plugin.get_port_from_device.return_value = { - 'id': 'fakeid', - 'status': q_const.PORT_STATUS_ACTIVE} - self.assertEqual( - self.callbacks.update_device_down("fake_context", - agent_id="123", - device="device", - host="host"), - {'device': 'device', 'exists': True} - ) - - def test_update_device_up(self): - with mock.patch.object(manager.NeutronManager, "get_plugin") as gp: - plugin = gp.return_value - plugin.get_port_from_device.return_value = { - 'id': 'fakeid', - 'status': q_const.PORT_STATUS_ACTIVE} - self.callbacks.update_device_up("fake_context", - agent_id="123", - device="device", - host="host") - plugin.get_port_from_device.assert_called_once_with('device') diff --git a/neutron/tests/unit/linuxbridge/test_rpcapi.py b/neutron/tests/unit/linuxbridge/test_rpcapi.py deleted file mode 100644 index ee2972f67..000000000 --- a/neutron/tests/unit/linuxbridge/test_rpcapi.py +++ /dev/null @@ -1,143 +0,0 @@ -# Copyright 2012, Red Hat, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Unit Tests for linuxbridge rpc -""" - -import fixtures -from oslo.config import cfg - -from neutron.agent import rpc as agent_rpc -from neutron.common import topics -from neutron.openstack.common import context -from neutron.plugins.linuxbridge import lb_neutron_plugin as plb -from neutron.tests import base - - -class rpcApiTestCase(base.BaseTestCase): - def _test_lb_api(self, rpcapi, topic, method, rpc_method, - expected_msg=None, **kwargs): - ctxt = context.RequestContext('fake_user', 'fake_project') - expected_retval = 'foo' if method == 'call' else None - expected_kwargs = {} - if topic: - expected_kwargs['topic'] = topic - if 'version' in kwargs: - expected_kwargs['version'] = kwargs.pop('version') - if not expected_msg: - expected_msg = rpcapi.make_msg(method, **kwargs) - if rpc_method == 'cast' and method == 'run_instance': - kwargs['call'] = False - - self.fake_args = None - self.fake_kwargs = None - - def _fake_rpc_method(*args, **kwargs): - self.fake_args = args - self.fake_kwargs = kwargs - if expected_retval: - return expected_retval - - self.useFixture(fixtures.MonkeyPatch( - 'neutron.common.rpc.RpcProxy.' + rpc_method, - _fake_rpc_method)) - - retval = getattr(rpcapi, method)(ctxt, **kwargs) - - self.assertEqual(expected_retval, retval) - expected_args = [ctxt, expected_msg] - - # skip the first argument which is 'self' - for arg, expected_arg in zip(self.fake_args[1:], expected_args): - self.assertEqual(expected_arg, arg) - self.assertEqual(expected_kwargs, self.fake_kwargs) - - def test_delete_network(self): - rpcapi = plb.AgentNotifierApi(topics.AGENT) - self._test_lb_api(rpcapi, - topics.get_topic_name(topics.AGENT, - topics.NETWORK, - topics.DELETE), - 'network_delete', rpc_method='fanout_cast', - network_id='fake_request_spec') - - def test_port_update(self): - cfg.CONF.set_override('rpc_support_old_agents', False, 'AGENT') - rpcapi = plb.AgentNotifierApi(topics.AGENT) - expected_msg = rpcapi.make_msg('port_update', - port='fake_port', - network_type='vlan', - physical_network='fake_net', - segmentation_id='fake_vlan_id') - self._test_lb_api(rpcapi, - topics.get_topic_name(topics.AGENT, - topics.PORT, - topics.UPDATE), - 'port_update', rpc_method='fanout_cast', - expected_msg=expected_msg, - port='fake_port', - physical_network='fake_net', - vlan_id='fake_vlan_id') - - def test_port_update_old_agent(self): - cfg.CONF.set_override('rpc_support_old_agents', True, 'AGENT') - rpcapi = plb.AgentNotifierApi(topics.AGENT) - expected_msg = rpcapi.make_msg('port_update', - port='fake_port', - network_type='vlan', - physical_network='fake_net', - segmentation_id='fake_vlan_id', - vlan_id='fake_vlan_id') - self._test_lb_api(rpcapi, - topics.get_topic_name(topics.AGENT, - topics.PORT, - topics.UPDATE), - 'port_update', rpc_method='fanout_cast', - expected_msg=expected_msg, - port='fake_port', - physical_network='fake_net', - vlan_id='fake_vlan_id') - - def test_device_details(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_lb_api(rpcapi, None, - 'get_device_details', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id', - host='fake_host') - - def test_devices_details_list(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_lb_api(rpcapi, None, - 'get_devices_details_list', rpc_method='call', - devices=['fake_device1', 'fake_device2'], - agent_id='fake_agent_id', host='fake_host', - version='1.3') - - def test_update_device_down(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_lb_api(rpcapi, None, - 'update_device_down', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id', - host='fake_host') - - def test_update_device_up(self): - rpcapi = agent_rpc.PluginApi(topics.PLUGIN) - self._test_lb_api(rpcapi, None, - 'update_device_up', rpc_method='call', - device='fake_device', - agent_id='fake_agent_id', - host='fake_host') diff --git a/neutron/tests/unit/test_quota_ext.py b/neutron/tests/unit/test_quota_ext.py index 262fb0441..ac46711a2 100644 --- a/neutron/tests/unit/test_quota_ext.py +++ b/neutron/tests/unit/test_quota_ext.py @@ -32,8 +32,7 @@ from neutron.tests.unit import test_api_v2 from neutron.tests.unit import testlib_api from neutron.tests.unit import testlib_plugin -TARGET_PLUGIN = ('neutron.plugins.linuxbridge.lb_neutron_plugin' - '.LinuxBridgePluginV2') +TARGET_PLUGIN = 'neutron.plugins.ml2.plugin.Ml2Plugin' _get_path = test_api_v2._get_path diff --git a/setup.cfg b/setup.cfg index ad30b0775..5793ad07c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -134,7 +134,6 @@ neutron.core_plugins = embrane = neutron.plugins.embrane.plugins.embrane_ml2_plugin:EmbraneMl2Plugin hyperv = neutron.plugins.hyperv.hyperv_neutron_plugin:HyperVNeutronPlugin ibm = neutron.plugins.ibm.sdnve_neutron_plugin:SdnvePluginV2 - linuxbridge = neutron.plugins.linuxbridge.lb_neutron_plugin:LinuxBridgePluginV2 midonet = neutron.plugins.midonet.plugin:MidonetPluginV2 ml2 = neutron.plugins.ml2.plugin:Ml2Plugin mlnx = neutron.plugins.mlnx.mlnx_plugin:MellanoxEswitchPlugin