From 1448045b943223a05604d65e1da72b36797d54ed Mon Sep 17 00:00:00 2001 From: garciadeblas Date: Tue, 10 Jan 2017 13:08:07 +0100 Subject: [PATCH] VNF creation with image name and checksum working properly. Fixes bug 73. Added new tests for this feature. Openmano client modified to allow modifying image name and checksum Change-Id: I6153fab0241778cba34414c8e45669cd40119eed Signed-off-by: garciadeblas --- nfvo.py | 29 +++++++++++++------ openmano | 18 ++++++++++-- scenarios/examples/complex5.yaml | 48 ++++++++++++++++++++++++++++++++ test/basictest.sh | 6 ++-- vimconn_openstack.py | 6 ++-- vnfs/examples/dataplaneVNF4.yaml | 4 +-- 6 files changed, 93 insertions(+), 18 deletions(-) create mode 100644 scenarios/examples/complex5.yaml diff --git a/nfvo.py b/nfvo.py index a1279694..49587626 100644 --- a/nfvo.py +++ b/nfvo.py @@ -266,18 +266,19 @@ def create_or_use_image(mydb, vims, image_dict, rollback_list, only_create_at_vi if return_on_error == None: return_on_error = True else: - if image_dict['location'] is not None: + if image_dict['location']: images = mydb.get_rows(FROM="images", WHERE={'location':image_dict['location'], 'metadata':image_dict['metadata']}) else: images = mydb.get_rows(FROM="images", WHERE={'universal_name':image_dict['universal_name'], 'checksum':image_dict['checksum']}) if len(images)>=1: image_mano_id = images[0]['uuid'] else: - #create image + #create image in MANO DB temp_image_dict={'name':image_dict['name'], 'description':image_dict.get('description',None), 'location':image_dict['location'], 'metadata':image_dict.get('metadata',None), 'universal_name':image_dict['universal_name'] , 'checksum':image_dict['checksum'] } + #temp_image_dict['location'] = image_dict.get('new_location') if image_dict['location'] is None image_mano_id = mydb.new_row('images', temp_image_dict, add_uuid=True) rollback_list.append({"where":"mano", "what":"image","uuid":image_mano_id}) #create image at every vim @@ -296,25 +297,31 @@ def create_or_use_image(mydb, vims, image_dict, rollback_list, only_create_at_vi filter_dict['checksum'] = image_dict['checksum'] #logger.debug('>>>>>>>> Filter dict: %s', str(filter_dict)) vim_images = vim.get_image_list(filter_dict) + #logger.debug('>>>>>>>> VIM images: %s', str(vim_images)) if len(vim_images) > 1: raise vimconn.vimconnException("More than one candidate VIM image found for filter: {}".format(str(filter_dict)), HTTP_Conflict) elif len(vim_images) == 0: raise vimconn.vimconnNotFoundException("Image not found at VIM with filter: '{}'".format(str(filter_dict))) else: - image_vim_id = vim_images[0].id + #logger.debug('>>>>>>>> VIM image 0: %s', str(vim_images[0])) + image_vim_id = vim_images[0]['id'] except vimconn.vimconnNotFoundException as e: - #Create the image in VIM + #Create the image in VIM only if image_dict['location'] or image_dict['new_location'] is not None try: - image_vim_id = vim.new_image(image_dict) - rollback_list.append({"where":"vim", "vim_id": vim_id, "what":"image","uuid":image_vim_id}) - image_created="true" + #image_dict['location']=image_dict.get('new_location') if image_dict['location'] is None + if image_dict['location']: + image_vim_id = vim.new_image(image_dict) + rollback_list.append({"where":"vim", "vim_id": vim_id, "what":"image","uuid":image_vim_id}) + image_created="true" + else: + raise vimconn.vimconnException("Cannot create image without location") except vimconn.vimconnException as e: if return_on_error: - logger.error("Error creating image at VIM: %s", str(e)) + logger.error("Error creating image at VIM '%s': %s", vim["name"], str(e)) raise image_vim_id = None - logger.warn("Error creating image at VIM: %s", str(e)) + logger.warn("Error creating image at VIM '%s': %s", vim["name"], str(e)) continue except vimconn.vimconnException as e: if return_on_error: @@ -366,6 +373,7 @@ def create_or_use_flavor(mydb, vims, flavor_dict, rollback_list, only_create_at_ image_dict['universal_name']=device.get('image name') image_dict['description']=flavor_dict['name']+str(dev_nb)+"-img" image_dict['location']=device.get('image') + #image_dict['new_location']=vnfc.get('image location') image_dict['checksum']=device.get('image checksum') image_metadata_dict = device.get('image metadata', None) image_metadata_str = None @@ -423,6 +431,7 @@ def create_or_use_flavor(mydb, vims, flavor_dict, rollback_list, only_create_at_ image_dict['universal_name']=device.get('image name') image_dict['description']=flavor_dict['name']+str(dev_nb)+"-img" image_dict['location']=device.get('image') + #image_dict['new_location']=device.get('image location') image_dict['checksum']=device.get('image checksum') image_metadata_dict = device.get('image metadata', None) image_metadata_str = None @@ -584,6 +593,7 @@ def new_vnf(mydb, tenant_id, vnf_descriptor): image_dict['universal_name']=vnfc.get('image name') image_dict['description']=vnfc.get('image name', VNFCDict[vnfc['name']]['description']) image_dict['location']=vnfc.get('VNFC image') + #image_dict['new_location']=vnfc.get('image location') image_dict['checksum']=vnfc.get('image checksum') image_metadata_dict = vnfc.get('image metadata', None) image_metadata_str = None @@ -722,6 +732,7 @@ def new_vnf_v02(mydb, tenant_id, vnf_descriptor): image_dict['universal_name']=vnfc.get('image name') image_dict['description']=vnfc.get('image name', VNFCDict[vnfc['name']]['description']) image_dict['location']=vnfc.get('VNFC image') + #image_dict['new_location']=vnfc.get('image location') image_dict['checksum']=vnfc.get('image checksum') image_metadata_dict = vnfc.get('image metadata', None) image_metadata_str = None diff --git a/openmano b/openmano index 6c546c12..11cc726f 100755 --- a/openmano +++ b/openmano @@ -28,7 +28,7 @@ openmano client used to interact with openmano-server (openmanod) ''' __author__="Alfonso Tierno, Gerardo Garcia" __date__ ="$09-oct-2014 09:09:48$" -__version__="0.4.7-r511" +__version__="0.4.8-r512" version_date="Oct 2016" from argcomplete.completers import FilesCompleter @@ -251,7 +251,7 @@ def vnf_create(args): tenant = _get_tenant() myvnf = _load_file_or_yaml(args.file) - if args.name or args.description or args.image_path: + if args.name or args.description or args.image_path or args.image_name or args.image_checksum: #print args.name try: if args.name: @@ -264,6 +264,16 @@ def vnf_create(args): #print "image-path", image_path_ myvnf['vnf']['VNFC'][index]['VNFC image']=image_path_ index=index+1 + if args.image_name: + index=0 + for image_name_ in args.image_name.split(","): + myvnf['vnf']['VNFC'][index]['image name']=image_name_ + index=index+1 + if args.image_checksum: + index=0 + for image_checksum_ in args.image_checksum.split(","): + myvnf['vnf']['VNFC'][index]['image checksum']=image_checksum_ + index=index+1 except (KeyError, TypeError), e: if str(e)=='vnf': error_pos= "missing field 'vnf'" elif str(e)=='name': error_pos= "missing field 'vnf':'name'" @@ -271,6 +281,8 @@ def vnf_create(args): elif str(e)=='VNFC': error_pos= "missing field 'vnf':'VNFC'" elif str(e)==str(index): error_pos= "field 'vnf':'VNFC' must be an array" elif str(e)=='VNFC image': error_pos= "missing field 'vnf':'VNFC'['VNFC image']" + elif str(e)=='image name': error_pos= "missing field 'vnf':'VNFC'['image name']" + elif str(e)=='image checksum': error_pos= "missing field 'vnf':'VNFC'['image checksum']" else: error_pos="wrong format" print "Wrong VNF descriptor: " + error_pos return -1 @@ -1207,6 +1219,8 @@ if __name__=="__main__": vnf_create_parser.add_argument("--name", action="store", help="name of the VNF (if it exists in the VNF descriptor, it is overwritten)") vnf_create_parser.add_argument("--description", action="store", help="description of the VNF (if it exists in the VNF descriptor, it is overwritten)") vnf_create_parser.add_argument("--image-path", action="store", help="change image path locations (overwritten)") + vnf_create_parser.add_argument("--image-name", action="store", help="change image name (overwritten)") + vnf_create_parser.add_argument("--image-checksum", action="store", help="change image checksum (overwritten)") vnf_create_parser.set_defaults(func=vnf_create) vnf_list_parser = subparsers.add_parser('vnf-list', parents=[parent_parser], help="lists information about a vnf") diff --git a/scenarios/examples/complex5.yaml b/scenarios/examples/complex5.yaml new file mode 100644 index 00000000..06335af0 --- /dev/null +++ b/scenarios/examples/complex5.yaml @@ -0,0 +1,48 @@ +## +# Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U. +# This file is part of openmano +# All Rights Reserved. +# +# 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. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: nfvlabs@tid.es +## +--- +schema_version: 2 +scenario: + name: complex5 + description: Complex network scenario consisting of 2 dataplane VNFs using image name instead of image location + public: false + vnfs: + VNF1: + vnf_name: dataplaneVNF4 + VNF2: + vnf_name: dataplaneVNF4 + networks: + dataconn1: + interfaces: + - VNF1: in + - VNF2: in + dataconn2: + interfaces: + - VNF1: out + - VNF2: out + default: + external: true + interfaces: + - VNF1: control0 + - VNF1: control1 + - VNF2: control0 + - VNF2: control1 + diff --git a/test/basictest.sh b/test/basictest.sh index 3b2b3535..b15269a6 100755 --- a/test/basictest.sh +++ b/test/basictest.sh @@ -152,11 +152,13 @@ then ${DIRmano}/openmano instance-scenario-delete -f complex2-instance || echo "fail" ${DIRmano}/openmano instance-scenario-delete -f complex3-instance || echo "fail" ${DIRmano}/openmano instance-scenario-delete -f complex4-instance || echo "fail" + ${DIRmano}/openmano instance-scenario-delete -f complex5-instance || echo "fail" ${DIRmano}/openmano scenario-delete -f simple || echo "fail" ${DIRmano}/openmano scenario-delete -f complex || echo "fail" ${DIRmano}/openmano scenario-delete -f complex2 || echo "fail" ${DIRmano}/openmano scenario-delete -f complex3 || echo "fail" ${DIRmano}/openmano scenario-delete -f complex4 || echo "fail" + ${DIRmano}/openmano scenario-delete -f complex5 || echo "fail" ${DIRmano}/openmano vnf-delete -f linux || echo "fail" ${DIRmano}/openmano vnf-delete -f linux_2VMs_v02 || echo "fail" ${DIRmano}/openmano vnf-delete -f dataplaneVNF_2VMs || echo "fail" @@ -214,7 +216,7 @@ then ! is_valid_uuid $vnf && echo FAIL && echo " $result" && $_exit 1 echo $vnf done - for NS in simple complex complex2 complex3 complex4 + for NS in simple complex complex2 complex3 complex4 complex5 do printf "%-50s" "Creating scenario '${NS}':" result=`$DIRmano/openmano scenario-create $DIRmano/scenarios/examples/${NS}.yaml` @@ -223,7 +225,7 @@ then echo $scenario done - for IS in simple complex complex2 complex3 + for IS in simple complex complex2 complex3 complex5 do printf "%-50s" "Creating instance-scenario '${IS}':" result=`$DIRmano/openmano instance-scenario-create --scenario ${IS} --name ${IS}-instance` diff --git a/vimconn_openstack.py b/vimconn_openstack.py index 2607e3f6..999aceed 100644 --- a/vimconn_openstack.py +++ b/vimconn_openstack.py @@ -561,7 +561,7 @@ class vimconnector(vimconn.vimconnector): #determine format http://docs.openstack.org/developer/glance/formats.html if "disk_format" in image_dict: disk_format=image_dict["disk_format"] - else: #autodiscover base on extention + else: #autodiscover based on extension if image_dict['location'][-6:]==".qcow2": disk_format="qcow2" elif image_dict['location'][-4:]==".vhd": @@ -652,8 +652,8 @@ class vimconnector(vimconn.vimconnector): filtered_list = [] for image in image_list: image_dict=self.glance.images.get(image.id) - if 'checksum' in filter_dict and image_dict['checksum']==filter_dict.get('checksum'): - filtered_list.append(image) + if 'checksum' not in filter_dict or image_dict['checksum']==filter_dict.get('checksum'): + filtered_list.append(image_dict) return filtered_list except (ksExceptions.ClientException, nvExceptions.ClientException, gl1Exceptions.CommunicationError, ConnectionError) as e: self._format_exception(e) diff --git a/vnfs/examples/dataplaneVNF4.yaml b/vnfs/examples/dataplaneVNF4.yaml index 294c4a0d..40762ec0 100644 --- a/vnfs/examples/dataplaneVNF4.yaml +++ b/vnfs/examples/dataplaneVNF4.yaml @@ -69,7 +69,7 @@ vnf: VNFC: - name: VNF_2VMs-VM1 description: "Dataplane VM1 with 4 threads, 2 GB hugepages, 2 SR-IOV interface" - image name: dataplaneVNF_2VMs-image + image name: linux-linux-VM-img disk: 10 numas: - paired-threads: 2 # "cores", "paired-threads", "threads" @@ -90,7 +90,7 @@ vnf: - name: VNF_2VMs-VM2 description: "Dataplane VM1 with 2 threads, 2 GB hugepages, 2 SR-IOV interface" - image name: dataplaneVNF_2VMs-image + image name: linux-linux-VM-img disk: 10 numas: - paired-threads: 1 # "cores", "paired-threads", "threads" -- 2.17.1