diff --git a/samples/tosca-templates/vnffgd/tosca-vnffgd-param-sample.yaml b/samples/tosca-templates/vnffgd/tosca-vnffgd-param-sample.yaml index 407f5dff8..01d2d343a 100644 --- a/samples/tosca-templates/vnffgd/tosca-vnffgd-param-sample.yaml +++ b/samples/tosca-templates/vnffgd/tosca-vnffgd-param-sample.yaml @@ -45,7 +45,7 @@ topology_template: properties: vendor: tacker version: 1.0 - number_of_endpoints: 5 + number_of_endpoints: 2 dependent_virtual_link: [VL12,VL22] connection_point: [CP12,CP22] constituent_vnfs: [VNFD1,VNFD2] diff --git a/samples/tosca-templates/vnffgd/tosca-vnffgd-sample.yaml b/samples/tosca-templates/vnffgd/tosca-vnffgd-sample.yaml index 133cc4870..2f8877c32 100644 --- a/samples/tosca-templates/vnffgd/tosca-vnffgd-sample.yaml +++ b/samples/tosca-templates/vnffgd/tosca-vnffgd-sample.yaml @@ -32,7 +32,7 @@ topology_template: properties: vendor: tacker version: 1.0 - number_of_endpoints: 5 + number_of_endpoints: 2 dependent_virtual_link: [VL12,VL22] connection_point: [CP12,CP22] constituent_vnfs: [VNFD1,VNFD2] diff --git a/tacker/db/nfvo/vnffg_db.py b/tacker/db/nfvo/vnffg_db.py index 6ddf1dcfc..d83cea80a 100644 --- a/tacker/db/nfvo/vnffg_db.py +++ b/tacker/db/nfvo/vnffg_db.py @@ -344,7 +344,7 @@ class VnffgPluginDbMixin(vnffg.VNFFGPluginBase, db_base.CommonDbMixin): template_db.template['vnffgd']['topology_template'] = \ vnffgd_topology_template - vnf_members = self._get_vnffg_property(template_db, + vnf_members = self._get_vnffg_property(template_db.template, 'constituent_vnfs') LOG.debug(_('Constituent VNFs: %s'), vnf_members) vnf_mapping = self._get_vnf_mapping(context, vnffg.get( @@ -479,8 +479,8 @@ class VnffgPluginDbMixin(vnffg.VNFFGPluginBase, db_base.CommonDbMixin): return chain_list @staticmethod - def _get_vnffg_property(template_db, vnffg_property): - template = template_db.template['vnffgd']['topology_template'] + def _get_vnffg_property(template, vnffg_property): + template = template['vnffgd']['topology_template'] vnffg_name = list(template['groups'].keys())[0] try: return template['groups'][vnffg_name]['properties'][vnffg_property] diff --git a/tacker/extensions/nfvo.py b/tacker/extensions/nfvo.py index fdcc8a5b7..a0ac50f89 100644 --- a/tacker/extensions/nfvo.py +++ b/tacker/extensions/nfvo.py @@ -117,6 +117,11 @@ class VnffgdCpNoForwardingException(exceptions.TackerException): "included in forwarding path") +class VnffgdWrongEndpointNumber(exceptions.TackerException): + message = _("Specified number_of_endpoints %(number)s is not equal to " + "the number of connection_point %(cps)s") + + class VnffgdInUse(exceptions.InUse): message = _('VNFFGD %(vnffgd_id)s is still in use') diff --git a/tacker/nfvo/nfvo_plugin.py b/tacker/nfvo/nfvo_plugin.py index ec4bc610d..b9016de57 100644 --- a/tacker/nfvo/nfvo_plugin.py +++ b/tacker/nfvo/nfvo_plugin.py @@ -211,6 +211,46 @@ class NfvoPlugin(nfvo_db.NfvoPluginDb, vnffg_db.VnffgPluginDbMixin, LOG.exception(_("tosca-parser error: %s"), str(e)) raise nfvo.ToscaParserFailed(error_msg_details=str(e)) + @log.log + def validate_vnffgd_path(self, template): + temp = template['vnffgd']['topology_template'] + vnffg_name = list(temp['groups'].keys())[0] + nfp_name = temp['groups'][vnffg_name]['members'][0] + path = self._get_nfp_attribute(template, nfp_name, + 'path') + + prev_element = None + known_forwarders = set() + for element in path: + if element.get('forwarder') in known_forwarders: + if prev_element is not None and element.get('forwarder')\ + != prev_element['forwarder']: + raise nfvo.VnffgdDuplicateForwarderException( + forwarder=element.get('forwarder') + ) + elif prev_element is not None and element.get( + 'capability') == prev_element['capability']: + raise nfvo.VnffgdDuplicateCPException( + cp=element.get('capability') + ) + else: + known_forwarders.add(element.get('forwarder')) + prev_element = element + + @log.log + def validate_vnffg_properties(self, template): + + # check whether number_of_endpoints is same with connection_point + connection_point = self._get_vnffg_property( + template, 'connection_point') + number_endpoint = self._get_vnffg_property( + template, 'number_of_endpoints') + + if len(connection_point) != number_endpoint: + raise nfvo.VnffgdWrongEndpointNumber( + number=number_endpoint, + cps=connection_point) + @log.log def create_vnffgd(self, context, vnffgd): template = vnffgd['vnffgd'] @@ -219,28 +259,11 @@ class NfvoPlugin(nfvo_db.NfvoPluginDb, vnffg_db.VnffgPluginDbMixin, raise nfvo.VnffgdInvalidTemplate(template=template.get('template')) else: self.validate_tosca(template['template']['vnffgd']) - temp = template['template']['vnffgd']['topology_template'] - vnffg_name = list(temp['groups'].keys())[0] - nfp_name = temp['groups'][vnffg_name]['members'][0] - path = self._get_nfp_attribute(template['template'], nfp_name, - 'path') - prev_element = None - known_forwarders = set() - for element in path: - if element.get('forwarder') in known_forwarders: - if prev_element is not None and element.get('forwarder')\ - != prev_element['forwarder']: - raise nfvo.VnffgdDuplicateForwarderException( - forwarder=element.get('forwarder') - ) - elif prev_element is not None and element.get( - 'capability') == prev_element['capability']: - raise nfvo.VnffgdDuplicateCPException( - cp=element.get('capability') - ) - else: - known_forwarders.add(element.get('forwarder')) - prev_element = element + + self.validate_vnffgd_path(template['template']) + + self.validate_vnffg_properties(template['template']) + return super(NfvoPlugin, self).create_vnffgd(context, vnffgd) @log.log @@ -295,7 +318,7 @@ class NfvoPlugin(nfvo_db.NfvoPluginDb, vnffg_db.VnffgPluginDbMixin, nfp['classifier_id']) template_db = self._get_resource(context, vnffg_db.VnffgTemplate, vnffg_dict['vnffgd_id']) - vnf_members = self._get_vnffg_property(template_db, + vnf_members = self._get_vnffg_property(template_db.template, 'constituent_vnfs') new_vnffg['vnf_mapping'] = super(NfvoPlugin, self)._get_vnf_mapping( context, new_vnffg.get('vnf_mapping'), vnf_members) diff --git a/tacker/tests/unit/db/utils.py b/tacker/tests/unit/db/utils.py index 6800e1d80..f9b254e2e 100644 --- a/tacker/tests/unit/db/utils.py +++ b/tacker/tests/unit/db/utils.py @@ -50,6 +50,8 @@ vnfd_alarm_respawn_tosca_template = _get_template( vnfd_alarm_scale_tosca_template = _get_template( 'test_tosca_vnfd_alarm_scale.yaml') nsd_tosca_template = yaml.safe_load(_get_template('tosca_nsd_template.yaml')) +vnffgd_wrong_cp_number_template = yaml.safe_load(_get_template( + 'tosca_vnffgd_wrong_cp_number_template.yaml')) def get_dummy_vnfd_obj(): diff --git a/tacker/tests/unit/nfvo/test_nfvo_plugin.py b/tacker/tests/unit/nfvo/test_nfvo_plugin.py index e83a0853b..ae1ed67b8 100644 --- a/tacker/tests/unit/nfvo/test_nfvo_plugin.py +++ b/tacker/tests/unit/nfvo/test_nfvo_plugin.py @@ -448,6 +448,16 @@ class TestNfvoPlugin(db_base.SqlTestCase): self.nfvo_plugin.validate_tosca, template) + def test_validate_vnffg_properties(self): + template = {'vnffgd': utils.vnffgd_tosca_template} + self.nfvo_plugin.validate_vnffg_properties(template) + + def test_validate_vnffg_properties_wrong_number(self): + template = {'vnffgd': utils.vnffgd_wrong_cp_number_template} + self.assertRaises(nfvo.VnffgdWrongEndpointNumber, + self.nfvo_plugin.validate_vnffg_properties, + template) + def test_create_vnffgd(self): vnffgd_obj = utils.get_dummy_vnffgd_obj() result = self.nfvo_plugin.create_vnffgd(self.context, vnffgd_obj) diff --git a/tacker/tests/unit/vnfm/infra_drivers/openstack/data/tosca_invalid_vnffgd_template.yaml b/tacker/tests/unit/vnfm/infra_drivers/openstack/data/tosca_invalid_vnffgd_template.yaml index 862c85883..d9fdb92e8 100644 --- a/tacker/tests/unit/vnfm/infra_drivers/openstack/data/tosca_invalid_vnffgd_template.yaml +++ b/tacker/tests/unit/vnfm/infra_drivers/openstack/data/tosca_invalid_vnffgd_template.yaml @@ -34,7 +34,7 @@ topology_template: properties: vendor: tacker version: 1.0 - number_of_endpoints: 5 + number_of_endpoints: 3 dependent_virtual_link: [VL1,VL2,VL3] connection_point: [CP11,CP12,CP32] constituent_vnfs: [VNF1,VNF3] diff --git a/tacker/tests/unit/vnfm/infra_drivers/openstack/data/tosca_vnffgd_param_template.yaml b/tacker/tests/unit/vnfm/infra_drivers/openstack/data/tosca_vnffgd_param_template.yaml index 5cf7867b9..4f43abb5f 100644 --- a/tacker/tests/unit/vnfm/infra_drivers/openstack/data/tosca_vnffgd_param_template.yaml +++ b/tacker/tests/unit/vnfm/infra_drivers/openstack/data/tosca_vnffgd_param_template.yaml @@ -39,7 +39,7 @@ topology_template: properties: vendor: tacker version: 1.0 - number_of_endpoints: 5 + number_of_endpoints: 3 dependent_virtual_link: [VL1,VL2,VL3] connection_point: [CP11,CP12,CP32] constituent_vnfs: [VNF1,VNF3] diff --git a/tacker/tests/unit/vnfm/infra_drivers/openstack/data/tosca_vnffgd_template.yaml b/tacker/tests/unit/vnfm/infra_drivers/openstack/data/tosca_vnffgd_template.yaml index 189b10836..5d0cd6507 100644 --- a/tacker/tests/unit/vnfm/infra_drivers/openstack/data/tosca_vnffgd_template.yaml +++ b/tacker/tests/unit/vnfm/infra_drivers/openstack/data/tosca_vnffgd_template.yaml @@ -34,7 +34,7 @@ topology_template: properties: vendor: tacker version: 1.0 - number_of_endpoints: 5 + number_of_endpoints: 3 dependent_virtual_link: [VL1,VL2,VL3] connection_point: [CP11,CP12,CP32] constituent_vnfs: [VNF1,VNF3] diff --git a/tacker/tests/unit/vnfm/infra_drivers/openstack/data/tosca_vnffgd_wrong_cp_number_template.yaml b/tacker/tests/unit/vnfm/infra_drivers/openstack/data/tosca_vnffgd_wrong_cp_number_template.yaml new file mode 100644 index 000000000..52e12c300 --- /dev/null +++ b/tacker/tests/unit/vnfm/infra_drivers/openstack/data/tosca_vnffgd_wrong_cp_number_template.yaml @@ -0,0 +1,41 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: example template + +topology_template: + description: Example VNFFG template + + node_templates: + + Forwarding_path1: + type: tosca.nodes.nfv.FP.Tacker + description: creates path (CP11->CP12->CP32) + properties: + id: 51 + policy: + type: ACL + criteria: + - blah: tenant1_net + - destination_port_range: 80-1024 + - ip_proto: 6 + - ip_dst_prefix: 192.168.1.2/24 + path: + - forwarder: VNF1 + capability: CP11 + - forwarder: VNF1 + capability: CP12 + - forwarder: VNF3 + capability: CP32 + + groups: + VNFFG1: + type: tosca.groups.nfv.VNFFG + description: HTTP to Corporate Net + properties: + vendor: tacker + version: 1.0 + number_of_endpoints: 4 + dependent_virtual_link: [VL1,VL2,VL3] + connection_point: [CP11,CP12,CP32] + constituent_vnfs: [VNF1,VNF3] + members: [Forwarding_path1] diff --git a/tacker/tests/unit/vnfm/infra_drivers/openstack/data/vnffgd_template.yaml b/tacker/tests/unit/vnfm/infra_drivers/openstack/data/vnffgd_template.yaml index fb9cbf780..c049ff0fc 100644 --- a/tacker/tests/unit/vnfm/infra_drivers/openstack/data/vnffgd_template.yaml +++ b/tacker/tests/unit/vnfm/infra_drivers/openstack/data/vnffgd_template.yaml @@ -25,7 +25,7 @@ properties: vendor: tacker version: 1.0 - number_of_endpoints: 5 + number_of_endpoints: 3 dependent_virtual_link: [VL1,VL2,VL3] connection_point: [CP11,CP12,CP32] constituent_vnfs: [VNF1,VNF3]