From 39c74b05339c43b1e6dfc1467786a2e3179a5b84 Mon Sep 17 00:00:00 2001 From: Mohit Malik Date: Thu, 18 Aug 2016 14:42:20 -0700 Subject: [PATCH] Add OVO for AutoAllocatedTopology This patch integrates and implements Oslo-Versioned Objects for Auto Allocated Topology. Change-Id: I478af7aa118a947cc9eab36b047cecea6ddd5170 Partially-Implements: blueprint adopt-oslo-versioned-objects-for-db Co-Authored-By: Anindita Das --- neutron/objects/auto_allocate.py | 37 +++++++++++++++++++ neutron/services/auto_allocate/db.py | 25 ++++--------- .../tests/unit/objects/test_auto_allocate.py | 36 ++++++++++++++++++ neutron/tests/unit/objects/test_objects.py | 1 + 4 files changed, 82 insertions(+), 17 deletions(-) create mode 100644 neutron/objects/auto_allocate.py create mode 100644 neutron/tests/unit/objects/test_auto_allocate.py diff --git a/neutron/objects/auto_allocate.py b/neutron/objects/auto_allocate.py new file mode 100644 index 00000000000..9fbc6766950 --- /dev/null +++ b/neutron/objects/auto_allocate.py @@ -0,0 +1,37 @@ +# Copyright (c) 2016 Intel Corporation. +# 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. + +from oslo_versionedobjects import base as obj_base +from oslo_versionedobjects import fields as obj_fields + +from neutron.objects import base +from neutron.objects import common_types +from neutron.services.auto_allocate import models + + +@obj_base.VersionedObjectRegistry.register +class AutoAllocatedTopology(base.NeutronDbObject): + # Version 1.0: Initial version + VERSION = '1.0' + + db_model = models.AutoAllocatedTopology + + primary_keys = ['project_id'] + + fields = { + 'project_id': obj_fields.StringField(), + 'network_id': common_types.UUIDField(), + 'router_id': common_types.UUIDField(nullable=True), + } diff --git a/neutron/services/auto_allocate/db.py b/neutron/services/auto_allocate/db.py index a2407432de1..01648afb8b8 100644 --- a/neutron/services/auto_allocate/db.py +++ b/neutron/services/auto_allocate/db.py @@ -17,7 +17,6 @@ from neutron_lib import constants from neutron_lib import exceptions as n_exc from neutron_lib.plugins import directory -from oslo_db import exception as db_exc from oslo_log import log as logging from sqlalchemy import sql @@ -35,9 +34,10 @@ from neutron.db.models import external_net as ext_net_models from neutron.db import models_v2 from neutron.db import standard_attr from neutron.extensions import l3 +from neutron.objects import auto_allocate as auto_allocate_obj +from neutron.objects import exceptions as obj_exc from neutron.plugins.common import utils as p_utils from neutron.services.auto_allocate import exceptions -from neutron.services.auto_allocate import models LOG = logging.getLogger(__name__) IS_DEFAULT = 'is_default' @@ -198,9 +198,8 @@ class AutoAllocatedTopologyMixin(common_db_mixin.CommonDbMixin): def _get_auto_allocated_topology(self, context, tenant_id): """Return the auto allocated topology record if present or None.""" - with context.session.begin(subtransactions=True): - return (context.session.query(models.AutoAllocatedTopology). - filter_by(tenant_id=tenant_id).first()) + return auto_allocate_obj.AutoAllocatedTopology.get_object( + context, project_id=tenant_id) def _get_auto_allocated_network(self, context, tenant_id): """Get the auto allocated network for the tenant.""" @@ -331,21 +330,13 @@ class AutoAllocatedTopologyMixin(common_db_mixin.CommonDbMixin): def _save(self, context, tenant_id, network_id, router_id, subnets): """Save auto-allocated topology, or revert in case of DB errors.""" try: - # NOTE(armax): saving the auto allocated topology in a - # separate transaction will keep the Neutron DB and the - # Neutron plugin backend in sync, thus allowing for a - # more bullet proof cleanup. Any other error will have - # to bubble up. - with context.session.begin(subtransactions=True): - context.session.add( - models.AutoAllocatedTopology( - tenant_id=tenant_id, - network_id=network_id, - router_id=router_id)) + auto_allocate_obj.AutoAllocatedTopology( + context, project_id=tenant_id, network_id=network_id, + router_id=router_id).create() self.core_plugin.update_network( context, network_id, {'network': {'admin_state_up': True}}) - except db_exc.DBDuplicateEntry: + except obj_exc.NeutronDbObjectDuplicateEntry: LOG.debug("Multiple auto-allocated networks detected for " "tenant %s. Attempting clean up for network %s " "and router %s.", diff --git a/neutron/tests/unit/objects/test_auto_allocate.py b/neutron/tests/unit/objects/test_auto_allocate.py new file mode 100644 index 00000000000..aa6a5cfa397 --- /dev/null +++ b/neutron/tests/unit/objects/test_auto_allocate.py @@ -0,0 +1,36 @@ +# Copyright (c) 2016 Intel Corporation. +# +# 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 neutron.objects import auto_allocate +from neutron.tests.unit.objects import test_base as obj_test_base +from neutron.tests.unit import testlib_api + + +class AutoAllocateTopologyIfaceObjectTestCase( + obj_test_base.BaseObjectIfaceTestCase): + + _test_class = auto_allocate.AutoAllocatedTopology + + +class AutoAllocateTopologyDbObjectTestCase(obj_test_base.BaseDbObjectTestCase, + testlib_api.SqlTestCase): + + _test_class = auto_allocate.AutoAllocatedTopology + + def setUp(self): + super(AutoAllocateTopologyDbObjectTestCase, self).setUp() + self._create_test_network() + self._create_test_router() + self.update_obj_fields({'network_id': self._network['id'], + 'router_id': self._router['id']}) diff --git a/neutron/tests/unit/objects/test_objects.py b/neutron/tests/unit/objects/test_objects.py index 7e4b80b024b..34fd40b0028 100644 --- a/neutron/tests/unit/objects/test_objects.py +++ b/neutron/tests/unit/objects/test_objects.py @@ -31,6 +31,7 @@ object_data = { 'AddressScope': '1.0-dd0dfdb67775892d3adc090e28e43bd8', 'Agent': '1.0-7106cb40117a8d1f042545796ed8787d', 'AllowedAddressPair': '1.0-9f9186b6f952fbf31d257b0458b852c0', + 'AutoAllocatedTopology': '1.0-74642e58c53bf3610dc224c59f81b242', 'DistributedPortBinding': '1.0-39c0d17b281991dcb66716fee5a8bef2', 'DNSNameServer': '1.0-bf87a85327e2d812d1666ede99d9918b', 'ExtraDhcpOpt': '1.0-632f689cbeb36328995a7aed1d0a78d3',