diff --git a/neutron/db/portbindings_base.py b/neutron/db/portbindings_base.py new file mode 100644 index 00000000000..615b017b754 --- /dev/null +++ b/neutron/db/portbindings_base.py @@ -0,0 +1,43 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 UnitedStack 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. +# @author: Yong Sheng Gong, UnitedStack Inc. + +from neutron.api.v2 import attributes +from neutron.db import db_base_plugin_v2 + + +class PortBindingBaseMixin(object): + base_binding_dict = None + + def _process_portbindings_create_and_update(self, context, port_data, + port): + self.extend_port_dict_binding(port, None) + + def extend_port_dict_binding(self, port_res, port_db): + if self.base_binding_dict: + port_res.update(self.base_binding_dict) + + +def _extend_port_dict_binding(plugin, port_res, port_db): + if not isinstance(plugin, PortBindingBaseMixin): + return + plugin.extend_port_dict_binding(port_res, port_db) + + +def register_port_dict_function(): + db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + attributes.PORTS, [_extend_port_dict_binding]) diff --git a/neutron/db/portbindings_db.py b/neutron/db/portbindings_db.py index a551064648d..8340e0f0985 100644 --- a/neutron/db/portbindings_db.py +++ b/neutron/db/portbindings_db.py @@ -23,11 +23,8 @@ from neutron.api.v2 import attributes from neutron.db import db_base_plugin_v2 from neutron.db import model_base from neutron.db import models_v2 +from neutron.db import portbindings_base from neutron.extensions import portbindings -from neutron.openstack.common import log as logging - - -LOG = logging.getLogger(__name__) class PortBindingPort(model_base.BASEV2): @@ -42,7 +39,7 @@ class PortBindingPort(model_base.BASEV2): cascade='delete')) -class PortBindingMixin(object): +class PortBindingMixin(portbindings_base.PortBindingBaseMixin): extra_binding_dict = None def _port_model_hook(self, context, original_model, query): @@ -77,7 +74,7 @@ class PortBindingMixin(object): host = port_data.get(portbindings.HOST_ID) host_set = attributes.is_attr_set(host) if not host_set: - _extend_port_dict_binding_host(self, port, None) + self._extend_port_dict_binding_host(port, None) return with context.session.begin(subtransactions=True): bind_port = context.session.query( @@ -87,7 +84,7 @@ class PortBindingMixin(object): host=host)) else: bind_port.host = host - _extend_port_dict_binding_host(self, port, host) + self._extend_port_dict_binding_host(port, host) def get_port_host(self, context, port_id): with context.session.begin(subtransactions=True): @@ -95,21 +92,22 @@ class PortBindingMixin(object): PortBindingPort).filter_by(port_id=port_id).first() return bind_port and bind_port.host or None + def _extend_port_dict_binding_host(self, port_res, host): + super(PortBindingMixin, self).extend_port_dict_binding( + port_res, None) + port_res[portbindings.HOST_ID] = host -def _extend_port_dict_binding_host(plugin, port_res, host): - port_res[portbindings.HOST_ID] = host - if plugin.extra_binding_dict: - port_res.update(plugin.extra_binding_dict) - return port_res + def extend_port_dict_binding(self, port_res, port_db): + host = (port_db.portbinding and port_db.portbinding.host or None) + self._extend_port_dict_binding_host(port_res, host) def _extend_port_dict_binding(plugin, port_res, port_db): if not isinstance(plugin, PortBindingMixin): return - host = (port_db.portbinding and port_db.portbinding.host or None) - return _extend_port_dict_binding_host( - plugin, port_res, host) + plugin.extend_port_dict_binding(port_res, port_db) - # Register dict extend functions for ports + +# Register dict extend functions for ports db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( attributes.PORTS, [_extend_port_dict_binding]) diff --git a/neutron/plugins/brocade/NeutronPlugin.py b/neutron/plugins/brocade/NeutronPlugin.py index 2a676e918d6..1534a312cfd 100644 --- a/neutron/plugins/brocade/NeutronPlugin.py +++ b/neutron/plugins/brocade/NeutronPlugin.py @@ -41,6 +41,7 @@ from neutron.db import db_base_plugin_v2 from neutron.db import dhcp_rpc_base from neutron.db import extraroute_db from neutron.db import l3_rpc_base +from neutron.db import portbindings_base from neutron.db import securitygroups_rpc_base as sg_db_rpc from neutron.extensions import portbindings from neutron.extensions import securitygroup as ext_sg @@ -199,7 +200,8 @@ class BrocadePluginV2(db_base_plugin_v2.NeutronDbPluginV2, extraroute_db.ExtraRoute_db_mixin, sg_db_rpc.SecurityGroupServerRpcMixin, agentschedulers_db.L3AgentSchedulerDbMixin, - agentschedulers_db.DhcpAgentSchedulerDbMixin): + agentschedulers_db.DhcpAgentSchedulerDbMixin, + portbindings_base.PortBindingBaseMixin): """BrocadePluginV2 is a Neutron plugin. Provides L2 Virtual Network functionality using VDX. Upper @@ -220,6 +222,8 @@ class BrocadePluginV2(db_base_plugin_v2.NeutronDbPluginV2, self.physical_interface = (cfg.CONF.PHYSICAL_INTERFACE. physical_interface) + self.base_binding_dict = self._get_base_binding_dict() + portbindings_base.register_port_dict_function() db.configure_db() self.ctxt = context.get_admin_context() self.ctxt.session = db.get_session() @@ -359,6 +363,9 @@ class BrocadePluginV2(db_base_plugin_v2.NeutronDbPluginV2, neutron_port = super(BrocadePluginV2, self).create_port(context, port) + self._process_portbindings_create_and_update(context, + port['port'], + neutron_port) interface_mac = neutron_port['mac_address'] port_id = neutron_port['id'] @@ -384,7 +391,7 @@ class BrocadePluginV2(db_base_plugin_v2.NeutronDbPluginV2, vlan_id, tenant_id, admin_state_up) # apply any extensions - return self._extend_port_dict_binding(context, neutron_port) + return neutron_port def delete_port(self, context, port_id): with context.session.begin(subtransactions=True): @@ -408,10 +415,12 @@ class BrocadePluginV2(db_base_plugin_v2.NeutronDbPluginV2, port['port'], port['port'][ext_sg.SECURITYGROUPS]) port_updated = True - + port_data = port['port'] port = super(BrocadePluginV2, self).update_port( context, port_id, port) - + self._process_portbindings_create_and_update(context, + port_data, + port) if original_port['admin_state_up'] != port['admin_state_up']: port_updated = True @@ -425,27 +434,7 @@ class BrocadePluginV2(db_base_plugin_v2.NeutronDbPluginV2, if port_updated: self._notify_port_updated(context, port) - return self._extend_port_dict_binding(context, port) - - def get_port(self, context, port_id, fields=None): - with context.session.begin(subtransactions=True): - port = super(BrocadePluginV2, self).get_port( - context, port_id, fields) - self._extend_port_dict_binding(context, port) - - return self._fields(port, fields) - - def get_ports(self, context, filters=None, fields=None): - res_ports = [] - with context.session.begin(subtransactions=True): - ports = super(BrocadePluginV2, self).get_ports(context, - filters, - fields) - for port in ports: - self._extend_port_dict_binding(context, port) - res_ports.append(self._fields(port, fields)) - - return res_ports + return port def _notify_port_updated(self, context, port): port_id = port['id'] @@ -454,12 +443,13 @@ class BrocadePluginV2(db_base_plugin_v2.NeutronDbPluginV2, bport.physical_interface, bport.vlan_id) - def _extend_port_dict_binding(self, context, port): - port[portbindings.VIF_TYPE] = portbindings.VIF_TYPE_BRIDGE - port[portbindings.CAPABILITIES] = { - portbindings.CAP_PORT_FILTER: - 'security-group' in self.supported_extension_aliases} - return port + def _get_base_binding_dict(self): + binding = { + portbindings.VIF_TYPE: portbindings.VIF_TYPE_BRIDGE, + portbindings.CAPABILITIES: { + portbindings.CAP_PORT_FILTER: + 'security-group' in self.supported_extension_aliases}} + return binding def get_plugin_version(self): """Get version number of the plugin.""" diff --git a/neutron/plugins/hyperv/hyperv_neutron_plugin.py b/neutron/plugins/hyperv/hyperv_neutron_plugin.py index fcb77c98a10..5b8523704e7 100644 --- a/neutron/plugins/hyperv/hyperv_neutron_plugin.py +++ b/neutron/plugins/hyperv/hyperv_neutron_plugin.py @@ -23,6 +23,7 @@ from neutron.common import exceptions as q_exc from neutron.common import topics from neutron.db import db_base_plugin_v2 from neutron.db import l3_gwmode_db +from neutron.db import portbindings_base from neutron.db import quota_db # noqa from neutron.extensions import portbindings from neutron.extensions import providernet as provider @@ -141,7 +142,8 @@ class VlanNetworkProvider(BaseNetworkProvider): class HyperVNeutronPlugin(db_base_plugin_v2.NeutronDbPluginV2, - l3_gwmode_db.L3_NAT_db_mixin): + l3_gwmode_db.L3_NAT_db_mixin, + portbindings_base.PortBindingBaseMixin): # This attribute specifies whether the plugin supports or not # bulk operations. Name mangling is used in order to ensure it @@ -153,7 +155,9 @@ class HyperVNeutronPlugin(db_base_plugin_v2.NeutronDbPluginV2, def __init__(self, configfile=None): self._db = hyperv_db.HyperVPluginDB() self._db.initialize() - + self.base_binding_dict = { + portbindings.VIF_TYPE: portbindings.VIF_TYPE_HYPERV} + portbindings_base.register_port_dict_function() self._set_tenant_network_type() self._parse_network_vlan_ranges() @@ -287,29 +291,22 @@ class HyperVNeutronPlugin(db_base_plugin_v2.NeutronDbPluginV2, return [self._fields(net, fields) for net in nets] - def _extend_port_dict_binding(self, context, port): - port[portbindings.VIF_TYPE] = portbindings.VIF_TYPE_HYPERV - return port - def create_port(self, context, port): + port_data = port['port'] port = super(HyperVNeutronPlugin, self).create_port(context, port) - return self._extend_port_dict_binding(context, port) - - def get_port(self, context, id, fields=None): - port = super(HyperVNeutronPlugin, self).get_port(context, id, fields) - return self._fields(self._extend_port_dict_binding(context, port), - fields) - - def get_ports(self, context, filters=None, fields=None): - ports = super(HyperVNeutronPlugin, self).get_ports( - context, filters, fields) - return [self._fields(self._extend_port_dict_binding(context, port), - fields) for port in ports] + self._process_portbindings_create_and_update(context, + port_data, + port) + return port def update_port(self, context, id, port): original_port = super(HyperVNeutronPlugin, self).get_port( context, id) + port_data = port['port'] port = super(HyperVNeutronPlugin, self).update_port(context, id, port) + self._process_portbindings_create_and_update(context, + port_data, + port) if original_port['admin_state_up'] != port['admin_state_up']: binding = self._db.get_network_binding( None, port['network_id']) @@ -317,7 +314,7 @@ class HyperVNeutronPlugin(db_base_plugin_v2.NeutronDbPluginV2, binding.network_type, binding.segmentation_id, binding.physical_network) - return self._extend_port_dict_binding(context, port) + return port def delete_port(self, context, id, l3_port_check=True): # if needed, check to see if this is a port owned by diff --git a/neutron/plugins/linuxbridge/lb_neutron_plugin.py b/neutron/plugins/linuxbridge/lb_neutron_plugin.py index 367d5d45d23..f161f256d20 100644 --- a/neutron/plugins/linuxbridge/lb_neutron_plugin.py +++ b/neutron/plugins/linuxbridge/lb_neutron_plugin.py @@ -232,7 +232,7 @@ class LinuxBridgePluginV2(db_base_plugin_v2.NeutronDbPluginV2, return self._aliases def __init__(self): - self.extra_binding_dict = { + self.base_binding_dict = { portbindings.VIF_TYPE: portbindings.VIF_TYPE_BRIDGE, portbindings.CAPABILITIES: { portbindings.CAP_PORT_FILTER: diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index 891386481ec..468b9fbd666 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -170,7 +170,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, def _extend_port_dict_binding(self, context, port): # TODO(rkukura): Implement based on host_id, agents, and # MechanismDrivers. Also set CAPABILITIES. Use - # extra_binding_dict if applicable, or maybe a new hook so + # base_binding_dict if applicable, or maybe a new hook so # base handles field processing and get_port and get_ports # don't need to be overridden. port[portbindings.VIF_TYPE] = portbindings.VIF_TYPE_UNBOUND diff --git a/neutron/plugins/nec/nec_plugin.py b/neutron/plugins/nec/nec_plugin.py index 17c0e62a872..25d22aaf8db 100644 --- a/neutron/plugins/nec/nec_plugin.py +++ b/neutron/plugins/nec/nec_plugin.py @@ -30,6 +30,7 @@ from neutron.db import dhcp_rpc_base from neutron.db import extraroute_db from neutron.db import l3_gwmode_db from neutron.db import l3_rpc_base +from neutron.db import portbindings_base from neutron.db import quota_db # noqa from neutron.db import securitygroups_rpc_base as sg_db_rpc from neutron.extensions import portbindings @@ -68,7 +69,8 @@ class NECPluginV2(db_base_plugin_v2.NeutronDbPluginV2, sg_db_rpc.SecurityGroupServerRpcMixin, agentschedulers_db.L3AgentSchedulerDbMixin, agentschedulers_db.DhcpAgentSchedulerDbMixin, - packet_filter.PacketFilterMixin): + packet_filter.PacketFilterMixin, + portbindings_base.PortBindingBaseMixin): """NECPluginV2 controls an OpenFlow Controller. The Neutron NECPluginV2 maps L2 logical networks to L2 virtualized networks @@ -98,9 +100,11 @@ class NECPluginV2(db_base_plugin_v2.NeutronDbPluginV2, return self._aliases def __init__(self): + ndb.initialize() self.ofc = ofc_manager.OFCManager() - + self.base_binding_dict = self._get_base_binding_dict() + portbindings_base.register_port_dict_function() # Set the plugin default extension path # if no api_extensions_path is specified. if not config.CONF.api_extensions_path: @@ -347,27 +351,32 @@ class NECPluginV2(db_base_plugin_v2.NeutronDbPluginV2, reason = _("delete_ofc_tenant() failed due to %s") % exc LOG.warn(reason) - def _extend_port_dict_binding(self, context, port): - port[portbindings.VIF_TYPE] = portbindings.VIF_TYPE_OVS - port[portbindings.CAPABILITIES] = { - portbindings.CAP_PORT_FILTER: - 'security-group' in self.supported_extension_aliases} - return port + def _get_base_binding_dict(self): + binding = { + portbindings.VIF_TYPE: portbindings.VIF_TYPE_OVS, + portbindings.CAPABILITIES: { + portbindings.CAP_PORT_FILTER: + 'security-group' in self.supported_extension_aliases}} + return binding def create_port(self, context, port): """Create a new port entry on DB, then try to activate it.""" LOG.debug(_("NECPluginV2.create_port() called, port=%s ."), port) + port_data = port['port'] with context.session.begin(subtransactions=True): self._ensure_default_security_group_on_port(context, port) sgids = self._get_security_groups_on_port(context, port) port = super(NECPluginV2, 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) self._update_resource_status(context, "port", port['id'], OperationalStatus.BUILD) self.activate_port_if_ready(context, port) - return self._extend_port_dict_binding(context, port) + return port def update_port(self, context, id, port): """Update port, and handle packetfilters associated with the port. @@ -382,6 +391,9 @@ class NECPluginV2(db_base_plugin_v2.NeutronDbPluginV2, with context.session.begin(subtransactions=True): old_port = super(NECPluginV2, self).get_port(context, id) new_port = super(NECPluginV2, self).update_port(context, id, port) + self._process_portbindings_create_and_update(context, + port['port'], + new_port) need_port_update_notify = self.update_security_group_on_port( context, id, port, old_port, new_port) @@ -397,7 +409,7 @@ class NECPluginV2(db_base_plugin_v2.NeutronDbPluginV2, else: self.deactivate_port(context, old_port) - return self._extend_port_dict_binding(context, new_port) + return new_port def delete_port(self, context, id, l3_port_check=True): """Delete port and packet_filters associated with the port.""" @@ -426,21 +438,6 @@ class NECPluginV2(db_base_plugin_v2.NeutronDbPluginV2, super(NECPluginV2, self).delete_port(context, id) self.notify_security_groups_member_updated(context, port) - def get_port(self, context, id, fields=None): - with context.session.begin(subtransactions=True): - port = super(NECPluginV2, self).get_port(context, id, fields) - self._extend_port_dict_binding(context, port) - return self._fields(port, fields) - - def get_ports(self, context, filters=None, fields=None): - with context.session.begin(subtransactions=True): - ports = super(NECPluginV2, self).get_ports(context, filters, - fields) - # TODO(amotoki) filter by security group - for port in ports: - self._extend_port_dict_binding(context, port) - return [self._fields(port, fields) for port in ports] - class NECPluginV2AgentNotifierApi(proxy.RpcProxy, sg_rpc.SecurityGroupAgentRpcApiMixin): diff --git a/neutron/plugins/nicira/NeutronPlugin.py b/neutron/plugins/nicira/NeutronPlugin.py index 597c5aa7516..2763d1e30ff 100644 --- a/neutron/plugins/nicira/NeutronPlugin.py +++ b/neutron/plugins/nicira/NeutronPlugin.py @@ -200,7 +200,7 @@ class NvpPluginV2(db_base_plugin_v2.NeutronDbPluginV2, self.nvp_opts.concurrent_connections, self.nvp_opts.nvp_gen_timeout) - self.extra_binding_dict = { + self.base_binding_dict = { pbin.VIF_TYPE: pbin.VIF_TYPE_OVS, pbin.CAPABILITIES: { pbin.CAP_PORT_FILTER: diff --git a/neutron/plugins/openvswitch/ovs_neutron_plugin.py b/neutron/plugins/openvswitch/ovs_neutron_plugin.py index bb29c91149c..baeef5ef548 100644 --- a/neutron/plugins/openvswitch/ovs_neutron_plugin.py +++ b/neutron/plugins/openvswitch/ovs_neutron_plugin.py @@ -263,7 +263,7 @@ class OVSNeutronPluginV2(db_base_plugin_v2.NeutronDbPluginV2, return self._aliases def __init__(self, configfile=None): - self.extra_binding_dict = { + self.base_binding_dict = { portbindings.VIF_TYPE: portbindings.VIF_TYPE_OVS, portbindings.CAPABILITIES: { portbindings.CAP_PORT_FILTER: diff --git a/neutron/plugins/ryu/ryu_neutron_plugin.py b/neutron/plugins/ryu/ryu_neutron_plugin.py index 1e10ca8b6f4..6a7e59153dc 100644 --- a/neutron/plugins/ryu/ryu_neutron_plugin.py +++ b/neutron/plugins/ryu/ryu_neutron_plugin.py @@ -32,7 +32,9 @@ from neutron.db import extraroute_db from neutron.db import l3_gwmode_db from neutron.db import l3_rpc_base from neutron.db import models_v2 +from neutron.db import portbindings_base from neutron.db import securitygroups_rpc_base as sg_db_rpc +from neutron.extensions import portbindings from neutron.openstack.common import log as logging from neutron.openstack.common import rpc from neutron.openstack.common.rpc import proxy @@ -88,10 +90,12 @@ class AgentNotifierApi(proxy.RpcProxy, class RyuNeutronPluginV2(db_base_plugin_v2.NeutronDbPluginV2, extraroute_db.ExtraRoute_db_mixin, l3_gwmode_db.L3_NAT_db_mixin, - sg_db_rpc.SecurityGroupServerRpcMixin): + sg_db_rpc.SecurityGroupServerRpcMixin, + portbindings_base.PortBindingBaseMixin): _supported_extension_aliases = ["router", "ext-gw-mode", - "extraroute", "security-group"] + "extraroute", "security-group", + "binding"] @property def supported_extension_aliases(self): @@ -102,6 +106,12 @@ class RyuNeutronPluginV2(db_base_plugin_v2.NeutronDbPluginV2, return self._aliases def __init__(self, configfile=None): + self.base_binding_dict = { + portbindings.VIF_TYPE: portbindings.VIF_TYPE_OVS, + portbindings.CAPABILITIES: { + portbindings.CAP_PORT_FILTER: + 'security-group' in self.supported_extension_aliases}} + portbindings_base.register_port_dict_function() db.configure_db() self.tunnel_key = db_api_v2.TunnelKey( cfg.CONF.OVS.tunnel_key_min, cfg.CONF.OVS.tunnel_key_max) @@ -185,10 +195,14 @@ class RyuNeutronPluginV2(db_base_plugin_v2.NeutronDbPluginV2, 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) port = super(RyuNeutronPluginV2, 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) @@ -219,6 +233,9 @@ class RyuNeutronPluginV2(db_base_plugin_v2.NeutronDbPluginV2, context, id) updated_port = super(RyuNeutronPluginV2, 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) @@ -234,15 +251,3 @@ class RyuNeutronPluginV2(db_base_plugin_v2.NeutronDbPluginV2, if deleted: db_api_v2.set_port_status(session, id, q_const.PORT_STATUS_DOWN) return updated_port - - def get_port(self, context, id, fields=None): - with context.session.begin(subtransactions=True): - port = super(RyuNeutronPluginV2, self).get_port(context, id, - fields) - return self._fields(port, fields) - - def get_ports(self, context, filters=None, fields=None): - with context.session.begin(subtransactions=True): - ports = super(RyuNeutronPluginV2, self).get_ports( - context, filters, fields) - return [self._fields(port, fields) for port in ports]