# -*- 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-neutronclient.

For the VNF forwarding graph, The OpenStack VIM connector calls the
networking-sfc Neutron extension methods, whose resources are mapped
to the VIM connector's SFC resources as follows:
- Classification (OSM) -> Flow Classifier (Neutron)
- Service Function Instance (OSM) -> Port Pair (Neutron)
- Service Function (OSM) -> Port Pair Group (Neutron)
- Service Function Path (OSM) -> Port Chain (Neutron)
'''
__author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes, xFlow Research, Igor D.C."
__date__  = "$22-sep-2017 23:59:59$"

import vimconn
# import json
import logging
import netaddr
import time
import yaml
import random
import re
import copy

from novaclient import client as nClient, exceptions as nvExceptions
from keystoneauth1.identity import v2, v3
from keystoneauth1 import session
import keystoneclient.exceptions as ksExceptions
import keystoneclient.v3.client as ksClient_v3
import keystoneclient.v2_0.client as ksClient_v2
from glanceclient import client as glClient
import glanceclient.client as gl1Client
import glanceclient.exc as gl1Exceptions
from  cinderclient import client as cClient
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'
                     }

supportedClassificationTypes = ['legacy_flow_classifier']

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

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
        '''
        api_version = config.get('APIversion')
        if api_version and api_version not in ('v3.3', 'v2.0', '2', '3'):
            raise vimconn.vimconnException("Invalid value '{}' for config:APIversion. "
                                           "Allowed values are 'v3.3', 'v2.0', '2' or '3'".format(api_version))
        vim_type = config.get('vim_type')
        if vim_type and vim_type not in ('vio', 'VIO'):
            raise vimconn.vimconnException("Invalid value '{}' for config:vim_type."
                            "Allowed values are 'vio' or 'VIO'".format(vim_type))

        if config.get('dataplane_net_vlan_range') is not None:
            #validate vlan ranges provided by user
            self._validate_vlan_ranges(config.get('dataplane_net_vlan_range'))

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

        self.insecure = self.config.get("insecure", False)
        if not url:
            raise TypeError('url param can not be NoneType')
        self.persistent_info = persistent_info
        self.availability_zone = persistent_info.get('availability_zone', None)
        self.session = persistent_info.get('session', {'reload_client': True})
        self.nova = self.session.get('nova')
        self.neutron = self.session.get('neutron')
        self.cinder = self.session.get('cinder')
        self.glance = self.session.get('glance')
        self.glancev1 = self.session.get('glancev1')
        self.keystone = self.session.get('keystone')
        self.api_version3 = self.session.get('api_version3')
        self.vim_type = self.config.get("vim_type")
        if self.vim_type:
            self.vim_type = self.vim_type.upper()
        if self.config.get("use_internal_endpoint"):
            self.endpoint_type = "internalURL"
        else:
            self.endpoint_type = None

        self.logger = logging.getLogger('openmano.vim.openstack')

        ####### VIO Specific Changes #########
        if self.vim_type == "VIO":
            self.logger = logging.getLogger('openmano.vim.vio')

        if log_level:
            self.logger.setLevel( getattr(logging, log_level))

    def __getitem__(self, index):
        """Get individuals parameters.
        Throw KeyError"""
        if index == 'project_domain_id':
            return self.config.get("project_domain_id")
        elif index == 'user_domain_id':
            return self.config.get("user_domain_id")
        else:
            return vimconn.vimconnector.__getitem__(self, index)

    def __setitem__(self, index, value):
        """Set individuals parameters and it is marked as dirty so to force connection reload.
        Throw KeyError"""
        if index == 'project_domain_id':
            self.config["project_domain_id"] = value
        elif index == 'user_domain_id':
                self.config["user_domain_id"] = value
        else:
            vimconn.vimconnector.__setitem__(self, index, value)
        self.session['reload_client'] = True

    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.session['reload_client']:
            if self.config.get('APIversion'):
                self.api_version3 = self.config['APIversion'] == 'v3.3' or self.config['APIversion'] == '3'
            else:  # get from ending auth_url that end with v3 or with v2.0
                self.api_version3 =  self.url.endswith("/v3") or self.url.endswith("/v3/")
            self.session['api_version3'] = self.api_version3
            if self.api_version3:
                if self.config.get('project_domain_id') or self.config.get('project_domain_name'):
                    project_domain_id_default = None
                else:
                    project_domain_id_default = 'default'
                if self.config.get('user_domain_id') or self.config.get('user_domain_name'):
                    user_domain_id_default = None
                else:
                    user_domain_id_default = 'default'
                auth = v3.Password(auth_url=self.url,
                                   username=self.user,
                                   password=self.passwd,
                                   project_name=self.tenant_name,
                                   project_id=self.tenant_id,
                                   project_domain_id=self.config.get('project_domain_id', project_domain_id_default),
                                   user_domain_id=self.config.get('user_domain_id', user_domain_id_default),
                                   project_domain_name=self.config.get('project_domain_name'),
                                   user_domain_name=self.config.get('user_domain_name'))
            else:
                auth = v2.Password(auth_url=self.url,
                                   username=self.user,
                                   password=self.passwd,
                                   tenant_name=self.tenant_name,
                                   tenant_id=self.tenant_id)
            sess = session.Session(auth=auth, verify=not self.insecure)
            if self.api_version3:
                self.keystone = ksClient_v3.Client(session=sess, endpoint_type=self.endpoint_type)
            else:
                self.keystone = ksClient_v2.Client(session=sess, endpoint_type=self.endpoint_type)
            self.session['keystone'] = self.keystone
            # In order to enable microversion functionality an explicit microversion must be specified in 'config'.
            # This implementation approach is due to the warning message in
            # https://developer.openstack.org/api-guide/compute/microversions.html
            # where it is stated that microversion backwards compatibility is not guaranteed and clients should
            # always require an specific microversion.
            # To be able to use 'device role tagging' functionality define 'microversion: 2.32' in datacenter config
            version = self.config.get("microversion")
            if not version:
                version = "2.1"
            self.nova = self.session['nova'] = nClient.Client(str(version), session=sess, endpoint_type=self.endpoint_type)
            self.neutron = self.session['neutron'] = neClient.Client('2.0', session=sess, endpoint_type=self.endpoint_type)
            self.cinder = self.session['cinder'] = cClient.Client(2, session=sess, endpoint_type=self.endpoint_type)
            if self.endpoint_type == "internalURL":
                glance_service_id = self.keystone.services.list(name="glance")[0].id
                glance_endpoint = self.keystone.endpoints.list(glance_service_id, interface="internal")[0].url
            else:
                glance_endpoint = None
            self.glance = self.session['glance'] = glClient.Client(2, session=sess, endpoint=glance_endpoint)
            #using version 1 of glance client in new_image()
            self.glancev1 = self.session['glancev1'] = glClient.Client('1', session=sess,
                                                                       endpoint=glance_endpoint)
            self.session['reload_client'] = False
            self.persistent_info['session'] = self.session
            # add availablity zone info inside  self.persistent_info
            self._set_availablity_zones()
            self.persistent_info['availability_zone'] = self.availability_zone

    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 __classification_os2mano(self, class_list_dict):
        """Transform the openstack format (Flow Classifier) to mano format
        (Classification) class_list_dict can be a list of dict or a single dict
        """
        if isinstance(class_list_dict, dict):
            class_list_ = [class_list_dict]
        elif isinstance(class_list_dict, list):
            class_list_ = class_list_dict
        else:
            raise TypeError(
                "param class_list_dict must be a list or a dictionary")
        for classification in class_list_:
            id = classification.pop('id')
            name = classification.pop('name')
            description = classification.pop('description')
            project_id = classification.pop('project_id')
            tenant_id = classification.pop('tenant_id')
            original_classification = copy.deepcopy(classification)
            classification.clear()
            classification['ctype'] = 'legacy_flow_classifier'
            classification['definition'] = original_classification
            classification['id'] = id
            classification['name'] = name
            classification['description'] = description
            classification['project_id'] = project_id
            classification['tenant_id'] = tenant_id

    def __sfi_os2mano(self, sfi_list_dict):
        """Transform the openstack format (Port Pair) to mano format (SFI)
        sfi_list_dict can be a list of dict or a single dict
        """
        if isinstance(sfi_list_dict, dict):
            sfi_list_ = [sfi_list_dict]
        elif isinstance(sfi_list_dict, list):
            sfi_list_ = sfi_list_dict
        else:
            raise TypeError(
                "param sfi_list_dict must be a list or a dictionary")
        for sfi in sfi_list_:
            sfi['ingress_ports'] = []
            sfi['egress_ports'] = []
            if sfi.get('ingress'):
                sfi['ingress_ports'].append(sfi['ingress'])
            if sfi.get('egress'):
                sfi['egress_ports'].append(sfi['egress'])
            del sfi['ingress']
            del sfi['egress']
            params = sfi.get('service_function_parameters')
            sfc_encap = False
            if params:
                correlation = params.get('correlation')
                if correlation:
                    sfc_encap = True
            sfi['sfc_encap'] = sfc_encap
            del sfi['service_function_parameters']

    def __sf_os2mano(self, sf_list_dict):
        """Transform the openstack format (Port Pair Group) to mano format (SF)
        sf_list_dict can be a list of dict or a single dict
        """
        if isinstance(sf_list_dict, dict):
            sf_list_ = [sf_list_dict]
        elif isinstance(sf_list_dict, list):
            sf_list_ = sf_list_dict
        else:
            raise TypeError(
                "param sf_list_dict must be a list or a dictionary")
        for sf in sf_list_:
            del sf['port_pair_group_parameters']
            sf['sfis'] = sf['port_pairs']
            del sf['port_pairs']

    def __sfp_os2mano(self, sfp_list_dict):
        """Transform the openstack format (Port Chain) to mano format (SFP)
        sfp_list_dict can be a list of dict or a single dict
        """
        if isinstance(sfp_list_dict, dict):
            sfp_list_ = [sfp_list_dict]
        elif isinstance(sfp_list_dict, list):
            sfp_list_ = sfp_list_dict
        else:
            raise TypeError(
                "param sfp_list_dict must be a list or a dictionary")
        for sfp in sfp_list_:
            params = sfp.pop('chain_parameters')
            sfc_encap = False
            if params:
                correlation = params.get('correlation')
                if correlation:
                    sfc_encap = True
            sfp['sfc_encap'] = sfc_encap
            sfp['spi'] = sfp.pop('chain_id')
            sfp['classifications'] = sfp.pop('flow_classifiers')
            sfp['service_functions'] = sfp.pop('port_pair_groups')

    # placeholder for now; read TODO note below
    def _validate_classification(self, type, definition):
        # only legacy_flow_classifier Type is supported at this point
        return True
        # TODO(igordcard): this method should be an abstract method of an
        # abstract Classification class to be implemented by the specific
        # Types. Also, abstract vimconnector should call the validation
        # method before the implemented VIM connectors are called.

    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))
        elif isinstance(exception, vimconn.vimconnException):
            raise
        else:  # ()
            self.logger.error("General Exception " + str(exception), exc_info=True)
            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.api_version3:
                project_class_list = self.keystone.projects.list(name=filter_dict.get("name"))
            else:
                project_class_list = self.keystone.tenants.findall(**filter_dict)
            project_list=[]
            for project in project_class_list:
                if filter_dict.get('id') and filter_dict["id"] != project.id:
                    continue
                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.api_version3:
                project = self.keystone.projects.create(tenant_name, self.config.get("project_domain_id", "default"),
                                                        description=tenant_description, is_domain=False)
            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.api_version3:
                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

                ####### VIO Specific Changes #########
                if self.vim_type == "VIO":
                    if vlan is not None:
                        network_dict["provider:segmentation_id"] = vlan
                    else:
                        if self.config.get('dataplane_net_vlan_range') is None:
                            raise vimconn.vimconnConflictException("You must provide "\
                                "'dataplane_net_vlan_range' in format [start_ID - end_ID]"\
                                "at config value before creating sriov network with vlan tag")

                        network_dict["provider:segmentation_id"] = self._genrate_vlanID()

            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']
                    }
            # Gateway should be set to None if not needed. Otherwise openstack assigns one by default
            subnet['gateway_ip'] = ip_profile.get('gateway_address')
            if ip_profile.get('dns_address'):
                subnet['dns_nameservers'] = ip_profile['dns_address'].split(";")
            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()
            filter_dict_os = filter_dict.copy()
            if self.api_version3 and "tenant_id" in filter_dict_os:
                filter_dict_os['project_id'] = filter_dict_os.pop('tenant_id')  #T ODO check
            net_dict = self.neutron.list_networks(**filter_dict_os)
            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
           flavor_dict: contains the required ram, vcpus, disk
           If 'use_existing_flavors' is set to True at config, the closer flavor that provides same or more ram, vcpus
                and disk is returned. Otherwise a flavor with exactly same ram, vcpus and disk is returned or a
                vimconnNotFoundException is raised
        """
        exact_match = False if self.config.get('use_existing_flavors') else True
        try:
            self._reload_connection()
            flavor_candidate_id = None
            flavor_candidate_data = (10000, 10000, 10000)
            flavor_target = (flavor_dict["ram"], flavor_dict["vcpus"], flavor_dict["disk"])
            # 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
                flavor_data = (flavor.ram, flavor.vcpus, flavor.disk)
                if flavor_data == flavor_target:
                    return flavor.id
                elif not exact_match and flavor_target < flavor_data < flavor_candidate_data:
                    flavor_candidate_id = flavor.id
                    flavor_candidate_data = flavor_data
            if not exact_match and flavor_candidate_id:
                return flavor_candidate_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"
                        if self.vim_type == "VIO":
                            numa_properties["vmware:extra_config"] = '{"numa.nodeAffinity":"0"}'
                            numa_properties["vmware:latency_sensitivity_level"] = "high"
                        for numa in numas:
                            #overwrite ram and vcpus
                            #check if key 'memory' is present in numa else use ram value at flavor
                            if 'memory' in numa:
                                ram = numa['memory']*1024
                            #See for reference: https://specs.openstack.org/openstack/nova-specs/specs/mitaka/implemented/virt-driver-cpu-thread-pinning.html
                            if 'paired-threads' in numa:
                                vcpus = numa['paired-threads']*2
                                #cpu_thread_policy "require" implies that the compute node must have an STM architecture
                                numa_properties["hw:cpu_thread_policy"] = "require"
                                numa_properties["hw:cpu_policy"] = "dedicated"
                            elif 'cores' in numa:
                                vcpus = numa['cores']
                                # cpu_thread_policy "prefer" implies that the host must not have an SMT architecture, or a non-SMT architecture will be emulated
                                numa_properties["hw:cpu_thread_policy"] = "isolate"
                                numa_properties["hw:cpu_policy"] = "dedicated"
                            elif 'threads' in numa:
                                vcpus = numa['threads']
                                # cpu_thread_policy "prefer" implies that the host may or may not have an SMT architecture
                                numa_properties["hw:cpu_thread_policy"] = "prefer"
                                numa_properties["hw:cpu_policy"] = "dedicated"
                            # 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',0),
                                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
        '''
        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 = self.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 = self.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:
                try:
                    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())
                except gl1Exceptions.HTTPNotFound:
                    pass
            return filtered_list
        except (ksExceptions.ClientException, nvExceptions.ClientException, gl1Exceptions.CommunicationError, ConnectionError) as e:
            self._format_exception(e)

    def __wait_for_vm(self, vm_id, status):
        """wait until vm is in the desired status and return True.
        If the VM gets in ERROR status, return false.
        If the timeout is reached generate an exception"""
        elapsed_time = 0
        while elapsed_time < server_timeout:
            vm_status = self.nova.servers.get(vm_id).status
            if vm_status == status:
                return True
            if vm_status == 'ERROR':
                return False
            time.sleep(1)
            elapsed_time += 1

        # if we exceeded the timeout rollback
        if elapsed_time >= server_timeout:
            raise vimconn.vimconnException('Timeout waiting for instance ' + vm_id + ' to get ' + status,
                                           http_code=vimconn.HTTP_Request_Timeout)

    def _get_openstack_availablity_zones(self):
        """
        Get from openstack availability zones available
        :return:
        """
        try:
            openstack_availability_zone = self.nova.availability_zones.list()
            openstack_availability_zone = [str(zone.zoneName) for zone in openstack_availability_zone
                                           if zone.zoneName != 'internal']
            return openstack_availability_zone
        except Exception as e:
            return None

    def _set_availablity_zones(self):
        """
        Set vim availablity zone
        :return:
        """

        if 'availability_zone' in self.config:
            vim_availability_zones = self.config.get('availability_zone')
            if isinstance(vim_availability_zones, str):
                self.availability_zone = [vim_availability_zones]
            elif isinstance(vim_availability_zones, list):
                self.availability_zone = vim_availability_zones
        else:
            self.availability_zone = self._get_openstack_availablity_zones()

    def _get_vm_availability_zone(self, availability_zone_index, availability_zone_list):
        """
        Return thge availability zone to be used by the created VM.
        :return: The VIM availability zone to be used or None
        """
        if availability_zone_index is None:
            if not self.config.get('availability_zone'):
                return None
            elif isinstance(self.config.get('availability_zone'), str):
                return self.config['availability_zone']
            else:
                # TODO consider using a different parameter at config for default AV and AV list match
                return self.config['availability_zone'][0]

        vim_availability_zones = self.availability_zone
        # check if VIM offer enough availability zones describe in the VNFD
        if vim_availability_zones and len(availability_zone_list) <= len(vim_availability_zones):
            # check if all the names of NFV AV match VIM AV names
            match_by_index = False
            for av in availability_zone_list:
                if av not in vim_availability_zones:
                    match_by_index = True
                    break
            if match_by_index:
                return vim_availability_zones[availability_zone_index]
            else:
                return availability_zone_list[availability_zone_index]
        else:
            raise vimconn.vimconnConflictException("No enough availability zones at VIM for this deployment")

    def new_vminstance(self, name, description, start, image_id, flavor_id, net_list, cloud_config=None, disk_list=None,
                       availability_zone_index=None, availability_zone_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', 'PCI-PASSTHROUGH'('PF'), 'SR-IOV'('VF'), 'VFnotShared'
                vim_id: filled/added by this function
                floating_ip: True/False (or it can be None)
                'cloud_config': (optional) dictionary with:
                'key-pairs': (optional) list of strings with the public key to be inserted to the default user
                'users': (optional) list of users to be inserted, each item is a dict with:
                    'name': (mandatory) user name,
                    'key-pairs': (optional) list of strings with the public key to be inserted to the user
                'user-data': (optional) string is a text script to be passed directly to cloud-init
                'config-files': (optional). List of files to be transferred. Each item is a dict with:
                    'dest': (mandatory) string with the destination absolute path
                    'encoding': (optional, by default text). Can be one of:
                        'b64', 'base64', 'gz', 'gz+b64', 'gz+base64', 'gzip+b64', 'gzip+base64'
                    'content' (mandatory): string with the content of the file
                    'permissions': (optional) string with file permissions, typically octal notation '0644'
                    'owner': (optional) file owner, string with the format 'owner:group'
                'boot-data-drive': boolean to indicate if user-data must be passed using a boot drive (hard disk)
            'disk_list': (optional) list with additional disks to the VM. Each item is a dict with:
                'image_id': (optional). VIM id of an existing image. If not provided an empty disk must be mounted
                'size': (mandatory) string with the size of the disk in GB
            availability_zone_index: Index of availability_zone_list to use for this this VM. None if not AV required
            availability_zone_list: list of availability zones given by user in the VNFD descriptor.  Ignore if
                availability_zone_index is None
                #TODO ip, security groups
        Returns a tuple with the instance identifier and created_items or raises an exception on error
            created_items can be None or a dictionary where this method can include key-values that will be passed to
            the method delete_vminstance and action_vminstance. Can be used to store created ports, volumes, etc.
            Format is vimconnector dependent, but do not use nested dictionaries and a value of None should be the same
            as not present.
        """
        self.logger.debug("new_vminstance input: image='%s' flavor='%s' nics='%s'",image_id, flavor_id,str(net_list))
        try:
            server = None
            created_items = {}
            # metadata = {}
            net_list_vim = []
            external_network = []   # list of external networks to be connected to instance, later on used to create floating_ip
            no_secured_ports = []   # List of port-is with port-security disabled
            self._reload_connection()
            # metadata_vpci = {}   # For a specific neutron plugin
            block_device_mapping = None
            for net in net_list:
                if not net.get("net_id"):   # skip non connected iface
                    continue

                port_dict={
                    "network_id": net["net_id"],
                    "name": net.get("name"),
                    "admin_state_up": True
                }
                if net["type"]=="virtual":
                    pass
                    # if "vpci" in net:
                    #     metadata_vpci[ net["net_id"] ] = [[ net["vpci"], "" ]]
                elif net["type"] == "VF" or net["type"] == "SR-IOV":  # 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"
                    # VIO specific Changes
                    if self.vim_type == "VIO":
                        # Need to create port with port_security_enabled = False and no-security-groups
                        port_dict["port_security_enabled"]=False
                        port_dict["provider_security_groups"]=[]
                        port_dict["security_groups"]=[]
                else:   # For PT PCI-PASSTHROUGH
                    # VIO specific Changes
                    # Current VIO release does not support port with type 'direct-physical'
                    # So no need to create virtual port in case of PCI-device.
                    # Will update port_dict code when support gets added in next VIO release
                    if self.vim_type == "VIO":
                        raise vimconn.vimconnNotSupportedException(
                            "Current VIO release does not support full passthrough (PT)")
                    # if "vpci" in net:
                    #     if "PF" not in metadata_vpci:
                    #         metadata_vpci["PF"]=[]
                    #     metadata_vpci["PF"].append([ net["vpci"], "" ])
                    port_dict["binding:vnic_type"]="direct-physical"
                if not port_dict["name"]:
                    port_dict["name"]=name
                if net.get("mac_address"):
                    port_dict["mac_address"]=net["mac_address"]
                new_port = self.neutron.create_port({"port": port_dict })
                created_items["port:" + str(new_port["port"]["id"])] = True
                net["mac_adress"] = new_port["port"]["mac_address"]
                net["vim_id"] = new_port["port"]["id"]
                # if try to use a network without subnetwork, it will return a emtpy list
                fixed_ips = new_port["port"].get("fixed_ips")
                if fixed_ips:
                    net["ip"] = fixed_ips[0].get("ip_address")
                else:
                    net["ip"] = None

                port = {"port-id": new_port["port"]["id"]}
                if float(self.nova.api_version.get_string()) >= 2.32:
                    port["tag"] = new_port["port"]["name"]
                net_list_vim.append(port)

                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 port security is disabled when the port has not yet been attached to the VM, then all vm traffic is dropped.
                # As a workaround we wait until the VM is active and then disable the port-security
                if net.get("port_security") == False:
                    no_secured_ports.append(new_port["port"]["id"])

            # 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'",
                              name, image_id, flavor_id, str(net_list_vim), description)

            security_groups = self.config.get('security_groups')
            if type(security_groups) is str:
                security_groups = ( security_groups, )
            # cloud config
            config_drive, userdata = self._create_user_data(cloud_config)

            # Create additional volumes in case these are present in disk_list
            base_disk_index = ord('b')
            if disk_list != None:
                block_device_mapping = {}
                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))
                    created_items["volume:" + str(volume.id)] = True
                    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:
                    raise vimconn.vimconnException('Timeout creating volumes for instance ' + name,
                                                   http_code=vimconn.HTTP_Request_Timeout)
            # get availability Zone
            vm_av_zone = self._get_vm_availability_zone(availability_zone_index, availability_zone_list)

            self.logger.debug("nova.servers.create({}, {}, {}, nics={}, security_groups={}, "
                              "availability_zone={}, key_name={}, userdata={}, config_drive={}, "
                              "block_device_mapping={})".format(name, image_id, flavor_id, net_list_vim,
                                                                security_groups, vm_av_zone, self.config.get('keypair'),
                                                                userdata, config_drive, block_device_mapping))
            server = self.nova.servers.create(name, image_id, flavor_id, nics=net_list_vim,
                                              security_groups=security_groups,
                                              availability_zone=vm_av_zone,
                                              key_name=self.config.get('keypair'),
                                              userdata=userdata,
                                              config_drive=config_drive,
                                              block_device_mapping=block_device_mapping
                                              )  # , description=description)

            # Previously mentioned workaround to wait until the VM is active and then disable the port-security
            if no_secured_ports:
                self.__wait_for_vm(server.id, 'ACTIVE')

            for port_id in no_secured_ports:
                try:
                    self.neutron.update_port(port_id, {"port": {"port_security_enabled": False, "security_groups": None} })
                except Exception as e:
                    self.logger.error("It was not possible to disable port security for port {}".format(port_id))
                    raise

            # print "DONE :-)", server

            pool_id = None
            if external_network:
                floating_ips = self.neutron.list_floatingips().get("floatingips", ())
                self.__wait_for_vm(server.id, 'ACTIVE')

            for floating_network in external_network:
                try:
                    assigned = False
                    while not assigned:
                        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
                    raise

            return server.id, created_items
