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

##
# Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
# This file is part of openmano
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# For those usages not covered by the Apache License, Version 2.0 please
# contact with: nfvlabs@tid.es
##

'''
osconnector implements all the methods to interact with openstack using the python-client.
'''
__author__="Alfonso Tierno, Gerardo Garcia, Pablo Montes, xFlow Research"
__date__ ="$22-jun-2014 11:19:29$"

import vimconn
import json
import yaml
import logging
import netaddr
import time
import yaml
import random

from novaclient import client as nClient_v2, exceptions as nvExceptions
from novaclient import api_versions
import keystoneclient.v2_0.client as ksClient_v2
from novaclient.v2.client import Client as nClient
import keystoneclient.v3.client as ksClient
import keystoneclient.exceptions as ksExceptions
import glanceclient.v2.client as glClient
import glanceclient.client as gl1Client
import glanceclient.exc as gl1Exceptions
import cinderclient.v2.client as cClient_v2
from httplib import HTTPException
from neutronclient.neutron import client as neClient_v2
from neutronclient.v2_0 import client as neClient
from neutronclient.common import exceptions as neExceptions
from requests.exceptions import ConnectionError

'''contain the openstack virtual machine status to openmano status'''
vmStatus2manoFormat={'ACTIVE':'ACTIVE',
                     'PAUSED':'PAUSED',
                     'SUSPENDED': 'SUSPENDED',
                     'SHUTOFF':'INACTIVE',
                     'BUILD':'BUILD',
                     'ERROR':'ERROR','DELETED':'DELETED'
                     }
netStatus2manoFormat={'ACTIVE':'ACTIVE','PAUSED':'PAUSED','INACTIVE':'INACTIVE','BUILD':'BUILD','ERROR':'ERROR','DELETED':'DELETED'
                     }

#global var to have a timeout creating and deleting volumes
volume_timeout = 60
server_timeout = 60

