Fix per-project quotas for L3 plugin
The GBP L3 plugin is using the old quotas driver. This prevents per-project quotas for L3 resources. The L3 plugin should be changed to support the new qutoas driver. Change-Id: Idbc651a905ca5c567527ba2094a83b2d0486ca9a Closes-Bug: 1709456 (cherry picked from commit194dd33947
) (cherry picked from commit41152b4fde
) (cherry picked from commitc5a45bd3ce
)
This commit is contained in:
parent
496f33f785
commit
1fb474945e
|
@ -33,6 +33,7 @@ extensions.get_extensions_path = get_extensions_path
|
|||
|
||||
|
||||
from neutron.db import models_v2
|
||||
from neutron.db.quota import driver # noqa
|
||||
from neutron.plugins.ml2 import db as ml2_db
|
||||
from neutron.plugins.ml2 import models
|
||||
from oslo_log import log as logging
|
||||
|
|
|
@ -19,10 +19,12 @@ from neutron.api import extensions
|
|||
from neutron.db import common_db_mixin
|
||||
from neutron.db import db_base_plugin_v2
|
||||
from neutron.db import extraroute_db
|
||||
from neutron.db import l3_db
|
||||
from neutron.db import l3_gwmode_db
|
||||
from neutron.extensions import l3
|
||||
from neutron.extensions import portbindings
|
||||
from neutron.plugins.common import constants
|
||||
from neutron.quota import resource_registry
|
||||
from neutron_lib import exceptions
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import excutils
|
||||
|
@ -54,6 +56,8 @@ class ApicL3Plugin(common_db_mixin.CommonDbMixin,
|
|||
def get_plugin_description():
|
||||
return _("L3 Router Service Plugin using the APIC via AIM")
|
||||
|
||||
@resource_registry.tracked_resources(router=l3_db.Router,
|
||||
floatingip=l3_db.FloatingIP)
|
||||
def __init__(self):
|
||||
LOG.info(_LI("APIC AIM L3 Plugin __init__"))
|
||||
extensions.append_api_extensions_path(extensions_pkg.__path__)
|
||||
|
|
|
@ -35,8 +35,31 @@ class TestCiscoApicAimL3Plugin(test_aim_mapping_driver.AIMBaseTestCase):
|
|||
class so that it can inherit test infrastructure from those classes.
|
||||
'''
|
||||
|
||||
def _verify_event_handler_calls(self, data, expected_call_count=1):
|
||||
if not hasattr(data, '__iter__') or isinstance(data, dict):
|
||||
data = [data]
|
||||
self.assertEqual(expected_call_count, self.handler_mock.call_count)
|
||||
call_idx = -1
|
||||
for item in data:
|
||||
if item:
|
||||
model = self.handler_mock.call_args_list[call_idx][0][-1]
|
||||
self.assertEqual(model['id'], item['id'])
|
||||
self.assertEqual(model['tenant_id'], item['tenant_id'])
|
||||
call_idx = call_idx - 1
|
||||
|
||||
def setUp(self):
|
||||
handler_patch = mock.patch(
|
||||
'neutron.quota.resource.TrackedResource._db_event_handler')
|
||||
self.handler_mock = handler_patch.start()
|
||||
def_sec_group_patch = mock.patch(
|
||||
'neutron.db.securitygroups_db.SecurityGroupDbMixin.'
|
||||
'_ensure_default_security_group')
|
||||
def_sec_group_patch.start()
|
||||
super(TestCiscoApicAimL3Plugin, self).setUp()
|
||||
get_sec_group_port_patch = mock.patch(
|
||||
'neutron.db.securitygroups_db.SecurityGroupDbMixin.'
|
||||
'_get_security_groups_on_port')
|
||||
get_sec_group_port_patch.start()
|
||||
|
||||
# Set up L2 objects for L3 test
|
||||
attr = {'tenant_id': TENANT}
|
||||
|
@ -93,3 +116,28 @@ class TestCiscoApicAimL3Plugin(test_aim_mapping_driver.AIMBaseTestCase):
|
|||
|
||||
def test_remove_router_interface_port(self):
|
||||
self._test_remove_router_interface(self.interface_info['port'])
|
||||
|
||||
def test_create_delete_floating_ip_triggers_event(self):
|
||||
net = self._make_network('json', 'meh', True)
|
||||
subnet = self._make_subnet('json', net, '14.0.0.1',
|
||||
'14.0.0.0/24')['subnet']
|
||||
self._set_net_external(subnet['network_id'])
|
||||
kwargs = {'floatingip': {'tenant_id': TENANT,
|
||||
'subnet_id': subnet['id'],
|
||||
'floating_network_id': subnet['network_id']}}
|
||||
self.handler_mock.reset_mock()
|
||||
floatingip = self.plugin.create_floatingip(self.context, kwargs)
|
||||
internal_ports = self._show('ports',
|
||||
floatingip['port_id'])['ports']
|
||||
for port in internal_ports:
|
||||
if port['device_owner'] == 'network:floatingip' and (
|
||||
port['device_id'] == floatingip['id']):
|
||||
internal_port = port
|
||||
# When a floatingip is created it also creates port, therefore
|
||||
# there will be four calls in total to the event handler
|
||||
self._verify_event_handler_calls(floatingip,
|
||||
expected_call_count=2)
|
||||
self._delete('floatingips', floatingip['id'])
|
||||
# Expecting 2 more calls - 1 for the port, 1 for the floatingip
|
||||
self._verify_event_handler_calls(
|
||||
[internal_port, floatingip], expected_call_count=4)
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
# 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 functools
|
||||
import mock
|
||||
|
||||
from neutron.api import extensions
|
||||
from neutron.tests.unit.plugins.ml2 import (
|
||||
test_tracked_resources as n_tracked)
|
||||
from neutron.tests.unit.plugins.ml2 import test_plugin
|
||||
|
||||
from gbpservice.neutron.db import implicitsubnetpool_db # noqa
|
||||
import gbpservice.neutron.extensions
|
||||
|
||||
PLUGIN_NAME = 'ml2plus'
|
||||
|
||||
|
||||
class Ml2PlusConfFixture(test_plugin.PluginConfFixture):
|
||||
|
||||
def __init__(self, parent_setup=None):
|
||||
super(Ml2PlusConfFixture, self).__init__(PLUGIN_NAME, parent_setup)
|
||||
|
||||
|
||||
class Ml2PlusTestTrackedResourcesEventHandler(
|
||||
n_tracked.TestTrackedResourcesEventHandler):
|
||||
|
||||
def setUp(self):
|
||||
extensions.append_api_extensions_path(
|
||||
gbpservice.neutron.extensions.__path__)
|
||||
# Prevent noise from default security group operations
|
||||
super(Ml2PlusTestTrackedResourcesEventHandler, self).setUp()
|
||||
get_sec_group_port_patch = mock.patch(
|
||||
'neutron.db.securitygroups_db.SecurityGroupDbMixin.'
|
||||
'_get_security_groups_on_port')
|
||||
get_sec_group_port_patch.start()
|
||||
|
||||
def setup_parent(self):
|
||||
"""Perform parent setup with the common plugin configuration class."""
|
||||
service_plugins = {'l3_plugin_name': self.l3_plugin}
|
||||
# Ensure that the parent setup can be called without arguments
|
||||
# by the common configuration setUp.
|
||||
parent_setup = functools.partial(
|
||||
super(test_plugin.Ml2PluginV2TestCase, self).setUp,
|
||||
plugin=PLUGIN_NAME,
|
||||
service_plugins=service_plugins,
|
||||
)
|
||||
self.useFixture(Ml2PlusConfFixture(parent_setup))
|
||||
self.port_create_status = 'DOWN'
|
||||
|
||||
|
||||
class Ml2PlusTestTrackedResources(n_tracked.TestTrackedResources):
|
||||
|
||||
def setUp(self):
|
||||
extensions.append_api_extensions_path(
|
||||
gbpservice.neutron.extensions.__path__)
|
||||
# Prevent noise from default security group operations
|
||||
super(Ml2PlusTestTrackedResources, self).setUp()
|
||||
get_sec_group_port_patch = mock.patch(
|
||||
'neutron.db.securitygroups_db.SecurityGroupDbMixin.'
|
||||
'_get_security_groups_on_port')
|
||||
get_sec_group_port_patch.start()
|
||||
|
||||
def setup_parent(self):
|
||||
"""Perform parent setup with the common plugin configuration class."""
|
||||
service_plugins = {'l3_plugin_name': self.l3_plugin}
|
||||
# Ensure that the parent setup can be called without arguments
|
||||
# by the common configuration setUp.
|
||||
parent_setup = functools.partial(
|
||||
super(test_plugin.Ml2PluginV2TestCase, self).setUp,
|
||||
plugin=PLUGIN_NAME,
|
||||
service_plugins=service_plugins,
|
||||
)
|
||||
self.useFixture(Ml2PlusConfFixture(parent_setup))
|
||||
self.port_create_status = 'DOWN'
|
Loading…
Reference in New Issue