Merge branch 'v1.0' 33/933/1
authorgarciadeblas <gerardo.garciadeblas@telefonica.com>
Thu, 12 Jan 2017 14:03:58 +0000 (15:03 +0100)
committergarciadeblas <gerardo.garciadeblas@telefonica.com>
Thu, 12 Jan 2017 14:03:58 +0000 (15:03 +0100)
1  2 
nfvo.py
openmano
scripts/install-openmano.sh
vimconn_openstack.py

diff --combined nfvo.py
+++ b/nfvo.py
@@@ -266,18 -266,19 +266,19 @@@ def create_or_use_image(mydb, vims, ima
          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
              if image_dict['location'] is not None:
                  image_vim_id = vim.get_image_id_from_path(image_dict['location'])
              else:
-                 filter_dict={}
-                 filter_dict['name']=image_dict['universal_name']
-                 filter_dict['checksum']=image_dict['checksum']
+                 filter_dict = {}
+                 filter_dict['name'] = image_dict['universal_name']
+                 if image_dict.get('checksum') != None:
+                     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 NfvoException("More than one candidate VIM image found for filter: " + str(filter_dict), HTTP_Conflict)
+                     raise vimconn.vimconnException("More than one candidate VIM image found for filter: {}".format(str(filter_dict)), HTTP_Conflict)
                  elif len(vim_images) == 0:
-                     raise NfvoException("Image not found at VIM with filter: '%s'", str(filter_dict))
+                     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:
                  raise
              logger.warn("Error contacting VIM to know if the image exists at VIM: %s", str(e))
              image_vim_id = None
-             continue    
+             continue
          #if we reach here, the image has been created or existed
          if len(image_db)==0:
              #add new vim_id at datacenters_images
@@@ -365,6 -373,7 +373,7 @@@ def create_or_use_flavor(mydb, vims, fl
                      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
                  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
@@@ -583,6 -593,7 +593,7 @@@ def new_vnf(mydb, tenant_id, vnf_descri
              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
@@@ -721,6 -732,7 +732,7 @@@ def new_vnf_v02(mydb, tenant_id, vnf_de
              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
@@@ -1481,10 -1493,6 +1493,10 @@@ def start_scenario(mydb, tenant_id, sce
                          netDict['vpci'] = iface['vpci']
                      if "mac" in iface and iface["mac"] is not None:
                          netDict['mac_address'] = iface['mac']
 +                    if "port-security" in iface and iface["port-security"] is not None:
 +                        netDict['port_security'] = iface['port-security']
 +                    if "floating-ip" in iface and iface["floating-ip"] is not None:
 +                        netDict['floating_ip'] = iface['floating-ip']
                      netDict['name'] = iface['internal_name']
                      if iface['net_id'] is None:
                          for vnf_iface in sce_vnf["interfaces"]:
@@@ -1765,6 -1773,7 +1777,7 @@@ def create_instance(mydb, tenant_id, in
                      myvims[d] = v
                      datacenter2tenant[d] = v['config']['datacenter_tenant_id']
                  scenario_vnf["datacenter"] = vnf_instance_desc["datacenter"]
      #0.1 parse cloud-config parameters
          cloud_config = scenarioDict.get("cloud-config", {})
          if instance_dict.get("cloud-config"):
                          netDict['vpci'] = iface['vpci']
                      if "mac" in iface and iface["mac"] is not None:
                          netDict['mac_address'] = iface['mac']
 +                    if "port-security" in iface and iface["port-security"] is not None:
 +                        netDict['port_security'] = iface['port-security']
 +                    if "floating-ip" in iface and iface["floating-ip"] is not None:
 +                        netDict['floating_ip'] = iface['floating-ip']
                      netDict['name'] = iface['internal_name']
                      if iface['net_id'] is None:
                          for vnf_iface in sce_vnf["interfaces"]:
diff --combined openmano
+++ b/openmano
@@@ -28,7 -28,7 +28,7 @@@ openmano client used to interact with o
  '''
  __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 +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:
                      #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'"
              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 
@@@ -579,7 -591,7 +591,7 @@@ def instance_create(args)
      if args.scenario != None:
          scenario = args.scenario
      if not scenario:
 -        print "you must provide an scenario in the file descriptor or with --scenario"
 +        print "you must provide a scenario in the file descriptor or with --scenario"
          return -1
      myInstance["instance"]["scenario"] = _get_item_uuid("scenarios", scenario, tenant)
      if args.netmap_use:
@@@ -1207,6 -1219,8 +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")
@@@ -267,13 -267,14 +267,14 @@@ sudo pip install --upgrade pi
  sudo pip install pyvcloud
  sudo pip install progressbar
  sudo pip install prettytable
+ sudo pip install pyvmomi
  
  #The only way to install python-bottle on Centos7 is with easy_install or pip
  [ "$_DISTRO" == "CentOS" -o "$_DISTRO" == "Red" ] && easy_install -U bottle
  
  #install openstack client needed for using openstack as a VIM
 -[ "$_DISTRO" == "Ubuntu" ] && install_packages "python-novaclient python-keystoneclient python-glanceclient python-neutronclient"
 -[ "$_DISTRO" == "CentOS" -o "$_DISTRO" == "Red" ] && install_packages "python-devel" && easy_install python-novaclient python-keystoneclient python-glanceclient python-neutronclient #TODO revise if gcc python-pip is needed
 +[ "$_DISTRO" == "Ubuntu" ] && install_packages "python-novaclient python-keystoneclient python-glanceclient python-neutronclient python-cinderclient"
 +[ "$_DISTRO" == "CentOS" -o "$_DISTRO" == "Red" ] && install_packages "python-devel" && easy_install python-novaclient python-keystoneclient python-glanceclient python-neutronclient python-cinderclient #TODO revise if gcc python-pip is needed
  fi  #[[ -z "$NO_PACKAGES" ]]
  
  if [[ -z $NOCLONE ]]; then
diff --combined vimconn_openstack.py
@@@ -62,7 -62,6 +62,7 @@@ netStatus2manoFormat={'ACTIVE':'ACTIVE'
  
  #global var to have a timeout creating and deleting volumes
  volume_timeout = 60
 +server_timeout = 60
  
  class vimconnector(vimconn.vimconnector):
      def __init__(self, uuid, name, tenant_id, tenant_name, url, url_admin=None, user=None, passwd=None, log_level=None, config={}):
@@@ -96,9 -95,6 +96,9 @@@
          if self.osc_api_version == 'v3.3':
              self.k_creds['project_name'] = tenant_name
              self.k_creds['project_id'] = tenant_id
 +        if config.get('region_name'):
 +            self.k_creds['region_name'] = config.get('region_name')
 +            self.n_creds['region_name'] = config.get('region_name')
  
          self.reload_client       = True
          self.logger = logging.getLogger('openmano.vim.openstack')
                  #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":
              filtered_list = []
              for image in image_list:
                  image_dict=self.glance.images.get(image.id)
-                 if 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)
                          port_dict["name"]=name
                      if net.get("mac_address"):
                          port_dict["mac_address"]=net["mac_address"]
 +                    if net.get("port_security") == False:
 +                        port_dict["port_security_enabled"]=net["port_security"]
                      new_port = self.neutron.create_port({"port": port_dict })
                      net["mac_adress"] = new_port["port"]["mac_address"]
                      net["vim_id"] = new_port["port"]["id"]
                      #delete ports we just created
                      for net_item  in net_list_vim:
                          if 'port-id' in net_item:
 -                            self.neutron.delete_port(net_item['port_id'])
 +                            self.neutron.delete_port(net_item['port-id'])
  
                      raise vimconn.vimconnException('Timeout creating volumes for instance ' + name,
                                                     http_code=vimconn.HTTP_Request_Timeout)
                                                block_device_mapping = block_device_mapping
                                                )  # , description=description)
              #print "DONE :-)", server
 -            
              pool_id = None
              floating_ips = self.neutron.list_floatingips().get("floatingips", ())
              for floating_network in external_network:
 +                # wait until vm is active
 +                elapsed_time = 0
 +                while elapsed_time < server_timeout:
 +                    status = self.nova.servers.get(server.id).status
 +                    if status == 'ACTIVE':
 +                        break
 +                    time.sleep(1)
 +                    elapsed_time += 1
 +
 +                #if we exceeded the timeout rollback
 +                if elapsed_time >= server_timeout:
 +                    self.delete_vminstance(server.id)
 +                    raise vimconn.vimconnException('Timeout creating instance ' + name,
 +                                                   http_code=vimconn.HTTP_Request_Timeout)
 +
                  assigned = False
                  while(assigned == False):
                      if floating_ips:
                          ip = floating_ips.pop(0)
 -                        if not ip.get("port_id", False):
 +                        if not ip.get("port_id", False) and ip.get('tenant_id') == server.tenant_id:
                              free_floating_ip = ip.get("floating_ip_address")
                              try:
                                  fix_ip = floating_network.get('ip')
                                  self.delete_vminstance(server.id)
                                  raise vimconn.vimconnException(type(e).__name__ + ": Cannot create floating_ip "+  str(e), http_code=vimconn.HTTP_Conflict)
                      else:
 -                        pool_id = floating_network.get('net_id')
 -                        param = {'floatingip': {'floating_network_id': pool_id}}
 +                        #Find the external network
 +                        external_nets = list()
 +                        for net in self.neutron.list_networks()['networks']:
 +                            if net['router:external']:
 +                                    external_nets.append(net)
 +
 +                        if len(external_nets) == 0:
 +                            self.delete_vminstance(server.id)
 +                            raise vimconn.vimconnException("Cannot create floating_ip automatically since no external "
 +                                                           "network is present",
 +                                                            http_code=vimconn.HTTP_Conflict)
 +                        if len(external_nets) > 1:
 +                            self.delete_vminstance(server.id)
 +                            raise vimconn.vimconnException("Cannot create floating_ip automatically since multiple "
 +                                                           "external networks are present",
 +                                                           http_code=vimconn.HTTP_Conflict)
 +
 +                        pool_id = external_nets[0].get('id')
 +                        param = {'floatingip': {'floating_network_id': pool_id, 'tenant_id': server.tenant_id}}
                          try:
                              #self.logger.debug("Creating floating IP")
                              new_floating_ip = self.neutron.create_floatingip(param)
  #            error_text= "vm instance %s not found" % vm_id
          except (ksExceptions.ClientException, nvExceptions.ClientException, ConnectionError
                  ) as e:
 +            # delete the volumes we just created
 +            if block_device_mapping != None:
 +                for volume_id in block_device_mapping.itervalues():
 +                    self.cinder.volumes.delete(volume_id)
 +
 +            # delete ports we just created
 +            for net_item in net_list_vim:
 +                if 'port-id' in net_item:
 +                    self.neutron.delete_port(net_item['port-id'])
              self._format_exception(e)
          except TypeError as e:
              raise vimconn.vimconnException(type(e).__name__ + ": "+  str(e), http_code=vimconn.HTTP_Bad_Request)