# -*- 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., Eduardo Sousa"
__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.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)

        if self.config.get("insecure") and self.config.get("ca_cert"):
            raise vimconn.vimconnException("options insecure and ca_cert are mutually exclusive")
        self.verify = True
        if self.config.get("insecure"):
            self.verify = False
        if self.config.get("ca_cert"):
            self.verify = self.config.get("ca_cert")

        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=self.verify)
            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 exception
        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 not ip_profile.get('subnet_address'):
                #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
            if ip_profile.get('gateway_address'):
                subnet['gateway_ip'] = ip_profile['gateway_address']
            else:
                subnet['gateway_ip'] = None
            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" or ip_profile['dhcp_enabled']==False else True
            if ip_profile.get('dhcp_start_address'):
                subnet['allocation_pools'] = []
                subnet['allocation_pools'].append(dict())
                subnet['allocation_pools'][0]['start'] = ip_profile['dhcp_start_address']
            if ip_profile.get('dhcp_count'):
                #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 Exception 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'].endswith(".qcow2"):
                        disk_format="qcow2"
                    elif image_dict['location'].endswith(".vhd"):
                        disk_format="vhd"
                    elif image_dict['location'].endswith(".vmdk"):
                        disk_format="vmdk"
                    elif image_dict['location'].endswith(".vdi"):
                        disk_format="vdi"
                    elif image_dict['location'].endswith(".iso"):
                        disk_format="iso"
                    elif image_dict['location'].endswith(".aki"):
                        disk_format="aki"
                    elif image_dict['location'].endswith(".ari"):
                        disk_format="ari"
                    elif image_dict['location'].endswith(".ami"):
                        disk_format="ami"
                    else:
                        disk_format="raw"
                self.logger.debug("new_image: '%s' loading from '%s'", image_dict['name'], image_dict['location'])
                new_image = self.glance.images.create(name=image_dict['name'])
                if image_dict['location'].startswith("http"):
                    # TODO there is not a method to direct download. It must be downloaded locally with requests
                    raise vimconn.vimconnNotImplemented("Cannot create image from URL")
                else: #local path
                    with open(image_dict['location']) as fimage:
                        self.glance.images.upload(new_image.id, 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)
                metadata_to_load = image_dict.get('metadata')
                #TODO location is a reserved word for current openstack versions. Use another word
                metadata_to_load['location'] = image_dict['location']
                self.glance.images.update(new_image.id, **metadata_to_load)
                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.glance.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.glance.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.
            image_list = self.glance.images.list()
            filtered_list = []
            for image in image_list:
                try:
                    if filter_dict.get("name") and image["name"] != filter_dict["name"]:
                        continue
                    if filter_dict.get("id") and image["id"] != filter_dict["id"]:
                        continue
                    if filter_dict.get("checksum") and image["checksum"] != filter_dict["checksum"]:
                        continue

                    filtered_list.append(image.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(5)
            elapsed_time += 5

        # 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
                'vim_id' (optional) should use this existing volume id
            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"]
                if net.get("ip_address"):
                    port_dict["fixed_ips"] = [{'ip_address': net["ip_address"]}]
                    # TODO add 'subnet_id': <subnet_id>
                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)
                    net['floating_ip'] = self.config.get('use_floating_ip')

                # 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 and not self.config.get("no_port_security_extension"):
                    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:
                block_device_mapping = {}
                for disk in disk_list:
                    if disk.get('vim_id'):
                        block_device_mapping['_vd' + chr(base_disk_index)] = disk['vim_id']
                    else:
                        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 created volumes are with status available
                elapsed_time = 0
                while elapsed_time < volume_timeout:
                    for created_item in created_items:
                        v, _, volume_id = created_item.partition(":")
                        if v == 'volume':
                            if self.cinder.volumes.get(volume_id).status != 'available':
                                break
                    else:  # all ready: break from while
                        break
                    time.sleep(5)
                    elapsed_time += 5
                # 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)

            vm_start_time = time.time()
            # 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:
                    raise vimconn.vimconnException("It was not possible to disable port security for port {}".format(
                        port_id))
            # print "DONE :-)", server

            # pool_id = None
            if external_network:
                floating_ips = self.neutron.list_floatingips().get("floatingips", ())
            for floating_network in external_network:
                try:
                    assigned = False
                    while not assigned:
                        if floating_ips:
                            ip = floating_ips.pop(0)
                            if ip.get("port_id", False) or ip.get('tenant_id') != server.tenant_id:
                                continue
                            if isinstance(floating_network['floating_ip'], str):
                                if ip.get("floating_network_id") != floating_network['floating_ip']:
                                    continue
                            free_floating_ip = ip.get("floating_ip_address")
                        else:
                            if isinstance(floating_network['floating_ip'], str) and \
                                floating_network['floating_ip'].lower() != "true":
                                pool_id = floating_network['floating_ip']
                            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']
                            except Exception as e:
                                raise vimconn.vimconnException(type(e).__name__ + ": Cannot create new floating_ip " +
                                                               str(e), http_code=vimconn.HTTP_Conflict)

                        fix_ip = floating_network.get('ip')
                        while not assigned:
                            try:
                                server.add_floating_ip(free_floating_ip, fix_ip)
                                assigned = True
                            except Exception as e:
                                # openstack need some time after VM creation to asign an IP. So retry if fails
                                vm_status = self.nova.servers.get(server.id).status
                                if vm_status != 'ACTIVE' and vm_status != 'ERROR':
                                    if time.time() - vm_start_time < server_timeout:
                                        time.sleep(5)
                                        continue
                                raise vimconn.vimconnException(
                                    "Cannot create floating_ip: {} {}".format(type(e).__name__, 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
                        try:
                            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") )
                        except Exception:
                            pass

                        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 {}: {}".format(type(e).__name__, e),
                                      exc_info=True)
            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, password=user_passwd, default_project=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
        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
            self.logger.debug("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
        self.logger.debug("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
        self.logger.debug("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)
