Add vnfd validity check 06/94006/1
authorhongyuzhao <zhao.hongyu@zte.com.cn>
Wed, 21 Aug 2019 03:50:28 +0000 (11:50 +0800)
committerhongyuzhao <zhao.hongyu@zte.com.cn>
Wed, 21 Aug 2019 03:54:41 +0000 (11:54 +0800)
Change-Id: I9fbdc1c8be274441abccef7f8ca879228037a8db
Issue-ID: VFC-1490
Signed-off-by: hongyuzhao <zhao.hongyu@zte.com.cn>
lcm/lcm/nf/biz/instantiate_vnf.py
lcm/lcm/pub/verifyvnfd/const.py
lcm/lcm/pub/verifyvnfd/tests.py
lcm/lcm/pub/verifyvnfd/verifyvnfd.py

index 13b29ea..788e582 100644 (file)
@@ -35,6 +35,7 @@ from lcm.nf.const import OPERATION_STATE_TYPE
 from lcm.nf.const import SUB_OPERATION_TASK
 from lcm.nf.biz import common
 from .operate_vnf_lcm_op_occ import VnfLcmOpOcc
+from lcm.pub.verifyvnfd import verifyvnfd
 
 logger = logging.getLogger(__name__)
 
@@ -122,6 +123,7 @@ class InstantiateVnf(Thread):
         vnf_package = query_vnfpackage_by_id(self.vnfd_id)
         pkg_info = ignore_case_get(vnf_package, "packageInfo")
         self.vnfd_info = json.loads(ignore_case_get(pkg_info, "vnfdModel"))
+        verifyvnfd.verify(self.vnfd_info)
 
         self.update_cps()
         metadata = ignore_case_get(self.vnfd_info, "metadata")
index 6869dd8..a5a3516 100644 (file)
@@ -824,3 +824,308 @@ vnfd_model3 = {
         "template_author": "ZTE"
     }
 }
