Merge "use core resource api defs from lib"

This commit is contained in:
Zuul 2017-11-14 22:20:18 +00:00 committed by Gerrit Code Review
commit 01543b12fe
12 changed files with 24 additions and 303 deletions

View File

@ -13,13 +13,11 @@
# License for the specific language governing permissions and limitations
# under the License.
from neutron_lib.api import converters as lib_converters
from neutron_lib.api import attributes as attrs
from neutron_lib.api.definitions import network as net_def
from neutron_lib.api.definitions import port as port_def
from neutron_lib.api.definitions import subnet as subnet_def
from neutron_lib.api.definitions import subnetpool as subnetpool_def
from neutron_lib import constants
from neutron_lib.db import constants as db_const
# Defining a constant to avoid repeating string literal in several modules
@ -30,250 +28,8 @@ CORE_RESOURCES = {net_def.RESOURCE_NAME: net_def.COLLECTION_NAME,
subnet_def.RESOURCE_NAME: subnet_def.COLLECTION_NAME,
subnetpool_def.RESOURCE_NAME: subnetpool_def.COLLECTION_NAME,
port_def.RESOURCE_NAME: port_def.COLLECTION_NAME}
# Note: a default of ATTR_NOT_SPECIFIED indicates that an
# attribute is not required, but will be generated by the plugin
# if it is not specified. Particularly, a value of ATTR_NOT_SPECIFIED
# is different from an attribute that has been specified with a value of
# None. For example, if 'gateway_ip' is omitted in a request to
# create a subnet, the plugin will receive ATTR_NOT_SPECIFIED
# and the default gateway_ip will be generated.
# However, if gateway_ip is specified as None, this means that
# the subnet does not have a gateway IP.
# The following is a short reference for understanding attribute info:
# default: default value of the attribute (if missing, the attribute
# becomes mandatory.
# allow_post: the attribute can be used on POST requests.
# allow_put: the attribute can be used on PUT requests.
# validate: specifies rules for validating data in the attribute.
# convert_to: transformation to apply to the value before it is returned
# is_visible: the attribute is returned in GET responses.
# required_by_policy: the attribute is required by the policy engine and
# should therefore be filled by the API layer even if not present in
# request body.
# enforce_policy: the attribute is actively part of the policy enforcing
# mechanism, ie: there might be rules which refer to this attribute.
RESOURCE_ATTRIBUTE_MAP = {
net_def.COLLECTION_NAME: {
'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True,
'primary_key': True},
'name': {'allow_post': True, 'allow_put': True,
'validate': {'type:string': db_const.NAME_FIELD_SIZE},
'default': '', 'is_visible': True},
'subnets': {'allow_post': False, 'allow_put': False,
'default': [],
'is_visible': True},
'admin_state_up': {'allow_post': True, 'allow_put': True,
'default': True,
'convert_to': lib_converters.convert_to_boolean,
'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {
'type:string': db_const.PROJECT_ID_FIELD_SIZE},
'required_by_policy': True,
'is_visible': True},
SHARED: {'allow_post': True,
'allow_put': True,
'default': False,
'convert_to': lib_converters.convert_to_boolean,
'is_visible': True,
'required_by_policy': True,
'enforce_policy': True},
},
port_def.COLLECTION_NAME: {
'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True,
'primary_key': True},
'name': {'allow_post': True, 'allow_put': True, 'default': '',
'validate': {'type:string': db_const.NAME_FIELD_SIZE},
'is_visible': True},
'network_id': {'allow_post': True, 'allow_put': False,
'required_by_policy': True,
'validate': {'type:uuid': None},
'is_visible': True},
'admin_state_up': {'allow_post': True, 'allow_put': True,
'default': True,
'convert_to': lib_converters.convert_to_boolean,
'is_visible': True},
'mac_address': {'allow_post': True, 'allow_put': True,
'default': constants.ATTR_NOT_SPECIFIED,
'validate': {'type:mac_address': None},
'enforce_policy': True,
'is_visible': True},
'fixed_ips': {'allow_post': True, 'allow_put': True,
'default': constants.ATTR_NOT_SPECIFIED,
'convert_list_to':
lib_converters.convert_kvp_list_to_dict,
'validate': {'type:fixed_ips': None},
'enforce_policy': True,
'is_visible': True},
'device_id': {'allow_post': True, 'allow_put': True,
'validate': {
'type:string': db_const.DEVICE_ID_FIELD_SIZE},
'default': '',
'is_visible': True},
'device_owner': {'allow_post': True, 'allow_put': True,
'validate': {
'type:string': db_const.DEVICE_OWNER_FIELD_SIZE},
'default': '', 'enforce_policy': True,
'is_visible': True},
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {
'type:string': db_const.PROJECT_ID_FIELD_SIZE},
'required_by_policy': True,
'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
},
subnet_def.COLLECTION_NAME: {
'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True,
'primary_key': True},
'name': {'allow_post': True, 'allow_put': True, 'default': '',
'validate': {'type:string': db_const.NAME_FIELD_SIZE},
'is_visible': True},
'ip_version': {'allow_post': True, 'allow_put': False,
'convert_to': lib_converters.convert_to_int,
'validate': {'type:values': [4, 6]},
'is_visible': True},
'network_id': {'allow_post': True, 'allow_put': False,
'required_by_policy': True,
'validate': {'type:uuid': None},
'is_visible': True},
'subnetpool_id': {'allow_post': True,
'allow_put': False,
'default': constants.ATTR_NOT_SPECIFIED,
'required_by_policy': False,
'validate': {'type:subnetpool_id_or_none': None},
'is_visible': True},
'prefixlen': {'allow_post': True,
'allow_put': False,
'validate': {'type:non_negative': None},
'convert_to': lib_converters.convert_to_int,
'default': constants.ATTR_NOT_SPECIFIED,
'required_by_policy': False,
'is_visible': False},
'cidr': {'allow_post': True,
'allow_put': False,
'default': constants.ATTR_NOT_SPECIFIED,
'validate': {'type:subnet_or_none': None},
'required_by_policy': False,
'is_visible': True},
'gateway_ip': {'allow_post': True, 'allow_put': True,
'default': constants.ATTR_NOT_SPECIFIED,
'validate': {'type:ip_address_or_none': None},
'is_visible': True},
'allocation_pools': {'allow_post': True, 'allow_put': True,
'default': constants.ATTR_NOT_SPECIFIED,
'validate': {'type:ip_pools': None},
'is_visible': True},
'dns_nameservers': {'allow_post': True, 'allow_put': True,
'convert_to':
lib_converters.convert_none_to_empty_list,
'default': constants.ATTR_NOT_SPECIFIED,
'validate': {'type:nameservers': None},
'is_visible': True},
'host_routes': {'allow_post': True, 'allow_put': True,
'convert_to':
lib_converters.convert_none_to_empty_list,
'default': constants.ATTR_NOT_SPECIFIED,
'validate': {'type:hostroutes': None},
'is_visible': True},
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {
'type:string': db_const.PROJECT_ID_FIELD_SIZE},
'required_by_policy': True,
'is_visible': True},
'enable_dhcp': {'allow_post': True, 'allow_put': True,
'default': True,
'convert_to': lib_converters.convert_to_boolean,
'is_visible': True},
'ipv6_ra_mode': {'allow_post': True, 'allow_put': False,
'default': constants.ATTR_NOT_SPECIFIED,
'validate': {'type:values': constants.IPV6_MODES},
'is_visible': True},
'ipv6_address_mode': {'allow_post': True, 'allow_put': False,
'default': constants.ATTR_NOT_SPECIFIED,
'validate': {'type:values':
constants.IPV6_MODES},
'is_visible': True},
SHARED: {'allow_post': False,
'allow_put': False,
'default': False,
'convert_to': lib_converters.convert_to_boolean,
'is_visible': False,
'required_by_policy': True,
'enforce_policy': True},
},
subnetpool_def.COLLECTION_NAME: {
'id': {'allow_post': False,
'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True,
'primary_key': True},
'name': {'allow_post': True,
'allow_put': True,
'validate': {'type:not_empty_string': None},
'is_visible': True},
'tenant_id': {'allow_post': True,
'allow_put': False,
'validate': {
'type:string': db_const.PROJECT_ID_FIELD_SIZE},
'required_by_policy': True,
'is_visible': True},
'prefixes': {'allow_post': True,
'allow_put': True,
'validate': {'type:subnet_list': None},
'is_visible': True},
'default_quota': {'allow_post': True,
'allow_put': True,
'validate': {'type:non_negative': None},
'convert_to': lib_converters.convert_to_int,
'default': constants.ATTR_NOT_SPECIFIED,
'is_visible': True},
'ip_version': {'allow_post': False,
'allow_put': False,
'is_visible': True},
'default_prefixlen': {'allow_post': True,
'allow_put': True,
'validate': {'type:non_negative': None},
'convert_to': lib_converters.convert_to_int,
'default': constants.ATTR_NOT_SPECIFIED,
'is_visible': True},
'min_prefixlen': {'allow_post': True,
'allow_put': True,
'default': constants.ATTR_NOT_SPECIFIED,
'validate': {'type:non_negative': None},
'convert_to': lib_converters.convert_to_int,
'is_visible': True},
'max_prefixlen': {'allow_post': True,
'allow_put': True,
'default': constants.ATTR_NOT_SPECIFIED,
'validate': {'type:non_negative': None},
'convert_to': lib_converters.convert_to_int,
'is_visible': True},
'is_default': {'allow_post': True,
'allow_put': True,
'default': False,
'convert_to': lib_converters.convert_to_boolean,
'is_visible': True,
'required_by_policy': True,
'enforce_policy': True},
SHARED: {'allow_post': True,
'allow_put': False,
'default': False,
'convert_to': lib_converters.convert_to_boolean,
'is_visible': True,
'required_by_policy': True,
'enforce_policy': True},
}
}
RESOURCE_ATTRIBUTE_MAP = attrs.RESOURCES
# Identify the attribute used by a resource to reference another resource

