b17735475f
Bug #1195047 This patch: 1. removes the iteration in get_ports to call extend_dict_binding 2. uses a unified way for plugins to do this kind of stuff ml2 will enhance the binding so that it can have different binding for port according to port's host. mlnx and bigswitch are also exceptions due to the dynamic binding info. Change-Id: I5a77eb7395e14482a856e033f536f72a1bf82e06
114 lines
4.3 KiB
Python
114 lines
4.3 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.db import portbindings_base
|
|
from neutron.extensions import portbindings
|
|
|
|
|
|
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(portbindings_base.PortBindingBaseMixin):
|
|
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:
|
|
self._extend_port_dict_binding_host(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
|
|
self._extend_port_dict_binding_host(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(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(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
|
|
plugin.extend_port_dict_binding(port_res, port_db)
|
|
|
|
|
|
# Register dict extend functions for ports
|
|
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
|
|
attributes.PORTS, [_extend_port_dict_binding])
|