diff --git a/gbpservice/neutron/services/sfc/aim/exceptions.py b/gbpservice/neutron/services/sfc/aim/exceptions.py index 88c337f5d..74d5b5bf1 100644 --- a/gbpservice/neutron/services/sfc/aim/exceptions.py +++ b/gbpservice/neutron/services/sfc/aim/exceptions.py @@ -112,3 +112,7 @@ class ConflictingNetworksDetectedInPortChain(exceptions.BadRequest): class DefaultExternalNetworkNotFound(exceptions.NotFound): message = _("Default External Network not found for SVI network " "%(id)s.") + + +class TooManyPPGsPerChainError(exceptions.BadRequest): + message = _("The max number of PPGs per chain supported is %(maxn)s.") diff --git a/gbpservice/neutron/services/sfc/aim/sfc_driver.py b/gbpservice/neutron/services/sfc/aim/sfc_driver.py index b82ac3eba..f5ef25162 100644 --- a/gbpservice/neutron/services/sfc/aim/sfc_driver.py +++ b/gbpservice/neutron/services/sfc/aim/sfc_driver.py @@ -42,6 +42,7 @@ FLOWC_DST = 'dst' LOG = logging.getLogger(__name__) PHYSDOM_TYPE = 'PhysDom' SUPPORTED_DOM_TYPES = [PHYSDOM_TYPE] +MAX_PPGS_PER_CHAIN = 3 class SfcAIMDriverBase(base.SfcDriverBase): @@ -290,6 +291,8 @@ class SfcAIMDriver(SfcAIMDriverBase): # can be removed once contract export is implemented. # TODO(ivar): two different chains cannot share left/right networks # TODO(ivar): right/left BDs same tenant as provider + if len(ppgs) > MAX_PPGS_PER_CHAIN: + raise exceptions.TooManyPPGsPerChainError(maxn=MAX_PPGS_PER_CHAIN) vrfs = set() for flowc in flowcs: provg = self._get_flowc_provider_group(p_ctx, flowc) diff --git a/gbpservice/neutron/tests/unit/services/sfc/test_aim_sfc_driver.py b/gbpservice/neutron/tests/unit/services/sfc/test_aim_sfc_driver.py index d27cbecf5..48a425aaf 100644 --- a/gbpservice/neutron/tests/unit/services/sfc/test_aim_sfc_driver.py +++ b/gbpservice/neutron/tests/unit/services/sfc/test_aim_sfc_driver.py @@ -1001,6 +1001,27 @@ class TestPortChain(TestAIMServiceFunctionChainingBase): self._verify_pc_mapping(pc) self._verify_pc_delete(pc) + def test_pc_max_ppg_validation(self): + fc = self._create_simple_flowc(src_svi=self.src_svi, + dst_svi=self.dst_svi) + ppg1 = self._create_simple_ppg(pairs=1) + ppg2 = self._create_simple_ppg(pairs=1) + ppg3 = self._create_simple_ppg(pairs=1) + ppg4 = self._create_simple_ppg(pairs=1) + self.create_port_chain(port_pair_groups=[ppg1['id'], ppg2['id'], + ppg3['id'], ppg4['id']], + flow_classifiers=[fc['id']], + expected_res_status=400) + pc = self.create_port_chain(port_pair_groups=[ppg1['id'], + ppg2['id'], + ppg3['id']], + flow_classifiers=[fc['id']], + expected_res_status=201)['port_chain'] + self.update_port_chain(pc['id'], + port_pair_groups=[ppg1['id'], ppg2['id'], + ppg3['id'], ppg4['id']], + expected_res_status=500) + class TestPortChainSVI(TestPortChain):