View File

@ -288,7 +288,7 @@ class BaseTestCase(DietTestCase):
super(BaseTestCase, self).setUp()
self.useFixture(lockutils.ExternalLockFixture())
self.useFixture(tools.AttributeMapMemento())
self.useFixture(fixture.APIDefinitionFixture())
cfg.CONF.set_override('state_path', self.get_default_temp_dir().path)

View File

@ -16,12 +16,12 @@
import os.path
from neutron_lib import context
from neutron_lib import fixture
from neutron.api import extensions
from neutron.api.v2 import attributes
from neutron import policy
from neutron.tests import base
from neutron.tests import tools
TEST_PATH = os.path.dirname(os.path.abspath(__file__))
@ -39,7 +39,7 @@ class APIPolicyTestCase(base.BaseTestCase):
def setUp(self):
super(APIPolicyTestCase, self).setUp()
self.useFixture(tools.AttributeMapMemento())
self.useFixture(fixture.APIDefinitionFixture())
self.extension_path = os.path.abspath(os.path.join(
TEST_PATH, "../../../extensions"))
self.addCleanup(policy.reset)

View File

@ -24,51 +24,16 @@ import fixtures
import mock
import netaddr
from neutron_lib import constants
from neutron_lib import fixture
from neutron_lib.utils import helpers
from neutron_lib.utils import net
from oslo_utils import netutils
from oslo_utils import timeutils
import unittest2
from neutron.api.v2 import attributes
from neutron.common import constants as n_const
from neutron.services.logapi.common import constants as log_const
class AttributeMapMemento(fixture.APIDefinitionFixture):
"""Create a copy of the resource attribute map so it can be restored during
test cleanup.
There are a few reasons why this is not included in a class derived
from BaseTestCase:
- Test cases may need more control about when the backup is
made, especially if they are not direct descendants of
BaseTestCase.
- Inheritance is a bit of overkill for this facility and it's a
stretch to rationalize the "is a" criteria.
"""
def _setUp(self):
self.backup_global_resources = False
super(AttributeMapMemento, self)._setUp()
# Shallow copy is not a proper choice for keeping a backup copy as
# the RESOURCE_ATTRIBUTE_MAP map is modified in place through the
# 0th level keys. Ideally deepcopy() would be used but this seems
# to result in test failures. A compromise is to copy one level
# deeper than a shallow copy.
self.contents_backup = {}
for res, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.items():
self.contents_backup[res] = attrs.copy()
self.addCleanup(self.restore)
def restore(self):
super(AttributeMapMemento, self)._restore()
attributes.RESOURCE_ATTRIBUTE_MAP = self.contents_backup
class WarningsFixture(fixtures.Fixture):
"""Filters out warnings during test runs."""

