# -*- coding: utf-8 -*-

##
# Copyright 2017 xFlow Research Pvt. Ltd
# 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: saboor.ahmad@xflowresearch.com
##

'''
AWS-connector implements all the methods to interact with AWS using the BOTO client
'''

__author__ = "Saboor Ahmad"
__date__ = "10-Apr-2017"

import vimconn
import yaml
import logging
import netaddr
import time

try:
    import boto
    import boto.ec2
    import boto.vpc
except:
    exit("Boto not avialable. Try activating your virtualenv OR `pip install boto`")


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={}, persistent_info={}):
        """ Params: uuid - id asigned to this VIM
                name - name assigned to this VIM, can be used for logging
                tenant_id - ID to be used for tenant
                tenant_name - name of tenant to be used VIM tenant to be used
                url_admin - optional, url used for administrative tasks
                user - credentials of the VIM user
                passwd - credentials of the VIM user
                log_level - if must use a different log_level than the general one
                config - dictionary with misc VIM information
                    region_name - name of region to deploy the instances
                    vpc_cidr_block - default CIDR block for VPC
                    security_groups - default security group to specify this instance
                persistent_info - dict where the class can store information that will be available among class
                    destroy/creation cycles. This info is unique per VIM/credential. At first call it will contain an
                    empty dict. Useful to store login/tokens information for speed up communication
        """

        vimconn.vimconnector.__init__(self, uuid, name, tenant_id, tenant_name, url, url_admin, user, passwd, log_level,
                                      config, persistent_info)

        self.persistent_info = persistent_info
        self.a_creds = {}
        if user:
            self.a_creds['aws_access_key_id'] = user
        else:
            raise vimconn.vimconnAuthException("Username is not specified")
        if passwd:
            self.a_creds['aws_secret_access_key'] = passwd
        else:
            raise vimconn.vimconnAuthException("Password is not specified")
        if 'region_name' in config:
            self.region = config.get('region_name')
        else:
            raise vimconn.vimconnNotFoundException("AWS region_name is not specified at config")

        self.vpc_data = {}
        self.subnet_data = {}
        self.conn = None
        self.conn_vpc = None
        self.account_id = None

        self.vpc_id = self.get_tenant_list()[0]['id']
        # we take VPC CIDR block if specified, otherwise we use the default CIDR
        # block suggested by AWS while creating instance
        self.vpc_cidr_block = '10.0.0.0/24'

        if tenant_id:
            self.vpc_id = tenant_id
        if 'vpc_cidr_block' in config:
            self.vpc_cidr_block = config['vpc_cidr_block']

        self.security_groups = None
        if 'security_groups' in config:
            self.security_groups = config['security_groups']

        self.key_pair = None
        if 'key_pair' in config:
            self.key_pair = config['key_pair']

        self.flavor_info = None
        if 'flavor_info' in config:
            flavor_data = config.get('flavor_info')
            if isinstance(flavor_data, str):
                try:
                    with open(flavor_data[1:], 'r') as stream:
                        self.flavor_info = yaml.load(stream)
                except yaml.YAMLError as e:
                    self.flavor_info = None
                    raise vimconn.vimconnException("Bad format at file '{}': {}".format(flavor_data[1:], e))
                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.logger = logging.getLogger('openmano.vim.aws')
        if log_level:
            self.logger.setLevel(getattr(logging, log_level))

    def __setitem__(self, index, value):
        """Params: index - name of value of set
                   value - value to set
        """
        if index == 'user':
            self.a_creds['aws_access_key_id'] = value
        elif index == 'passwd':
            self.a_creds['aws_secret_access_key'] = value
        elif index == 'region':
            self.region = value
        else:
            vimconn.vimconnector.__setitem__(self, index, value)

    def _reload_connection(self):
        """Returns: sets boto.EC2 and boto.VPC connection to work with AWS services
        """

        try:
            self.conn = boto.ec2.connect_to_region(self.region, aws_access_key_id=self.a_creds['aws_access_key_id'],
                                                   aws_secret_access_key=self.a_creds['aws_secret_access_key'])
            self.conn_vpc = boto.vpc.connect_to_region(self.region, aws_access_key_id=self.a_creds['aws_access_key_id'],
                                                       aws_secret_access_key=self.a_creds['aws_secret_access_key'])
            # client = boto3.client("sts", aws_access_key_id=self.a_creds['aws_access_key_id'], aws_secret_access_key=self.a_creds['aws_secret_access_key'])
            # self.account_id = client.get_caller_identity()["Account"]
        except Exception as e:
            self.format_vimconn_exception(e)

    def format_vimconn_exception(self, e):
        """Params: an Exception object
        Returns: Raises the exception 'e' passed in mehtod parameters
        """

        self.conn = None
        self.conn_vpc = None
        raise vimconn.vimconnConnectionException(type(e).__name__ + ": " + str(e))

    def get_availability_zones_list(self):
        """Obtain AvailabilityZones from AWS
        """

        try:
            self._reload_connection()
            az_list = []
            for az in self.conn.get_all_zones():
                az_list.append(az.name)
            return az_list
        except Exception as e:
            self.format_vimconn_exception(e)

    def get_tenant_list(self, filter_dict={}):
        """Obtain tenants of VIM
        filter_dict dictionary that can contain the following keys:
            name: filter by tenant name
            id: filter by tenant uuid/id
            <other VIM specific>
        Returns the tenant list of dictionaries, and empty list if no tenant match all the filers:
            [{'name':'<name>, 'id':'<id>, ...}, ...]
        """

        try:
            self._reload_connection()
            vpc_ids = []
            tfilters = {}
            if filter_dict != {}:
                if 'id' in filter_dict:
                    vpc_ids.append(filter_dict['id'])
                    tfilters['name'] = filter_dict['id']
            tenants = self.conn_vpc.get_all_vpcs(vpc_ids, tfilters)
            tenant_list = []
            for tenant in tenants:
                tenant_list.append({'id': str(tenant.id), 'name': str(tenant.id), 'status': str(tenant.state),
                                    'cidr_block': str(tenant.cidr_block)})
            return tenant_list
        except Exception as e:
            self.format_vimconn_exception(e)

    def new_tenant(self, tenant_name, tenant_description):
        """Adds a new tenant to VIM with this name and description, this is done using admin_url if provided
        "tenant_name": string max lenght 64
        "tenant_description": string max length 256
        returns the tenant identifier or raise exception
        """

        self.logger.debug("Adding a new VPC")
        try:
            self._reload_connection()
            vpc = self.conn_vpc.create_vpc(self.vpc_cidr_block)
            self.conn_vpc.modify_vpc_attribute(vpc.id, enable_dns_support=True)
            self.conn_vpc.modify_vpc_attribute(vpc.id, enable_dns_hostnames=True)

            gateway = self.conn_vpc.create_internet_gateway()
            self.conn_vpc.attach_internet_gateway(gateway.id, vpc.id)
            route_table = self.conn_vpc.create_route_table(vpc.id)
            self.conn_vpc.create_route(route_table.id, '0.0.0.0/0', gateway.id)

            self.vpc_data[vpc.id] = {'gateway': gateway.id, 'route_table': route_table.id,
                                     'subnets': self.subnet_sizes(len(self.get_availability_zones_list()),
                                                                  self.vpc_cidr_block)}
            return vpc.id
        except Exception as e:
            self.format_vimconn_exception(e)

    def delete_tenant(self, tenant_id):
        """Delete a tenant from VIM
        tenant_id: returned VIM tenant_id on "new_tenant"
        Returns None on success. Raises and exception of failure. If tenant is not found raises vimconnNotFoundException
        """

        self.logger.debug("Deleting specified VPC")
        try:
            self._reload_connection()
            vpc = self.vpc_data.get(tenant_id)
            if 'gateway' in vpc and 'route_table' in vpc:
                gateway_id, route_table_id = vpc['gateway'], vpc['route_table']
                self.conn_vpc.detach_internet_gateway(gateway_id, tenant_id)
                self.conn_vpc.delete_vpc(tenant_id)
                self.conn_vpc.delete_route(route_table_id, '0.0.0.0/0')
            else:
                self.conn_vpc.delete_vpc(tenant_id)
        except Exception as e:
            self.format_vimconn_exception(e)

    def subnet_sizes(self, availability_zones, cidr):
        """Calcualtes possible subnets given CIDR value of VPC
        """

        if availability_zones != 2 and availability_zones != 3:
            self.logger.debug("Number of AZs should be 2 or 3")
            raise vimconn.vimconnNotSupportedException("Number of AZs should be 2 or 3")

        netmasks = ('255.255.252.0', '255.255.254.0', '255.255.255.0', '255.255.255.128')
        ip = netaddr.IPNetwork(cidr)
        mask = ip.netmask

        if str(mask) not in netmasks:
            self.logger.debug("Netmask " + str(mask) + " not found")
            raise vimconn.vimconnNotFoundException("Netmask " + str(mask) + " not found")

        if availability_zones == 2:
            for n, netmask in enumerate(netmasks):
                if str(mask) == netmask:
                    subnets = list(ip.subnet(n + 24))
        else:
            for n, netmask in enumerate(netmasks):
                if str(mask) == netmask:
                    pub_net = list(ip.subnet(n + 24))
                    pri_subs = pub_net[1:]
                    pub_mask = pub_net[0].netmask
            pub_split = list(ip.subnet(26)) if (str(pub_mask) == '255.255.255.0') else list(ip.subnet(27))
            pub_subs = pub_split[:3]
            subnets = pub_subs + pri_subs

        return map(str, subnets)

    def new_network(self, net_name, net_type, ip_profile=None, shared=False, vlan=None):
        """Adds a tenant network to VIM
        Params:
            'net_name': name of the network
            'net_type': one of:
                'bridge': overlay isolated network
                'data':   underlay E-LAN network for Passthrough and SRIOV interfaces
                'ptp':    underlay E-LINE network for Passthrough and SRIOV interfaces.
            'ip_profile': is a dict containing the IP parameters of the network (Currently only IPv4 is implemented)
                'ip-version': can be one of ["IPv4","IPv6"]
                'subnet-address': ip_prefix_schema, that is X.X.X.X/Y
                'gateway-address': (Optional) ip_schema, that is X.X.X.X
                'dns-address': (Optional) ip_schema,
                'dhcp': (Optional) dict containing
                    'enabled': {"type": "boolean"},
                    'start-address': ip_schema, first IP to grant
                    'count': number of IPs to grant.
            'shared': if this network can be seen/use by other tenants/organization
            'vlan': in case of a data or ptp net_type, the intended vlan tag to be used for the network
        Returns the network identifier on success or raises and exception on failure
        """

        self.logger.debug("Adding a subnet to VPC")
        try:
            self._reload_connection()
            subnet = None
            vpc_id = self.vpc_id
            if self.vpc_data.get(vpc_id, None):
                cidr_block = list(set(self.vpc_data[vpc_id]['subnets']) - set(self.get_network_details({'tenant_id': vpc_id}, detail='cidr_block')))[0]
            else:
                vpc = self.get_tenant_list({'id': vpc_id})[0]
                subnet_list = self.subnet_sizes(len(self.get_availability_zones_list()), vpc['cidr_block'])
                cidr_block = list(set(subnet_list) - set(self.get_network_details({'tenant_id': vpc['id']}, detail='cidr_block')))[0]
            subnet = self.conn_vpc.create_subnet(vpc_id, cidr_block)
            return subnet.id
        except Exception as e:
            self.format_vimconn_exception(e)

    def get_network_details(self, filters, detail):
        """Get specified details related to a subnet
        """
        detail_list = []
        subnet_list = self.get_network_list(filters)
        for net in subnet_list:
            detail_list.append(net[detail])
        return detail_list

    def get_network_list(self, filter_dict={}):
        """Obtain tenant networks of VIM
        Params:
            'filter_dict' (optional) contains entries to return only networks that matches ALL entries:
                name: string  => returns only networks with this name
                id:   string  => returns networks with this VIM id, this imply returns one network at most
                shared: boolean >= returns only networks that are (or are not) shared
                tenant_id: sting => returns only networks that belong to this tenant/project
                ,#(not used yet) admin_state_up: boolean => returns only networks that are (or are not) in admin state active
                #(not used yet) status: 'ACTIVE','ERROR',... => filter networks that are on this status
        Returns the network list of dictionaries. each dictionary contains:
            'id': (mandatory) VIM network id
            'name': (mandatory) VIM network name
            'status': (mandatory) can be 'ACTIVE', 'INACTIVE', 'DOWN', 'BUILD', 'ERROR', 'VIM_ERROR', 'OTHER'
            'error_msg': (optional) text that explains the ERROR status
            other VIM specific fields: (optional) whenever possible using the same naming of filter_dict param
        List can be empty if no network map the filter_dict. Raise an exception only upon VIM connectivity,
            authorization, or some other unspecific error
        """

        self.logger.debug("Getting all subnets from VIM")
        try:
            self._reload_connection()
            tfilters = {}
            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)
            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)})
            return net_list
        except Exception as e:
            self.format_vimconn_exception(e)

    def get_network(self, net_id):
        """Obtain network details from the 'net_id' VIM network
        Return a dict that contains:
            'id': (mandatory) VIM network id, that is, net_id
            'name': (mandatory) VIM network name
            'status': (mandatory) can be 'ACTIVE', 'INACTIVE', 'DOWN', 'BUILD', 'ERROR', 'VIM_ERROR', 'OTHER'
            'error_msg': (optional) text that explains the ERROR status
            other VIM specific fields: (optional) whenever possible using the same naming of filter_dict param
        Raises an exception upon error or when network is not found
        """

        self.logger.debug("Getting Subnet from VIM")
        try:
            self._reload_connection()
            subnet = self.conn_vpc.get_all_subnets(net_id)[0]
            return {'id': str(subnet.id), 'name': str(subnet.id), 'status': str(subnet.state),
                    'vpc_id': str(subnet.vpc_id), 'cidr_block': str(subnet.cidr_block)}
        except Exception as e:
            self.format_vimconn_exception(e)

    def delete_network(self, net_id):
        """Deletes a tenant network from VIM
        Returns the network identifier or raises an exception upon error or when network is not found
        """

        self.logger.debug("Deleting subnet from VIM")
        try:
            self._reload_connection()
            self.logger.debug("DELETING NET_ID: " + str(net_id))
            self.conn_vpc.delete_subnet(net_id)
            return net_id
        except Exception as e:
            self.format_vimconn_exception(e)

    def refresh_nets_status(self, net_list):
        """Get the status of the networks
        Params:
            'net_list': a list with the VIM network id to be get the status
        Returns a dictionary with:
            'net_id':         #VIM id of this network
                status:     #Mandatory. Text with one of:
                    #  DELETED (not found at vim)
                    #  VIM_ERROR (Cannot connect to VIM, authentication problems, VIM response error, ...)
                    #  OTHER (Vim reported other status not understood)
                    #  ERROR (VIM indicates an ERROR status)
                    #  ACTIVE, INACTIVE, DOWN (admin down),
                    #  BUILD (on building process)
                error_msg:  #Text with VIM error message, if any. Or the VIM connection ERROR
                vim_info:   #Text with plain information obtained from vim (yaml.safe_dump)
            'net_id2': ...
        """

        self._reload_connection()
        try:
            dict_entry = {}
            for net_id in net_list:
                subnet_dict = {}
                subnet = None
                try:
                    subnet = self.conn_vpc.get_all_subnets(net_id)[0]
                    if subnet.state == "pending":
                        subnet_dict['status'] = "BUILD"
                    elif subnet.state == "available":
                        subnet_dict['status'] = 'ACTIVE'
                    else:
                        subnet_dict['status'] = 'ERROR'
                    subnet_dict['error_msg'] = ''
                except Exception as e:
                    subnet_dict['status'] = 'DELETED'
                    subnet_dict['error_msg'] = 'Network not found'
                finally:
                    try:
                        subnet_dict['vim_info'] = yaml.safe_dump(subnet, default_flow_style=True, width=256)
                    except yaml.YAMLError as e:
                        subnet_dict['vim_info'] = str(subnet)
                dict_entry[net_id] = subnet_dict
            return dict_entry
        except Exception as e:
            self.format_vimconn_exception(e)

    def get_flavor(self, flavor_id):
        """Obtain flavor details from the VIM
        Returns the flavor dict details {'id':<>, 'name':<>, other vim specific }
        Raises an exception upon error or if not found
        """

        self.logger.debug("Getting instance type")
        try:
            if flavor_id in self.flavor_info:
                return self.flavor_info[flavor_id]
            else:
                raise vimconn.vimconnNotFoundException("Cannot find flavor with this flavor ID/Name")
        except Exception as e:
            self.format_vimconn_exception(e)

    def get_flavor_id_from_data(self, flavor_dict):
        """Obtain flavor id that match the flavor description
        Params:
            'flavor_dict': dictionary that contains:
                'disk': main hard disk in GB
                'ram': memory in MB
                'vcpus': number of virtual cpus
                #todo: complete parameters for EPA
        Returns the flavor_id or raises a vimconnNotFoundException
        """

        self.logger.debug("Getting flavor id from data")
        try:
            flavor = None
            for key, values in self.flavor_info.iteritems():
                if (values["ram"], values["cpus"], values["disk"]) == (
                flavor_dict["ram"], flavor_dict["vcpus"], flavor_dict["disk"]):
                    flavor = (key, values)
                    break
                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]["ram"], flavor[1]["cpus"], flavor[1]["disk"]) >= (
                        values["ram"], values["cpus"], values["disk"]):
                            flavor = (key, values)
            if flavor:
                return flavor[0]
            raise vimconn.vimconnNotFoundException("Cannot find flavor with this flavor ID/Name")
        except Exception as e:
            self.format_vimconn_exception(e)

    def new_image(self, image_dict):
        """ Adds a tenant image to VIM
        Params: image_dict
                    name (string) - The name of the AMI. Valid only for EBS-based images.
                    description (string) - The description of the AMI.
                    image_location (string) - Full path to your AMI manifest in Amazon S3 storage. Only used for S3-based AMI’s.
                    architecture (string) - The architecture of the AMI. Valid choices are: * i386 * x86_64
                    kernel_id (string) -  The ID of the kernel with which to launch the instances
                    root_device_name (string) - The root device name (e.g. /dev/sdh)
                    block_device_map (boto.ec2.blockdevicemapping.BlockDeviceMapping) - A BlockDeviceMapping data structure describing the EBS volumes associated with the Image.
                    virtualization_type (string) - The virutalization_type of the image. Valid choices are: * paravirtual * hvm
                    sriov_net_support (string) - Advanced networking support. Valid choices are: * simple
                    snapshot_id (string) - A snapshot ID for the snapshot to be used as root device for the image. Mutually exclusive with block_device_map, requires root_device_name
                    delete_root_volume_on_termination (bool) - Whether to delete the root volume of the image after instance termination. Only applies when creating image from snapshot_id. Defaults to False. Note that leaving volumes behind after instance termination is not free
        Returns: image_id - image ID of the newly created image
        """

        try:
            self._reload_connection()
            image_location = image_dict.get('image_location', None)
            if image_location:
                image_location = str(self.account_id) + str(image_location)

            image_id = self.conn.register_image(image_dict.get('name', None), image_dict.get('description', None),
                                                image_location, image_dict.get('architecture', None),
                                                image_dict.get('kernel_id', None),
                                                image_dict.get('root_device_name', None),
                                                image_dict.get('block_device_map', None),
                                                image_dict.get('virtualization_type', None),
                                                image_dict.get('sriov_net_support', None),
                                                image_dict.get('snapshot_id', None),
                                                image_dict.get('delete_root_volume_on_termination', None))
            return image_id
        except Exception as e:
            self.format_vimconn_exception(e)

    def delete_image(self, image_id):
        """Deletes a tenant image from VIM
        Returns the image_id if image is deleted or raises an exception on error"""

        try:
            self._reload_connection()
            self.conn.deregister_image(image_id)
            return image_id
        except Exception as e:
            self.format_vimconn_exception(e)

    def get_image_id_from_path(self, path):
        '''
        Params: path - location of the image
        Returns: image_id - ID of the matching image
        '''
        self._reload_connection()
        try:
            filters = {}
            if path:
                tokens = path.split('/')
                filters['owner_id'] = tokens[0]
                filters['name'] = '/'.join(tokens[1:])
            image = self.conn.get_all_images(filters=filters)[0]
            return image.id
        except Exception as e:
            self.format_vimconn_exception(e)

    def get_image_list(self, filter_dict={}):
        """Obtain tenant images from VIM
        Filter_dict can be:
            name: image name
            id: image uuid
            checksum: image checksum
            location: image path
        Returns the image list of dictionaries:
            [{<the fields at Filter_dict plus some VIM specific>}, ...]
            List can be empty
        """

        self.logger.debug("Getting image list from VIM")
        try:
            self._reload_connection()
            image_id = None
            filters = {}
            if 'id' in filter_dict:
                image_id = filter_dict['id']
            if 'name' in filter_dict:
                filters['name'] = filter_dict['name']
            if 'location' in filter_dict:
                filters['location'] = filter_dict['location']
            # filters['image_type'] = 'machine'
            # filter_dict['owner_id'] = self.account_id
            images = self.conn.get_all_images(image_id, filters=filters)
            image_list = []
            for image in images:
                image_list.append({'id': str(image.id), 'name': str(image.name), 'status': str(image.state),
                                   'owner': str(image.owner_id), 'location': str(image.location),
                                   'is_public': str(image.is_public), 'architecture': str(image.architecture),
                                   'platform': str(image.platform)})
            return image_list
        except Exception as e:
            self.format_vimconn_exception(e)

    def new_vminstance(self, name, description, start, image_id, flavor_id, net_list, cloud_config=None,
                       disk_list=None):
        """Create a new VM/instance in AWS
        Params: name
                decription
                start: (boolean) indicates if VM must start or created in pause mode.
                image_id - image ID in AWS
                flavor_id - instance type ID in AWS
                net_list
                    name
                    net_id - subnet_id from AWS
                    vpci - (optional) virtual vPCI address to assign at the VM. Can be ignored depending on VIM capabilities
                    model: (optional and only have sense for type==virtual) interface model: virtio, e2000, ...
                    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.
                        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
                    port_security': (optional) If False it must avoid any traffic filtering at this interface. If missing or True, it must apply the default VIM behaviour
                    vim_id': must be filled/added by this method with the VIM identifier generated by the VIM for this interface. 'net_list' is modified
                    elastic_ip - True/False to define if an elastic_ip is required
                cloud_config': (optional) dictionary with:
                    key-pairs': (optional) list of strings with the public key to be inserted to the default user
                    users': (optional) list of users to be inserted, each item is a dict with:
                        name': (mandatory) user name,
                        key-pairs': (optional) list of strings with the public key to be inserted to the user
                    user-data': (optional) string is a text script to be passed directly to cloud-init
                    config-files': (optional). List of files to be transferred. Each item is a dict with:
                        dest': (mandatory) string with the destination absolute path
                        encoding': (optional, by default text). Can be one of:
                            b64', 'base64', 'gz', 'gz+b64', 'gz+base64', 'gzip+b64', 'gzip+base64'
                        content' (mandatory): string with the content of the file
                        permissions': (optional) string with file permissions, typically octal notation '0644'
                        owner: (optional) file owner, string with the format 'owner:group'
                    boot-data-drive: boolean to indicate if user-data must be passed using a boot drive (hard disk)
                    security-groups:
                        subnet_id
                        security_group_id
                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
        """

        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

            if not net_list:
                reservation = self.conn.run_instances(
                    image_id,
                    key_name=self.key_pair,
                    instance_type=flavor_id,
                    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,
                                                                                       associate_public_ip_address=True)

                    if subnet.get('elastic_ip'):
                        eip = self.conn.allocate_address()
                        self.conn.associate_address(allocation_id=eip.allocation_id, network_interface_id=net_intr.id)

                    if index == 0:
                        reservation = self.conn.run_instances(
                            image_id,
                            key_name=self.key_pair,
                            instance_type=flavor_id,
                            security_groups=self.security_groups,
                            network_interfaces=boto.ec2.networkinterface.NetworkInterfaceCollection(net_intr),
                            user_data=userdata
                        )
                        instance = reservation.instances[0]
                    else:
                        while True:
                            try:
                                self.conn.attach_network_interface(
                                    network_interface_id=boto.ec2.networkinterface.NetworkInterfaceCollection(net_intr),
                                    instance_id=instance.id, device_index=0)
                                break
                            except:
                                time.sleep(10)
            return instance.id
        except Exception as e:
            self.format_vimconn_exception(e)

    def get_vminstance(self, vm_id):
        """Returns the VM instance information from VIM"""

        try:
            self._reload_connection()
            reservation = self.conn.get_all_instances(vm_id)
            return reservation[0].instances[0].__dict__
        except Exception as e:
            self.format_vimconn_exception(e)

    def delete_vminstance(self, vm_id):
        """Removes a VM instance from VIM
        Returns the instance identifier"""

        try:
            self._reload_connection()
            self.logger.debug("DELETING VM_ID: " + str(vm_id))
            self.conn.terminate_instances(vm_id)
            return vm_id
        except Exception as e:
            self.format_vimconn_exception(e)

    def refresh_vms_status(self, vm_list):
        """ Get the status of the virtual machines and their interfaces/ports
        Params: the list of VM identifiers
        Returns a dictionary with:
            vm_id:          #VIM id of this Virtual Machine
                status:     #Mandatory. Text with one of:
                            #  DELETED (not found at vim)
                            #  VIM_ERROR (Cannot connect to VIM, VIM response error, ...)
                            #  OTHER (Vim reported other status not understood)
                            #  ERROR (VIM indicates an ERROR status)
                            #  ACTIVE, PAUSED, SUSPENDED, INACTIVE (not running),
                            #  BUILD (on building process), ERROR
                            #  ACTIVE:NoMgmtIP (Active but any of its interface has an IP address
                            #
                error_msg:  #Text with VIM error message, if any. Or the VIM connection ERROR
                vim_info:   #Text with plain information obtained from vim (yaml.safe_dump)
                interfaces: list with interface info. Each item a dictionary with:
                    vim_interface_id -  The ID of the ENI.
                    vim_net_id - The ID of the VPC subnet.
                    mac_address - The MAC address of the interface.
                    ip_address - The IP address of the interface within the subnet.
        """
        self.logger.debug("Getting VM instance information from VIM")
        try:
            self._reload_connection()
            reservation = self.conn.get_all_instances(vm_list)[0]
            instances = {}
            instance_dict = {}
            for instance in reservation.instances:
                try:
                    if instance.state in ("pending"):
                        instance_dict['status'] = "BUILD"
                    elif instance.state in ("available", "running", "up"):
                        instance_dict['status'] = 'ACTIVE'
                    else:
                        instance_dict['status'] = 'ERROR'
                    instance_dict['error_msg'] = ""
                    instance_dict['interfaces'] = []
                    interface_dict = {}
                    for interface in instance.interfaces:
                        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
                        instance_dict['interfaces'].append(interface_dict)
                except Exception as e:
                    self.logger.error("Exception getting vm status: %s", str(e), exc_info=True)
                    instance_dict['status'] = "DELETED"
                    instance_dict['error_msg'] = str(e)
                finally:
                    try:
                        instance_dict['vim_info'] = yaml.safe_dump(instance, default_flow_style=True, width=256)
                    except yaml.YAMLError as e:
                        # self.logger.error("Exception getting vm status: %s", str(e), exc_info=True)
                        instance_dict['vim_info'] = str(instance)
                instances[instance.id] = instance_dict
            return instances
        except Exception as e:
            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):
        """Send and action over a VM instance from VIM
        Returns the vm_id if the action was successfully sent to the VIM"""

        self.logger.debug("Action over VM '%s': %s", vm_id, str(action_dict))
        try:
            self._reload_connection()
            if "start" in action_dict:
                self.conn.start_instances(vm_id)
            elif "stop" in action_dict or "stop" in action_dict:
                self.conn.stop_instances(vm_id)
            elif "terminate" in action_dict:
                self.conn.terminate_instances(vm_id)
            elif "reboot" in action_dict:
                self.conn.reboot_instances(vm_id)
            return vm_id
        except Exception as e:
            self.format_vimconn_exception(e)
