[apic_mapping] preexisting support for ASR L3out

1. added the error checkings while creating external segment.
2. added UTs for the above.

Change-Id: Ia2bff93b66f81c6820c3b41bc875f65c3b70c18d
Partial-Bug: 1547723
(cherry picked from commit 6fa1b06228)
This commit is contained in:
Kent Wu
2016-04-12 16:39:39 -07:00
parent 5f076fe8bc
commit 6eb389c4a8
2 changed files with 114 additions and 5 deletions

View File

@@ -155,6 +155,21 @@ class ASRBadVlanRange(gpexc.GroupPolicyBadRequest):
"when router_type is ASR.")
class ASRWrongL3OutIFType(gpexc.GroupPolicyBadRequest):
message = _("L3Out %(l3out)s can only support routed "
"sub-interfaces in the interface profiles when router_type "
"is ASR.")
class ASRWrongL3OutAuthTypeForBGP(gpexc.GroupPolicyBadRequest):
message = _("L3Out %(l3out)s can only support no authentication "
"for BGP interface profile when router_type is ASR.")
class ASRWrongL3OutAuthTypeForOSPF(gpexc.GroupPolicyBadRequest):
message = _("L3Out %(l3out)s can only support no authentication "
"for OSPF interface profile when router_type is ASR.")
REVERSE_PREFIX = 'reverse-'
SHADOW_PREFIX = 'Shd-'
SERVICE_PREFIX = 'Svc-'
@@ -3128,10 +3143,13 @@ class ApicMappingDriver(api.ResourceMappingDriver,
def _check_pre_existing_es(self, context, es):
if not self._is_pre_existing(es):
return
ext_info = self.apic_manager.ext_net_dict.get(es['name'])
is_asr_router = self._is_asr_router_type(ext_info)
l3out_info = self._query_l3out_info(
self.name_mapper.name_mapper.pre_existing(
context, es['name']),
self.name_mapper.tenant(es))
self.name_mapper.tenant(es),
return_full=is_asr_router)
if not l3out_info:
raise PreExistingL3OutNotFound(l3out=es['name'])
l3out_info['l3out_tenant'] = str(l3out_info['l3out_tenant'])
@@ -3141,6 +3159,22 @@ class ApicMappingDriver(api.ResourceMappingDriver,
raise PreExistingL3OutInIncorrectTenant(
l3out_tenant=l3out_info['l3out_tenant'],
l3out=es['name'], es=es['name'], es_tenant=es_tenant)
if is_asr_router:
l3out_str = str(l3out_info['l3out'])
for match in re.finditer("u'ifInstT': u'([^']+)'",
l3out_str):
if match.group(1) != 'sub-interface':
raise ASRWrongL3OutIFType(l3out=es['name'])
for match in re.finditer("u'authType': u'([^']+)'",
l3out_str):
if match.group(1) != 'none':
raise ASRWrongL3OutAuthTypeForOSPF(l3out=es['name'])
for match in re.finditer(
"u'bfdIfP': {u'attributes': {((?!u'attributes': {).)*u'type':"
" u'([^']+)'",
l3out_str):
if match.group(2) == 'sha1':
raise ASRWrongL3OutAuthTypeForBGP(l3out=es['name'])
def _create_tenant_filter(self, rule_name, tenant, entries=None,
transaction=None):

View File

@@ -190,7 +190,9 @@ class ApicMappingTestCase(
u'children': [{u'l3extLIfP':
{u'children': [{u'l3extRsPathL3OutAtt':
{u'attributes':
{u'encap': u'vlan-3101'}}}]}}
{u'encap': u'vlan-3101',
u'ifInstT': u'sub-interface'
}}}]}}
]}},
{u'l3extRsEctx':
{u'attributes':
@@ -204,9 +206,9 @@ class ApicMappingTestCase(
{"tnBgpPeerPfxPolName": ""}}, {"eigrpRsIfPol": {"tnEigrpIfPolName": ""}}, \
{"l3extLNodeP": {"attributes": {"dn": "uni/tn-test-tenant/out-Shd-Sub/\
lnodep-Leaf3-4_NP"}, "children": [{"l3extLIfP": {"children": [{"\
l3extRsPathL3OutAtt": {"attributes": {"encap": "vlan-999"}}}]}}]}}, {\
"l3extRsEctx": {"attributes": {"dn": "uni/tn-test-tenant/out-Shd-Sub/rsectx", \
"tnFvCtxName": "myl3p"}}}]}}'
l3extRsPathL3OutAtt": {"attributes": {"ifInstT": "sub-interface", "encap": \
"vlan-999"}}}]}}]}}, {"l3extRsEctx": {"attributes": {"dn": "uni/tn-test-tenant\
/out-Shd-Sub/rsectx", "tnFvCtxName": "myl3p"}}}]}}'
self.driver.apic_manager.apic.fvTenant.rn = echo2
self.driver.apic_manager.apic.l3extOut.rn = echo2
self.driver.l3out_vlan_alloc.reserve_vlan.return_value = 999
@@ -3197,6 +3199,79 @@ class TestExternalSegmentPreL3Out(TestExternalSegment):
tenant_id='some_other_tenant', cidr='192.168.0.2/24',
expected_res_status=201)
def test_asr_wrong_L3out_IF_type_rejected(self):
self._mock_external_dict([('supported', '192.168.0.2/24')],
is_asr_mode=True)
self.driver._query_l3out_info.return_value['l3out'] = (
[{u'l3extLNodeP':
{u'attributes':
{u'dn': u'uni/tn-common/out-supported/lnodep-Leaf3-4_NP'},
u'children': [{u'l3extLIfP':
{u'children': [{u'l3extRsPathL3OutAtt':
{u'attributes':
{u'ifInstT': u'ext-svi'
}}}]}}]}}])
res = self.create_external_segment(
name='supported', expected_res_status=400)
self.assertEqual('ASRWrongL3OutIFType', res['NeutronError']['type'])
def test_asr_wrong_L3out_OSPF_Auth_type_rejected(self):
self._mock_external_dict([('supported', '192.168.0.2/24')],
is_asr_mode=True)
self.driver._query_l3out_info.return_value['l3out'] = (
[{u'l3extLNodeP':
{u'attributes':
{u'dn': u'uni/tn-common/out-supported/lnodep-Leaf3-4_NP'},
u'children': [{u'l3extLIfP':
{u'children': [{u'ospfIfP':
{u'attributes':
{u'authType': u'simple'
}}}]}}]}}])
res = self.create_external_segment(
name='supported', expected_res_status=400)
self.assertEqual('ASRWrongL3OutAuthTypeForOSPF',
res['NeutronError']['type'])
def test_asr_wrong_L3out_BGP_Auth_type_rejected(self):
self._mock_external_dict([('supported', '192.168.0.2/24')],
is_asr_mode=True)
self.driver._query_l3out_info.return_value['l3out'] = (
[{u'l3extLNodeP':
{u'attributes':
{u'dn': u'uni/tn-common/out-supported/lnodep-Leaf3-4_NP'},
u'children': [{u'l3extLIfP':
{u'children': [{u'l3extRsNodeL3OutAtt':
{u'attributes':
{u'type': u'sha1'}}},
{u'bfdIfP':
{u'attributes':
{u'type': u'sha1'}}},
{u'l3extRsNodeL3OutAtt':
{u'attributes':
{u'type': u'sha1'}}}]}}]}}])
res = self.create_external_segment(
name='supported', expected_res_status=400)
self.assertEqual('ASRWrongL3OutAuthTypeForBGP',
res['NeutronError']['type'])
# try again with a good input
self.driver._query_l3out_info.return_value['l3out'] = (
[{u'l3extLNodeP':
{u'attributes':
{u'dn': u'uni/tn-common/out-supported/lnodep-Leaf3-4_NP'},
u'children': [{u'l3extLIfP':
{u'children': [{u'l3extRsNodeL3OutAtt':
{u'attributes':
{u'type': u'sha1'}}},
{u'bfdIfP':
{u'attributes':
{u'type': u'none'}}},
{u'l3extRsNodeL3OutAtt':
{u'attributes':
{u'type': u'sha1'}}}]}}]}}])
res = self.create_external_segment(
name='supported', expected_res_status=201)
class TestExternalSegmentNoNatPreL3Out(TestExternalSegmentPreL3Out):
def setUp(self):