View File

@ -21,6 +21,7 @@ from neutron_lib.callbacks import registry
from neutron_lib import constants
from neutron_lib import context
from neutron_lib import exceptions as n_exc
from neutron_lib import fixture
from neutron_lib.plugins import directory
from oslo_config import cfg
from oslo_db import exception as db_exc
@ -42,7 +43,6 @@ from neutron import quota
from neutron.quota import resource_registry
from neutron.tests import base
from neutron.tests import fake_notifier
from neutron.tests import tools
from neutron.tests.unit import dummy_plugin
from neutron.tests.unit import testlib_api
@ -1123,7 +1123,7 @@ class SubresourceTest(base.BaseTestCase):
plugin = 'neutron.tests.unit.api.v2.test_base.TestSubresourcePlugin'
extensions.PluginAwareExtensionManager._instance = None
self.useFixture(tools.AttributeMapMemento())
self.useFixture(fixture.APIDefinitionFixture())
self.config_parse()
self.setup_coreplugin(plugin, load_plugins=False)
@ -1454,7 +1454,7 @@ class ExtensionTestCase(base.BaseTestCase):
# Ensure existing ExtensionManager is not used
extensions.PluginAwareExtensionManager._instance = None
self.useFixture(tools.AttributeMapMemento())
self.useFixture(fixture.APIDefinitionFixture())
# Create the default configurations
self.config_parse()

