vmware-nsx/neutron/db/portbindings_db.py
armando-migliaccio 4a8c3af72f Add support to the port binding extension for the NVP plugin.
Also, this patch removes the non-serializable object for
port profile. This went undetected for quite some time.

Implements blueprint nvp-port-binding-extension

Change-Id: I380570f08e92f75d6431dcda6fac2a770887bb48
2013-07-23 12:19:11 -07:00

116 lines
4.2 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 IBM Corp.
# 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, IBM, Corp.
import sqlalchemy as sa
from sqlalchemy import orm
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.extensions import portbindings
from neutron.openstack.common import log as logging
LOG = logging.getLogger(__name__)
class PortBindingPort(model_base.BASEV2):
port_id = sa.Column(sa.String(36),
sa.ForeignKey('ports.id', ondelete="CASCADE"),
primary_key=True)
host = sa.Column(sa.String(255), nullable=False)
port = orm.relationship(
models_v2.Port,
backref=orm.backref("portbinding",
lazy='joined', uselist=False,
cascade='delete'))
class PortBindingMixin(object):
extra_binding_dict = None
def _port_model_hook(self, context, original_model, query):
query = query.outerjoin(PortBindingPort,
(original_model.id ==
PortBindingPort.port_id))
return query
def _port_result_filter_hook(self, query, filters):
values = filters and filters.get(portbindings.HOST_ID, [])
if not values:
return query
if len(values) == 1:
query = query.filter(PortBindingPort.host == values[0])
else:
query = query.filter(PortBindingPort.host.in_(values))
return query
db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook(
models_v2.Port,
"portbindings_port",
_port_model_hook,
None,
_port_result_filter_hook)
def _process_portbindings_create_and_update(self, context, port_data,
port):
binding_profile = port.get(portbindings.PROFILE)
binding_profile_set = attributes.is_attr_set(binding_profile)
if not binding_profile_set and binding_profile is not None:
del port[portbindings.PROFILE]
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)
return
with context.session.begin(subtransactions=True):
bind_port = context.session.query(
PortBindingPort).filter_by(port_id=port['id']).first()
if not bind_port:
context.session.add(PortBindingPort(port_id=port['id'],
host=host))
else:
bind_port.host = host
_extend_port_dict_binding_host(self, port, host)
def get_port_host(self, context, port_id):
with context.session.begin(subtransactions=True):
bind_port = context.session.query(
PortBindingPort).filter_by(port_id=port_id).first()
return bind_port and bind_port.host or None
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(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)
# Register dict extend functions for ports
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attributes.PORTS, [_extend_port_dict_binding])