+
+vnfd_model_miss_required = {
+    "volume_storages": [
+        {
+            "volume_storage_id": "test",
+            "properties": {
+                "location_info": {
+                    "vimid": "vim_1",
+                    "tenant": "chinamobile",
+                    "availability_zone": "test",
+                },
+                "volume_name": "test",
+                "custom_volume_type": "test",
+                "size_of_storage": "\"10 GB\"",
+            },
+            "image_file": "test",
+        },
+    ],
+    "vnf": {
+        "type": "tosca.nodes.nfv.VNF",
+        "requirements": {
+            "virtual_link": [
+                "ext_cp",
+                "virtual_link"
+            ]
+        },
+        "properties": {
+            "descriptor_id": "b1bb0ce7-1234-4fa7-95ed-4840d70a1179",
+            "flavour_description": "simple",
+            "descriptor_verison": "1.0",
+            "software_version": "1.0.0",
+            "template_name": "test",
+            "vnfm_info": [
+                "vnfm"
+            ],
+            "descriptor_version": "1.0.0",
+            "provider": "zte",
+            "flavour_id": "simple",
+            "product_name": "test"
+        },
+        "capabilities": {
+
+        },
+        "metadata": {
+            "template_name": "test",
+            "template_version": "1.0",
+            "template_author": "ZTE"
+        }
+    },
+    "vdus": [
+        {
+            "description": "",
+            "virtual_storages": [
+                {
+                    "virtual_storage_id": "test",
+                    "type_of_storage": "ephemeral",
+                    "size_of_storage": "10 GB",
+                }
+            ],
+            "volume_storages": [
+                {
+                    "volume_storage_id": "test",
+                }
+            ],
+            "vdu_id": "sunshine",
+            "artifacts": [
+                {
+                    "artifact_name": "sw_image",
+                    "type": "tosca.artifacts.nfv.SwImage",
+                    "file": "sss.vmdk"
+                }
+            ],
+            "dependencies": [
+
+            ],
+            "virtual_compute": {
+                "virtual_cpu": {
+                    "num_virtual_cpu": 2
+                },
+                "virtual_memory": {
+                    "virtual_mem_size": "4096 MB"
+                },
+            },
+            "vls": [
+
+            ],
+            "cps": [
+                "ext_cp"
+            ],
+            "type": "tosca.nodes.nfv.Vdu.Compute",
+            "properties": {
+                "vdu_profile": {
+                    "max_number_of_instances": 3,
+                    "min_number_of_instances": 1
+                },
+                "name": "sunshine1234",
+                "sw_image_data": {
+                    "operating_system": "linux",
+                    "name": "ubuntu",
+                    "checksum": {
+                        "hash": "d0e7828293355a07c2dccaaa765c80b507e60e6167067c950dc2e6b0da0dbd34",
+                        "algorithm": "SHA-256"
+                    },
+                    "min_ram": "2 GB",
+                    "disk_format": "qcow2",
+                    "version": 16.04,
+                    "container_format": "bare",
+                    "min_disk": "2 GB",
+                    "size": "2 GB"
+                },
+                "description": "vdu test",
+                "location_info": {
+                    "vimid": "",
+                    "tenant": "",
+                    "availability_zone": "",
+                    "vnfId": "",
+                    "vnfName": "",
+                    "cloudOwner": "",
+                    "cloudRegionId": "",
+                    "vduInfo": [
+                        {
+                            "vduName": "sunshine1234",
+                            "flavorId": "12345",
+                            "directive": ""
+                        }
+                    ]
+                }
+            }
+        }
+    ],
+    "description": "test",
+    "inputs": {
+
+    },
+    "graph": {
+        "sunshine": [
+            "ext_cp"
+        ],
+        "ext_cp": [
+
+        ]
+    },
+    "basepath": "/tmp/tmpil6wVG",
+    "vnf_exposed": {
+        "external_cps": [
+            {
+                "key_name": "virtual_link",
+                "cpd_id": "ext_cp"
+            }
+        ],
+        "forward_cps": [
+
+        ]
+    },
+    "policies": [
+        {
+            "type": "tosca.policies.nfv.InstantiationLevels",
+            "targets": "",
+            "properties": {
+                "default_level": "instantiation_level_1",
+                "levels": {
+                    "instantiation_level_1": {
+                        "scale_info": {
+                            "sunshine_aspect": {
+                                "scale_level": 0
+                            }
+                        },
+                        "description": "vnf test instantiation_level_1"
+                    },
+                    "instantiation_level_2": {
+                        "scale_info": {
+                            "sunshine_aspect": {
+                                "scale_level": 1
+                            }
+                        },
+                        "description": "vnf test instantiation_level_2"
+                    },
+                    "instantiation_level_3": {
+                        "scale_info": {
+                            "sunshine_aspect": {
+                                "scale_level": 2
+                            }
+                        },
+                        "description": "vnf test instantiation_level_3"
+                    }
+                }
+            }
+        },
+        {
+            "type": "tosca.policies.nfv.VduInstantiationLevels",
+            "targets": [
+                "sunshine"
+            ],
+            "properties": {
+                "levels": {
+                    "instantiation_level_1": {
+                        "number_of_instances": 1
+                    },
+                    "instantiation_level_2": {
+                        "number_of_instances": 2
+                    },
+                    "instantiation_level_3": {
+                        "number_of_instances": 3
+                    }
+                }
+            }
+        },
+        {
+            "type": "tosca.policies.nfv.ScalingAspects",
+            "targets": "",
+            "properties": {
+                "aspects": {
+                    "sunshine_aspect": {
+                        "max_scale_level": 2,
+                        "description": "sunshine aspect",
+                        "name": "sunshine_aspect",
+                        "step_deltas": [
+                            "sunshine_delta"
+                        ]
+                    }
+                }
+            }
+        },
+        {
+            "type": "tosca.policies.nfv.VduInitialDelta",
+            "targets": [
+                "sunshine"
+            ],
+            "properties": {
+                "initial_delta": {
+                    "number_of_instances": 1
+                }
+            }
+        },
+        {
+            "type": "tosca.policies.nfv.VduScalingAspectDeltas",
+            "targets": [
+                "sunshine"
+            ],
+            "properties": {
+                "deltas": {
+                    "sunshine_delta": {
+                        "number_of_instances": 1
+                    }
+                },
+                "aspect": "sunshine_aspect"
+            }
+        }
+    ],
+    "vls": [
+        {
+            # "vl_id": "test", //required
+            "properties": {
+                "location_info": {
+                    "vimid": "test",
+                    "tenant": "chinamobile",
+                },
+                "vl_profile": {
+                    # "networkName": "test", //required
+                    "networkType": "test",
+                    "physicalNetwork": "test",
+                    "vlanTransparent": "test",
+                    "segmentationId": "1",
+                    "cidr": "test",
+                    "dhcpEnabled": "test",
+                    "gatewayIp": "test",
+                    "startIp": "test",
+                    "endIp": "test",
+                },
+                # "connectivity_type": {
+                #     "layer_protocol": "ipv4",
+                # },
+                "dns_nameservers": "test",
+                "host_routes": "test",
+            },
+            "route_external": "test",
+        }
+    ],
+    "cps": [
+        {
+            "vl_id": "",
+            "description": "",
+            "vdu_id": "sunshine",
+            "properties": {
+                "trunk_mode": "false",
+                "protocol_data": [{
+                    "address_data": {
+                        "address_type": "ip_address",
+                        # "l3_address_data": {
+                        #     "floating_ip_activated": False,
+                        #     "ip_address_assignment": False
+                        # }
+                    }
+                }]
+            },
+            # "cp_id": "ext_cp", //required
+            "cpd_id": "ext_cp"
+        }
+    ],
+    "metadata": {
+        "template_name": "test",
+        "template_version": "1.0",
+        "template_author": "ZTE"
+    }
+}
index 86e2d04..bc0e974 100644 (file)
@@ -13,8 +13,9 @@
 # limitations under the License.
 
 import unittest
