Add VIF binding extensions
The is part of the blueprint vif-plugging-improvements. The patch adds an extension to Quantum that enables the plugin to return VIF details. At the moment it supports openvswitch and linuxbridge. Change-Id: Ib9b4d34e668e2ddc61c152c2c4cd4a01f2d0de40
This commit is contained in:
parent
4aaf0fe474
commit
64f2a38bc9
@ -15,6 +15,9 @@
|
|||||||
"extension:router:add_router_interface": "rule:admin_or_owner",
|
"extension:router:add_router_interface": "rule:admin_or_owner",
|
||||||
"extension:router:remove_router_interface": "rule:admin_or_owner",
|
"extension:router:remove_router_interface": "rule:admin_or_owner",
|
||||||
|
|
||||||
|
"extension:port_binding:view": "rule:admin_only",
|
||||||
|
"extension:port_binding:set": "rule:admin_only",
|
||||||
|
|
||||||
"subnets:private:read": "rule:admin_or_owner",
|
"subnets:private:read": "rule:admin_or_owner",
|
||||||
"subnets:private:write": "rule:admin_or_owner",
|
"subnets:private:write": "rule:admin_or_owner",
|
||||||
"subnets:shared:read": "rule:regular_user",
|
"subnets:shared:read": "rule:regular_user",
|
||||||
|
82
quantum/extensions/portbindings.py
Normal file
82
quantum/extensions/portbindings.py
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
# Copyright (c) 2012 OpenStack, LLC.
|
||||||
|
#
|
||||||
|
# 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 quantum.api.v2 import attributes
|
||||||
|
|
||||||
|
# The service will return the vif type for the specific port.
|
||||||
|
VIF_TYPE = 'binding:vif_type'
|
||||||
|
# In some cases different implementations may be run on different hosts.
|
||||||
|
# The host on which the port will be allocated.
|
||||||
|
HOST_ID = 'binding:host_id'
|
||||||
|
# The profile will be a dictionary that enables the application running
|
||||||
|
# on the specific host to pass and receive vif port specific information to
|
||||||
|
# the plugin.
|
||||||
|
PROFILE = 'binding:profile'
|
||||||
|
|
||||||
|
VIF_TYPE_OVS = 'ovs'
|
||||||
|
VIF_TYPE_BRIDGE = 'bridge'
|
||||||
|
VIF_TYPE_802_QBG = '802.1qbg'
|
||||||
|
VIF_TYPE_802_QBH = '802.1qbh'
|
||||||
|
VIF_TYPE_OTHER = 'other'
|
||||||
|
|
||||||
|
EXTENDED_ATTRIBUTES_2_0 = {
|
||||||
|
'ports': {
|
||||||
|
VIF_TYPE: {'allow_post': False, 'allow_put': False,
|
||||||
|
'default': attributes.ATTR_NOT_SPECIFIED,
|
||||||
|
'is_visible': True},
|
||||||
|
HOST_ID: {'allow_post': True, 'allow_put': True,
|
||||||
|
'default': attributes.ATTR_NOT_SPECIFIED,
|
||||||
|
'is_visible': True},
|
||||||
|
PROFILE: {'allow_post': True, 'allow_put': True,
|
||||||
|
'default': attributes.ATTR_NOT_SPECIFIED,
|
||||||
|
'is_visible': True},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Portbindings(object):
|
||||||
|
"""Extension class supporting port bindings.
|
||||||
|
|
||||||
|
This class is used by quantum's extension framework to make
|
||||||
|
metadata about the port bindings available to external applications.
|
||||||
|
|
||||||
|
With admin rights one will be able to update and read the values.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_name(cls):
|
||||||
|
return "Port Binding"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_alias(cls):
|
||||||
|
return "binding"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_description(cls):
|
||||||
|
return "Expose port bindings of a virtual port to external application"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_namespace(cls):
|
||||||
|
return "http://docs.openstack.org/ext/binding/api/v1.0"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_updated(cls):
|
||||||
|
return "2012-11-14T10:00:00-00:00"
|
||||||
|
|
||||||
|
def get_extended_resources(self, version):
|
||||||
|
if version == "2.0":
|
||||||
|
return EXTENDED_ATTRIBUTES_2_0
|
||||||
|
else:
|
||||||
|
return {}
|
@ -25,6 +25,7 @@ from quantum.db import db_base_plugin_v2
|
|||||||
from quantum.db import dhcp_rpc_base
|
from quantum.db import dhcp_rpc_base
|
||||||
from quantum.db import l3_db
|
from quantum.db import l3_db
|
||||||
from quantum.db import l3_rpc_base
|
from quantum.db import l3_rpc_base
|
||||||
|
from quantum.extensions import portbindings
|
||||||
from quantum.extensions import providernet as provider
|
from quantum.extensions import providernet as provider
|
||||||
from quantum.openstack.common import cfg
|
from quantum.openstack.common import cfg
|
||||||
from quantum.openstack.common import log as logging
|
from quantum.openstack.common import log as logging
|
||||||
@ -143,6 +144,9 @@ class LinuxBridgePluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
handled, by adding support for extended attributes to the
|
handled, by adding support for extended attributes to the
|
||||||
QuantumDbPluginV2 base class. When that occurs, this class should
|
QuantumDbPluginV2 base class. When that occurs, this class should
|
||||||
be updated to take advantage of it.
|
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
|
# This attribute specifies whether the plugin supports or not
|
||||||
@ -150,7 +154,12 @@ class LinuxBridgePluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
# is qualified by class
|
# is qualified by class
|
||||||
__native_bulk_support = True
|
__native_bulk_support = True
|
||||||
|
|
||||||
supported_extension_aliases = ["provider", "router"]
|
supported_extension_aliases = ["provider", "router", "binding"]
|
||||||
|
|
||||||
|
network_view = "extension:provider_network:view"
|
||||||
|
network_set = "extension:provider_network:set"
|
||||||
|
binding_view = "extension:port_binding:view"
|
||||||
|
binding_set = "extension:port_binding:set"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
db.initialize()
|
db.initialize()
|
||||||
@ -197,6 +206,12 @@ class LinuxBridgePluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
self._add_network(entry)
|
self._add_network(entry)
|
||||||
LOG.debug("network VLAN ranges: %s" % self.network_vlan_ranges)
|
LOG.debug("network VLAN ranges: %s" % self.network_vlan_ranges)
|
||||||
|
|
||||||
|
def _check_view_auth(self, context, resource, action):
|
||||||
|
return policy.check(context, action, resource)
|
||||||
|
|
||||||
|
def _enforce_set_auth(self, context, resource, action):
|
||||||
|
policy.enforce(context, action, resource)
|
||||||
|
|
||||||
def _add_network_vlan_range(self, physical_network, vlan_min, vlan_max):
|
def _add_network_vlan_range(self, physical_network, vlan_min, vlan_max):
|
||||||
self._add_network(physical_network)
|
self._add_network(physical_network)
|
||||||
self.network_vlan_ranges[physical_network].append((vlan_min, vlan_max))
|
self.network_vlan_ranges[physical_network].append((vlan_min, vlan_max))
|
||||||
@ -208,18 +223,8 @@ class LinuxBridgePluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
# REVISIT(rkukura) Use core mechanism for attribute authorization
|
# REVISIT(rkukura) Use core mechanism for attribute authorization
|
||||||
# when available.
|
# when available.
|
||||||
|
|
||||||
def _check_provider_view_auth(self, context, network):
|
|
||||||
return policy.check(context,
|
|
||||||
"extension:provider_network:view",
|
|
||||||
network)
|
|
||||||
|
|
||||||
def _enforce_provider_set_auth(self, context, network):
|
|
||||||
return policy.enforce(context,
|
|
||||||
"extension:provider_network:set",
|
|
||||||
network)
|
|
||||||
|
|
||||||
def _extend_network_dict_provider(self, context, network):
|
def _extend_network_dict_provider(self, context, network):
|
||||||
if self._check_provider_view_auth(context, network):
|
if self._check_view_auth(context, network, self.network_view):
|
||||||
binding = db.get_network_binding(context.session, network['id'])
|
binding = db.get_network_binding(context.session, network['id'])
|
||||||
if binding.vlan_id == constants.FLAT_VLAN_ID:
|
if binding.vlan_id == constants.FLAT_VLAN_ID:
|
||||||
network[provider.NETWORK_TYPE] = constants.TYPE_FLAT
|
network[provider.NETWORK_TYPE] = constants.TYPE_FLAT
|
||||||
@ -248,7 +253,7 @@ class LinuxBridgePluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
return (None, None, None)
|
return (None, None, None)
|
||||||
|
|
||||||
# Authorize before exposing plugin details to client
|
# Authorize before exposing plugin details to client
|
||||||
self._enforce_provider_set_auth(context, attrs)
|
self._enforce_set_auth(context, attrs, self.network_set)
|
||||||
|
|
||||||
if not network_type_set:
|
if not network_type_set:
|
||||||
msg = _("provider:network_type required")
|
msg = _("provider:network_type required")
|
||||||
@ -312,7 +317,7 @@ class LinuxBridgePluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Authorize before exposing plugin details to client
|
# Authorize before exposing plugin details to client
|
||||||
self._enforce_provider_set_auth(context, attrs)
|
self._enforce_set_auth(context, attrs, self.network_set)
|
||||||
|
|
||||||
msg = _("plugin does not support updating provider attributes")
|
msg = _("plugin does not support updating provider attributes")
|
||||||
raise q_exc.InvalidInput(error_message=msg)
|
raise q_exc.InvalidInput(error_message=msg)
|
||||||
@ -392,6 +397,26 @@ class LinuxBridgePluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
|
|
||||||
return [self._fields(net, fields) for net in nets]
|
return [self._fields(net, fields) for net in nets]
|
||||||
|
|
||||||
|
def _extend_port_dict_binding(self, context, port):
|
||||||
|
if self._check_view_auth(context, port, self.binding_view):
|
||||||
|
port[portbindings.VIF_TYPE] = portbindings.VIF_TYPE_BRIDGE
|
||||||
|
return port
|
||||||
|
|
||||||
|
def create_port(self, context, port):
|
||||||
|
port = super(LinuxBridgePluginV2, self).create_port(context, port)
|
||||||
|
return self._extend_port_dict_binding(context, port)
|
||||||
|
|
||||||
|
def get_port(self, context, id, fields=None):
|
||||||
|
port = super(LinuxBridgePluginV2, 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(LinuxBridgePluginV2, self).get_ports(context, filters,
|
||||||
|
fields)
|
||||||
|
return [self._fields(self._extend_port_dict_binding(context, port),
|
||||||
|
fields) for port in ports]
|
||||||
|
|
||||||
def update_port(self, context, id, port):
|
def update_port(self, context, id, port):
|
||||||
original_port = super(LinuxBridgePluginV2, self).get_port(context,
|
original_port = super(LinuxBridgePluginV2, self).get_port(context,
|
||||||
id)
|
id)
|
||||||
@ -402,7 +427,7 @@ class LinuxBridgePluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
self.notifier.port_update(context, port,
|
self.notifier.port_update(context, port,
|
||||||
binding.physical_network,
|
binding.physical_network,
|
||||||
binding.vlan_id)
|
binding.vlan_id)
|
||||||
return port
|
return self._extend_port_dict_binding(context, port)
|
||||||
|
|
||||||
def delete_port(self, context, id, l3_port_check=True):
|
def delete_port(self, context, id, l3_port_check=True):
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ from quantum.db import db_base_plugin_v2
|
|||||||
from quantum.db import dhcp_rpc_base
|
from quantum.db import dhcp_rpc_base
|
||||||
from quantum.db import l3_db
|
from quantum.db import l3_db
|
||||||
from quantum.db import l3_rpc_base
|
from quantum.db import l3_rpc_base
|
||||||
|
from quantum.extensions import portbindings
|
||||||
from quantum.extensions import providernet as provider
|
from quantum.extensions import providernet as provider
|
||||||
from quantum.openstack.common import cfg
|
from quantum.openstack.common import cfg
|
||||||
from quantum.openstack.common import log as logging
|
from quantum.openstack.common import log as logging
|
||||||
@ -124,7 +125,7 @@ class OVSRpcCallbacks(dhcp_rpc_base.DhcpRpcCallbackMixin,
|
|||||||
|
|
||||||
|
|
||||||
class AgentNotifierApi(proxy.RpcProxy):
|
class AgentNotifierApi(proxy.RpcProxy):
|
||||||
'''Agent side of the linux bridge rpc API.
|
'''Agent side of the openvswitch rpc API.
|
||||||
|
|
||||||
API version history:
|
API version history:
|
||||||
1.0 - Initial version.
|
1.0 - Initial version.
|
||||||
@ -184,13 +185,21 @@ class OVSQuantumPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
handled, by adding support for extended attributes to the
|
handled, by adding support for extended attributes to the
|
||||||
QuantumDbPluginV2 base class. When that occurs, this class should
|
QuantumDbPluginV2 base class. When that occurs, this class should
|
||||||
be updated to take advantage of it.
|
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
|
# This attribute specifies whether the plugin supports or not
|
||||||
# bulk operations. Name mangling is used in order to ensure it
|
# bulk operations. Name mangling is used in order to ensure it
|
||||||
# is qualified by class
|
# is qualified by class
|
||||||
__native_bulk_support = True
|
__native_bulk_support = True
|
||||||
supported_extension_aliases = ["provider", "router"]
|
supported_extension_aliases = ["provider", "router", "binding"]
|
||||||
|
|
||||||
|
network_view = "extension:provider_network:view"
|
||||||
|
network_set = "extension:provider_network:set"
|
||||||
|
binding_view = "extension:port_binding:view"
|
||||||
|
binding_set = "extension:port_binding:set"
|
||||||
|
|
||||||
def __init__(self, configfile=None):
|
def __init__(self, configfile=None):
|
||||||
ovs_db_v2.initialize()
|
ovs_db_v2.initialize()
|
||||||
@ -271,18 +280,14 @@ class OVSQuantumPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
# TODO(rkukura) Use core mechanism for attribute authorization
|
# TODO(rkukura) Use core mechanism for attribute authorization
|
||||||
# when available.
|
# when available.
|
||||||
|
|
||||||
def _check_provider_view_auth(self, context, network):
|
def _check_view_auth(self, context, resource, action):
|
||||||
return policy.check(context,
|
return policy.check(context, action, resource)
|
||||||
"extension:provider_network:view",
|
|
||||||
network)
|
|
||||||
|
|
||||||
def _enforce_provider_set_auth(self, context, network):
|
def _enforce_set_auth(self, context, resource, action):
|
||||||
return policy.enforce(context,
|
policy.enforce(context, action, resource)
|
||||||
"extension:provider_network:set",
|
|
||||||
network)
|
|
||||||
|
|
||||||
def _extend_network_dict_provider(self, context, network):
|
def _extend_network_dict_provider(self, context, network):
|
||||||
if self._check_provider_view_auth(context, network):
|
if self._check_view_auth(context, network, self.network_view):
|
||||||
binding = ovs_db_v2.get_network_binding(context.session,
|
binding = ovs_db_v2.get_network_binding(context.session,
|
||||||
network['id'])
|
network['id'])
|
||||||
network[provider.NETWORK_TYPE] = binding.network_type
|
network[provider.NETWORK_TYPE] = binding.network_type
|
||||||
@ -313,7 +318,7 @@ class OVSQuantumPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
return (None, None, None)
|
return (None, None, None)
|
||||||
|
|
||||||
# Authorize before exposing plugin details to client
|
# Authorize before exposing plugin details to client
|
||||||
self._enforce_provider_set_auth(context, attrs)
|
self._enforce_set_auth(context, attrs, self.network_set)
|
||||||
|
|
||||||
if not network_type_set:
|
if not network_type_set:
|
||||||
msg = _("provider:network_type required")
|
msg = _("provider:network_type required")
|
||||||
@ -390,7 +395,7 @@ class OVSQuantumPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Authorize before exposing plugin details to client
|
# Authorize before exposing plugin details to client
|
||||||
self._enforce_provider_set_auth(context, attrs)
|
self._enforce_set_auth(context, attrs, self.network_set)
|
||||||
|
|
||||||
msg = _("plugin does not support updating provider attributes")
|
msg = _("plugin does not support updating provider attributes")
|
||||||
raise q_exc.InvalidInput(error_message=msg)
|
raise q_exc.InvalidInput(error_message=msg)
|
||||||
@ -480,6 +485,26 @@ class OVSQuantumPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
|
|
||||||
return [self._fields(net, fields) for net in nets]
|
return [self._fields(net, fields) for net in nets]
|
||||||
|
|
||||||
|
def _extend_port_dict_binding(self, context, port):
|
||||||
|
if self._check_view_auth(context, port, self.binding_view):
|
||||||
|
port[portbindings.VIF_TYPE] = portbindings.VIF_TYPE_OVS
|
||||||
|
return port
|
||||||
|
|
||||||
|
def create_port(self, context, port):
|
||||||
|
port = super(OVSQuantumPluginV2, self).create_port(context, port)
|
||||||
|
return self._extend_port_dict_binding(context, port)
|
||||||
|
|
||||||
|
def get_port(self, context, id, fields=None):
|
||||||
|
port = super(OVSQuantumPluginV2, 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(OVSQuantumPluginV2, self).get_ports(context, filters,
|
||||||
|
fields)
|
||||||
|
return [self._fields(self._extend_port_dict_binding(context, port),
|
||||||
|
fields) for port in ports]
|
||||||
|
|
||||||
def update_port(self, context, id, port):
|
def update_port(self, context, id, port):
|
||||||
original_port = super(OVSQuantumPluginV2, self).get_port(context,
|
original_port = super(OVSQuantumPluginV2, self).get_port(context,
|
||||||
id)
|
id)
|
||||||
@ -491,7 +516,7 @@ class OVSQuantumPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
|||||||
binding.network_type,
|
binding.network_type,
|
||||||
binding.segmentation_id,
|
binding.segmentation_id,
|
||||||
binding.physical_network)
|
binding.physical_network)
|
||||||
return port
|
return self._extend_port_dict_binding(context, port)
|
||||||
|
|
||||||
def delete_port(self, context, id, l3_port_check=True):
|
def delete_port(self, context, id, l3_port_check=True):
|
||||||
|
|
||||||
|
@ -13,6 +13,12 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import contextlib
|
||||||
|
|
||||||
|
from quantum import context
|
||||||
|
from quantum.extensions import portbindings
|
||||||
|
from quantum.manager import QuantumManager
|
||||||
|
from quantum.openstack.common import cfg
|
||||||
from quantum.tests.unit import test_db_plugin as test_plugin
|
from quantum.tests.unit import test_db_plugin as test_plugin
|
||||||
|
|
||||||
|
|
||||||
@ -37,7 +43,41 @@ class TestLinuxBridgeV2HTTPResponse(test_plugin.TestV2HTTPResponse,
|
|||||||
|
|
||||||
class TestLinuxBridgePortsV2(test_plugin.TestPortsV2,
|
class TestLinuxBridgePortsV2(test_plugin.TestPortsV2,
|
||||||
LinuxBridgePluginV2TestCase):
|
LinuxBridgePluginV2TestCase):
|
||||||
pass
|
def test_port_vif_details(self):
|
||||||
|
plugin = QuantumManager.get_plugin()
|
||||||
|
with self.port(name='name') as port:
|
||||||
|
port_id = port['port']['id']
|
||||||
|
self.assertEqual(port['port']['binding:vif_type'],
|
||||||
|
portbindings.VIF_TYPE_BRIDGE)
|
||||||
|
# By default user is admin - now test non admin user
|
||||||
|
ctx = context.Context(user_id=None,
|
||||||
|
tenant_id=self._tenant_id,
|
||||||
|
is_admin=False,
|
||||||
|
read_deleted="no")
|
||||||
|
non_admin_port = plugin.get_port(ctx, port_id)
|
||||||
|
self.assertTrue('status' in non_admin_port)
|
||||||
|
self.assertFalse('binding:vif_type' in non_admin_port)
|
||||||
|
|
||||||
|
def test_ports_vif_details(self):
|
||||||
|
cfg.CONF.set_default('allow_overlapping_ips', True)
|
||||||
|
plugin = QuantumManager.get_plugin()
|
||||||
|
with contextlib.nested(self.port(), self.port()) as (port1, port2):
|
||||||
|
ctx = context.get_admin_context()
|
||||||
|
ports = plugin.get_ports(ctx)
|
||||||
|
self.assertEqual(len(ports), 2)
|
||||||
|
for port in ports:
|
||||||
|
self.assertEqual(port['binding:vif_type'],
|
||||||
|
portbindings.VIF_TYPE_BRIDGE)
|
||||||
|
# By default user is admin - now test non admin user
|
||||||
|
ctx = context.Context(user_id=None,
|
||||||
|
tenant_id=self._tenant_id,
|
||||||
|
is_admin=False,
|
||||||
|
read_deleted="no")
|
||||||
|
ports = plugin.get_ports(ctx)
|
||||||
|
self.assertEqual(len(ports), 2)
|
||||||
|
for non_admin_port in ports:
|
||||||
|
self.assertTrue('status' in non_admin_port)
|
||||||
|
self.assertFalse('binding:vif_type' in non_admin_port)
|
||||||
|
|
||||||
|
|
||||||
class TestLinuxBridgeNetworksV2(test_plugin.TestNetworksV2,
|
class TestLinuxBridgeNetworksV2(test_plugin.TestNetworksV2,
|
||||||
|
@ -13,6 +13,12 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import contextlib
|
||||||
|
|
||||||
|
from quantum import context
|
||||||
|
from quantum.extensions import portbindings
|
||||||
|
from quantum.manager import QuantumManager
|
||||||
|
from quantum.openstack.common import cfg
|
||||||
from quantum.tests.unit import test_db_plugin as test_plugin
|
from quantum.tests.unit import test_db_plugin as test_plugin
|
||||||
|
|
||||||
|
|
||||||
@ -37,7 +43,41 @@ class TestOpenvswitchV2HTTPResponse(test_plugin.TestV2HTTPResponse,
|
|||||||
|
|
||||||
class TestOpenvswitchPortsV2(test_plugin.TestPortsV2,
|
class TestOpenvswitchPortsV2(test_plugin.TestPortsV2,
|
||||||
OpenvswitchPluginV2TestCase):
|
OpenvswitchPluginV2TestCase):
|
||||||
pass
|
def test_port_vif_details(self):
|
||||||
|
plugin = QuantumManager.get_plugin()
|
||||||
|
with self.port(name='name') as port:
|
||||||
|
port_id = port['port']['id']
|
||||||
|
self.assertEqual(port['port']['binding:vif_type'],
|
||||||
|
portbindings.VIF_TYPE_OVS)
|
||||||
|
# By default user is admin - now test non admin user
|
||||||
|
ctx = context.Context(user_id=None,
|
||||||
|
tenant_id=self._tenant_id,
|
||||||
|
is_admin=False,
|
||||||
|
read_deleted="no")
|
||||||
|
non_admin_port = plugin.get_port(ctx, port_id)
|
||||||
|
self.assertTrue('status' in non_admin_port)
|
||||||
|
self.assertFalse('binding:vif_type' in non_admin_port)
|
||||||
|
|
||||||
|
def test_ports_vif_details(self):
|
||||||
|
cfg.CONF.set_default('allow_overlapping_ips', True)
|
||||||
|
plugin = QuantumManager.get_plugin()
|
||||||
|
with contextlib.nested(self.port(), self.port()) as (port1, port2):
|
||||||
|
ctx = context.get_admin_context()
|
||||||
|
ports = plugin.get_ports(ctx)
|
||||||
|
self.assertEqual(len(ports), 2)
|
||||||
|
for port in ports:
|
||||||
|
self.assertEqual(port['binding:vif_type'],
|
||||||
|
portbindings.VIF_TYPE_OVS)
|
||||||
|
# By default user is admin - now test non admin user
|
||||||
|
ctx = context.Context(user_id=None,
|
||||||
|
tenant_id=self._tenant_id,
|
||||||
|
is_admin=False,
|
||||||
|
read_deleted="no")
|
||||||
|
ports = plugin.get_ports(ctx)
|
||||||
|
self.assertEqual(len(ports), 2)
|
||||||
|
for non_admin_port in ports:
|
||||||
|
self.assertTrue('status' in non_admin_port)
|
||||||
|
self.assertFalse('binding:vif_type' in non_admin_port)
|
||||||
|
|
||||||
|
|
||||||
class TestOpenvswitchNetworksV2(test_plugin.TestNetworksV2,
|
class TestOpenvswitchNetworksV2(test_plugin.TestNetworksV2,
|
||||||
|
Loading…
Reference in New Issue
Block a user