diff --git a/vimconn_openstack.py b/vimconn_openstack.py
new file mode 100644
index 0000000..3a323a8
--- /dev/null
+++ b/vimconn_openstack.py
@@ -0,0 +1,1097 @@
+# -*- 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"
+__date__ ="$22-jun-2014 11:19:29$"
+
+import vimconn
+import json
+import yaml
+
+from novaclient import client as nClient, exceptions as nvExceptions
+import keystoneclient.v2_0.client as ksClient
+import keystoneclient.exceptions as ksExceptions
+import glanceclient.v2.client as glClient
+import glanceclient.client as gl1Client
+import glanceclient.exc as gl1Exceptions
+from httplib import HTTPException
+from neutronclient.neutron 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'
+                     }
+
+class vimconnector(vimconn.vimconnector):
+    def __init__(self, uuid, name, tenant, url, url_admin=None, user=None, passwd=None, debug=True, config={}):
+        '''using common constructor parameters. In this case 
+        'url' is the keystone authorization url,
+        'url_admin' is not use
+        '''
+        vimconn.vimconnector.__init__(self, uuid, name, tenant, url, url_admin, user, passwd, debug, config)
+        
+        self.k_creds={}
+        self.n_creds={}
+        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:
+            self.k_creds['tenant_name'] = tenant
+            self.n_creds['project_id']  = tenant
+        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
+        self.reload_client       = True
+    
+    def __setitem__(self,index, value):
+        '''Set individuals parameters 
+        Throw TypeError, KeyError
+        '''
+        if index=='tenant':
+            self.reload_client=True
+            self.tenant = value
+            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")
+            self.nova = nClient.Client(2, **self.n_creds)
+            self.keystone = ksClient.Client(**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.ne_endpoint=self.keystone.service_catalog.url_for(service_type='network', endpoint_type='publicURL')
+            self.neutron = neClient.Client('2.0', endpoint_url=self.ne_endpoint, token=self.keystone.auth_token, **self.k_creds)
+            self.reload_client = False
+    
+    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'''
+        if self.debug:
+            print "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 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.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 "new_tenant " + 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 new_tenant(self,tenant_name,tenant_description):
+        '''Adds a new tenant to openstack VIM'''
+        '''Returns the tenant identifier'''
+        if self.debug:
+            print "osconnector: Adding a new tenant to VIM"
+        try:
+            self._reload_connection()
+            tenant=self.keystone.tenants.create(tenant_name, tenant_description)
+            #self.keystone.tenants.add_user(self.k_creds["username"], #role)
+            return 1, tenant.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:
+            print "new_tenant " + error_text
+        return error_value, error_text
+
+    def delete_tenant(self,tenant_id):
+        '''Delete a tenant from openstack VIM'''
+        '''Returns the tenant identifier'''
+        if self.debug:
+            print "osconnector: Deleting  a  tenant from VIM"
+        try:
+            self._reload_connection()
+            self.keystone.tenants.delete(tenant_id)
+            #self.keystone.tenants.add_user(self.k_creds["username"], #role)
+            return 1, tenant_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:
+            print "delete_tenant " + error_text
+        return error_value, error_text
+
+    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 new_tenant_network(self,net_name,net_type,public=False,cidr=None,vlan=None):
+        '''Adds a tenant network to VIM'''
+        '''Returns the network identifier'''
+        if self.debug:
+            print "osconnector: Adding a new tenant network to VIM (tenant: " + self.tenant + ", type: " + net_type + "): "+ net_name
+        try:
+            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:
+                    return -vimconn.HTTP_Bad_Request, "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"]=public
+            new_net=self.neutron.create_network({'network':network_dict})
+            #print new_net
+            #create fake subnetwork
+            if not cidr:
+                cidr="192.168.111.0/24"
+            subnet={"name":net_name+"-subnet",
+                    "network_id": new_net["network"]["id"],
+                    "ip_version": 4,
+                    "cidr": cidr
+                    }
+            self.neutron.create_subnet({"subnet": subnet} )
+            return 1, new_net["network"]["id"]
+        except neExceptions.ConnectionFailed 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, neExceptions.NeutronException) 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 "new_tenant_network " + error_text
+        return error_value, error_text
+
+    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
+        '''
+        if self.debug:
+            print "osconnector.get_network_list(): Getting network from VIM (filter: " + str(filter_dict) + "): "
+        try:
+            self._reload_connection()
+            net_dict=self.neutron.list_networks(**filter_dict)
+            net_list=net_dict["networks"]
+            self.__net_os2mano(net_list)
+            return 1, net_list
+        except neClient.exceptions.ConnectionFailed 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, neExceptions.NeutronException) 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_network_list " + error_text
+        return error_value, error_text
+
+    def get_tenant_network(self, net_id, tenant_id=None):
+        '''Obtain tenant networks of VIM'''
+        '''Returns the network information from a network id'''
+        if self.debug:
+            print "osconnector.get_tenant_network(): Getting tenant network %s from VIM" % net_id
+        filter_dict={"id": net_id}
+        if tenant_id:
+            filter_dict["tenant_id"] = tenant_id
+        r, net_list = self.get_network_list(filter_dict)
+        if r<0:
+            return r, net_list
+        if len(net_list)==0:
+            return -vimconn.HTTP_Not_Found, "Network '%s' not found" % net_id
+        elif len(net_list)>1:
+            return -vimconn.HTTP_Conflict, "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:
+                error_text= type(e).__name__ + ": "+  (str(e) if len(e.args)==0 else str(e.args[0]))
+                print "osconnector.get_tenant_network(): Error getting subnet %s %s" % (net_id, error_text)
+                subnet = {"id": subnet_id, "fault": error_text}
+            subnets.append(subnet)
+        net["subnets"] = subnets
+        return 1, net
+
+
+    def delete_tenant_network(self, net_id):
+        '''Deletes a tenant network from VIM'''
+        '''Returns the network identifier'''
+        if self.debug:
+            print "osconnector: Deleting a new tenant network from VIM tenant: " + self.tenant + ", id: " + 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:
+                    print "Error deleting port: " + type(e).__name__ + ": "+  str(e)
+            self.neutron.delete_network(net_id)
+            return 1, net_id
+        except neClient.exceptions.ConnectionFailed 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 neExceptions.NetworkNotFoundClient as e:
+            error_value=-vimconn.HTTP_Not_Found
+            error_text= type(e).__name__ + ": "+  str(e.args[0])
+        except (ksExceptions.ClientException, neExceptions.NeutronException) 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 "delete_tenant_network " + error_text
+        return error_value, error_text
+
+    def get_tenant_flavor(self, flavor_id):
+        '''Obtain flavor details from the  VIM
+            Returns the flavor dict details
+        '''
+        print "VIMConnector: Getting flavor from VIM"
+        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 1, {"flavor": flavor.to_dict()}
+        except nvExceptions.NotFound as e:
+            error_value=-vimconn.HTTP_Not_Found
+            error_text= "flavor instance %s not found" % flavor_id
+        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_tenant_flavor " + error_text
+        return error_value, error_text        
+
+    def new_tenant_flavor(self, flavor_dict, 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
+        Returns the flavor identifier
+        '''
+        retry=0
+        name_suffix = 0
+        name=flavor_dict['name']
+        while retry<2:
+            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_dict['name']+"-" + str(name_suffix)
+                        
+                ram = flavor_dict.get('ram',64)
+                vcpus = flavor_dict.get('vcpus',1)
+                numa_properties=None
+
+                extended=flavor_dict.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":
+                                    error_value=-vimconn.HTTP_Bad_Request
+                                    error_text= "Passthrough interfaces are not supported for the openstack connector"
+                                    break
+                                #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_dict.get('disk',1),
+                                is_public=flavor_dict.get('is_public', True)
+                            ) 
+                #add metadata
+                if numa_properties:
+                    new_flavor.set_keys(numa_properties)
+                return 1, new_flavor.id
+            except nvExceptions.Conflict as e:
+                error_value=-vimconn.HTTP_Conflict
+                error_text= str(e)
+                if change_name_if_used:
+                    continue
+                break
+            #except nvExceptions.BadRequest as e:
+            except (ksExceptions.ClientException, nvExceptions.ClientException, 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]))
+                break
+        #TODO insert exception vimconn.HTTP_Unauthorized
+        #if reaching here is because an exception
+        if self.debug:
+            print "new_tenant_flavor " + error_text
+        return error_value, error_text
+
+    def delete_tenant_flavor(self,flavor_id):
+        '''Deletes a tenant flavor from openstack VIM
+           Returns >0,id if ok; or <0,error_text if error
+        '''
+        retry=0
+        while retry<2:
+            retry+=1
+            try:
+                self._reload_connection()
+                self.nova.flavors.delete(flavor_id)
+                return 1, flavor_id
+            except nvExceptions.NotFound as e:
+                error_value = -vimconn.HTTP_Not_Found
+                error_text  = "flavor '%s' not found" % flavor_id
+                break
+            #except nvExceptions.BadRequest as e:
+            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]))
+                break
+        if self.debug:
+            print "delete_tenant_flavor " + error_text
+        #if reaching here is because an exception
+        return error_value, error_text
+
+    def new_tenant_image(self,image_dict):
+        '''
+        Adds a tenant image to VIM
+        if change_name_if_used is True, it will change name in case of conflict
+        Returns:
+            >1, image-id        if the image is created
+            <0, message          if there is an error
+        '''
+        retry=0
+        #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
+        while retry<2:
+            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 base on extention
+                    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"
+                print "new_tenant_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 1, new_image.id
+            except nvExceptions.Conflict as e:
+                error_value=-vimconn.HTTP_Conflict
+                error_text= type(e).__name__ + ": "+  (str(e) if len(e.args)==0 else str(e.args[0]))
+                break
+            except (HTTPException, gl1Exceptions.HTTPException, gl1Exceptions.CommunicationError) 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]))
+                continue
+            except IOError as e:  #can not open the file
+                error_value=-vimconn.HTTP_Bad_Request
+                error_text= type(e).__name__ + ": "+  (str(e) if len(e.args)==0 else str(e.args[0])) + " for " + image_dict['location']
+                break
+            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]))
+                break
+        #TODO insert exception vimconn.HTTP_Unauthorized
+        #if reaching here is because an exception
+        if self.debug:
+            print "new_tenant_image " + error_text
+        return error_value, error_text
+     
+    def delete_tenant_image(self, image_id):
+        '''Deletes a tenant image from openstack VIM
+        Returns >0,id if ok; or <0,error_text if error
+        '''
+        retry=0
+        while retry<2:
+            retry+=1
+            try:
+                self._reload_connection()
+                self.nova.images.delete(image_id)
+                return 1, image_id
+            except nvExceptions.NotFound as e:
+                error_value = -vimconn.HTTP_Not_Found
+                error_text  = "flavor '%s' not found" % image_id
+                break
+            #except nvExceptions.BadRequest as e:
+            except (ksExceptions.ClientException, nvExceptions.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]))
+                break
+        if self.debug:
+            print "delete_tenant_image " + error_text
+        #if reaching here is because an exception
+        return error_value, error_text
+        
+    def new_tenant_vminstance(self,name,description,start,image_id,flavor_id,net_list):
+        '''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
+                #TODO ip, security groups
+        Returns >=0, the instance identifier
+                <0, error_text
+        '''
+        if self.debug:
+            print "osconnector: Creating VM into VIM"
+            print "   image %s  flavor %s   nics=%s" %(image_id, flavor_id,net_list)
+        try:
+            metadata=[]
+            net_list_vim=[]
+            self._reload_connection()
+            metadata_vpci={}
+            for net in net_list:
+                if not net.get("net_id"): #skip non connected iface
+                    continue
+                if net["type"]=="virtual":
+                    net_list_vim.append({'net-id': net["net_id"]})
+                    if "vpci" in net:
+                        metadata_vpci[ net["net_id"] ] = [[ net["vpci"], "" ]]
+                elif net["type"]=="PF":
+                    print "new_tenant_vminstance: Warning, can not connect a passthrough interface "
+                    #TODO insert this when openstack consider passthrough ports as openstack neutron ports
+                else: #VF
+                    if "vpci" in net:
+                        if "VF" not in metadata_vpci:
+                            metadata_vpci["VF"]=[]
+                        metadata_vpci["VF"].append([ net["vpci"], "" ])
+                    port_dict={
+                         "network_id": net["net_id"],
+                         "name": net.get("name"),
+                         "binding:vnic_type": "direct", 
+                         "admin_state_up": True
+                    }
+                    if not port_dict["name"]:
+                        port_dict["name"] = name
+                    if net.get("mac_address"):
+                        port_dict["mac_address"]=net["mac_address"]
+                    #TODO: manage having SRIOV without vlan tag
+                    #if net["type"] == "VFnotShared"
+                    #    port_dict["vlan"]=0
+                    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"]})
+            if metadata_vpci:
+                metadata = {"pci_assignement": json.dumps(metadata_vpci)}
+            
+            print "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, )
+            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'),
+                                        ) #, description=description)
+            
+            
+            print "DONE :-)", server
+            
+#             #TODO   server.add_floating_ip("10.95.87.209")
+#             #To look for a free floating_ip
+#             free_floating_ip = None
+#             for floating_ip in self.neutron.list_floatingips().get("floatingips", () ):
+#                 if not floating_ip["port_id"]:
+#                     free_floating_ip = floating_ip["floating_ip_address"]
+#                     break
+#             if free_floating_ip:
+#                 server.add_floating_ip(free_floating_ip)
+                
+            
+            return 1, 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, TypeError) 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 neClient.exceptions.ConnectionFailed 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 "new_tenant_vminstance Exception",e, error_text
+        return error_value, error_text    
+
+    def get_tenant_vminstance(self,vm_id):
+        '''Returns the VM instance information from VIM'''
+        if self.debug:
+            print "osconnector: 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 1, {"server": server.to_dict()}
+        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) 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_tenant_vminstance " + error_text
+        return error_value, error_text        
+                
+    def get_tenant_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 <0, text on error, for example not available
+                1, URL/text with the console parameters
+        '''
+        if self.debug:
+            print "osconnector: 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:
+                return -vimconn.HTTP_Bad_Request, "console type '%s' not allowed" % console_type
+            
+            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 1, console_dict
+            return -vimconn.HTTP_Internal_Server_Error, "Unexpected response from VIM"
+            
+            #TODO parse input and translate to VIM format (openmano_schemas.new_vminstance_response_schema)
+            return 1, {"server": server.to_dict()}
+        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, nvExceptions.BadRequest) 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_tenant_vminstance " + error_text
+        return error_value, error_text        
+
+
+    def delete_tenant_vminstance(self, vm_id):
+        '''Removes a VM instance from VIM
+        Returns >0, the instance identifier
+                <0, error_text
+        '''
+        if self.debug:
+            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:
+                    print "Error deleting port: " + type(e).__name__ + ": "+  str(e)
+            self.nova.servers.delete(vm_id)
+            return 1, vm_id
+        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_tenant_vminstance " + error_text
+        return error_value, error_text        
+
+    def refresh_tenant_vms_and_nets(self, vmDict, netDict):
+        '''Refreshes the status of the dictionaries of VM instances and nets passed as arguments. It modifies the dictionaries
+        Returns:
+            - result: 0 if all elements could be refreshed (even if its status didn't change)
+                      n>0, the number of elements that couldn't be refreshed,
+                      <0 if error (foreseen)
+            - error_msg: text with reference to possible errors
+        '''
+        #vms_refreshed = []
+        #nets_refreshed = []
+        vms_unrefreshed = []
+        nets_unrefreshed = []
+        if self.debug:
+            print "osconnector refresh_tenant_vms and nets: Getting tenant VM instance information from VIM"
+        for vm_id in vmDict:
+            vmDict[vm_id] = {'error_msg':None, 'vim_info':None}
+            r,c = self.get_tenant_vminstance(vm_id)
+            if r<0:
+                print "osconnector refresh_tenant_vm. Error getting vm_id '%s' status: %s" % (vm_id, c)
+                if r==-vimconn.HTTP_Not_Found:
+                    vmDict[vm_id]['status'] = "DELETED" 
+                else:
+                    vmDict[vm_id]['status'] = "VIM_ERROR"
+                    vmDict[vm_id]['error_msg'] = c
+                    vms_unrefreshed.append(vm_id)
+            else:
+                try:
+                    vmDict[vm_id]['status']    =  vmStatus2manoFormat[ c['server']['status'] ]
+                    vmDict[vm_id]['vim_info']  = yaml.safe_dump(c['server'])
+                    vmDict[vm_id]["interfaces"] = []
+                    if c['server'].get('fault'):
+                        vmDict[vm_id]['error_msg'] = str(c['server']['fault'])
+                    #get interfaces
+                    try:
+                        self._reload_connection()
+                        port_dict=self.neutron.list_ports(device_id=vm_id)
+                        for port in port_dict["ports"]:
+                            interface={}
+                            interface['vim_info']  = yaml.safe_dump(port)
+                            interface["mac_address"] = port.get("mac_address")
+                            interface["vim_net_id"] = port["network_id"]
+                            interface["vim_interface_id"] = port["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)
+                            vmDict[vm_id]["interfaces"].append(interface)
+                    except Exception as e:
+                        print type(e).__name__ + ": "+  (str(e) if len(e.args)==0 else str(e.args[0]))
+                
+                    
+                    #error message at server.fault["message"]
+                except KeyError as e:
+                    print "osconnector refresh_tenant_elements KeyError %s getting vm_id '%s' status  %s" % (str(e), vm_id, c['server']['status'])
+                    vmDict[vm_id]['status'] = "VIM_ERROR"
+                    vmDict[vm_id]['error_msg'] = str(e)
+                    vms_unrefreshed.append(vm_id)
+        
+        #print "VMs refreshed: %s" % str(vms_refreshed)
+        for net_id in netDict:
+            netDict[net_id]={'error_msg':None, 'vim_info':None}
+            r,c = self.get_tenant_network(net_id)
+            if r<0:
+                print "osconnector refresh_tenant_network. Error getting net_id '%s' status: %s" % (net_id, c)
+                if r==-vimconn.HTTP_Not_Found:
+                    netDict[net_id]['status'] = "DELETED" #TODO check exit status
+                else:
+                    netDict[vm_id]['status'] = "VIM_ERROR"
+                    netDict[vm_id]['error_msg'] = c
+                    nets_unrefreshed.append(net_id)
+            else:
+                try:
+                    netDict[net_id]['status'] = netStatus2manoFormat[ c['status'] ]
+                    if c['status'] == "ACIVE" and not c['admin_state_up']:
+                        netDict[net_id]['status'] = 'DOWN'
+                    netDict[net_id]['vim_info']  = yaml.safe_dump(c)
+                    if c.get('fault'):  #TODO
+                        netDict[net_id]['error_msg'] = str(c['fault'])
+                except KeyError as e:
+                    print "osconnector refresh_tenant_elements KeyError %s getting vm_id '%s' status  %s" % (str(e), vm_id, c['network']['status'])
+                    netDict[net_id]['status'] = "VIM_ERROR"
+                    netDict[net_id]['error_msg'] = str(e)
+                    nets_unrefreshed.append(net_id)
+
+        #print "Nets refreshed: %s" % str(nets_refreshed)
+        
+        error_msg=""
+        if len(vms_unrefreshed)+len(nets_unrefreshed)>0:
+            error_msg += "VMs unrefreshed: " + str(vms_unrefreshed) + "; nets unrefreshed: " + str(nets_unrefreshed)
+            print error_msg
+
+        #return len(vms_unrefreshed)+len(nets_unrefreshed), error_msg, vms_refreshed, nets_refreshed
+        return len(vms_unrefreshed)+len(nets_unrefreshed), error_msg
+    
+    def action_tenant_vminstance(self, vm_id, action_dict):
+        '''Send and action over a VM instance from VIM
+        Returns the status'''
+        if self.debug:
+            print "osconnector: Action over VM instance from VIM " + vm_id
+        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:
+                    return -vimconn.HTTP_Bad_Request, "console type '%s' not allowed" % console_type
+                
+                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:
+                        print "action_tenant_vminstance, console: response", str(console_dict)
+                        return -vimconn.HTTP_Internal_Server_Error, "Unexpected response from VIM"
+                    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:] 
+                                  }
+                    protocol_index += 2
+                    return 1, console_dict2               
+                except:
+                    print "action_tenant_vminstance, console: response", str(console_dict)
+                    return -vimconn.HTTP_Internal_Server_Error, "Unexpected response from VIM"
+            
+            return 1, vm_id
+        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 "action_tenant_vminstance " + 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        
+  
+    def get_image_id_from_path(self, path):
+        '''Get the image id from image path in the VIM database'''
+        '''Returns:
+             0,"Image not found"   if there are no images with that path
+             1,image-id            if there is one image with that path
+             <0,message            if there was an error (Image not found, error contacting VIM, more than 1 image with that path, etc.) 
+        '''
+        try:
+            self._reload_connection()
+            images = self.nova.images.list()
+            for image in images:
+                if image.metadata.get("location")==path:
+                    return 1, image.id
+            return 0, "image with location '%s' not found" % path
+        except (ksExceptions.ClientException, nvExceptions.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]))
+        if self.debug:
+            print "get_image_id_from_path " + error_text
+        #if reaching here is because an exception
+        return error_value, error_text
+        
+