-from . import verifyvnfd
+from lcm.pub.verifyvnfd import verifyvnfd
 from . import const
+from lcm.pub.exceptions import NFLCMException
 
 
 class VerifyVnfdTest(unittest.TestCase):
@@ -26,12 +27,18 @@ class VerifyVnfdTest(unittest.TestCase):
 
     def test_vnfd_verfify_success1(self):
         ret = verifyvnfd.verify(const.vnfd_model1)
-        self.assertEqual(ret, [])
+        self.assertEqual(ret, True)
 
     def test_vnfd_verfify_success2(self):
         ret = verifyvnfd.verify(const.vnfd_model2)
-        self.assertEqual(ret, [])
+        self.assertEqual(ret, True)
 
     def test_vnfd_verfify_success3(self):
         ret = verifyvnfd.verify(const.vnfd_model3)
-        self.assertEqual(ret, [])
+        self.assertEqual(ret, True)
+
+    def test_vnfd_verfify_fail_for_missing_required(self):
+        try:
+            verifyvnfd.verify(const.vnfd_model_miss_required)
+        except NFLCMException as e:
+            self.assertNotEqual(e.args[0], "")
index b4ed040..6fa5ac2 100644 (file)
@@ -13,7 +13,9 @@
 # limitations under the License.
 
 import json
+import re
 import os
+import six
 import logging
 import jsonschema
 from lcm.pub.exceptions import NFLCMException
@@ -21,6 +23,29 @@ from lcm.pub.exceptions import NFLCMException
 logger = logging.getLogger(__name__)
 
 
+def _format_validation_error(error):
+    """
+    :param error: validation error to format
+    :type error: jsonchema.exceptions.ValidationError
+    :returns: string representation of the validation error
+    :rtype: str
+    """
+    match = re.search("(.+) is a required property", error.message)
+    if match:
+        message = 'Error: missing required property {}.'.format(
+            match.group(1))
+    else:
+        message = 'Error: {}\n'.format(error.message)
+        if len(error.absolute_path) > 0:
+            message += 'Path: {}\n'.format(
+                       '.'.join(
+                           [six.text_type(path)
+                            for path in error.absolute_path]))
+        message += 'Value: {}'.format(json.dumps(error.instance))
+
+    return message
+
+
 def verify(new_vnfd):
     errors_found = []
     vnfd_schema_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "vnf_vnfd_schema.json")
@@ -28,8 +53,8 @@ def verify(new_vnfd):
         vnfd_schema = json.load(fvnfd_schema)
         vnfd_validator = jsonschema.validators.Draft4Validator(schema=vnfd_schema)
         for error in vnfd_validator.iter_errors(new_vnfd):
-            logger.error("vnfd verify fail:%s" % error)
-            errors_found.append(error)
-        if len(errors_found) > 0:
-            raise NFLCMException(errors_found)
-        return errors_found
+            logger.error("vnfd verify fail,%s" % _format_validation_error(error))
+            errors_found.append(_format_validation_error(error))
+    if len(errors_found) > 0:
+        raise NFLCMException(errors_found)
+    return True