[AIM] Add Policy Enforcement Pref to network extension
Add apic:policy_enforcement_pref attribute to the cisco_apic network extension. Change-Id: Ied38d60a6624791c7c0a9a92e247b04fe969402e
This commit is contained in:
parent
f123939b8a
commit
3cb18aca75
@ -0,0 +1,37 @@
|
||||
# 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.
|
||||
|
||||
"""add policy enforcement pref attribute
|
||||
|
||||
Revision ID: 872bf4ba86a6
|
||||
Revises: 016a678fafd4
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '872bf4ba86a6'
|
||||
down_revision = '016a678fafd4'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.add_column('apic_aim_network_extensions',
|
||||
sa.Column('policy_enforcement_pref',
|
||||
sa.Enum('unenforced', 'enforced', ''),
|
||||
server_default="unenforced",
|
||||
nullable=False))
|
||||
|
||||
|
||||
def downgrade():
|
||||
pass
|
@ -1 +1 @@
|
||||
016a678fafd4
|
||||
872bf4ba86a6
|
||||
|
@ -48,6 +48,7 @@ EXTRA_PROVIDED_CONTRACTS = 'apic:extra_provided_contracts'
|
||||
EXTRA_CONSUMED_CONTRACTS = 'apic:extra_consumed_contracts'
|
||||
EPG_CONTRACT_MASTERS = 'apic:epg_contract_masters'
|
||||
ERSPAN_CONFIG = 'apic:erspan_config'
|
||||
POLICY_ENFORCEMENT_PREF = 'apic:policy_enforcement_pref'
|
||||
|
||||
BD = 'BridgeDomain'
|
||||
EPG = 'EndpointGroup'
|
||||
@ -336,6 +337,11 @@ NET_ATTRIBUTES = {
|
||||
},
|
||||
}
|
||||
},
|
||||
POLICY_ENFORCEMENT_PREF: {
|
||||
'allow_post': True, 'allow_put': True,
|
||||
'is_visible': True, 'default': 'unenforced',
|
||||
'validate': {'type:values': ['unenforced', 'enforced', '']},
|
||||
},
|
||||
}
|
||||
|
||||
EXT_NET_ATTRIBUTES = {
|
||||
|
@ -115,6 +115,11 @@ class InvalidNetworkForEpgContractMaster(exceptions.BadRequest):
|
||||
"an external or SVI network.")
|
||||
|
||||
|
||||
class InvalidNetworkForPolicyEnforcementPref(exceptions.BadRequest):
|
||||
message = _("apic:policy_enforcement_pref cannot be 'enforced' for "
|
||||
"SVI network.")
|
||||
|
||||
|
||||
class InvalidNetworkForQos(exceptions.BadRequest):
|
||||
message = _("Cannot specify qos policy for "
|
||||
"an external or SVI network.")
|
||||
|
@ -66,6 +66,9 @@ class NetworkExtensionDb(model_base.BASEV2):
|
||||
default='default_export',
|
||||
nullable=False)
|
||||
bgp_asn = sa.Column(sa.String(64), default='0', nullable=False)
|
||||
policy_enforcement_pref = sa.Column(sa.Enum('unenforced', 'enforced', ''),
|
||||
default='unenforced',
|
||||
nullable=False)
|
||||
|
||||
network = orm.relationship(models_v2.Network,
|
||||
backref=orm.backref(
|
||||
@ -331,6 +334,8 @@ class ExtensionDbMixin(object):
|
||||
net_res[cisco_apic.EPG_CONTRACT_MASTERS] = [
|
||||
{'app_profile_name': m.app_profile_name,
|
||||
'name': m.name} for m in db_masters]
|
||||
net_res[cisco_apic.POLICY_ENFORCEMENT_PREF] = db_obj[
|
||||
'policy_enforcement_pref']
|
||||
if net_res.get(cisco_apic.EXTERNAL_NETWORK):
|
||||
net_res[cisco_apic.EXTERNAL_CIDRS] = [c.cidr for c in db_cidrs]
|
||||
return net_res
|
||||
@ -376,6 +381,9 @@ class ExtensionDbMixin(object):
|
||||
if cisco_apic.NESTED_DOMAIN_NODE_NETWORK_VLAN in res_dict:
|
||||
db_obj['nested_domain_node_network_vlan'] = res_dict[
|
||||
cisco_apic.NESTED_DOMAIN_NODE_NETWORK_VLAN]
|
||||
if cisco_apic.POLICY_ENFORCEMENT_PREF in res_dict:
|
||||
db_obj['policy_enforcement_pref'] = res_dict[
|
||||
cisco_apic.POLICY_ENFORCEMENT_PREF]
|
||||
session.add(db_obj)
|
||||
|
||||
if cisco_apic.EXTERNAL_CIDRS in res_dict:
|
||||
|
@ -158,6 +158,8 @@ class ApicExtensionDriver(api_plus.ExtensionDriver,
|
||||
data.get(cisco_apic.EXTRA_CONSUMED_CONTRACTS),
|
||||
cisco_apic.EPG_CONTRACT_MASTERS:
|
||||
data.get(cisco_apic.EPG_CONTRACT_MASTERS),
|
||||
cisco_apic.POLICY_ENFORCEMENT_PREF:
|
||||
data.get(cisco_apic.POLICY_ENFORCEMENT_PREF, "unenforced"),
|
||||
}
|
||||
if cisco_apic.VLANS_LIST in (data.get(
|
||||
cisco_apic.NESTED_DOMAIN_ALLOWED_VLANS) or {}):
|
||||
@ -219,7 +221,8 @@ class ApicExtensionDriver(api_plus.ExtensionDriver,
|
||||
cisco_apic.NESTED_DOMAIN_ALLOWED_VLANS,
|
||||
cisco_apic.EXTRA_PROVIDED_CONTRACTS,
|
||||
cisco_apic.EXTRA_CONSUMED_CONTRACTS,
|
||||
cisco_apic.EPG_CONTRACT_MASTERS]
|
||||
cisco_apic.EPG_CONTRACT_MASTERS,
|
||||
cisco_apic.POLICY_ENFORCEMENT_PREF]
|
||||
if not(set(update_attrs) & set(data.keys())):
|
||||
return
|
||||
|
||||
@ -238,7 +241,8 @@ class ApicExtensionDriver(api_plus.ExtensionDriver,
|
||||
cisco_apic.NESTED_DOMAIN_NODE_NETWORK_VLAN,
|
||||
cisco_apic.EXTRA_PROVIDED_CONTRACTS,
|
||||
cisco_apic.EXTRA_CONSUMED_CONTRACTS,
|
||||
cisco_apic.EPG_CONTRACT_MASTERS]
|
||||
cisco_apic.EPG_CONTRACT_MASTERS,
|
||||
cisco_apic.POLICY_ENFORCEMENT_PREF]
|
||||
for e_k in ext_keys:
|
||||
if e_k in data:
|
||||
res_dict.update({e_k: data[e_k]})
|
||||
|
@ -792,6 +792,10 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
||||
if (current[cisco_apic.EPG_CONTRACT_MASTERS] and (is_ext or is_svi)):
|
||||
raise exceptions.InvalidNetworkForEpgContractMaster()
|
||||
|
||||
if current[cisco_apic.POLICY_ENFORCEMENT_PREF] == 'enforced' and \
|
||||
is_svi:
|
||||
raise exceptions.InvalidNetworkForPolicyEnforcementPref()
|
||||
|
||||
if (current.get(qos_consts.QOS_POLICY_ID) and (is_ext or is_svi)):
|
||||
raise exceptions.InvalidNetworkForQos()
|
||||
|
||||
@ -928,6 +932,8 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
||||
cisco_apic.EXTRA_CONSUMED_CONTRACTS]
|
||||
epg.epg_contract_masters = current[
|
||||
cisco_apic.EPG_CONTRACT_MASTERS]
|
||||
epg.policy_enforcement_pref = current[
|
||||
cisco_apic.POLICY_ENFORCEMENT_PREF]
|
||||
epg.qos_name = current.get(qos_consts.QOS_POLICY_ID, None)
|
||||
self.aim.create(aim_ctx, epg)
|
||||
|
||||
@ -1016,6 +1022,17 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
||||
self.aim.update(
|
||||
aim_ctx, epg, epg_contract_masters=curr_masters)
|
||||
|
||||
# Update Policy Enforcement Pref if changed.
|
||||
curr_masters = current[cisco_apic.POLICY_ENFORCEMENT_PREF]
|
||||
orig_masters = original[cisco_apic.POLICY_ENFORCEMENT_PREF]
|
||||
if curr_masters != orig_masters:
|
||||
if curr_masters == 'enforced' and is_svi:
|
||||
raise exceptions.InvalidNetworkForPolicyEnforcementPref()
|
||||
|
||||
epg = self.aim.get(aim_ctx, self._get_network_epg(mapping))
|
||||
self.aim.update(
|
||||
aim_ctx, epg, policy_enforcement_pref=curr_masters)
|
||||
|
||||
if is_ext:
|
||||
_, ext_net, ns = self._get_aim_nat_strategy(current)
|
||||
if ext_net:
|
||||
@ -6940,6 +6957,8 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
||||
for key in ('app_profile_name', 'name')}
|
||||
for x in
|
||||
net_db.aim_extension_epg_contract_masters]
|
||||
policy_enforcement_pref = (
|
||||
net_db.aim_extension_mapping.policy_enforcement_pref)
|
||||
|
||||
# REVISIT: Refactor to share code.
|
||||
dname = aim_utils.sanitize_display_name(net_db.name)
|
||||
@ -6956,7 +6975,7 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
||||
|
||||
epg.display_name = dname
|
||||
epg.bd_name = bd.name
|
||||
epg.policy_enforcement_pref = 'unenforced'
|
||||
epg.policy_enforcement_pref = policy_enforcement_pref
|
||||
epg.provided_contract_names = provided_contract_names
|
||||
epg.consumed_contract_names = consumed_contract_names
|
||||
epg.openstack_vmm_domain_names = []
|
||||
|
@ -1020,6 +1020,7 @@ class TestAimMapping(ApicAimTestCase):
|
||||
consumed_contract_names = set(
|
||||
router_anames + net['apic:extra_consumed_contracts'])
|
||||
epg_contract_masters = net['apic:epg_contract_masters']
|
||||
policy_enforcement_pref = net['apic:policy_enforcement_pref']
|
||||
|
||||
if routers:
|
||||
if vrf:
|
||||
@ -1098,6 +1099,8 @@ class TestAimMapping(ApicAimTestCase):
|
||||
aim_epg.consumed_contract_names)
|
||||
self.assertItemsEqual(epg_contract_masters,
|
||||
aim_epg.epg_contract_masters)
|
||||
self.assertItemsEqual(policy_enforcement_pref,
|
||||
aim_epg.policy_enforcement_pref)
|
||||
# REVISIT(rkukura): Check openstack_vmm_domain_names and
|
||||
# physical_domain_names?
|
||||
self._check_dn_is_resource(dns, 'EndpointGroup', aim_epg)
|
||||
@ -1402,7 +1405,8 @@ class TestAimMapping(ApicAimTestCase):
|
||||
'apic:epg_contract_masters': [{'app_profile_name': 'ap1',
|
||||
'name': 'epg1'},
|
||||
{'app_profile_name': 'ap2',
|
||||
'name': 'epg2'}]}
|
||||
'name': 'epg2'}],
|
||||
'apic:policy_enforcement_pref': 'enforced'}
|
||||
net = self._make_network(
|
||||
self.fmt, 'net1', True, arg_list=tuple(list(kwargs.keys())),
|
||||
**kwargs)['network']
|
||||
@ -1421,7 +1425,8 @@ class TestAimMapping(ApicAimTestCase):
|
||||
'apic:epg_contract_masters': [{'app_profile_name': 'ap1',
|
||||
'name': 'epg2'},
|
||||
{'app_profile_name': 'ap3',
|
||||
'name': 'epg2'}]}}
|
||||
'name': 'epg2'}],
|
||||
'apic:policy_enforcement_pref': 'enforced'}}
|
||||
net = self._update('networks', net_id, data)['network']
|
||||
self._check_network(net)
|
||||
|
||||
@ -1610,11 +1615,39 @@ class TestAimMapping(ApicAimTestCase):
|
||||
'InvalidNetworkForEpgContractMaster',
|
||||
result['NeutronError']['type'])
|
||||
|
||||
def _test_invalid_policy_enforcement_pref(self, kwargs):
|
||||
# Verify creating network with Policy Enforcement Pref fails.
|
||||
kwargs['apic:policy_enforcement_pref'] = 'enforced'
|
||||
|
||||
resp = self._create_network(
|
||||
self.fmt, 'net', True, arg_list=tuple(list(kwargs.keys())),
|
||||
**kwargs)
|
||||
result = self.deserialize(self.fmt, resp)
|
||||
self.assertEqual(
|
||||
'InvalidNetworkForPolicyEnforcementPref',
|
||||
result['NeutronError']['type'])
|
||||
del kwargs['apic:policy_enforcement_pref']
|
||||
|
||||
# Create network with default Policy Enforcement Pref
|
||||
net_id = self._make_network(
|
||||
self.fmt, 'net', True,
|
||||
arg_list=tuple(list(kwargs.keys())), **kwargs)['network']['id']
|
||||
|
||||
# Verify setting Policy Enforcement Pref on network fails.
|
||||
result = self._update(
|
||||
'networks', net_id,
|
||||
{'network': {'apic:policy_enforcement_pref': 'enforced'}},
|
||||
webob.exc.HTTPBadRequest.code)
|
||||
self.assertEqual(
|
||||
'InvalidNetworkForPolicyEnforcementPref',
|
||||
result['NeutronError']['type'])
|
||||
|
||||
def test_external_network_exceptions(self):
|
||||
self._test_invalid_network_exceptions({'router:external': True})
|
||||
|
||||
def test_svi_network_exceptions(self):
|
||||
self._test_invalid_network_exceptions({'apic:svi': True})
|
||||
self._test_invalid_policy_enforcement_pref({'apic:svi': True})
|
||||
|
||||
def test_security_group_lifecycle(self):
|
||||
# Test create
|
||||
@ -6546,6 +6579,49 @@ class TestExtensionAttributes(ApicAimTestCase):
|
||||
network_id=net_id).all())
|
||||
self.assertEqual([], db_masters)
|
||||
|
||||
def test_network_with_policy_enforcement_pref_lifecycle(self):
|
||||
session = db_api.get_reader_session()
|
||||
extn = extn_db.ExtensionDbMixin()
|
||||
|
||||
# Create network with default Policy Enforcement Pref
|
||||
net = self._make_network(
|
||||
self.fmt, 'net1', True)['network']
|
||||
net_id = net['id']
|
||||
self.assertItemsEqual('unenforced',
|
||||
net['apic:policy_enforcement_pref'])
|
||||
|
||||
# Test show.
|
||||
net = self._show('networks', net_id)['network']
|
||||
self.assertItemsEqual('unenforced',
|
||||
net['apic:policy_enforcement_pref'])
|
||||
|
||||
# Test list.
|
||||
net = self._list(
|
||||
'networks', query_params=('id=%s' % net_id))['networks'][0]
|
||||
self.assertItemsEqual('unenforced',
|
||||
net['apic:policy_enforcement_pref'])
|
||||
|
||||
# Test update with Policy Enforcement Pref
|
||||
net = self._update(
|
||||
'networks', net_id,
|
||||
{'network':
|
||||
{'apic:policy_enforcement_pref': 'enforced'}})['network']
|
||||
self.assertItemsEqual('enforced',
|
||||
net['apic:policy_enforcement_pref'])
|
||||
|
||||
# Test show after update.
|
||||
net = self._show('networks', net_id)['network']
|
||||
self.assertItemsEqual('enforced',
|
||||
net['apic:policy_enforcement_pref'])
|
||||
|
||||
# Test delete.
|
||||
self._delete('networks', net_id)
|
||||
self.assertFalse(extn.get_network_extn_db(session, net_id))
|
||||
db_masters = (session.query(
|
||||
extn_db.NetworkExtEpgContractMasterDb).filter_by(
|
||||
network_id=net_id).all())
|
||||
self.assertEqual([], db_masters)
|
||||
|
||||
def test_external_network_lifecycle(self):
|
||||
session = db_api.get_reader_session()
|
||||
extn = extn_db.ExtensionDbMixin()
|
||||
|
@ -473,7 +473,8 @@ class TestNeutronMapping(AimValidationTestCase):
|
||||
'apic:epg_contract_masters': [{'app_profile_name': 'ap1',
|
||||
'name': 'ec3'},
|
||||
{'app_profile_name': 'ap2',
|
||||
'name': 'ec4'}]}
|
||||
'name': 'ec4'}],
|
||||
'apic:policy_enforcement_pref': 'unenforced'}
|
||||
if preexisting_bd:
|
||||
kwargs.update(
|
||||
{'apic:distinguished_names':
|
||||
|
Loading…
Reference in New Issue
Block a user