class vimconnector(vimconn.vimconnector):
    def __init__(self, uuid, name, tenant_id, tenant_name, url, url_admin=None, user=None, passwd=None,
                 log_level=None, config={}, persistent_info={}):
        '''using common constructor parameters. In this case
        'url' is the keystone authorization url,
        'url_admin' is not use
        '''
        self.osc_api_version = 'v2.0'
        if config.get('APIversion') == 'v3.3':
            self.osc_api_version = 'v3.3'
        vimconn.vimconnector.__init__(self, uuid, name, tenant_id, tenant_name, url, url_admin, user, passwd, log_level, config)

        self.persistent_info = persistent_info
        self.k_creds={}
        self.n_creds={}
        if self.config.get("insecure"):
            self.k_creds["insecure"] = True
            self.n_creds["insecure"] = True
        if not url:
            raise TypeError, 'url param can not be NoneType'
        self.k_creds['auth_url'] = url
        self.n_creds['auth_url'] = url
        if tenant_name:
            self.k_creds['tenant_name'] = tenant_name
            self.n_creds['project_id']  = tenant_name
        if tenant_id:
            self.k_creds['tenant_id'] = tenant_id
            self.n_creds['tenant_id']  = tenant_id
        if user:
            self.k_creds['username'] = user
            self.n_creds['username'] = user
        if passwd:
            self.k_creds['password'] = passwd
            self.n_creds['api_key']  = passwd
        if self.osc_api_version == 'v3.3':
            self.k_creds['project_name'] = tenant_name
            self.k_creds['project_id'] = tenant_id
        if config.get('region_name'):
            self.k_creds['region_name'] = config.get('region_name')
            self.n_creds['region_name'] = config.get('region_name')

        self.reload_client       = True
        self.logger = logging.getLogger('openmano.vim.openstack')
        if log_level:
            self.logger.setLevel( getattr(logging, log_level) )
    
    def __setitem__(self,index, value):
        '''Set individuals parameters 
        Throw TypeError, KeyError
        '''
        if index=='tenant_id':
            self.reload_client=True
            self.tenant_id = value
            if self.osc_api_version == 'v3.3':
                if value:
                    self.k_creds['project_id'] = value
                    self.n_creds['project_id']  = value
                else:
                    del self.k_creds['project_id']
                    del self.n_creds['project_id']
            else:
                if value:
                    self.k_creds['tenant_id'] = value
                    self.n_creds['tenant_id']  = value
                else:
                    del self.k_creds['tenant_id']
                    del self.n_creds['tenant_id']
        elif index=='tenant_name':
            self.reload_client=True
            self.tenant_name = value
            if self.osc_api_version == 'v3.3':
                if value:
                    self.k_creds['project_name'] = value
                    self.n_creds['project_name']  = value
                else:
                    del self.k_creds['project_name']
                    del self.n_creds['project_name']
            else:
                if value:
                    self.k_creds['tenant_name'] = value
                    self.n_creds['project_id']  = value
                else:
                    del self.k_creds['tenant_name']
                    del self.n_creds['project_id']
        elif index=='user':
            self.reload_client=True
            self.user = value
            if value:
                self.k_creds['username'] = value
                self.n_creds['username'] = value
            else:
                del self.k_creds['username']
                del self.n_creds['username']
        elif index=='passwd':
            self.reload_client=True
            self.passwd = value
            if value:
                self.k_creds['password'] = value
                self.n_creds['api_key']  = value
            else:
                del self.k_creds['password']
                del self.n_creds['api_key']
        elif index=='url':
            self.reload_client=True
            self.url = value
            if value:
                self.k_creds['auth_url'] = value
                self.n_creds['auth_url'] = value
            else:
                raise TypeError, 'url param can not be NoneType'
        else:
            vimconn.vimconnector.__setitem__(self,index, value)
     
    def _reload_connection(self):
        '''Called before any operation, it check if credentials has changed
        Throw keystoneclient.apiclient.exceptions.AuthorizationFailure
        '''
        #TODO control the timing and possible token timeout, but it seams that python client does this task for us :-) 
        if self.reload_client:
            #test valid params
            if len(self.n_creds) <4:
                raise ksExceptions.ClientException("Not enough parameters to connect to openstack")
            if self.osc_api_version == 'v3.3':
                self.nova = nClient(api_version=api_versions.APIVersion(version_str='2.0'), **self.n_creds)
                #TODO To be updated for v3
                #self.cinder = cClient.Client(**self.n_creds)
                self.keystone = ksClient.Client(**self.k_creds)
                self.ne_endpoint=self.keystone.service_catalog.url_for(service_type='network', endpoint_type='publicURL')
                self.neutron = neClient.Client(api_version=api_versions.APIVersion(version_str='2.0'), endpoint_url=self.ne_endpoint, token=self.keystone.auth_token, **self.k_creds)
            else:
                self.nova = nClient_v2.Client(version='2', **self.n_creds)
                self.cinder = cClient_v2.Client(**self.n_creds)
                self.keystone = ksClient_v2.Client(**self.k_creds)
                self.ne_endpoint=self.keystone.service_catalog.url_for(service_type='network', endpoint_type='publicURL')
                self.neutron = neClient_v2.Client('2.0', endpoint_url=self.ne_endpoint, token=self.keystone.auth_token, **self.k_creds)
            self.glance_endpoint = self.keystone.service_catalog.url_for(service_type='image', endpoint_type='publicURL')
            self.glance = glClient.Client(self.glance_endpoint, token=self.keystone.auth_token, **self.k_creds)  #TODO check k_creds vs n_creds
            self.reload_client = False

    def __net_os2mano(self, net_list_dict):
        '''Transform the net openstack format to mano format
        net_list_dict can be a list of dict or a single dict'''
        if type(net_list_dict) is dict:
            net_list_=(net_list_dict,)
        elif type(net_list_dict) is list:
            net_list_=net_list_dict
        else:
            raise TypeError("param net_list_dict must be a list or a dictionary")
        for net in net_list_:
            if net.get('provider:network_type') == "vlan":
                net['type']='data'
            else:
                net['type']='bridge'
                
                
            
    def _format_exception(self, exception):
        '''Transform a keystone, nova, neutron  exception into a vimconn exception'''
        if isinstance(exception, (HTTPException, gl1Exceptions.HTTPException, gl1Exceptions.CommunicationError,
                                  ConnectionError, ksExceptions.ConnectionError, neExceptions.ConnectionFailed
                                  )):
            raise vimconn.vimconnConnectionException(type(exception).__name__ + ": " + str(exception))            
        elif isinstance(exception, (nvExceptions.ClientException, ksExceptions.ClientException, 
                                    neExceptions.NeutronException, nvExceptions.BadRequest)):
            raise vimconn.vimconnUnexpectedResponse(type(exception).__name__ + ": " + str(exception))
        elif isinstance(exception, (neExceptions.NetworkNotFoundClient, nvExceptions.NotFound)):
            raise vimconn.vimconnNotFoundException(type(exception).__name__ + ": " + str(exception))
        elif isinstance(exception, nvExceptions.Conflict):
            raise vimconn.vimconnConflictException(type(exception).__name__ + ": " + str(exception))
        else: # ()
            raise vimconn.vimconnConnectionException(type(exception).__name__ + ": " + str(exception))

    def get_tenant_list(self, filter_dict={}):
        '''Obtain tenants of VIM
        filter_dict 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: [{'name':'<name>, 'id':'<id>, ...}, ...]
        '''
        self.logger.debug("Getting tenants from VIM filter: '%s'", str(filter_dict))
        try:
            self._reload_connection()
            if self.osc_api_version == 'v3.3':
                project_class_list=self.keystone.projects.findall(**filter_dict)
            else:
                project_class_list=self.keystone.tenants.findall(**filter_dict)
            project_list=[]
            for project in project_class_list:
                project_list.append(project.to_dict())
            return project_list
        except (ksExceptions.ConnectionError, ksExceptions.ClientException, ConnectionError)  as e:
            self._format_exception(e)

    def new_tenant(self, tenant_name, tenant_description):
        '''Adds a new tenant to openstack VIM. Returns the tenant identifier'''
        self.logger.debug("Adding a new tenant name: %s", tenant_name)
        try:
            self._reload_connection()
            if self.osc_api_version == 'v3.3':
                project=self.keystone.projects.create(tenant_name, tenant_description)
            else:
                project=self.keystone.tenants.create(tenant_name, tenant_description)
            return project.id
        except (ksExceptions.ConnectionError, ksExceptions.ClientException, ConnectionError)  as e:
            self._format_exception(e)

    def delete_tenant(self, tenant_id):
        '''Delete a tenant from openstack VIM. Returns the old tenant identifier'''
        self.logger.debug("Deleting tenant %s from VIM", tenant_id)
        try:
            self._reload_connection()
            if self.osc_api_version == 'v3.3':
                self.keystone.projects.delete(tenant_id)
            else:
                self.keystone.tenants.delete(tenant_id)
            return tenant_id
        except (ksExceptions.ConnectionError, ksExceptions.ClientException, ConnectionError)  as e:
            self._format_exception(e)

    def new_network(self,net_name, net_type, ip_profile=None, shared=False, vlan=None):
        '''Adds a tenant network to VIM. Returns the network identifier'''
        self.logger.debug("Adding a new network to VIM name '%s', type '%s'", net_name, net_type)
        #self.logger.debug(">>>>>>>>>>>>>>>>>> IP profile %s", str(ip_profile))
        try:
            new_net = None
            self._reload_connection()
            network_dict = {'name': net_name, 'admin_state_up': True}
            if net_type=="data" or net_type=="ptp":
                if self.config.get('dataplane_physical_net') == None:
                    raise vimconn.vimconnConflictException("You must provide a 'dataplane_physical_net' at config value before creating sriov network")
                network_dict["provider:physical_network"] = self.config['dataplane_physical_net'] #"physnet_sriov" #TODO physical
                network_dict["provider:network_type"]     = "vlan"
                if vlan!=None:
                    network_dict["provider:network_type"] = vlan
            network_dict["shared"]=shared
            new_net=self.neutron.create_network({'network':network_dict})
            #print new_net
            #create subnetwork, even if there is no profile
            if not ip_profile:
                ip_profile = {}
            if 'subnet_address' not in ip_profile:
                #Fake subnet is required
                subnet_rand = random.randint(0, 255)
                ip_profile['subnet_address'] = "192.168.{}.0/24".format(subnet_rand)
            if 'ip_version' not in ip_profile: 
                ip_profile['ip_version'] = "IPv4"
            subnet={"name":net_name+"-subnet",
                    "network_id": new_net["network"]["id"],
                    "ip_version": 4 if ip_profile['ip_version']=="IPv4" else 6,
                    "cidr": ip_profile['subnet_address']
                    }
            if 'gateway_address' in ip_profile:
                subnet['gateway_ip'] = ip_profile['gateway_address']
            if ip_profile.get('dns_address'):
                #TODO: manage dns_address as a list of addresses separated by commas 
                subnet['dns_nameservers'] = []
                subnet['dns_nameservers'].append(ip_profile['dns_address'])
            if 'dhcp_enabled' in ip_profile:
                subnet['enable_dhcp'] = False if ip_profile['dhcp_enabled']=="false" else True
            if 'dhcp_start_address' in ip_profile:
                subnet['allocation_pools']=[]
                subnet['allocation_pools'].append(dict())
                subnet['allocation_pools'][0]['start'] = ip_profile['dhcp_start_address']
            if 'dhcp_count' in ip_profile:
                #parts = ip_profile['dhcp_start_address'].split('.')
                #ip_int = (int(parts[0]) << 24) + (int(parts[1]) << 16) + (int(parts[2]) << 8) + int(parts[3])
                ip_int = int(netaddr.IPAddress(ip_profile['dhcp_start_address']))
                ip_int += ip_profile['dhcp_count'] - 1
                ip_str = str(netaddr.IPAddress(ip_int))
                subnet['allocation_pools'][0]['end'] = ip_str
            #self.logger.debug(">>>>>>>>>>>>>>>>>> Subnet: %s", str(subnet))
            self.neutron.create_subnet({"subnet": subnet} )
            return new_net["network"]["id"]
        except (neExceptions.ConnectionFailed, ksExceptions.ClientException, neExceptions.NeutronException, ConnectionError) as e:
            if new_net:
                self.neutron.delete_network(new_net['network']['id'])
            self._format_exception(e)

    def get_network_list(self, filter_dict={}):
        '''Obtain tenant networks of VIM
        Filter_dict can be:
            name: network name
            id: network uuid
            shared: boolean
            tenant_id: tenant
            admin_state_up: boolean
            status: 'ACTIVE'
        Returns the network list of dictionaries
        '''
        self.logger.debug("Getting network from VIM filter: '%s'", str(filter_dict))
        try:
            self._reload_connection()
            if self.osc_api_version == 'v3.3' and "tenant_id" in filter_dict:
                filter_dict['project_id'] = filter_dict.pop('tenant_id')
            net_dict=self.neutron.list_networks(**filter_dict)
            net_list=net_dict["networks"]
            self.__net_os2mano(net_list)
            return net_list
        except (neExceptions.ConnectionFailed, ksExceptions.ClientException, neExceptions.NeutronException, ConnectionError) as e:
            self._format_exception(e)

    def get_network(self, net_id):
        '''Obtain details of network from VIM
        Returns the network information from a network id'''
        self.logger.debug(" Getting tenant network %s from VIM", net_id)
        filter_dict={"id": net_id}
        net_list = self.get_network_list(filter_dict)
        if len(net_list)==0:
            raise vimconn.vimconnNotFoundException("Network '{}' not found".format(net_id))
        elif len(net_list)>1:
            raise vimconn.vimconnConflictException("Found more than one network with this criteria")
        net = net_list[0]
        subnets=[]
        for subnet_id in net.get("subnets", () ):
            try:
                subnet = self.neutron.show_subnet(subnet_id)
            except Exception as e:
                self.logger.error("osconnector.get_network(): Error getting subnet %s %s" % (net_id, str(e)))
                subnet = {"id": subnet_id, "fault": str(e)}
            subnets.append(subnet)
        net["subnets"] = subnets
        net["encapsulation"] = net.get('provider:network_type')
        net["segmentation_id"] = net.get('provider:segmentation_id')
        return net

    def delete_network(self, net_id):
        '''Deletes a tenant network from VIM. Returns the old network identifier'''
        self.logger.debug("Deleting network '%s' from VIM", net_id)
        try:
            self._reload_connection()
            #delete VM ports attached to this networks before the network
            ports = self.neutron.list_ports(network_id=net_id)
            for p in ports['ports']:
                try:
                    self.neutron.delete_port(p["id"])
                except Exception as e:
                    self.logger.error("Error deleting port %s: %s", p["id"], str(e))
            self.neutron.delete_network(net_id)
            return net_id
        except (neExceptions.ConnectionFailed, neExceptions.NetworkNotFoundClient, neExceptions.NeutronException,
                ksExceptions.ClientException, neExceptions.NeutronException, ConnectionError) as e:
            self._format_exception(e)

    def refresh_nets_status(self, net_list):
        '''Get the status of the networks
           Params: the list of network identifiers
           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, 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_dict={}
        for net_id in net_list:
            net = {}
            try:
                net_vim = self.get_network(net_id)
                if net_vim['status'] in netStatus2manoFormat:
                    net["status"] = netStatus2manoFormat[ net_vim['status'] ]
                else:
                    net["status"] = "OTHER"
                    net["error_msg"] = "VIM status reported " + net_vim['status']
                    
                if net['status'] == "ACTIVE" and not net_vim['admin_state_up']:
                    net['status'] = 'DOWN'
                try:
                    net['vim_info'] = yaml.safe_dump(net_vim, default_flow_style=True, width=256)
                except yaml.representer.RepresenterError:
                    net['vim_info'] = str(net_vim)
                if net_vim.get('fault'):  #TODO
                    net['error_msg'] = str(net_vim['fault'])
            except vimconn.vimconnNotFoundException as e:
                self.logger.error("Exception getting net status: %s", str(e))
                net['status'] = "DELETED"
                net['error_msg'] = str(e)
            except vimconn.vimconnException as e:
                self.logger.error("Exception getting net status: %s", str(e))
                net['status'] = "VIM_ERROR"
                net['error_msg'] = str(e)
            net_dict[net_id] = net
        return net_dict

    def get_flavor(self, flavor_id):
        '''Obtain flavor details from the  VIM. Returns the flavor dict details'''
        self.logger.debug("Getting flavor '%s'", flavor_id)
        try:
            self._reload_connection()
            flavor = self.nova.flavors.find(id=flavor_id)
            #TODO parse input and translate to VIM format (openmano_schemas.new_vminstance_response_schema)
            return flavor.to_dict()
        except (nvExceptions.NotFound, nvExceptions.ClientException, ksExceptions.ClientException, ConnectionError) as e:
            self._format_exception(e)

    def get_flavor_id_from_data(self, flavor_dict):
        """Obtain flavor id that match the flavor description
           Returns the flavor_id or raises a vimconnNotFoundException
        """
        try:
            self._reload_connection()
            numa=None
            numas = flavor_dict.get("extended",{}).get("numas")
            if numas:
                #TODO
                raise vimconn.vimconnNotFoundException("Flavor with EPA still not implemted")
                # if len(numas) > 1:
                #     raise vimconn.vimconnNotFoundException("Cannot find any flavor with more than one numa")
                # numa=numas[0]
                # numas = extended.get("numas")
            for flavor in self.nova.flavors.list():
                epa = flavor.get_keys()
                if epa:
                    continue
                    #TODO 
                if flavor.ram != flavor_dict["ram"]:
                    continue
                if flavor.vcpus != flavor_dict["vcpus"]:
                    continue
                if flavor.disk != flavor_dict["disk"]:
                    continue
                return flavor.id
            raise vimconn.vimconnNotFoundException("Cannot find any flavor matching '{}'".format(str(flavor_dict)))
        except (nvExceptions.NotFound, nvExceptions.ClientException, ksExceptions.ClientException, ConnectionError) as e:
            self._format_exception(e)


    def new_flavor(self, flavor_data, change_name_if_used=True):
        '''Adds a tenant flavor to openstack VIM
        if change_name_if_used is True, it will change name in case of conflict, because it is not supported name repetition
        Returns the flavor identifier
        '''
        self.logger.debug("Adding flavor '%s'", str(flavor_data))
        retry=0
        max_retries=3
        name_suffix = 0
        name=flavor_data['name']
        while retry<max_retries:
            retry+=1
            try:
                self._reload_connection()
                if change_name_if_used:
                    #get used names
                    fl_names=[]
                    fl=self.nova.flavors.list()
                    for f in fl:
                        fl_names.append(f.name)
                    while name in fl_names:
                        name_suffix += 1
                        name = flavor_data['name']+"-" + str(name_suffix)
                        
                ram = flavor_data.get('ram',64)
                vcpus = flavor_data.get('vcpus',1)
                numa_properties=None

                extended = flavor_data.get("extended")
                if extended:
                    numas=extended.get("numas")
                    if numas:
                        numa_nodes = len(numas)
                        if numa_nodes > 1:
                            return -1, "Can not add flavor with more than one numa"
                        numa_properties = {"hw:numa_nodes":str(numa_nodes)}
                        numa_properties["hw:mem_page_size"] = "large"
                        numa_properties["hw:cpu_policy"] = "dedicated"
                        numa_properties["hw:numa_mempolicy"] = "strict"
                        for numa in numas:
                            #overwrite ram and vcpus
                            ram = numa['memory']*1024
                            if 'paired-threads' in numa:
                                vcpus = numa['paired-threads']*2
                                numa_properties["hw:cpu_threads_policy"] = "prefer"
                            elif 'cores' in numa:
                                vcpus = numa['cores']
                                #numa_properties["hw:cpu_threads_policy"] = "prefer"
                            elif 'threads' in numa:
                                vcpus = numa['threads']
                                numa_properties["hw:cpu_policy"] = "isolated"
                            for interface in numa.get("interfaces",() ):
                                if interface["dedicated"]=="yes":
                                    raise vimconn.vimconnException("Passthrough interfaces are not supported for the openstack connector", http_code=vimconn.HTTP_Service_Unavailable)
                                #TODO, add the key 'pci_passthrough:alias"="<label at config>:<number ifaces>"' when a way to connect it is available
                                
                #create flavor                 
                new_flavor=self.nova.flavors.create(name, 
                                ram, 
                                vcpus, 
                                flavor_data.get('disk',1),
                                is_public=flavor_data.get('is_public', True)
                            ) 
                #add metadata
                if numa_properties:
                    new_flavor.set_keys(numa_properties)
                return new_flavor.id
            except nvExceptions.Conflict as e:
                if change_name_if_used and retry < max_retries:
                    continue
                self._format_exception(e)
            #except nvExceptions.BadRequest as e:
            except (ksExceptions.ClientException, nvExceptions.ClientException, ConnectionError) as e:
                self._format_exception(e)

    def delete_flavor(self,flavor_id):
        '''Deletes a tenant flavor from openstack VIM. Returns the old flavor_id
        '''
        try:
            self._reload_connection()
            self.nova.flavors.delete(flavor_id)
            return flavor_id
        #except nvExceptions.BadRequest as e:
        except (nvExceptions.NotFound, ksExceptions.ClientException, nvExceptions.ClientException, ConnectionError) as e:
            self._format_exception(e)

    def new_image(self,image_dict):
        '''
        Adds a tenant image to VIM. imge_dict is a dictionary with:
            name: name
            disk_format: qcow2, vhd, vmdk, raw (by default), ...
            location: path or URI
            public: "yes" or "no"
            metadata: metadata of the image
        Returns the image_id
        '''
        #using version 1 of glance client
        glancev1 = gl1Client.Client('1',self.glance_endpoint, token=self.keystone.auth_token, **self.k_creds)  #TODO check k_creds vs n_creds
        retry=0
        max_retries=3
        while retry<max_retries:
            retry+=1
            try:
                self._reload_connection()
                #determine format  http://docs.openstack.org/developer/glance/formats.html
                if "disk_format" in image_dict:
                    disk_format=image_dict["disk_format"]
                else: #autodiscover based on extension
                    if image_dict['location'][-6:]==".qcow2":
                        disk_format="qcow2"
                    elif image_dict['location'][-4:]==".vhd":
                        disk_format="vhd"
                    elif image_dict['location'][-5:]==".vmdk":
                        disk_format="vmdk"
                    elif image_dict['location'][-4:]==".vdi":
                        disk_format="vdi"
                    elif image_dict['location'][-4:]==".iso":
                        disk_format="iso"
                    elif image_dict['location'][-4:]==".aki":
                        disk_format="aki"
                    elif image_dict['location'][-4:]==".ari":
                        disk_format="ari"
                    elif image_dict['location'][-4:]==".ami":
                        disk_format="ami"
                    else:
                        disk_format="raw"
                self.logger.debug("new_image: '%s' loading from '%s'", image_dict['name'], image_dict['location'])
                if image_dict['location'][0:4]=="http":
                    new_image = glancev1.images.create(name=image_dict['name'], is_public=image_dict.get('public',"yes")=="yes",
                            container_format="bare", location=image_dict['location'], disk_format=disk_format)
                else: #local path
                    with open(image_dict['location']) as fimage:
                        new_image = glancev1.images.create(name=image_dict['name'], is_public=image_dict.get('public',"yes")=="yes",
                            container_format="bare", data=fimage, disk_format=disk_format)
                #insert metadata. We cannot use 'new_image.properties.setdefault' 
                #because nova and glance are "INDEPENDENT" and we are using nova for reading metadata
                new_image_nova=self.nova.images.find(id=new_image.id)
                new_image_nova.metadata.setdefault('location',image_dict['location'])
                metadata_to_load = image_dict.get('metadata')
                if metadata_to_load:
                    for k,v in yaml.load(metadata_to_load).iteritems():
                        new_image_nova.metadata.setdefault(k,v)
                return new_image.id
            except (nvExceptions.Conflict, ksExceptions.ClientException, nvExceptions.ClientException) as e:
                self._format_exception(e)
            except (HTTPException, gl1Exceptions.HTTPException, gl1Exceptions.CommunicationError, ConnectionError) as e:
                if retry==max_retries:
                    continue
                self._format_exception(e)
            except IOError as e:  #can not open the file
                raise vimconn.vimconnConnectionException(type(e).__name__ + ": " + str(e)+ " for " + image_dict['location'],
                                                         http_code=vimconn.HTTP_Bad_Request)
     
    def delete_image(self, image_id):
        '''Deletes a tenant image from openstack VIM. Returns the old id
        '''
        try:
            self._reload_connection()
            self.nova.images.delete(image_id)
            return image_id
        except (nvExceptions.NotFound, ksExceptions.ClientException, nvExceptions.ClientException, gl1Exceptions.CommunicationError, ConnectionError) as e: #TODO remove
            self._format_exception(e)

    def get_image_id_from_path(self, path):
        '''Get the image id from image path in the VIM database. Returns the image_id''' 
        try:
            self._reload_connection()
            images = self.nova.images.list()
            for image in images:
                if image.metadata.get("location")==path:
                    return image.id
            raise vimconn.vimconnNotFoundException("image with location '{}' not found".format( path))
        except (ksExceptions.ClientException, nvExceptions.ClientException, gl1Exceptions.CommunicationError, ConnectionError) as e:
            self._format_exception(e)
        
    def get_image_list(self, filter_dict={}):
        '''Obtain tenant images from VIM
        Filter_dict can be:
            id: image id
            name: image name
            checksum: image checksum
        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 filter: '%s'", str(filter_dict))
        try:
            self._reload_connection()
            filter_dict_os=filter_dict.copy()
            #First we filter by the available filter fields: name, id. The others are removed.
            filter_dict_os.pop('checksum',None)
            image_list=self.nova.images.findall(**filter_dict_os)
            if len(image_list)==0:
                return []
            #Then we filter by the rest of filter fields: checksum
            filtered_list = []
            for image in image_list:
                image_class=self.glance.images.get(image.id)
                if 'checksum' not in filter_dict or image_class['checksum']==filter_dict.get('checksum'):
                    filtered_list.append(image_class.copy())
            return filtered_list
        except (ksExceptions.ClientException, nvExceptions.ClientException, gl1Exceptions.CommunicationError, ConnectionError) as e:
            self._format_exception(e)

    def new_vminstance(self,name,description,start,image_id,flavor_id,net_list,cloud_config=None,disk_list=None):
        '''Adds a VM instance to VIM
        Params:
            start: indicates if VM must start or boot in pause mode. Ignored
            image_id,flavor_id: iamge and flavor uuid
            net_list: list of interfaces, each one is a dictionary with:
                name:
                net_id: network uuid to connect
                vpci: virtual vcpi to assign, ignored because openstack lack #TODO
                model: interface model, ignored #TODO
                mac_address: used for  SR-IOV ifaces #TODO for other types
                use: 'data', 'bridge',  'mgmt'
                type: 'virtual', 'PF', 'VF', 'VFnotShared'
                vim_id: filled/added by this function
                floating_ip: True/False (or it can be None)
                #TODO ip, security groups
        Returns the instance identifier
        '''
        self.logger.debug("new_vminstance input: image='%s' flavor='%s' nics='%s'",image_id, flavor_id,str(net_list))
        try:
            metadata={}
            net_list_vim=[]
            external_network=[] #list of external networks to be connected to instance, later on used to create floating_ip
            self._reload_connection()
            metadata_vpci={} #For a specific neutron plugin 
            for net in net_list:
                if not net.get("net_id"): #skip non connected iface
                    continue
                if net["type"]=="virtual" or net["type"]=="VF":
                    port_dict={
                        "network_id": net["net_id"],
                        "name": net.get("name"),
                        "admin_state_up": True
                    }    
                    if net["type"]=="virtual":
                        if "vpci" in net:
                            metadata_vpci[ net["net_id"] ] = [[ net["vpci"], "" ]]
                    else: # for VF
                        if "vpci" in net:
                            if "VF" not in metadata_vpci:
                                metadata_vpci["VF"]=[]
                            metadata_vpci["VF"].append([ net["vpci"], "" ])
                        port_dict["binding:vnic_type"]="direct"
                    if not port_dict["name"]:
                        port_dict["name"]=name
                    if net.get("mac_address"):
                        port_dict["mac_address"]=net["mac_address"]
                    if net.get("port_security") == False:
                        port_dict["port_security_enabled"]=net["port_security"]
                    new_port = self.neutron.create_port({"port": port_dict })
                    net["mac_adress"] = new_port["port"]["mac_address"]
                    net["vim_id"] = new_port["port"]["id"]
                    net["ip"] = new_port["port"].get("fixed_ips", [{}])[0].get("ip_address")
                    net_list_vim.append({"port-id": new_port["port"]["id"]})
                else:   # for PF
                    self.logger.warn("new_vminstance: Warning, can not connect a passthrough interface ")
                    #TODO insert this when openstack consider passthrough ports as openstack neutron ports
                if net.get('floating_ip', False):
                    net['exit_on_floating_ip_error'] = True
                    external_network.append(net)
                elif net['use'] == 'mgmt' and self.config.get('use_floating_ip'):
                    net['exit_on_floating_ip_error'] = False
                    external_network.append(net)

            if metadata_vpci:
                metadata = {"pci_assignement": json.dumps(metadata_vpci)}
                if len(metadata["pci_assignement"]) >255:
                    #limit the metadata size
                    #metadata["pci_assignement"] = metadata["pci_assignement"][0:255]
                    self.logger.warn("Metadata deleted since it exceeds the expected length (255) ")
                    metadata = {}
            
            self.logger.debug("name '%s' image_id '%s'flavor_id '%s' net_list_vim '%s' description '%s' metadata %s",
                              name, image_id, flavor_id, str(net_list_vim), description, str(metadata))
            
            security_groups   = self.config.get('security_groups')
            if type(security_groups) is str:
                security_groups = ( security_groups, )
            #cloud config
            userdata=None
            config_drive = None
            if isinstance(cloud_config, dict):
                if cloud_config.get("user-data"):
                    userdata=cloud_config["user-data"]
                if cloud_config.get("boot-data-drive") != None:
                    config_drive = cloud_config["boot-data-drive"]
                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

            #Create additional volumes in case these are present in disk_list
            block_device_mapping = None
            base_disk_index = ord('b')
            if disk_list != None:
                block_device_mapping = dict()
                for disk in disk_list:
                    if 'image_id' in disk:
                        volume = self.cinder.volumes.create(size = disk['size'],name = name + '_vd' +
                                    chr(base_disk_index), imageRef = disk['image_id'])
                    else:
                        volume = self.cinder.volumes.create(size=disk['size'], name=name + '_vd' +
                                    chr(base_disk_index))
                    block_device_mapping['_vd' +  chr(base_disk_index)] = volume.id
                    base_disk_index += 1

                #wait until volumes are with status available
                keep_waiting = True
                elapsed_time = 0
                while keep_waiting and elapsed_time < volume_timeout:
                    keep_waiting = False
                    for volume_id in block_device_mapping.itervalues():
                        if self.cinder.volumes.get(volume_id).status != 'available':
                            keep_waiting = True
                    if keep_waiting:
                        time.sleep(1)
                        elapsed_time += 1

                #if we exceeded the timeout rollback
                if elapsed_time >= volume_timeout:
                    #delete the volumes we just created
                    for volume_id in block_device_mapping.itervalues():
                        self.cinder.volumes.delete(volume_id)

                    #delete ports we just created
                    for net_item  in net_list_vim:
                        if 'port-id' in net_item:
                            self.neutron.delete_port(net_item['port-id'])

                    raise vimconn.vimconnException('Timeout creating volumes for instance ' + name,
                                                   http_code=vimconn.HTTP_Request_Timeout)

            server = self.nova.servers.create(name, image_id, flavor_id, nics=net_list_vim, meta=metadata,
                                              security_groups=security_groups,
                                              availability_zone=self.config.get('availability_zone'),
                                              key_name=self.config.get('keypair'),
                                              userdata=userdata,
                                              config_drive = config_drive,
                                              block_device_mapping = block_device_mapping
                                              )  # , description=description)
            #print "DONE :-)", server
            pool_id = None
            floating_ips = self.neutron.list_floatingips().get("floatingips", ())
            for floating_network in external_network:
                try:
                    # wait until vm is active
                    elapsed_time = 0
                    while elapsed_time < server_timeout:
                        status = self.nova.servers.get(server.id).status
                        if status == 'ACTIVE':
                            break
                        time.sleep(1)
                        elapsed_time += 1

                    #if we exceeded the timeout rollback
                    if elapsed_time >= server_timeout:
                        raise vimconn.vimconnException('Timeout creating instance ' + name,
                                                       http_code=vimconn.HTTP_Request_Timeout)

                    assigned = False
                    while(assigned == False):
                        if floating_ips:
                            ip = floating_ips.pop(0)
                            if not ip.get("port_id", False) and ip.get('tenant_id') == server.tenant_id:
                                free_floating_ip = ip.get("floating_ip_address")
                                try:
                                    fix_ip = floating_network.get('ip')
                                    server.add_floating_ip(free_floating_ip, fix_ip)
                                    assigned = True
                                except Exception as e:
                                    raise vimconn.vimconnException(type(e).__name__ + ": Cannot create floating_ip "+  str(e), http_code=vimconn.HTTP_Conflict)
                        else:
                            #Find the external network
                            external_nets = list()
                            for net in self.neutron.list_networks()['networks']:
                                if net['router:external']:
                                        external_nets.append(net)

                            if len(external_nets) == 0:
                                raise vimconn.vimconnException("Cannot create floating_ip automatically since no external "
                                                               "network is present",
                                                                http_code=vimconn.HTTP_Conflict)
                            if len(external_nets) > 1:
                                raise vimconn.vimconnException("Cannot create floating_ip automatically since multiple "
                                                               "external networks are present",
                                                               http_code=vimconn.HTTP_Conflict)

                            pool_id = external_nets[0].get('id')
                            param = {'floatingip': {'floating_network_id': pool_id, 'tenant_id': server.tenant_id}}
                            try:
                                #self.logger.debug("Creating floating IP")
                                new_floating_ip = self.neutron.create_floatingip(param)
                                free_floating_ip = new_floating_ip['floatingip']['floating_ip_address']
                                fix_ip = floating_network.get('ip')
                                server.add_floating_ip(free_floating_ip, fix_ip)
                                assigned=True
                            except Exception as e:
                                raise vimconn.vimconnException(type(e).__name__ + ": Cannot assign floating_ip "+  str(e), http_code=vimconn.HTTP_Conflict)
                except Exception as e:
                    if not floating_network['exit_on_floating_ip_error']:
                        self.logger.warn("Cannot create floating_ip. %s", str(e))
                        continue
                    self.delete_vminstance(server.id)
                    raise

            return server.id
