bug 425 fix SR-IOV PCI-PASSTHROUGH interfaces
[osm/RO.git] / osm_ro / vimconn_aws.py
index 4520293..12b2411 100644 (file)
@@ -117,7 +117,7 @@ class vimconnector(vimconn.vimconnector):
                 except IOError as e:
                     raise vimconn.vimconnException("Error reading file '{}': {}".format(flavor_data[1:], e))
             elif isinstance(flavor_data, dict):
-                self.flavor_data = flavor_data
+                self.flavor_info = flavor_data
 
         self.logger = logging.getLogger('openmano.vim.aws')
         if log_level:
@@ -351,12 +351,12 @@ class vimconnector(vimconn.vimconnector):
             if filter_dict != {}:
                 if 'tenant_id' in filter_dict:
                     tfilters['vpcId'] = filter_dict['tenant_id']
-            subnets = self.conn_vpc.get_all_subnets(subnet_ids=filter_dict.get('id', None), filters=tfilters)
+            subnets = self.conn_vpc.get_all_subnets(subnet_ids=filter_dict.get('name', None), filters=tfilters)
             net_list = []
             for net in subnets:
                 net_list.append(
                     {'id': str(net.id), 'name': str(net.id), 'status': str(net.state), 'vpc_id': str(net.vpc_id),
-                     'cidr_block': str(net.cidr_block)})
+                     'cidr_block': str(net.cidr_block), 'type': 'bridge'})
             return net_list
         except Exception as e:
             self.format_vimconn_exception(e)
@@ -471,17 +471,17 @@ class vimconnector(vimconn.vimconnector):
         try:
             flavor = None
             for key, values in self.flavor_info.iteritems():
-                if (values["memory"], values["cores"], values["disk"]) == (
-                flavor_dict["ram"], flavor_dict["cpus"], flavor_dict["disk"]):
+                if (values["ram"], values["cpus"], values["disk"]) == (
+                flavor_dict["ram"], flavor_dict["vcpus"], flavor_dict["disk"]):
                     flavor = (key, values)
                     break
-                elif (values["memory"], values["cores"], values["disk"]) >= (
-                flavor_dict["ram"], flavor_dict["cpus"], flavor_dict["disk"]):
+                elif (values["ram"], values["cpus"], values["disk"]) >= (
+                flavor_dict["ram"], flavor_dict["vcpus"], flavor_dict["disk"]):
                     if not flavor:
                         flavor = (key, values)
                     else:
-                        if (flavor[1]["memory"], flavor[1]["cores"], flavor[1]["disk"]) >= (
-                        values["memory"], values["cores"], values["disk"]):
+                        if (flavor[1]["ram"], flavor[1]["cpus"], flavor[1]["disk"]) >= (
+                        values["ram"], values["cpus"], values["disk"]):
                             flavor = (key, values)
             if flavor:
                 return flavor[0]
@@ -590,7 +590,7 @@ class vimconnector(vimconn.vimconnector):
             self.format_vimconn_exception(e)
 
     def new_vminstance(self, name, description, start, image_id, flavor_id, net_list, cloud_config=None,
-                       disk_list=None):
+                       disk_list=None, availability_zone_index=None, availability_zone_list=None):
         """Create a new VM/instance in AWS
         Params: name
                 decription
@@ -605,9 +605,9 @@ class vimconnector(vimconn.vimconnector):
                     mac_address: (optional) mac address to assign to this interface
                     type: (mandatory) can be one of:
                         virtual, in this case always connected to a network of type 'net_type=bridge'
-                        PF - (passthrough): depending on VIM capabilities it can be connected to a data/ptp network ot it
-                               can created unconnected
-                        VF - (SRIOV with VLAN tag): same as PF for network connectivity.
+                        'PCI-PASSTHROUGH' or 'PF' (passthrough): depending on VIM capabilities it can be connected to a data/ptp network ot it
+                           can created unconnected
+                        'SR-IOV' or 'VF' (SRIOV with VLAN tag): same as PF for network connectivity.
                         VFnotShared - (SRIOV without VLAN tag) same as PF for network connectivity. VF where no other VFs
                             are allocated on the same physical NIC
                     bw': (optional) only for PF/VF/VFnotShared. Minimal Bandwidth required for the interface in GBPS
@@ -634,59 +634,18 @@ class vimconnector(vimconn.vimconnector):
                 disk_list': (optional) list with additional disks to the VM. Each item is a dict with:
                     image_id': (optional). VIM id of an existing image. If not provided an empty disk must be mounted
                     size': (mandatory) string with the size of the disk in GB
-        Returns: instance identifier or raises an exception on error
+        Returns a tuple with the instance identifier and created_items or raises an exception on error
+            created_items can be None or a dictionary where this method can include key-values that will be passed to
+            the method delete_vminstance and action_vminstance. Can be used to store created ports, volumes, etc.
+            Format is vimconnector dependent, but do not use nested dictionaries and a value of None should be the same
+            as not present.
         """
 
         self.logger.debug("Creating a new VM instance")
         try:
             self._reload_connection()
             instance = None
