OVO External Networks
This patch introduces and implements Olso-Versioned Objects for network extension External Networks. There were joined performed to order the fetching of external networks by standard attribute which seems useless because, in networks/services/auto_allocated/db.py while fetching external networks it logs error when multiple networks are returned. Expected default external network there is one, so ordering does not make much sense. Co-Authored-By: Manjeet Singh Bhatia <manjeet.s.bhatia@intel.com> Co-Authored-By: Victor Morales <victor.morales@intel.com> Change-Id: Iad609f72945b84df7881b43d1fdf9a188e5816bc Partially-Implements: blueprint adopt-oslo-versioned-objects-for-db
This commit is contained in:
parent
4118ea2e7b
commit
55090400ad
@ -17,7 +17,6 @@ from neutron_lib.api import validators
|
||||
from neutron_lib import constants
|
||||
from neutron_lib import exceptions as n_exc
|
||||
from neutron_lib.plugins import directory
|
||||
from sqlalchemy.orm import exc
|
||||
from sqlalchemy.sql import expression as expr
|
||||
|
||||
from neutron._i18n import _
|
||||
@ -28,12 +27,12 @@ from neutron.callbacks import registry
|
||||
from neutron.callbacks import resources
|
||||
from neutron.db import _utils as db_utils
|
||||
from neutron.db import db_base_plugin_v2
|
||||
from neutron.db.models import external_net as ext_net_models
|
||||
from neutron.db.models import l3 as l3_models
|
||||
from neutron.db import models_v2
|
||||
from neutron.db import rbac_db_models as rbac_db
|
||||
from neutron.extensions import external_net
|
||||
from neutron.extensions import rbac as rbac_ext
|
||||
from neutron.objects import network as net_obj
|
||||
|
||||
|
||||
DEVICE_OWNER_ROUTER_GW = constants.DEVICE_OWNER_ROUTER_GW
|
||||
@ -79,13 +78,8 @@ class External_net_db_mixin(object):
|
||||
'_network_result_filter_hook')
|
||||
|
||||
def _network_is_external(self, context, net_id):
|
||||
try:
|
||||
context.session.query(
|
||||
ext_net_models.ExternalNetwork).filter_by(
|
||||
network_id=net_id).one()
|
||||
return True
|
||||
except exc.NoResultFound:
|
||||
return False
|
||||
return net_obj.ExternalNetwork.objects_exist(
|
||||
context, network_id=net_id)
|
||||
|
||||
def _extend_network_dict_l3(self, network_res, network_db):
|
||||
# Comparing with None for converting uuid into bool
|
||||
@ -104,8 +98,8 @@ class External_net_db_mixin(object):
|
||||
return
|
||||
|
||||
if external:
|
||||
context.session.add(
|
||||
ext_net_models.ExternalNetwork(network_id=net_data['id']))
|
||||
net_obj.ExternalNetwork(
|
||||
context, network_id=net_data['id']).create()
|
||||
context.session.add(rbac_db.NetworkRBAC(
|
||||
object_id=net_data['id'], action='access_as_external',
|
||||
target_tenant='*', tenant_id=net_data['tenant_id']))
|
||||
@ -138,8 +132,8 @@ class External_net_db_mixin(object):
|
||||
return
|
||||
|
||||
if new_value:
|
||||
context.session.add(
|
||||
ext_net_models.ExternalNetwork(network_id=net_id))
|
||||
net_obj.ExternalNetwork(
|
||||
context, network_id=net_id).create()
|
||||
net_data[external_net.EXTERNAL] = True
|
||||
if allow_all:
|
||||
context.session.add(rbac_db.NetworkRBAC(
|
||||
@ -155,9 +149,8 @@ class External_net_db_mixin(object):
|
||||
if port:
|
||||
raise external_net.ExternalNetworkInUse(net_id=net_id)
|
||||
|
||||
for edb in (context.session.query(ext_net_models.ExternalNetwork).
|
||||
filter_by(network_id=net_id)):
|
||||
context.session.delete(edb)
|
||||
net_obj.ExternalNetwork.delete_objects(
|
||||
context, network_id=net_id)
|
||||
for rbdb in (context.session.query(rbac_db.NetworkRBAC).filter_by(
|
||||
object_id=net_id, action='access_as_external')):
|
||||
context.session.delete(rbdb)
|
||||
@ -226,10 +219,8 @@ class External_net_db_mixin(object):
|
||||
# deleting the wildcard is okay as long as the tenants with
|
||||
# attached routers have their own entries and the network is
|
||||
# not the default external network.
|
||||
is_default = context.session.query(
|
||||
ext_net_models.ExternalNetwork).filter_by(
|
||||
network_id=policy['object_id'], is_default=True).count()
|
||||
if is_default:
|
||||
if net_obj.ExternalNetwork.objects_exist(
|
||||
context, network_id=policy['object_id'], is_default=True):
|
||||
msg = _("Default external networks must be shared to "
|
||||
"everyone.")
|
||||
raise rbac_ext.RbacPolicyInUse(object_id=policy['object_id'],
|
||||
|
@ -17,6 +17,7 @@ from oslo_versionedobjects import fields as obj_fields
|
||||
|
||||
from neutron.db import api as db_api
|
||||
from neutron.db.models import dns as dns_models
|
||||
from neutron.db.models import external_net as ext_net_model
|
||||
from neutron.db.models import segment as segment_model
|
||||
from neutron.db import models_v2
|
||||
from neutron.db.port_security import models as ps_models
|
||||
@ -76,6 +77,23 @@ class NetworkPortSecurity(base_ps._PortSecurity):
|
||||
fields_need_translation = {'id': 'network_id'}
|
||||
|
||||
|
||||
@obj_base.VersionedObjectRegistry.register
|
||||
class ExternalNetwork(base.NeutronDbObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
db_model = ext_net_model.ExternalNetwork
|
||||
|
||||
foreign_keys = {'Network': {'network_id': 'id'}}
|
||||
|
||||
primary_keys = ['network_id']
|
||||
|
||||
fields = {
|
||||
'network_id': common_types.UUIDField(),
|
||||
'is_default': obj_fields.BooleanField(default=False),
|
||||
}
|
||||
|
||||
|
||||
@obj_base.VersionedObjectRegistry.register
|
||||
class Network(rbac_db.NeutronRbacObject):
|
||||
# Version 1.0: Initial version
|
||||
|
@ -18,7 +18,6 @@ from neutron_lib import constants
|
||||
from neutron_lib import exceptions as n_exc
|
||||
from neutron_lib.plugins import directory
|
||||
from oslo_log import log as logging
|
||||
from sqlalchemy import sql
|
||||
|
||||
from neutron._i18n import _, _LE
|
||||
from neutron.api.v2 import attributes
|
||||
@ -30,12 +29,11 @@ from neutron.db import _utils as db_utils
|
||||
from neutron.db import api as db_api
|
||||
from neutron.db import common_db_mixin
|
||||
from neutron.db import db_base_plugin_v2
|
||||
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 base as base_obj
|
||||
from neutron.objects import exceptions as obj_exc
|
||||
from neutron.objects import network as net_obj
|
||||
from neutron.plugins.common import utils as p_utils
|
||||
from neutron.services.auto_allocate import exceptions
|
||||
|
||||
@ -58,16 +56,20 @@ def _ensure_external_network_default_value_callback(
|
||||
is_default = request.get(IS_DEFAULT, False)
|
||||
if event in (events.BEFORE_CREATE, events.BEFORE_UPDATE) and is_default:
|
||||
# ensure there is only one default external network at any given time
|
||||
obj = (context.session.query(ext_net_models.ExternalNetwork).
|
||||
filter_by(is_default=True)).first()
|
||||
if obj and network['id'] != obj.network_id:
|
||||
raise exceptions.DefaultExternalNetworkExists(
|
||||
net_id=obj.network_id)
|
||||
pager = base_obj.Pager(limit=1)
|
||||
objs = net_obj.ExternalNetwork.get_objects(context,
|
||||
_pager=pager, is_default=True)
|
||||
if objs:
|
||||
if objs[0] and network['id'] != objs[0].network_id:
|
||||
raise exceptions.DefaultExternalNetworkExists(
|
||||
net_id=objs[0].network_id)
|
||||
|
||||
# Reflect the status of the is_default on the create/update request
|
||||
obj = (context.session.query(ext_net_models.ExternalNetwork).
|
||||
filter_by(network_id=network['id']))
|
||||
obj.update({IS_DEFAULT: is_default})
|
||||
obj = net_obj.ExternalNetwork.get_object(context,
|
||||
network_id=network['id'])
|
||||
if obj:
|
||||
obj.is_default = is_default
|
||||
obj.update()
|
||||
|
||||
|
||||
class AutoAllocatedTopologyMixin(common_db_mixin.CommonDbMixin):
|
||||
@ -216,13 +218,9 @@ class AutoAllocatedTopologyMixin(common_db_mixin.CommonDbMixin):
|
||||
|
||||
def _get_default_external_network(self, context):
|
||||
"""Get the default external network for the deployment."""
|
||||
with context.session.begin(subtransactions=True):
|
||||
default_external_networks = (context.session.query(
|
||||
ext_net_models.ExternalNetwork).
|
||||
filter_by(is_default=sql.true()).
|
||||
join(models_v2.Network).
|
||||
join(standard_attr.StandardAttribute).
|
||||
order_by(standard_attr.StandardAttribute.id).all())
|
||||
|
||||
default_external_networks = net_obj.ExternalNetwork.get_objects(
|
||||
context, is_default=True)
|
||||
|
||||
if not default_external_networks:
|
||||
LOG.error(_LE("Unable to find default external network "
|
||||
|
@ -21,7 +21,7 @@ from neutron_lib import context
|
||||
from oslo_utils import uuidutils
|
||||
import testscenarios
|
||||
|
||||
from neutron.db.models import external_net as ext_net_models
|
||||
from neutron.objects import network as net_obj
|
||||
from neutron.scheduler import l3_agent_scheduler
|
||||
from neutron.services.l3_router import l3_router_plugin
|
||||
from neutron.tests.common import helpers
|
||||
@ -570,9 +570,9 @@ class L3DVRSchedulerBaseTest(L3SchedulerBaseTest):
|
||||
network = self.plugin.create_network(self.adminContext,
|
||||
{'network': network_dict})
|
||||
if external:
|
||||
with self.adminContext.session.begin():
|
||||
network = ext_net_models.ExternalNetwork(network_id=net_id)
|
||||
self.adminContext.session.add(network)
|
||||
network = net_obj.ExternalNetwork(
|
||||
self.adminContext, network_id=net_id)
|
||||
network.create()
|
||||
|
||||
return network
|
||||
|
||||
|
@ -30,7 +30,6 @@ from neutron.common import utils
|
||||
from neutron.db import api as db_api
|
||||
from neutron.db import l3_db
|
||||
from neutron.db import l3_gwmode_db
|
||||
from neutron.db.models import external_net as ext_net_models
|
||||
from neutron.db.models import l3 as l3_models
|
||||
from neutron.db import models_v2
|
||||
from neutron.extensions import l3
|
||||
@ -138,10 +137,10 @@ class TestL3GwModeMixin(testlib_api.SqlTestCase):
|
||||
project_id=self.tenant_id,
|
||||
admin_state_up=True,
|
||||
status=constants.NET_STATUS_ACTIVE)
|
||||
self.net_ext = ext_net_models.ExternalNetwork(
|
||||
network_id=self.ext_net_id)
|
||||
self.net_ext = net_obj.ExternalNetwork(
|
||||
self.context, network_id=self.ext_net_id)
|
||||
self.network.create()
|
||||
self.context.session.add(self.net_ext)
|
||||
self.net_ext.create()
|
||||
self.router = l3_models.Router(
|
||||
id=_uuid(),
|
||||
name=None,
|
||||
|
@ -32,7 +32,6 @@ import testtools
|
||||
from neutron.common import constants
|
||||
from neutron.common import utils
|
||||
from neutron.db import db_base_plugin_v2
|
||||
from neutron.db.models import external_net as ext_net_model
|
||||
from neutron.db.models import l3 as l3_model
|
||||
from neutron.db import standard_attr
|
||||
from neutron import objects
|
||||
@ -1278,12 +1277,10 @@ class BaseDbObjectTestCase(_BaseObjectTestCase,
|
||||
|
||||
def _create_external_network(self):
|
||||
test_network = self._create_network()
|
||||
# TODO(manjeets) replace this with ext_net ovo
|
||||
# once it is implemented
|
||||
return obj_db_api.create_object(
|
||||
self.context,
|
||||
ext_net_model.ExternalNetwork,
|
||||
{'network_id': test_network['id']})
|
||||
ext_net = net_obj.ExternalNetwork(self.context,
|
||||
network_id=test_network['id'])
|
||||
ext_net.create()
|
||||
return ext_net
|
||||
|
||||
def _create_test_fip(self):
|
||||
fake_fip = '172.23.3.0'
|
||||
|
@ -181,3 +181,20 @@ class NetworkDNSDomainDbObjectTestcase(obj_test_base.BaseDbObjectTestCase,
|
||||
super(NetworkDNSDomainDbObjectTestcase, self).setUp()
|
||||
self.update_obj_fields(
|
||||
{'network_id': lambda: self._create_network().id})
|
||||
|
||||
|
||||
class ExternalNetworkIfaceObjectTestCase(
|
||||
obj_test_base.BaseObjectIfaceTestCase):
|
||||
|
||||
_test_class = network.ExternalNetwork
|
||||
|
||||
|
||||
class ExternalNetworkDbObjectTestCase(obj_test_base.BaseDbObjectTestCase,
|
||||
testlib_api.SqlTestCase):
|
||||
|
||||
_test_class = network.ExternalNetwork
|
||||
|
||||
def setUp(self):
|
||||
super(ExternalNetworkDbObjectTestCase, self).setUp()
|
||||
self.update_obj_fields(
|
||||
{'network_id': lambda: self._create_network().id})
|
||||
|
@ -34,6 +34,7 @@ object_data = {
|
||||
'AutoAllocatedTopology': '1.0-74642e58c53bf3610dc224c59f81b242',
|
||||
'DistributedPortBinding': '1.0-39c0d17b281991dcb66716fee5a8bef2',
|
||||
'DNSNameServer': '1.0-bf87a85327e2d812d1666ede99d9918b',
|
||||
'ExternalNetwork': '1.0-53d885e033cb931f9bb3bdd6bbe3f0ce',
|
||||
'ExtraDhcpOpt': '1.0-632f689cbeb36328995a7aed1d0a78d3',
|
||||
'FlatAllocation': '1.0-bf666f24f4642b047eeca62311fbcb41',
|
||||
'Flavor': '1.0-82194de5c9aafce08e8527bb7977f5c6',
|
||||
|
@ -25,10 +25,14 @@ from neutron.services.auto_allocate import exceptions
|
||||
from neutron.tests.unit import testlib_api
|
||||
|
||||
|
||||
class AutoAllocateTestCase(testlib_api.SqlTestCaseLight):
|
||||
DB_PLUGIN_KLASS = 'neutron.db.db_base_plugin_v2.NeutronDbPluginV2'
|
||||
|
||||
|
||||
class AutoAllocateTestCase(testlib_api.SqlTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(AutoAllocateTestCase, self).setUp()
|
||||
self.setup_coreplugin(core_plugin=DB_PLUGIN_KLASS)
|
||||
self.ctx = context.get_admin_context()
|
||||
self.mixin = db.AutoAllocatedTopologyMixin()
|
||||
self.mixin._l3_plugin = mock.Mock()
|
||||
|
Loading…
x
Reference in New Issue
Block a user