# -*- 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={}):
        """ 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
        """

        vimconn.vimconnector.__init__(self, uuid, name, tenant_id, tenant_name, url, url_admin, user, passwd, log_level,
                                      config)
        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["memory"], values["cores"], values["disk"]) == (
                flavor_dict["ram"], flavor_dict["cpus"], flavor_dict["disk"]):
                    flavor = (key, values)
                    break
                elif (values["memory"], values["cores"], values["disk"]) >= (
                flavor_dict["ram"], flavor_dict["cpus"], 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"]):
                            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)
