Merge "Pre-existing SVI networks can not use the same L3out"

This commit is contained in:
Zuul 2018-03-12 20:47:30 +00:00 committed by Gerrit Code Review
commit 152ac15dd8
4 changed files with 37 additions and 2 deletions

View File

@ -60,6 +60,11 @@ class PreExistingSVICannotBeConnectedToRouter(exceptions.BadRequest):
"be connected to a router.")
class PreExistingSVICannotUseSameL3out(exceptions.BadRequest):
message = _("Can not create a SVI network with pre-existing l3out "
"if that l3out has been used by another SVI network.")
class OnlyOneSubnetInSVINetwork(exceptions.BadRequest):
message = _("Only one subnet is allowed in SVI network.")

View File

@ -17,6 +17,7 @@ from neutron.db import models_v2
from neutron_lib.db import model_base
import sqlalchemy as sa
from sqlalchemy import orm
from sqlalchemy.sql.expression import true
from gbpservice.neutron.extensions import cisco_apic
from gbpservice.neutron.extensions import cisco_apic_l3
@ -140,6 +141,14 @@ class ExtensionDbMixin(object):
ids = ids.with_lockmode('update')
return [i[0] for i in ids]
def get_svi_network_ids_by_l3out_dn(self, session, dn, lock_update=False):
ids = session.query(NetworkExtensionDb.network_id).filter(
NetworkExtensionDb.external_network_dn.like(dn + "/%"),
NetworkExtensionDb.svi == true())
if lock_update:
ids = ids.with_lockmode('update')
return [i[0] for i in ids]
def get_external_cidrs_by_ext_net_dn(self, session, dn, lock_update=False):
ctab = NetworkExtensionCidrDb
ntab = NetworkExtensionDb

View File

@ -499,10 +499,18 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
elif isinstance(resource, aim_resource.VRF):
vrf = resource
elif self._is_svi(current):
_, ext_net, _ = self._get_aim_external_objects(current)
l3out, ext_net, _ = self._get_aim_external_objects(current)
if ext_net:
extn_db = extension_db.ExtensionDbMixin()
other_nets = set(
extn_db.get_svi_network_ids_by_l3out_dn(session, l3out.dn,
lock_update=True))
other_nets.discard(current['id'])
if other_nets:
raise exceptions.PreExistingSVICannotUseSameL3out()
# This means no DN is being provided. Then we should try to create
# the l3out automatically
if not ext_net:
else:
tenant_aname = self.name_mapper.project(session,
current['tenant_id'])
vrf = self._map_unrouted_vrf()

View File

@ -1379,6 +1379,19 @@ class TestAimMapping(ApicAimTestCase):
n_context.get_admin_context(), router_id,
{'subnet_id': subnet1_id})
def test_preexist_svi_can_not_use_same_l3out(self):
self._make_network(
self.fmt, 'net1', True, arg_list=self.extension_attributes,
**{'apic:svi': 'True',
DN: {'ExternalNetwork': self.dn_t1_l1_n1}})
# Create another SVI network with same l3out should fail.
self.assertRaises(webob.exc.HTTPClientError, self._make_network,
self.fmt, 'net2', True,
arg_list=self.extension_attributes,
**{'apic:svi': 'True',
DN: {'ExternalNetwork': self.dn_t1_l1_n1}})
def test_only_one_subnet_allowed_in_svi(self):
# Create network.
net_resp = self._make_network(