Merge "Port location tracking for BigSwitch Plugin"
This commit is contained in:
commit
81382be9ca
@ -22,6 +22,14 @@ servers=localhost:8080
|
|||||||
# default: ovs
|
# default: ovs
|
||||||
# vif_type = ovs
|
# vif_type = ovs
|
||||||
|
|
||||||
|
# Overrides for vif types based on nova compute node host IDs
|
||||||
|
# Comma separated list of host IDs to fix to a specific VIF type
|
||||||
|
# The VIF type is taken from the end of the configuration item
|
||||||
|
# node_override_vif_<vif_type>
|
||||||
|
# For example, the following would set the VIF type to IVS for
|
||||||
|
# host-id1 and host-id2
|
||||||
|
# node_overrride_vif_ivs=host-id1,host-id2
|
||||||
|
|
||||||
[router]
|
[router]
|
||||||
# Specify the default router rules installed in newly created tenant routers
|
# Specify the default router rules installed in newly created tenant routers
|
||||||
# Specify multiple times for multiple rules
|
# Specify multiple times for multiple rules
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
#
|
||||||
|
# Copyright 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""Table to track port to host associations
|
||||||
|
|
||||||
|
Revision ID: 3cabb850f4a5
|
||||||
|
Revises: 5918cbddab04
|
||||||
|
Create Date: 2013-06-24 14:30:33.533562
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '3cabb850f4a5'
|
||||||
|
down_revision = '5918cbddab04'
|
||||||
|
|
||||||
|
# Change to ['*'] if this migration applies to all plugins
|
||||||
|
|
||||||
|
migration_for_plugins = [
|
||||||
|
'quantum.plugins.bigswitch.plugin.QuantumRestProxyV2'
|
||||||
|
]
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
from quantum.db import migration
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(active_plugin=None, options=None):
|
||||||
|
if not migration.should_run(active_plugin, migration_for_plugins):
|
||||||
|
return
|
||||||
|
|
||||||
|
### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table('portlocations',
|
||||||
|
sa.Column('port_id', sa.String(length=255),
|
||||||
|
primary_key=True, nullable=False),
|
||||||
|
sa.Column('host_id',
|
||||||
|
sa.String(length=255), nullable=False)
|
||||||
|
)
|
||||||
|
### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade(active_plugin=None, options=None):
|
||||||
|
if not migration.should_run(active_plugin, migration_for_plugins):
|
||||||
|
return
|
||||||
|
|
||||||
|
### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_table('portlocations')
|
||||||
|
### end Alembic commands ###
|
@ -44,6 +44,10 @@ VIF_TYPE_802_QBG = '802.1qbg'
|
|||||||
VIF_TYPE_802_QBH = '802.1qbh'
|
VIF_TYPE_802_QBH = '802.1qbh'
|
||||||
VIF_TYPE_HYPERV = 'hyperv'
|
VIF_TYPE_HYPERV = 'hyperv'
|
||||||
VIF_TYPE_OTHER = 'other'
|
VIF_TYPE_OTHER = 'other'
|
||||||
|
VIF_TYPES = [VIF_TYPE_UNBOUND, VIF_TYPE_BINDING_FAILED, VIF_TYPE_OVS,
|
||||||
|
VIF_TYPE_IVS, VIF_TYPE_BRIDGE, VIF_TYPE_802_QBG,
|
||||||
|
VIF_TYPE_802_QBH, VIF_TYPE_HYPERV, VIF_TYPE_OTHER]
|
||||||
|
|
||||||
|
|
||||||
EXTENDED_ATTRIBUTES_2_0 = {
|
EXTENDED_ATTRIBUTES_2_0 = {
|
||||||
'ports': {
|
'ports': {
|
||||||
|
18
quantum/plugins/bigswitch/db/__init__.py
Normal file
18
quantum/plugins/bigswitch/db/__init__.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright 2013 Big Switch Networks, 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: Kevin Benton, Big Switch Networks, Inc.
|
46
quantum/plugins/bigswitch/db/porttracker_db.py
Normal file
46
quantum/plugins/bigswitch/db/porttracker_db.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
#
|
||||||
|
# Copyright 2013, Big Switch Networks
|
||||||
|
# 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 sqlalchemy as sa
|
||||||
|
|
||||||
|
from quantum.db import model_base
|
||||||
|
from quantum.openstack.common import log as logging
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class PortLocation(model_base.BASEV2):
|
||||||
|
port_id = sa.Column(sa.String(255), primary_key=True)
|
||||||
|
host_id = sa.Column(sa.String(255), nullable=False)
|
||||||
|
|
||||||
|
|
||||||
|
def get_port_hostid(context, port_id):
|
||||||
|
with context.session.begin(subtransactions=True):
|
||||||
|
query = context.session.query(PortLocation)
|
||||||
|
res = query.filter_by(port_id=port_id).first()
|
||||||
|
if not res:
|
||||||
|
return False
|
||||||
|
return res.host_id
|
||||||
|
|
||||||
|
|
||||||
|
def put_port_hostid(context, port_id, host_id):
|
||||||
|
if port_id == '':
|
||||||
|
LOG.warning(_("Received an empty port ID for host '%s'"), host_id)
|
||||||
|
return
|
||||||
|
with context.session.begin(subtransactions=True):
|
||||||
|
location = PortLocation(port_id=port_id, host_id=host_id)
|
||||||
|
context.session.add(location)
|
@ -68,6 +68,7 @@ from quantum.extensions import l3
|
|||||||
from quantum.extensions import portbindings
|
from quantum.extensions import portbindings
|
||||||
from quantum.openstack.common import log as logging
|
from quantum.openstack.common import log as logging
|
||||||
from quantum.openstack.common import rpc
|
from quantum.openstack.common import rpc
|
||||||
|
from quantum.plugins.bigswitch.db import porttracker_db
|
||||||
from quantum.plugins.bigswitch import routerrule_db
|
from quantum.plugins.bigswitch import routerrule_db
|
||||||
from quantum.plugins.bigswitch.version import version_string_with_vcs
|
from quantum.plugins.bigswitch.version import version_string_with_vcs
|
||||||
|
|
||||||
@ -126,6 +127,15 @@ nova_opts = [
|
|||||||
"Nova compute nodes")),
|
"Nova compute nodes")),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Each VIF Type can have a list of nova host IDs that are fixed to that type
|
||||||
|
for i in portbindings.VIF_TYPES:
|
||||||
|
opt = cfg.ListOpt('node_override_vif_' + i, default=[],
|
||||||
|
help=_("Nova compute nodes to manually set VIF "
|
||||||
|
"type to %s") % i)
|
||||||
|
nova_opts.append(opt)
|
||||||
|
|
||||||
|
# Add the vif types for reference later
|
||||||
|
nova_opts.append(cfg.ListOpt('vif_types', default=portbindings.VIF_TYPES))
|
||||||
|
|
||||||
cfg.CONF.register_opts(nova_opts, "NOVA")
|
cfg.CONF.register_opts(nova_opts, "NOVA")
|
||||||
|
|
||||||
@ -569,6 +579,10 @@ class QuantumRestProxyV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
|
|
||||||
# Update DB
|
# Update DB
|
||||||
port["port"]["admin_state_up"] = False
|
port["port"]["admin_state_up"] = False
|
||||||
|
if (portbindings.HOST_ID in port['port']
|
||||||
|
and 'device_id' in port['port']):
|
||||||
|
porttracker_db.put_port_hostid(context, port['port']['device_id'],
|
||||||
|
port['port'][portbindings.HOST_ID])
|
||||||
new_port = super(QuantumRestProxyV2, self).create_port(context, port)
|
new_port = super(QuantumRestProxyV2, self).create_port(context, port)
|
||||||
net = super(QuantumRestProxyV2,
|
net = super(QuantumRestProxyV2,
|
||||||
self).get_network(context, new_port["network_id"])
|
self).get_network(context, new_port["network_id"])
|
||||||
@ -661,7 +675,10 @@ class QuantumRestProxyV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
# Update DB
|
# Update DB
|
||||||
new_port = super(QuantumRestProxyV2, self).update_port(context,
|
new_port = super(QuantumRestProxyV2, self).update_port(context,
|
||||||
port_id, port)
|
port_id, port)
|
||||||
|
if (portbindings.HOST_ID in port['port']
|
||||||
|
and 'device_id' in port['port']):
|
||||||
|
porttracker_db.put_port_hostid(context, port['port']['device_id'],
|
||||||
|
port['port'][portbindings.HOST_ID])
|
||||||
# update on networl ctrl
|
# update on networl ctrl
|
||||||
try:
|
try:
|
||||||
resource = PORTS_PATH % (orig_port["tenant_id"],
|
resource = PORTS_PATH % (orig_port["tenant_id"],
|
||||||
@ -1335,10 +1352,21 @@ class QuantumRestProxyV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
"[%s]. Defaulting to ovs. "),
|
"[%s]. Defaulting to ovs. "),
|
||||||
cfg_vif_type)
|
cfg_vif_type)
|
||||||
cfg_vif_type = portbindings.VIF_TYPE_OVS
|
cfg_vif_type = portbindings.VIF_TYPE_OVS
|
||||||
|
hostid = porttracker_db.get_port_hostid(context,
|
||||||
|
port.get("device_id"))
|
||||||
|
if hostid:
|
||||||
|
override = self._check_hostvif_override(hostid)
|
||||||
|
if override:
|
||||||
|
cfg_vif_type = override
|
||||||
port[portbindings.VIF_TYPE] = cfg_vif_type
|
port[portbindings.VIF_TYPE] = cfg_vif_type
|
||||||
|
|
||||||
port[portbindings.CAPABILITIES] = {
|
port[portbindings.CAPABILITIES] = {
|
||||||
portbindings.CAP_PORT_FILTER:
|
portbindings.CAP_PORT_FILTER:
|
||||||
'security-group' in self.supported_extension_aliases}
|
'security-group' in self.supported_extension_aliases}
|
||||||
return port
|
return port
|
||||||
|
|
||||||
|
def _check_hostvif_override(self, hostid):
|
||||||
|
for v in cfg.CONF.NOVA.vif_types:
|
||||||
|
if hostid in getattr(cfg.CONF.NOVA, "node_override_vif_" + v, []):
|
||||||
|
return v
|
||||||
|
return False
|
||||||
|
@ -30,6 +30,9 @@ serverssl=False
|
|||||||
# options: ivs or ovs
|
# options: ivs or ovs
|
||||||
# default: ovs
|
# default: ovs
|
||||||
vif_type = ovs
|
vif_type = ovs
|
||||||
|
# Overrides for vif types based on nova compute node host IDs
|
||||||
|
# Comma separated list of host IDs to fix to a specific VIF type
|
||||||
|
node_override_vif_ivs = ivshost
|
||||||
|
|
||||||
[router]
|
[router]
|
||||||
# Specify the default router rules installed in newly created tenant routers
|
# Specify the default router rules installed in newly created tenant routers
|
||||||
|
@ -19,6 +19,7 @@ import os
|
|||||||
|
|
||||||
from mock import patch
|
from mock import patch
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
|
import webob.exc
|
||||||
|
|
||||||
import quantum.common.test_lib as test_lib
|
import quantum.common.test_lib as test_lib
|
||||||
from quantum.extensions import portbindings
|
from quantum.extensions import portbindings
|
||||||
@ -106,6 +107,38 @@ class TestBigSwitchProxyPortsV2IVS(test_plugin.TestPortsV2,
|
|||||||
cfg.CONF.set_override('vif_type', 'ivs', 'NOVA')
|
cfg.CONF.set_override('vif_type', 'ivs', 'NOVA')
|
||||||
|
|
||||||
|
|
||||||
|
class TestBigSwitchVIFOverride(test_plugin.TestPortsV2,
|
||||||
|
BigSwitchProxyPluginV2TestCase,
|
||||||
|
test_bindings.PortBindingsTestCase):
|
||||||
|
VIF_TYPE = portbindings.VIF_TYPE_OVS
|
||||||
|
HAS_PORT_FILTER = False
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestBigSwitchVIFOverride,
|
||||||
|
self).setUp()
|
||||||
|
cfg.CONF.set_override('vif_type', 'ovs', 'NOVA')
|
||||||
|
|
||||||
|
def test_port_vif_details(self):
|
||||||
|
kwargs = {'name': 'name', 'binding:host_id': 'ivshost',
|
||||||
|
'device_id': 'override_dev'}
|
||||||
|
with self.port(**kwargs) as port:
|
||||||
|
self.assertEqual(port['port']['binding:vif_type'],
|
||||||
|
portbindings.VIF_TYPE_IVS)
|
||||||
|
kwargs = {'name': 'name2', 'binding:host_id': 'someotherhost',
|
||||||
|
'device_id': 'other_dev'}
|
||||||
|
with self.port(**kwargs) as port:
|
||||||
|
self.assertEqual(port['port']['binding:vif_type'], self.VIF_TYPE)
|
||||||
|
|
||||||
|
def _make_port(self, fmt, net_id, expected_res_status=None, **kwargs):
|
||||||
|
res = self._create_port(fmt, net_id, expected_res_status,
|
||||||
|
('binding:host_id', ), **kwargs)
|
||||||
|
# Things can go wrong - raise HTTP exc with res code only
|
||||||
|
# so it can be caught by unit tests
|
||||||
|
if res.status_int >= 400:
|
||||||
|
raise webob.exc.HTTPClientError(code=res.status_int)
|
||||||
|
return self.deserialize(fmt, res)
|
||||||
|
|
||||||
|
|
||||||
class TestBigSwitchProxyNetworksV2(test_plugin.TestNetworksV2,
|
class TestBigSwitchProxyNetworksV2(test_plugin.TestNetworksV2,
|
||||||
BigSwitchProxyPluginV2TestCase):
|
BigSwitchProxyPluginV2TestCase):
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user