View File

@ -26,6 +26,7 @@ from neutron_lib.callbacks import registry
from neutron_lib import constants
from neutron_lib import context
from neutron_lib import exceptions as lib_exc
from neutron_lib import fixture
from neutron_lib.plugins import directory
from neutron_lib.utils import helpers
from neutron_lib.utils import net
@ -116,7 +117,7 @@ class NeutronDbPluginV2TestCase(testlib_api.WebTestCase):
extensions.PluginAwareExtensionManager._instance = None
# Save the attributes map in case the plugin will alter it
# loading extensions
self.useFixture(tools.AttributeMapMemento())
self.useFixture(fixture.APIDefinitionFixture())
self._tenant_id = TEST_TENANT_ID
if not plugin:
@ -6652,7 +6653,7 @@ class DbOperationBoundMixin(object):
def setUp(self, *args, **kwargs):
super(DbOperationBoundMixin, self).setUp(*args, **kwargs)
self.useFixture(tools.AttributeMapMemento())
self.useFixture(fixture.APIDefinitionFixture())
self._recorded_statements = []
def _event_incrementer(conn, clauseelement, *args, **kwargs):

View File

@ -17,6 +17,7 @@
# under the License.
import mock
from neutron_lib import fixture
from oslo_config import cfg
from oslo_utils import uuidutils
from webob import exc
@ -25,7 +26,6 @@ import webtest
from neutron.api import extensions
from neutron import manager
from neutron import quota
from neutron.tests import tools
from neutron.tests.unit.api import test_extensions
from neutron.tests.unit.api.v2 import test_base
from neutron.tests.unit import testlib_api
@ -54,7 +54,7 @@ class ExtensionTestCase(testlib_api.WebTestCase):
# Ensure existing ExtensionManager is not used
extensions.PluginAwareExtensionManager._instance = None
self.useFixture(tools.AttributeMapMemento())
self.useFixture(fixture.APIDefinitionFixture())
# Create the default configurations
self.config_parse()

View File