#        except nvExceptions.NotFound as e:
#            error_value=-vimconn.HTTP_Not_Found
#            error_text= "vm instance %s not found" % vm_id
#        except TypeError as e:
#            raise vimconn.vimconnException(type(e).__name__ + ": "+  str(e), http_code=vimconn.HTTP_Bad_Request)

        except Exception as e:
            server_id = None
            if server:
                server_id = server.id
            try:
                self.delete_vminstance(server_id, created_items)
            except Exception as e2:
                self.logger.error("new_vminstance rollback fail {}".format(e2))

            self._format_exception(e)

    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, created_items=None):
        '''Removes a VM instance from VIM. Returns the old identifier
        '''
        #print "osconnector: Getting VM from VIM"
        if created_items == None:
            created_items = {}
        try:
            self._reload_connection()
            # delete VM ports attached to this networks before the virtual machine
            for k, v in created_items.items():
                if not v:  # skip already deleted
                    continue
                try:
                    k_item, _, k_id = k.partition(":")
                    if k_item == "port":
                        self.neutron.delete_port(k_id)
                except Exception as e:
                    self.logger.error("Error deleting port: {}: {}".format(type(e).__name__, 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']   #volume['id']
            # #for volume in volumes_attached_dict:
            # #    self.cinder.volumes.detach(volume['id'])

            if vm_id:
                self.nova.servers.delete(vm_id)

            # delete volumes. Although having detached, they should have in active status before deleting
            # we ensure in this loop
            keep_waiting = True
            elapsed_time = 0
            while keep_waiting and elapsed_time < volume_timeout:
                keep_waiting = False
                for k, v in created_items.items():
                    if not v:  # skip already deleted
                        continue
                    try:
                        k_item, _, k_id = k.partition(":")
                        if k_item == "volume":
                            if self.cinder.volumes.get(k_id).status != 'available':
                                keep_waiting = True
                            else:
                                self.cinder.volumes.delete(k_id)
                    except Exception as e:
                        self.logger.error("Error deleting volume: {}: {}".format(type(e).__name__, e))
                if keep_waiting:
                    time.sleep(1)
                    elapsed_time += 1
            return None
        except (nvExceptions.NotFound, ksExceptions.ClientException, nvExceptions.ClientException, ConnectionError) as e:
            self._format_exception(e)

    def refresh_vms_status(self, vm_list):
        '''Get the status of the virtual machines and their interfaces/ports
           Params: the list of VM identifiers
           Returns a dictionary with:
                vm_id:          #VIM id of this Virtual Machine
                    status:     #Mandatory. Text with one of:
                                #  DELETED (not found at vim)
                                #  VIM_ERROR (Cannot connect to VIM, VIM response error, ...) 
                                #  OTHER (Vim reported other status not understood)
                                #  ERROR (VIM indicates an ERROR status)
                                #  ACTIVE, PAUSED, SUSPENDED, INACTIVE (not running), 
                                #  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
                        compute_node:     #identification of compute node where PF,VF interface is allocated
                        pci:              #PCI address of the NIC that hosts the PF,VF
                        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"]
                        # check if OS-EXT-SRV-ATTR:host is there, 
                        # in case of non-admin credentials, it will be missing
                        if vm_vim.get('OS-EXT-SRV-ATTR:host'):
                            interface["compute_node"] = vm_vim['OS-EXT-SRV-ATTR:host']
                        interface["pci"] = None

                        # check if binding:profile is there, 
                        # in case of non-admin credentials, it will be missing
                        if port.get('binding:profile'):
                            if port['binding:profile'].get('pci_slot'):
                                # 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
                                #   CHANGE DDDD:BB:SS.F to DDDD:BB:00.(F%2)   assuming there are 2 ports per nic
                                pci = port['binding:profile']['pci_slot']
                                # interface["pci"] = pci[:-4] + "00." + str(int(pci[-1]) % 2)
                                interface["pci"] = pci
                        interface["vlan"] = None
                        #if network is of type vlan and port is of type direct (sr-iov) then set vlan id
                        network = self.neutron.show_network(port["network_id"])
                        if network['network'].get('provider:network_type') == 'vlan' and \
                            port.get("binding:vnic_type") == "direct":
                            interface["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, created_items={}):
        '''Send and action over a VM instance from VIM
        Returns None or the console dict 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 None
        except (ksExceptions.ClientException, nvExceptions.ClientException, nvExceptions.NotFound, ConnectionError) as e:
            self._format_exception(e)
        #TODO insert exception vimconn.HTTP_Unauthorized

    ####### VIO Specific Changes #########
    def _genrate_vlanID(self):
        """
         Method to get unused vlanID
            Args:
                None
            Returns:
                vlanID
        """
        #Get used VLAN IDs
        usedVlanIDs = []
        networks = self.get_network_list()
        for net in networks:
            if net.get('provider:segmentation_id'):
                usedVlanIDs.append(net.get('provider:segmentation_id'))
        used_vlanIDs = set(usedVlanIDs)

        #find unused VLAN ID
        for vlanID_range in self.config.get('dataplane_net_vlan_range'):
            try:
                start_vlanid , end_vlanid = map(int, vlanID_range.replace(" ", "").split("-"))
                for vlanID in xrange(start_vlanid, end_vlanid + 1):
                    if vlanID not in used_vlanIDs:
                        return vlanID
            except Exception as exp:
                raise vimconn.vimconnException("Exception {} occurred while generating VLAN ID.".format(exp))
        else:
            raise vimconn.vimconnConflictException("Unable to create the SRIOV VLAN network."\
                " All given Vlan IDs {} are in use.".format(self.config.get('dataplane_net_vlan_range')))


    def _validate_vlan_ranges(self, dataplane_net_vlan_range):
        """
        Method to validate user given vlanID ranges
            Args:  None
            Returns: None
        """
        for vlanID_range in dataplane_net_vlan_range:
            vlan_range = vlanID_range.replace(" ", "")
            #validate format
            vlanID_pattern = r'(\d)*-(\d)*$'
            match_obj = re.match(vlanID_pattern, vlan_range)
            if not match_obj:
                raise vimconn.vimconnConflictException("Invalid dataplane_net_vlan_range {}.You must provide "\
                "'dataplane_net_vlan_range' in format [start_ID - end_ID].".format(vlanID_range))

            start_vlanid , end_vlanid = map(int,vlan_range.split("-"))
            if start_vlanid <= 0 :
                raise vimconn.vimconnConflictException("Invalid dataplane_net_vlan_range {}."\
                "Start ID can not be zero. For VLAN "\
                "networks valid IDs are 1 to 4094 ".format(vlanID_range))
            if end_vlanid > 4094 :
                raise vimconn.vimconnConflictException("Invalid dataplane_net_vlan_range {}."\
                "End VLAN ID can not be greater than 4094. For VLAN "\
                "networks valid IDs are 1 to 4094 ".format(vlanID_range))

            if start_vlanid > end_vlanid:
                raise vimconn.vimconnConflictException("Invalid dataplane_net_vlan_range {}."\
                    "You must provide a 'dataplane_net_vlan_range' in format start_ID - end_ID and "\
                    "start_ID < end_ID ".format(vlanID_range))

#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

    def new_classification(self, name, ctype, definition):
        self.logger.debug(
            'Adding a new (Traffic) Classification to VIM, named %s', name)
        try:
            new_class = None
            self._reload_connection()
            if ctype not in supportedClassificationTypes:
                raise vimconn.vimconnNotSupportedException(
                        'OpenStack VIM connector doesn\'t support provided '
                        'Classification Type {}, supported ones are: '
                        '{}'.format(ctype, supportedClassificationTypes))
            if not self._validate_classification(ctype, definition):
                raise vimconn.vimconnException(
                    'Incorrect Classification definition '
                    'for the type specified.')
            classification_dict = definition
            classification_dict['name'] = name

            new_class = self.neutron.create_sfc_flow_classifier(
                {'flow_classifier': classification_dict})
            return new_class['flow_classifier']['id']
        except (neExceptions.ConnectionFailed, ksExceptions.ClientException,
                neExceptions.NeutronException, ConnectionError) as e:
            self.logger.error(
                'Creation of Classification failed.')
            self._format_exception(e)

    def get_classification(self, class_id):
        self.logger.debug(" Getting Classification %s from VIM", class_id)
        filter_dict = {"id": class_id}
        class_list = self.get_classification_list(filter_dict)
        if len(class_list) == 0:
            raise vimconn.vimconnNotFoundException(
                "Classification '{}' not found".format(class_id))
        elif len(class_list) > 1:
            raise vimconn.vimconnConflictException(
                "Found more than one Classification with this criteria")
        classification = class_list[0]
        return classification

    def get_classification_list(self, filter_dict={}):
        self.logger.debug("Getting Classifications from VIM filter: '%s'",
                          str(filter_dict))
        try:
            filter_dict_os = filter_dict.copy()
            self._reload_connection()
            if self.api_version3 and "tenant_id" in filter_dict_os:
                filter_dict_os['project_id'] = filter_dict_os.pop('tenant_id')
            classification_dict = self.neutron.list_sfc_flow_classifiers(
                **filter_dict_os)
            classification_list = classification_dict["flow_classifiers"]
            self.__classification_os2mano(classification_list)
            return classification_list
        except (neExceptions.ConnectionFailed, ksExceptions.ClientException,
                neExceptions.NeutronException, ConnectionError) as e:
            self._format_exception(e)

    def delete_classification(self, class_id):
        self.logger.debug("Deleting Classification '%s' from VIM", class_id)
        try:
            self._reload_connection()
            self.neutron.delete_sfc_flow_classifier(class_id)
            return class_id
        except (neExceptions.ConnectionFailed, neExceptions.NeutronException,
                ksExceptions.ClientException, neExceptions.NeutronException,
                ConnectionError) as e:
            self._format_exception(e)

    def new_sfi(self, name, ingress_ports, egress_ports, sfc_encap=True):
        self.logger.debug(
            "Adding a new Service Function Instance to VIM, named '%s'", name)
        try:
            new_sfi = None
            self._reload_connection()
            correlation = None
            if sfc_encap:
                correlation = 'nsh'
            if len(ingress_ports) != 1:
                raise vimconn.vimconnNotSupportedException(
                    "OpenStack VIM connector can only have "
                    "1 ingress port per SFI")
            if len(egress_ports) != 1:
                raise vimconn.vimconnNotSupportedException(
                    "OpenStack VIM connector can only have "
                    "1 egress port per SFI")
            sfi_dict = {'name': name,
                        'ingress': ingress_ports[0],
                        'egress': egress_ports[0],
                        'service_function_parameters': {
                            'correlation': correlation}}
            new_sfi = self.neutron.create_sfc_port_pair({'port_pair': sfi_dict})
            return new_sfi['port_pair']['id']
        except (neExceptions.ConnectionFailed, ksExceptions.ClientException,
                neExceptions.NeutronException, ConnectionError) as e:
            if new_sfi:
                try:
                    self.neutron.delete_sfc_port_pair(
                        new_sfi['port_pair']['id'])
                except Exception:
                    self.logger.error(
                        'Creation of Service Function Instance failed, with '
                        'subsequent deletion failure as well.')
            self._format_exception(e)

    def get_sfi(self, sfi_id):
        self.logger.debug(
            'Getting Service Function Instance %s from VIM', sfi_id)
        filter_dict = {"id": sfi_id}
        sfi_list = self.get_sfi_list(filter_dict)
        if len(sfi_list) == 0:
            raise vimconn.vimconnNotFoundException(
                "Service Function Instance '{}' not found".format(sfi_id))
        elif len(sfi_list) > 1:
            raise vimconn.vimconnConflictException(
                'Found more than one Service Function Instance '
                'with this criteria')
        sfi = sfi_list[0]
        return sfi

    def get_sfi_list(self, filter_dict={}):
        self.logger.debug("Getting Service Function Instances from "
                          "VIM filter: '%s'", str(filter_dict))
        try:
            self._reload_connection()
            filter_dict_os = filter_dict.copy()
            if self.api_version3 and "tenant_id" in filter_dict_os:
                filter_dict_os['project_id'] = filter_dict_os.pop('tenant_id')
            sfi_dict = self.neutron.list_sfc_port_pairs(**filter_dict_os)
            sfi_list = sfi_dict["port_pairs"]
            self.__sfi_os2mano(sfi_list)
            return sfi_list
        except (neExceptions.ConnectionFailed, ksExceptions.ClientException,
                neExceptions.NeutronException, ConnectionError) as e:
            self._format_exception(e)

    def delete_sfi(self, sfi_id):
        self.logger.debug("Deleting Service Function Instance '%s' "
                          "from VIM", sfi_id)
        try:
            self._reload_connection()
            self.neutron.delete_sfc_port_pair(sfi_id)
            return sfi_id
        except (neExceptions.ConnectionFailed, neExceptions.NeutronException,
                ksExceptions.ClientException, neExceptions.NeutronException,
                ConnectionError) as e:
            self._format_exception(e)

    def new_sf(self, name, sfis, sfc_encap=True):
        self.logger.debug("Adding a new Service Function to VIM, "
                          "named '%s'", name)
        try:
            new_sf = None
            self._reload_connection()
            correlation = None
            if sfc_encap:
                correlation = 'nsh'
            for instance in sfis:
                sfi = self.get_sfi(instance)
                if sfi.get('sfc_encap') != sfc_encap:
                    raise vimconn.vimconnNotSupportedException(
                        "OpenStack VIM connector requires all SFIs of the "
                        "same SF to share the same SFC Encapsulation")
            sf_dict = {'name': name,
                       'port_pairs': sfis}
            new_sf = self.neutron.create_sfc_port_pair_group({
                'port_pair_group': sf_dict})
            return new_sf['port_pair_group']['id']
        except (neExceptions.ConnectionFailed, ksExceptions.ClientException,
                neExceptions.NeutronException, ConnectionError) as e:
            if new_sf:
                try:
                    self.neutron.delete_sfc_port_pair_group(
                        new_sf['port_pair_group']['id'])
                except Exception:
                    self.logger.error(
                        'Creation of Service Function failed, with '
                        'subsequent deletion failure as well.')
            self._format_exception(e)

    def get_sf(self, sf_id):
        self.logger.debug("Getting Service Function %s from VIM", sf_id)
        filter_dict = {"id": sf_id}
        sf_list = self.get_sf_list(filter_dict)
        if len(sf_list) == 0:
            raise vimconn.vimconnNotFoundException(
                "Service Function '{}' not found".format(sf_id))
        elif len(sf_list) > 1:
            raise vimconn.vimconnConflictException(
                "Found more than one Service Function with this criteria")
        sf = sf_list[0]
        return sf

    def get_sf_list(self, filter_dict={}):
        self.logger.debug("Getting Service Function from VIM filter: '%s'",
                          str(filter_dict))
        try:
            self._reload_connection()
            filter_dict_os = filter_dict.copy()
            if self.api_version3 and "tenant_id" in filter_dict_os:
                filter_dict_os['project_id'] = filter_dict_os.pop('tenant_id')
            sf_dict = self.neutron.list_sfc_port_pair_groups(**filter_dict_os)
            sf_list = sf_dict["port_pair_groups"]
            self.__sf_os2mano(sf_list)
            return sf_list
        except (neExceptions.ConnectionFailed, ksExceptions.ClientException,
                neExceptions.NeutronException, ConnectionError) as e:
            self._format_exception(e)

    def delete_sf(self, sf_id):
        self.logger.debug("Deleting Service Function '%s' from VIM", sf_id)
        try:
            self._reload_connection()
            self.neutron.delete_sfc_port_pair_group(sf_id)
            return sf_id
        except (neExceptions.ConnectionFailed, neExceptions.NeutronException,
                ksExceptions.ClientException, neExceptions.NeutronException,
                ConnectionError) as e:
            self._format_exception(e)

    def new_sfp(self, name, classifications, sfs, sfc_encap=True, spi=None):
        self.logger.debug("Adding a new Service Function Path to VIM, "
                          "named '%s'", name)
        try:
            new_sfp = None
            self._reload_connection()
            # In networking-sfc the MPLS encapsulation is legacy
            # should be used when no full SFC Encapsulation is intended
            sfc_encap = 'mpls'
            if sfc_encap:
                correlation = 'nsh'
            sfp_dict = {'name': name,
                        'flow_classifiers': classifications,
                        'port_pair_groups': sfs,
                        'chain_parameters': {'correlation': correlation}}
            if spi:
                sfp_dict['chain_id'] = spi
            new_sfp = self.neutron.create_sfc_port_chain({'port_chain': sfp_dict})
            return new_sfp["port_chain"]["id"]
        except (neExceptions.ConnectionFailed, ksExceptions.ClientException,
                neExceptions.NeutronException, ConnectionError) as e:
            if new_sfp:
                try:
                    self.neutron.delete_sfc_port_chain(new_sfp['port_chain']['id'])
                except Exception:
                    self.logger.error(
                        'Creation of Service Function Path failed, with '
                        'subsequent deletion failure as well.')
            self._format_exception(e)

    def get_sfp(self, sfp_id):
        self.logger.debug(" Getting Service Function Path %s from VIM", sfp_id)
        filter_dict = {"id": sfp_id}
        sfp_list = self.get_sfp_list(filter_dict)
        if len(sfp_list) == 0:
            raise vimconn.vimconnNotFoundException(
                "Service Function Path '{}' not found".format(sfp_id))
        elif len(sfp_list) > 1:
            raise vimconn.vimconnConflictException(
                "Found more than one Service Function Path with this criteria")
        sfp = sfp_list[0]
        return sfp

    def get_sfp_list(self, filter_dict={}):
        self.logger.debug("Getting Service Function Paths from VIM filter: "
                          "'%s'", str(filter_dict))
        try:
            self._reload_connection()
            filter_dict_os = filter_dict.copy()
            if self.api_version3 and "tenant_id" in filter_dict_os:
                filter_dict_os['project_id'] = filter_dict_os.pop('tenant_id')
            sfp_dict = self.neutron.list_sfc_port_chains(**filter_dict_os)
            sfp_list = sfp_dict["port_chains"]
            self.__sfp_os2mano(sfp_list)
            return sfp_list
        except (neExceptions.ConnectionFailed, ksExceptions.ClientException,
                neExceptions.NeutronException, ConnectionError) as e:
            self._format_exception(e)

    def delete_sfp(self, sfp_id):
        self.logger.debug(
            "Deleting Service Function Path '%s' from VIM", sfp_id)
        try:
            self._reload_connection()
            self.neutron.delete_sfc_port_chain(sfp_id)
            return sfp_id
        except (neExceptions.ConnectionFailed, neExceptions.NeutronException,
                ksExceptions.ClientException, neExceptions.NeutronException,
                ConnectionError) as e:
            self._format_exception(e)