-            userdata = None
-            if isinstance(cloud_config, dict):
-                if cloud_config.get("user-data"):
-                    userdata = cloud_config["user-data"]
-                if cloud_config.get("config-files") or cloud_config.get("users") or cloud_config.get("key-pairs"):
-                    if userdata:
-                        raise vimconn.vimconnConflictException(
-                            "Cloud-config cannot contain both 'userdata' and 'config-files'/'users'/'key-pairs'")
-                    userdata_dict = {}
-                    # default user
-                    if cloud_config.get("key-pairs"):
-                        userdata_dict["ssh-authorized-keys"] = cloud_config["key-pairs"]
-                        userdata_dict["users"] = [{"default": None, "ssh-authorized-keys": cloud_config["key-pairs"]}]
-                    if cloud_config.get("users"):
-                        if "users" not in userdata_dict:
-                            userdata_dict["users"] = ["default"]
-                        for user in cloud_config["users"]:
-                            user_info = {
-                                "name": user["name"],
-                                "sudo": "ALL = (ALL)NOPASSWD:ALL"
-                            }
-                            if "user-info" in user:
-                                user_info["gecos"] = user["user-info"]
-                            if user.get("key-pairs"):
-                                user_info["ssh-authorized-keys"] = user["key-pairs"]
-                            userdata_dict["users"].append(user_info)
-
-                    if cloud_config.get("config-files"):
-                        userdata_dict["write_files"] = []
-                        for file in cloud_config["config-files"]:
-                            file_info = {
-                                "path": file["dest"],
-                                "content": file["content"]
-                            }
-                            if file.get("encoding"):
-                                file_info["encoding"] = file["encoding"]
-                            if file.get("permissions"):
-                                file_info["permissions"] = file["permissions"]
-                            if file.get("owner"):
-                                file_info["owner"] = file["owner"]
-                            userdata_dict["write_files"].append(file_info)
-                    userdata = "#cloud-config\n"
-                    userdata += yaml.safe_dump(userdata_dict, indent=4, default_flow_style=False)
-                self.logger.debug("userdata: %s", userdata)
-            elif isinstance(cloud_config, str):
-                userdata = cloud_config
+            _, userdata = self._create_user_data(cloud_config)
 
             if not net_list:
                 reservation = self.conn.run_instances(
@@ -696,9 +655,7 @@ class vimconnector(vimconn.vimconnector):
                     security_groups=self.security_groups,
                     user_data=userdata
                 )
-                instance = reservation.instances[0]
             else:
-                net_list = [net_list[0]]
                 for index, subnet in enumerate(net_list):
                     net_intr = boto.ec2.networkinterface.NetworkInterfaceSpecification(subnet_id=subnet.get('net_id'),
                                                                                        groups=None,
@@ -717,7 +674,6 @@ class vimconnector(vimconn.vimconnector):
                             network_interfaces=boto.ec2.networkinterface.NetworkInterfaceCollection(net_intr),
                             user_data=userdata
                         )
-                        instance = reservation.instances[0]
                     else:
                         while True:
                             try:
@@ -727,7 +683,10 @@ class vimconnector(vimconn.vimconnector):
                                 break
                             except:
                                 time.sleep(10)
-            return instance.id
+                    net_list[index]['vim_id'] = reservation.instances[0].interfaces[index].id
+
+            instance = reservation.instances[0]
+            return instance.id, None
         except Exception as e:
             self.format_vimconn_exception(e)
 
@@ -741,7 +700,7 @@ class vimconnector(vimconn.vimconnector):
         except Exception as e:
             self.format_vimconn_exception(e)
 
-    def delete_vminstance(self, vm_id):
+    def delete_vminstance(self, vm_id, created_items=None):
         """Removes a VM instance from VIM
         Returns the instance identifier"""
 
@@ -796,7 +755,10 @@ class vimconnector(vimconn.vimconnector):
                         interface_dict['vim_interface_id'] = interface.id
                         interface_dict['vim_net_id'] = interface.subnet_id
                         interface_dict['mac_address'] = interface.mac_address
-                        interface_dict['ip_address'] = interface.private_ip_address
+                        if hasattr(interface, 'publicIp') and interface.publicIp != None:
+                            interface_dict['ip_address'] = interface.publicIp + ";" + interface.private_ip_address
+                        else:
+                            interface_dict['ip_address'] = interface.private_ip_address
                         instance_dict['interfaces'].append(interface_dict)
                 except Exception as e:
                     self.logger.error("Exception getting vm status: %s", str(e), exc_info=True)
@@ -814,7 +776,7 @@ class vimconnector(vimconn.vimconnector):
             self.logger.error("Exception getting vm status: %s", str(e), exc_info=True)
             self.format_vimconn_exception(e)
 
-    def action_vminstance(self, vm_id, action_dict):
+    def action_vminstance(self, vm_id, action_dict, created_items={}):
         """Send and action over a VM instance from VIM
         Returns the vm_id if the action was successfully sent to the VIM"""
 
@@ -829,6 +791,6 @@ class vimconnector(vimconn.vimconnector):
                 self.conn.terminate_instances(vm_id)
             elif "reboot" in action_dict:
                 self.conn.reboot_instances(vm_id)
-            return vm_id
+            return None
         except Exception as e:
             self.format_vimconn_exception(e)