#        except nvExceptions.NotFound as e:
#            error_value=-vimconn.HTTP_Not_Found
#            error_text= "vm instance %s not found" % vm_id
        except (ksExceptions.ClientException, nvExceptions.ClientException, ConnectionError) as e:
            # delete the volumes we just created
            if block_device_mapping != None:
                for volume_id in block_device_mapping.itervalues():
                    self.cinder.volumes.delete(volume_id)

            # delete ports we just created
            for net_item in net_list_vim:
                if 'port-id' in net_item:
                    self.neutron.delete_port(net_item['port-id'])
            self._format_exception(e)
        except TypeError as e:
            raise vimconn.vimconnException(type(e).__name__ + ": "+  str(e), http_code=vimconn.HTTP_Bad_Request)

    def get_vminstance(self,vm_id):
        '''Returns the VM instance information from VIM'''
        #self.logger.debug("Getting VM from VIM")
        try:
            self._reload_connection()
            server = self.nova.servers.find(id=vm_id)
            #TODO parse input and translate to VIM format (openmano_schemas.new_vminstance_response_schema)
            return server.to_dict()
        except (ksExceptions.ClientException, nvExceptions.ClientException, nvExceptions.NotFound, ConnectionError) as e:
            self._format_exception(e)

    def get_vminstance_console(self,vm_id, console_type="vnc"):
        '''
        Get a console for the virtual machine
        Params:
            vm_id: uuid of the VM
            console_type, can be:
                "novnc" (by default), "xvpvnc" for VNC types, 
                "rdp-html5" for RDP types, "spice-html5" for SPICE types
        Returns dict with the console parameters:
                protocol: ssh, ftp, http, https, ...
                server:   usually ip address 
                port:     the http, ssh, ... port 
                suffix:   extra text, e.g. the http path and query string   
        '''
        self.logger.debug("Getting VM CONSOLE from VIM")
        try:
            self._reload_connection()
            server = self.nova.servers.find(id=vm_id)
            if console_type == None or console_type == "novnc":
                console_dict = server.get_vnc_console("novnc")
            elif console_type == "xvpvnc":
                console_dict = server.get_vnc_console(console_type)
            elif console_type == "rdp-html5":
                console_dict = server.get_rdp_console(console_type)
            elif console_type == "spice-html5":
                console_dict = server.get_spice_console(console_type)
            else:
                raise vimconn.vimconnException("console type '{}' not allowed".format(console_type), http_code=vimconn.HTTP_Bad_Request)
            
            console_dict1 = console_dict.get("console")
            if console_dict1:
                console_url = console_dict1.get("url")
                if console_url:
                    #parse console_url
                    protocol_index = console_url.find("//")
                    suffix_index = console_url[protocol_index+2:].find("/") + protocol_index+2
                    port_index = console_url[protocol_index+2:suffix_index].find(":") + protocol_index+2
                    if protocol_index < 0 or port_index<0 or suffix_index<0:
                        return -vimconn.HTTP_Internal_Server_Error, "Unexpected response from VIM"
                    console_dict={"protocol": console_url[0:protocol_index],
                                  "server":   console_url[protocol_index+2:port_index], 
                                  "port":     console_url[port_index:suffix_index], 
                                  "suffix":   console_url[suffix_index+1:] 
                                  }
                    protocol_index += 2
                    return console_dict
            raise vimconn.vimconnUnexpectedResponse("Unexpected response from VIM")
            
        except (nvExceptions.NotFound, ksExceptions.ClientException, nvExceptions.ClientException, nvExceptions.BadRequest, ConnectionError) as e:
            self._format_exception(e)

    def delete_vminstance(self, vm_id):
        '''Removes a VM instance from VIM. Returns the old identifier
        '''
        #print "osconnector: Getting VM from VIM"
        try:
            self._reload_connection()
            #delete VM ports attached to this networks before the virtual machine
            ports = self.neutron.list_ports(device_id=vm_id)
            for p in ports['ports']:
                try:
                    self.neutron.delete_port(p["id"])
                except Exception as e:
                    self.logger.error("Error deleting port: " + type(e).__name__ + ": "+  str(e))

            #commented because detaching the volumes makes the servers.delete not work properly ?!?
            #dettach volumes attached
            server = self.nova.servers.get(vm_id)
            volumes_attached_dict = server._info['os-extended-volumes:volumes_attached']
            #for volume in volumes_attached_dict:
            #    self.cinder.volumes.detach(volume['id'])

            self.nova.servers.delete(vm_id)

            #delete volumes.
            #Although having detached them should have them  in active status
            #we ensure in this loop
            keep_waiting = True
            elapsed_time = 0
            while keep_waiting and elapsed_time < volume_timeout:
                keep_waiting = False
                for volume in volumes_attached_dict:
                    if self.cinder.volumes.get(volume['id']).status != 'available':
                        keep_waiting = True
                    else:
                        self.cinder.volumes.delete(volume['id'])
                if keep_waiting:
                    time.sleep(1)
                    elapsed_time += 1

            return vm_id
        except (nvExceptions.NotFound, ksExceptions.ClientException, nvExceptions.ClientException, ConnectionError) as e:
            self._format_exception(e)
        #TODO insert exception vimconn.HTTP_Unauthorized
        #if reaching here is because an exception

    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), 
                                #  CREATING (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:
                     -  vim_info:         #Text with plain information obtained from vim (yaml.safe_dump)
                        mac_address:      #Text format XX:XX:XX:XX:XX:XX
                        vim_net_id:       #network id where this interface is connected
                        vim_interface_id: #interface/port VIM id
                        ip_address:       #null, or text with IPv4, IPv6 address
                        physical_compute: #identification of compute node where PF,VF interface is allocated
                        physical_pci:     #PCI address of the NIC that hosts the PF,VF
                        physical_vlan:    #physical VLAN used for VF
        '''
        vm_dict={}
        self.logger.debug("refresh_vms status: Getting tenant VM instance information from VIM")
        for vm_id in vm_list:
            vm={}
            try:
                vm_vim = self.get_vminstance(vm_id)
                if vm_vim['status'] in vmStatus2manoFormat:
                    vm['status']    =  vmStatus2manoFormat[ vm_vim['status'] ]
                else:
                    vm['status']    = "OTHER"
                    vm['error_msg'] = "VIM status reported " + vm_vim['status']
                try:
                    vm['vim_info']  = yaml.safe_dump(vm_vim, default_flow_style=True, width=256)
                except yaml.representer.RepresenterError:
                    vm['vim_info'] = str(vm_vim)
                vm["interfaces"] = []
                if vm_vim.get('fault'):
                    vm['error_msg'] = str(vm_vim['fault'])
                #get interfaces
                try:
                    self._reload_connection()
                    port_dict=self.neutron.list_ports(device_id=vm_id)
                    for port in port_dict["ports"]:
                        interface={}
                        try:
                            interface['vim_info'] = yaml.safe_dump(port, default_flow_style=True, width=256)
                        except yaml.representer.RepresenterError:
                            interface['vim_info'] = str(port)
                        interface["mac_address"] = port.get("mac_address")
                        interface["vim_net_id"] = port["network_id"]
                        interface["vim_interface_id"] = port["id"]
                        interface["physical_compute"] = vm_vim['OS-EXT-SRV-ATTR:host']
                        interface["physical_pci"] = None
                        # TODO: At the moment sr-iov pci addresses are converted to PF pci addresses by setting the slot to 0x00
                        # TODO: This is just a workaround valid for niantinc. Find a better way to do so
                        if 'pci_slot' in port['binding:profile']:
                            pci = list(port['binding:profile']['pci_slot'])
                            pci[-4] = '0'
                            pci[-3] = '0'
                            interface["physical_pci"] = ''.join(pci)
                        interface["physical_vlan"] = None
                        network = self.neutron.show_network(port["network_id"])
                        if network['network'].get('provider:network_type') == 'vlan':
                            interface["physical_vlan"] = network['network'].get('provider:segmentation_id')
                        ips=[]
                        #look for floating ip address
                        floating_ip_dict = self.neutron.list_floatingips(port_id=port["id"])
                        if floating_ip_dict.get("floatingips"):
                            ips.append(floating_ip_dict["floatingips"][0].get("floating_ip_address") )

                        for subnet in port["fixed_ips"]:
                            ips.append(subnet["ip_address"])
                        interface["ip_address"] = ";".join(ips)
                        vm["interfaces"].append(interface)
                except Exception as e:
                    self.logger.error("Error getting vm interface information " + type(e).__name__ + ": "+  str(e))
            except vimconn.vimconnNotFoundException as e:
                self.logger.error("Exception getting vm status: %s", str(e))
                vm['status'] = "DELETED"
                vm['error_msg'] = str(e)
            except vimconn.vimconnException as e:
                self.logger.error("Exception getting vm status: %s", str(e))
                vm['status'] = "VIM_ERROR"
                vm['error_msg'] = str(e)
            vm_dict[vm_id] = vm
        return vm_dict
    
    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()
            server = self.nova.servers.find(id=vm_id)
            if "start" in action_dict:
                if action_dict["start"]=="rebuild":  
                    server.rebuild()
                else:
                    if server.status=="PAUSED":
                        server.unpause()
                    elif server.status=="SUSPENDED":
                        server.resume()
                    elif server.status=="SHUTOFF":
                        server.start()
            elif "pause" in action_dict:
                server.pause()
            elif "resume" in action_dict:
                server.resume()
            elif "shutoff" in action_dict or "shutdown" in action_dict:
                server.stop()
            elif "forceOff" in action_dict:
                server.stop() #TODO
            elif "terminate" in action_dict:
                server.delete()
            elif "createImage" in action_dict:
                server.create_image()
                #"path":path_schema,
                #"description":description_schema,
                #"name":name_schema,
                #"metadata":metadata_schema,
                #"imageRef": id_schema,
                #"disk": {"oneOf":[{"type": "null"}, {"type":"string"}] },
            elif "rebuild" in action_dict:
                server.rebuild(server.image['id'])
            elif "reboot" in action_dict:
                server.reboot() #reboot_type='SOFT'
            elif "console" in action_dict:
                console_type = action_dict["console"]
                if console_type == None or console_type == "novnc":
                    console_dict = server.get_vnc_console("novnc")
                elif console_type == "xvpvnc":
                    console_dict = server.get_vnc_console(console_type)
                elif console_type == "rdp-html5":
                    console_dict = server.get_rdp_console(console_type)
                elif console_type == "spice-html5":
                    console_dict = server.get_spice_console(console_type)
                else:
                    raise vimconn.vimconnException("console type '{}' not allowed".format(console_type), 
                                                   http_code=vimconn.HTTP_Bad_Request)
                try:
                    console_url = console_dict["console"]["url"]
                    #parse console_url
                    protocol_index = console_url.find("//")
                    suffix_index = console_url[protocol_index+2:].find("/") + protocol_index+2
                    port_index = console_url[protocol_index+2:suffix_index].find(":") + protocol_index+2
                    if protocol_index < 0 or port_index<0 or suffix_index<0:
                        raise vimconn.vimconnException("Unexpected response from VIM " + str(console_dict))
                    console_dict2={"protocol": console_url[0:protocol_index],
                                  "server":   console_url[protocol_index+2 : port_index], 
                                  "port":     int(console_url[port_index+1 : suffix_index]), 
                                  "suffix":   console_url[suffix_index+1:] 
                                  }
                    return console_dict2               
                except Exception as e:
                    raise vimconn.vimconnException("Unexpected response from VIM " + str(console_dict))
            
            return vm_id
        except (ksExceptions.ClientException, nvExceptions.ClientException, nvExceptions.NotFound, ConnectionError) as e:
            self._format_exception(e)
        #TODO insert exception vimconn.HTTP_Unauthorized

#NOT USED FUNCTIONS
    
    def new_external_port(self, port_data):
        #TODO openstack if needed
        '''Adds a external port to VIM'''
        '''Returns the port identifier'''
        return -vimconn.HTTP_Internal_Server_Error, "osconnector.new_external_port() not implemented" 
        
    def connect_port_network(self, port_id, network_id, admin=False):
        #TODO openstack if needed
        '''Connects a external port to a network'''
        '''Returns status code of the VIM response'''
        return -vimconn.HTTP_Internal_Server_Error, "osconnector.connect_port_network() not implemented" 
    
    def new_user(self, user_name, user_passwd, tenant_id=None):
        '''Adds a new user to openstack VIM'''
        '''Returns the user identifier'''
        self.logger.debug("osconnector: Adding a new user to VIM")
        try:
            self._reload_connection()
            user=self.keystone.users.create(user_name, user_passwd, tenant_id=tenant_id)
            #self.keystone.tenants.add_user(self.k_creds["username"], #role)
            return user.id
        except ksExceptions.ConnectionError as e:
            error_value=-vimconn.HTTP_Bad_Request
            error_text= type(e).__name__ + ": "+  (str(e) if len(e.args)==0 else str(e.args[0]))
        except ksExceptions.ClientException as e: #TODO remove
            error_value=-vimconn.HTTP_Bad_Request
            error_text= type(e).__name__ + ": "+  (str(e) if len(e.args)==0 else str(e.args[0]))
        #TODO insert exception vimconn.HTTP_Unauthorized
        #if reaching here is because an exception
        if self.debug:
            self.logger.debug("new_user " + error_text)
        return error_value, error_text        

    def delete_user(self, user_id):
        '''Delete a user from openstack VIM'''
        '''Returns the user identifier'''
        if self.debug:
            print "osconnector: Deleting  a  user from VIM"
        try:
            self._reload_connection()
            self.keystone.users.delete(user_id)
            return 1, user_id
        except ksExceptions.ConnectionError as e:
            error_value=-vimconn.HTTP_Bad_Request
            error_text= type(e).__name__ + ": "+  (str(e) if len(e.args)==0 else str(e.args[0]))
        except ksExceptions.NotFound as e:
            error_value=-vimconn.HTTP_Not_Found
            error_text= type(e).__name__ + ": "+  (str(e) if len(e.args)==0 else str(e.args[0]))
        except ksExceptions.ClientException as e: #TODO remove
            error_value=-vimconn.HTTP_Bad_Request
            error_text= type(e).__name__ + ": "+  (str(e) if len(e.args)==0 else str(e.args[0]))
        #TODO insert exception vimconn.HTTP_Unauthorized
        #if reaching here is because an exception
        if self.debug:
            print "delete_tenant " + error_text
        return error_value, error_text
 
    def get_hosts_info(self):
        '''Get the information of deployed hosts
        Returns the hosts content'''
        if self.debug:
            print "osconnector: Getting Host info from VIM"
        try:
            h_list=[]
            self._reload_connection()
            hypervisors = self.nova.hypervisors.list()
            for hype in hypervisors:
                h_list.append( hype.to_dict() )
            return 1, {"hosts":h_list}
        except nvExceptions.NotFound as e:
            error_value=-vimconn.HTTP_Not_Found
            error_text= (str(e) if len(e.args)==0 else str(e.args[0]))
        except (ksExceptions.ClientException, nvExceptions.ClientException) as e:
            error_value=-vimconn.HTTP_Bad_Request
            error_text= type(e).__name__ + ": "+  (str(e) if len(e.args)==0 else str(e.args[0]))
        #TODO insert exception vimconn.HTTP_Unauthorized
        #if reaching here is because an exception
        if self.debug:
            print "get_hosts_info " + error_text
        return error_value, error_text        

    def get_hosts(self, vim_tenant):
        '''Get the hosts and deployed instances
        Returns the hosts content'''
        r, hype_dict = self.get_hosts_info()
        if r<0:
            return r, hype_dict
        hypervisors = hype_dict["hosts"]
        try:
            servers = self.nova.servers.list()
            for hype in hypervisors:
                for server in servers:
                    if server.to_dict()['OS-EXT-SRV-ATTR:hypervisor_hostname']==hype['hypervisor_hostname']:
                        if 'vm' in hype:
                            hype['vm'].append(server.id)
                        else:
                            hype['vm'] = [server.id]
            return 1, hype_dict
        except nvExceptions.NotFound as e:
            error_value=-vimconn.HTTP_Not_Found
            error_text= (str(e) if len(e.args)==0 else str(e.args[0]))
        except (ksExceptions.ClientException, nvExceptions.ClientException) as e:
            error_value=-vimconn.HTTP_Bad_Request
            error_text= type(e).__name__ + ": "+  (str(e) if len(e.args)==0 else str(e.args[0]))
        #TODO insert exception vimconn.HTTP_Unauthorized
        #if reaching here is because an exception
        if self.debug:
            print "get_hosts " + error_text
        return error_value, error_text        
  