@ -16,6 +16,7 @@
import mock
from neutron_lib.api.definitions import provider_net
from neutron_lib import context
from neutron_lib import fixture
from neutron_lib.plugins import constants
from neutron_lib.plugins import directory
from oslo_config import cfg
@ -27,7 +28,6 @@ from neutron.api import extensions
from neutron.api.v2 import router
from neutron.extensions import providernet as pnet
from neutron import quota
from neutron.tests import tools
from neutron.tests.unit.api import test_extensions
from neutron.tests.unit.api.v2 import test_base
from neutron.tests.unit import testlib_api
@ -59,7 +59,7 @@ class ProvidernetExtensionTestCase(testlib_api.WebTestCase):
# Ensure existing ExtensionManager is not used
extensions.PluginAwareExtensionManager._instance = None
self.useFixture(tools.AttributeMapMemento())
self.useFixture(fixture.APIDefinitionFixture())
# Update the plugin and extensions path
self.setup_coreplugin(plugin, load_plugins=False)

View File

@ -18,6 +18,7 @@ import sys
import mock
from neutron_lib import context
from neutron_lib.db import constants
from neutron_lib import fixture
from oslo_config import cfg
import testtools
from webob import exc
@ -32,7 +33,6 @@ from neutron.db.quota import driver
from neutron import quota
from neutron.quota import resource_registry
from neutron.tests import base
from neutron.tests import tools
from neutron.tests.unit.api.v2 import test_base
from neutron.tests.unit import testlib_api
@ -49,7 +49,7 @@ class QuotaExtensionTestCase(testlib_api.WebTestCase):
# Ensure existing ExtensionManager is not used
extensions.PluginAwareExtensionManager._instance = None
self.useFixture(tools.AttributeMapMemento())
self.useFixture(fixture.APIDefinitionFixture())
# Create the default configurations
self.config_parse()

View File

@ -15,17 +15,16 @@
import mock
from neutron_lib import context
from neutron_lib import fixture
from oslo_config import cfg
import webtest
from neutron_lib import context
from neutron.api import extensions
from neutron.api.v2 import router
from neutron.common import config
from neutron.conf import quota as qconf
from neutron import quota
from neutron.tests import tools
from neutron.tests.unit.api.v2 import test_base
from neutron.tests.unit import testlib_api
@ -42,7 +41,7 @@ class DetailQuotaExtensionTestCase(testlib_api.WebTestCase):
# Ensure existing ExtensionManager is not used
extensions.PluginAwareExtensionManager._instance = None
self.useFixture(tools.AttributeMapMemento())
self.useFixture(fixture.APIDefinitionFixture())
# Create the default configurations
self.config_parse()

View File

@ -22,10 +22,10 @@ from neutron_lib.callbacks import registry
from neutron_lib.callbacks import resources
from neutron_lib import constants as const
from neutron_lib import context
from neutron_lib import fixture
from neutron_lib.plugins import directory
from neutron.extensions import securitygroup as ext_sg
from neutron.tests import tools
from neutron.tests.unit.agent import test_securitygroups_rpc as test_sg_rpc
from neutron.tests.unit.api.v2 import test_base
from neutron.tests.unit.extensions import test_securitygroup as test_sg
@ -41,7 +41,7 @@ class Ml2SecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase):
notifier_cls = notifier_p.start()
self.notifier = mock.Mock()
notifier_cls.return_value = self.notifier
self.useFixture(tools.AttributeMapMemento())
self.useFixture(fixture.APIDefinitionFixture())
super(Ml2SecurityGroupsTestCase, self).setUp('ml2')

View File

@ -12,10 +12,10 @@
import mock
from neutron_lib import context
from neutron_lib import fixture
from oslo_utils import uuidutils
from neutron.db.quota import api as quota_db_api
from neutron.tests import tools
from neutron.tests.unit.api import test_extensions
from neutron.tests.unit.extensions import test_l3
from neutron.tests.unit.extensions import test_securitygroup
@ -162,7 +162,7 @@ class TestL3ResourcesEventHandler(BaseTestEventHandler,
def setUp(self):
super(TestL3ResourcesEventHandler, self).setUp()
self.useFixture(tools.AttributeMapMemento())
self.useFixture(fixture.APIDefinitionFixture())
ext_mgr = test_l3.L3TestExtensionManager()
self.ext_api = test_extensions.setup_extensions_middleware(ext_mgr)