#!/usr/bin/env python
# -*- coding: utf-8 -*-

##
# Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U.
# This file is part of openvim
# 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
##

"""
This is the thread for the http server North API. 
Two thread will be launched, with normal and administrative permissions.
"""

import threading
import yaml
import vim_db
import logging
# import imp
import os.path
import argparse
from netaddr import IPNetwork
from jsonschema import validate as js_v, exceptions as js_e
import host_thread as ht
import dhcp_thread as dt
import openflow_thread as oft
import openflow_conn

__author__ = "Alfonso Tierno, Leonardo Mirabal"
__date__ = "$06-Feb-2017 12:07:15$"
__version__ = "0.5.29-r549"
version_date = "Sep 2018"
database_version = 23      #needed database schema version

HTTP_Bad_Request =          400
HTTP_Unauthorized =         401
HTTP_Not_Found =            404
HTTP_Forbidden =            403
HTTP_Method_Not_Allowed =   405
HTTP_Not_Acceptable =       406
HTTP_Request_Timeout =      408
HTTP_Conflict =             409
HTTP_Service_Unavailable =  503
HTTP_Internal_Server_Error= 500


def convert_boolean(data, items):
    '''Check recursively the content of data, and if there is an key contained in items, convert value from string to boolean
    It assumes that bandwidth is well formed
    Attributes:
        'data': dictionary bottle.FormsDict variable to be checked. None or empty is consideted valid
        'items': tuple of keys to convert
    Return:
        None
    '''
    if type(data) is dict:
        for k in data.keys():
            if type(data[k]) is dict or type(data[k]) is tuple or type(data[k]) is list:
                convert_boolean(data[k], items)
            if k in items:
                if type(data[k]) is str:
                    if data[k] == "false":
                        data[k] = False
                    elif data[k] == "true":
                        data[k] = True
    if type(data) is tuple or type(data) is list:
        for k in data:
            if type(k) is dict or type(k) is tuple or type(k) is list:
                convert_boolean(k, items)



class ovimException(Exception):
    def __init__(self, message, http_code=HTTP_Bad_Request):
        self.http_code = http_code
        Exception.__init__(self, message)


class ovim():
    running_info = {} #TODO OVIM move the info of running threads from config_dic to this static variable
    of_module = {}

    def __init__(self, configuration):
        self.config = configuration
        self.logger_name = configuration.get("logger_name", "openvim")
        self.logger = logging.getLogger(self.logger_name)
        self.db = None
        self.db = self._create_database_connection()
        self.of_test_mode = False

    def _create_database_connection(self):
        db = vim_db.vim_db((self.config["network_vlan_range_start"], self.config["network_vlan_range_end"]),
                           self.logger_name + ".db", self.config.get('log_level_db'))
        if db.connect(self.config['db_host'], self.config['db_user'], self.config['db_passwd'],
                      self.config['db_name']) == -1:
            # self.logger.error("Cannot connect to database %s at %s@%s", self.config['db_name'], self.config['db_user'],
            #              self.config['db_host'])
            raise ovimException("Cannot connect to database {} at {}@{}".format(self.config['db_name'],
                                                                                self.config['db_user'],
                                                                                self.config['db_host']) )
        return db

    @staticmethod
    def get_version():
        return __version__

    @staticmethod
    def get_version_date():
        return version_date

    @staticmethod
    def get_database_version():
        return database_version

    @staticmethod
    def _check_dhcp_data_integrity(network):
        """
        Check if all dhcp parameter for anet are valid, if not will be calculated from cidr value
        :param network: list with user nets paramters
        :return:
        """
        if "cidr" in network:
            cidr = network["cidr"]
            ip_tools = IPNetwork(cidr)
            cidr_len = ip_tools.prefixlen
            if cidr_len > 29:
                return False

            ips = IPNetwork(cidr)
            if "dhcp_first_ip" not in network:
                network["dhcp_first_ip"] = str(ips[3])
            if "dhcp_last_ip" not in network:
                network["dhcp_last_ip"] = str(ips[-2])
            if "gateway_ip" not in network:
                network["gateway_ip"] = str(ips[1])

            return True
        else:
            return False

    @staticmethod
    def _check_valid_uuid(uuid):
        id_schema = {"type": "string", "pattern": "^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$"}
        try:
            js_v(uuid, id_schema)
            return True
        except js_e.ValidationError:
            return False

    def start_service(self):
        """
        Start ovim services
        :return:
        """
        global database_version
        # if self.running_info:
        #    return  #TODO service can be checked and rebuild broken threads
        r = self.db.get_db_version()
        db_path = __file__
        db_path = db_path[:db_path.rfind("/")]
        if os.path.exists(db_path + "/database_utils/migrate_vim_db.sh"):
            db_path += "/database_utils"
        else:
            db_path += "/../database_utils"

        if r[0] < 0:
            raise ovimException("DATABASE is not valid. If you think it is corrupted, you can init it with"
                                " '{db_path}/init_vim_db.sh' script".format(db_path=db_path))
        elif r[0] != database_version:
            raise ovimException("DATABASE wrong version '{current}'. Try to upgrade/downgrade to version '{target}'"
                                " with '{db_path}/migrate_vim_db.sh {target}'".format(
                                current=r[0], target=database_version,  db_path=db_path))
        self.logger.critical("Starting ovim server version: '{} {}' database version '{}'".format(
            self.get_version(), self.get_version_date(), self.get_database_version()))
        # create database connection for openflow threads
        self.config["db"] = self._create_database_connection()

        self.of_test_mode = False if self.config['mode'] == 'normal' or self.config['mode'] == "OF only" else True

        # Create one thread for each host
        host_test_mode = True if self.config['mode'] == 'test' or self.config['mode'] == "OF only" else False
        host_develop_mode = True if self.config['mode'] == 'development' else False
        host_develop_bridge_iface = self.config.get('development_bridge', None)

        # get host list from data base before starting threads
        r, hosts = self.db.get_table(SELECT=('name', 'ip_name', 'user', 'uuid', 'hypervisors', 'password', 'keyfile'),
                                     FROM='hosts', WHERE={'status': 'ok'}) #Unikernels extension
        if r < 0:
            raise ovimException("Cannot get hosts from database {}".format(hosts))

        self.config['host_threads'] = {}

        for host in hosts:
            thread = ht.host_thread(name=host['name'], user=host['user'], host=host['ip_name'], db=self.config["db"],
                                    password=host['password'],
                                    keyfile=host.get('keyfile', self.config["host_ssh_keyfile"]),
                                    test=host_test_mode,
                                    image_path=self.config['host_image_path'],
                                    version=self.config['version'], host_id=host['uuid'],
                                    develop_mode=host_develop_mode,
                                    develop_bridge_iface=host_develop_bridge_iface,
                                    hypervisors=host['hypervisors'],  #Unikernels extension
                                    logger_name=self.logger_name + ".host." + host['name'],
                                    debug=self.config.get('log_level_host'))

            try:
                thread.check_connectivity()
            except Exception as e:
                self.logger.critical('Error detected for compute = {} with ip = {}'
                                     .format(host['name'], host['ip_name']))
            thread.start()
            self.config['host_threads'][host['uuid']] = thread

        # precreate interfaces; [bridge:<host_bridge_name>, VLAN used at Host, uuid of network camping in this bridge,
        # speed in Gbit/s

        self.config['dhcp_nets'] = []
        self.config['bridge_nets'] = []
        for bridge, vlan_speed in self.config["bridge_ifaces"].items():
            # skip 'development_bridge'
            if self.config['mode'] == 'development' and self.config['development_bridge'] == bridge:
                continue
            self.config['bridge_nets'].append([bridge, vlan_speed[0], vlan_speed[1], None])

        # check if this bridge is already used (present at database) for a network)
        used_bridge_nets = []
        for brnet in self.config['bridge_nets']:
            r, nets = self.db.get_table(SELECT=('uuid',), FROM='nets', WHERE={'provider': "bridge:" + brnet[0]})
            if r > 0:
                brnet[3] = nets[0]['uuid']
                used_bridge_nets.append(brnet[0])
                if self.config.get("dhcp_server"):
                    if brnet[0] in self.config["dhcp_server"]["bridge_ifaces"]:
                        self.config['dhcp_nets'].append(nets[0]['uuid'])
        if len(used_bridge_nets) > 0:
            self.logger.info("found used bridge nets: " + ",".join(used_bridge_nets))
        # get nets used by dhcp
        if self.config.get("dhcp_server"):
            for net in self.config["dhcp_server"].get("nets", ()):
                r, nets = self.db.get_table(SELECT=('uuid',), FROM='nets', WHERE={'name': net})
                if r > 0:
                    self.config['dhcp_nets'].append(nets[0]['uuid'])

        # OFC default
        self._start_ofc_default_task()

        # OFC per tenant in DB
        self._start_of_db_tasks()

        # create dhcp_server thread
        host_test_mode = True if self.config['mode'] == 'test' or self.config['mode'] == "OF only" else False
        dhcp_params = self.config.get("dhcp_server")
        if dhcp_params:
            thread = dt.dhcp_thread(dhcp_params=dhcp_params, test=host_test_mode, dhcp_nets=self.config["dhcp_nets"],
                                    db=self.config["db"],
                                    logger_name=self.logger_name + ".dhcp",
                                    debug=self.config.get('log_level_of'))
            thread.start()
            self.config['dhcp_thread'] = thread



        # create ovs dhcp thread
        result, content = self.db.get_table(FROM='nets')
        if result < 0:
            self.logger.error("http_get_ports Error %d %s", result, content)
            raise ovimException(str(content), -result)

        for net in content:
            net_type = net['type']
            if net['status'] != "INACTIVE" and (net_type == 'bridge_data' or net_type == 'bridge_man') and \
                    net["provider"][:4] == 'OVS:' and net["enable_dhcp"] == "true":
                try:
                    config_routes = net.get('routes')
                    if config_routes:
                        routes = yaml.safe_load(config_routes)
                    else:
                        routes = None

                    config_dns = net.get('dns')
                    if config_dns:
                        dns = yaml.safe_load(config_dns)
                    else:
                        dns = None

                    links = net.get('links')
                    if links:
                        links = yaml.safe_load(net.get('links'))
                    if net.get('enable_dhcp'):
                        self.launch_dhcp_server(net.get('vlan'),
                                                net.get('dhcp_first_ip'),
                                                net.get('dhcp_last_ip'),
                                                net.get('cidr'),
                                                net.get('gateway_ip'),
                                                dns,
                                                routes)
                    self.launch_link_bridge_to_ovs(net['vlan'], net.get('gateway_ip'), net.get('cidr'), links, routes)
                    if net["status"] == "ERROR":
                        self.db.update_rows("nets", UPDATE={"status": "ACTIVE", "last_error": None},
                                            WHERE={"uuid": net["uuid"]})
                except Exception as e:
                    self.logger.error("Fail at launching dhcp server for net_id='%s' net_name='%s': %s",
                                      net["uuid"], net["name"], str(e))
                    self.db.update_rows("nets", UPDATE={"status": "ERROR",
                                                 "last_error": "Fail at launching dhcp server: " + str(e)},
                                        WHERE={"uuid": net["uuid"]})

    def _start_of_db_tasks(self):
        """
        Start ofc task for existing ofcs in database
        :param db_of:
        :return:
        """
        ofcs = self.get_of_controllers()

        for ofc in ofcs:
            of_conn = self._load_of_module(ofc)
            # create ofc thread per of controller
            self._create_ofc_task(ofc['uuid'], ofc['dpid'], of_conn)

    def _create_ofc_task(self, ofc_uuid, dpid, of_conn):
        """
        Create an ofc thread for handle each sdn controllers
        :param ofc_uuid: sdn controller uuid
        :param dpid:  sdn controller dpid
        :param of_conn: OF_conn module
        :return:
        """
        if 'ofcs_thread' not in self.config and 'ofcs_thread_dpid' not in self.config:
            ofcs_threads = {}
            ofcs_thread_dpid = []
        else:
            ofcs_threads = self.config['ofcs_thread']
            ofcs_thread_dpid = self.config['ofcs_thread_dpid']

        if ofc_uuid not in ofcs_threads:
            ofc_thread = self._create_ofc_thread(of_conn, ofc_uuid)
            if ofc_uuid == "Default":
                self.config['of_thread'] = ofc_thread

            ofcs_threads[ofc_uuid] = ofc_thread
            self.config['ofcs_thread'] = ofcs_threads

            ofcs_thread_dpid.append({dpid: ofc_thread})
            self.config['ofcs_thread_dpid'] = ofcs_thread_dpid

    def _start_ofc_default_task(self):
        """
        Create default ofc thread
        """
        if 'of_controller' not in self.config \
                and 'of_controller_ip' not in self.config \
                and 'of_controller_port' not in self.config \
                and 'of_controller_dpid' not in self.config:
            return

        # OF THREAD
        db_config = {}
        db_config['ip'] = self.config.get('of_controller_ip')
        db_config['port'] = self.config.get('of_controller_port')
        db_config['dpid'] = self.config.get('of_controller_dpid')
        db_config['type'] = self.config.get('of_controller')
        db_config['user'] = self.config.get('of_user')
        db_config['password'] = self.config.get('of_password')

        # create connector to the openflow controller
        # load other parameters starting by of_ from config dict in a temporal dict

        of_conn = self._load_of_module(db_config)
        # create openflow thread
        self._create_ofc_task("Default", db_config['dpid'], of_conn)

    def _load_of_module(self, db_config):
        """
        import python module for each SDN controller supported
        :param db_config: SDN dn information
        :return: Module
        """
        if not db_config:
            raise ovimException("No module found it", HTTP_Internal_Server_Error)

        module_info = None

        try:
            if self.of_test_mode:
                return openflow_conn.OfTestConnector({"name": db_config['type'],
                                                      "dpid": db_config['dpid'],
                                                      "of_debug": self.config['log_level_of']})
            temp_dict = {}

            if db_config:
                temp_dict['of_ip'] = db_config['ip']
                temp_dict['of_port'] = db_config['port']
                temp_dict['of_dpid'] = db_config['dpid']
                temp_dict['of_controller'] = db_config['type']
                temp_dict['of_user'] = db_config.get('user')
                temp_dict['of_password'] = db_config.get('password')

            temp_dict['of_debug'] = self.config['log_level_of']

            if temp_dict['of_controller'] == 'opendaylight':
                module = "ODL"
            else:
                module = temp_dict['of_controller']

            if module not in ovim.of_module:
                try:
                    pkg = __import__("osm_openvim." + module)
                    of_conn_module = getattr(pkg, module)
                    ovim.of_module[module] = of_conn_module
                    self.logger.debug("Module load from {}".format("osm_openvim." + module))
                except Exception as e:
                    self.logger.error("Cannot open openflow controller module of type '%s'", module)
                    raise ovimException("Cannot open openflow controller of type module '{}'"
                                        "Revise it is installed".format(module),
                                        HTTP_Internal_Server_Error)
            else:
                of_conn_module = ovim.of_module[module]
            return of_conn_module.OF_conn(temp_dict)
        except Exception as e:
            self.logger.error("Cannot open the Openflow controller '%s': %s", type(e).__name__, str(e))
            raise ovimException("Cannot open the Openflow controller '{}': '{}'".format(type(e).__name__, str(e)),
                                HTTP_Internal_Server_Error)

    def _create_ofc_thread(self, of_conn, ofc_uuid="Default"):
        """
        Create and launch a of thread
        :return: thread obj
        """
        # create openflow thread

        #if 'of_controller_nets_with_same_vlan' in self.config:
        #    ofc_net_same_vlan = self.config['of_controller_nets_with_same_vlan']
        #else:
        #    ofc_net_same_vlan = False
        ofc_net_same_vlan = False

        thread = oft.openflow_thread(ofc_uuid, of_conn, of_test=self.of_test_mode, db=self.config["db"],
                                     pmp_with_same_vlan=ofc_net_same_vlan,
                                     logger_name=self.logger_name + ".ofc." + ofc_uuid,
                                     debug=self.config.get('log_level_of'))
        #r, c = thread.OF_connector.obtain_port_correspondence()
        #if r < 0:
        #    raise ovimException("Cannot get openflow information %s", c)
        thread.start()
        return thread

    def stop_service(self):
        threads = self.config.get('host_threads', {})
        if 'of_thread' in self.config:
            threads['of'] = (self.config['of_thread'])
        if 'ofcs_thread' in self.config:
            ofcs_thread = self.config['ofcs_thread']
            for ofc in ofcs_thread:
                threads[ofc] = ofcs_thread[ofc]

        if 'dhcp_thread' in self.config:
            threads['dhcp'] = (self.config['dhcp_thread'])

        for thread_id, thread in threads.items():
            if thread_id == 'openvim_controller':
                continue
            thread.insert_task("exit")
        for thread_id, thread in threads.items():
            if thread_id == 'openvim_controller':
                continue
            thread.join()

    def get_networks(self, columns=None, db_filter={}, limit=None):
        """
        Retreive networks available
        :param columns: List with select query parameters
        :param db_filter: List with where query parameters
        :param limit: Query limit result
        :return:
        """
        result, content = self.db.get_table(SELECT=columns, FROM='nets', WHERE=db_filter, LIMIT=limit)

        if result < 0:
            raise ovimException(str(content), -result)

        convert_boolean(content, ('shared', 'admin_state_up', 'enable_dhcp'))

        return content

    def show_network(self, network_id, db_filter={}, skip_on_not_found=False):
        """
        Get network from DB by id
        :param network_id: net Id
        :param db_filter: List with where query parameters
        :return:
        """
        # obtain data
        if not network_id:
            raise ovimException("Not network id was not found")
        db_filter['uuid'] = network_id

        result, content = self.db.get_table(FROM='nets', WHERE=db_filter, LIMIT=100)

        if result < 0:
            raise ovimException(str(content), -result)
        elif result == 0:
            if skip_on_not_found:
                return
            raise ovimException("show_network network '%s' not found" % network_id, HTTP_Not_Found)
        else:
            convert_boolean(content, ('shared', 'admin_state_up', 'enable_dhcp'))
            # get ports from DB
            result, ports = self.db.get_table(FROM='ports', SELECT=('uuid as port_id',),
                                              WHERE={'net_id': network_id}, LIMIT=100)
            if len(ports) > 0:
                content[0]['ports'] = ports
            convert_boolean(content, ('shared', 'admin_state_up', 'enable_dhcp'))

            result, flows = self.db.get_table(FROM='of_flows', SELECT=('priority', 'vlan_id', 'ingress_port', 'src_mac', 'dst_mac', 'actions'),
                                              WHERE={'net_id': network_id}, LIMIT=100)
            if len(flows) > 0:
                content[0]['flows'] = flows
            return content[0]

    def new_network(self, network):
        """
        Create a net in DB
        :return:
        """
        tenant_id = network.get('tenant_id')

        if tenant_id:
            result, _ = self.db.get_table(FROM='tenants', SELECT=('uuid',), WHERE={'uuid': tenant_id, "enabled": True})
            if result <= 0:
                raise ovimException("set_network error, no tenant found", -result)

        bridge_net = None
        # check valid params
        net_provider = network.get('provider')
        net_type = network.get('type')
        net_vlan = network.get("vlan")
        net_bind_net = network.get("bind_net")
        net_bind_type = network.get("bind_type")
        net_region = network.get("region")
        name = network["name"]

        # check if network name ends with :<vlan_tag> and network exist in order to make and automated bindning
        vlan_index = name.rfind(":")
        if not net_bind_net and not net_bind_type and vlan_index > 1:
            try:
                vlan_tag = int(name[vlan_index + 1:])
                if not vlan_tag and vlan_tag < 4096:
                    net_bind_net = name[:vlan_index]
                    net_bind_type = "vlan:" + name[vlan_index + 1:]
            except:
                pass

        if net_bind_net:
            # look for a valid net
            if self._check_valid_uuid(net_bind_net):
                net_bind_key = "uuid"
            else:
                net_bind_key = "name"
            result, content = self.db.get_table(FROM='nets', WHERE={net_bind_key: net_bind_net})
            if result < 0:
                raise ovimException(' getting nets from db ' + content, HTTP_Internal_Server_Error)
            elif result == 0:
                raise ovimException(" bind_net %s '%s'not found" % (net_bind_key, net_bind_net), HTTP_Bad_Request)
            elif result > 1:
                raise ovimException(" more than one bind_net %s '%s' found, use uuid" % (net_bind_key, net_bind_net), HTTP_Bad_Request)
            network["bind_net"] = content[0]["uuid"]

        if net_bind_type:
            if net_bind_type[0:5] != "vlan:":
                raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>'", HTTP_Bad_Request)
            if int(net_bind_type[5:]) > 4095 or int(net_bind_type[5:]) <= 0:
                raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>' with a tag between 1 and 4095",
                                    HTTP_Bad_Request)
            network["bind_type"] = net_bind_type

        if net_provider:
            if net_provider[:9] == "openflow:":
                if net_type:
                    if net_type != "ptp" and net_type != "data":
                        raise ovimException(" only 'ptp' or 'data' net types can be bound to 'openflow'",
                                            HTTP_Bad_Request)
                else:
                    net_type = 'data'
            else:
                if net_type:
                    if net_type != "bridge_man" and net_type != "bridge_data":
                        raise ovimException("Only 'bridge_man' or 'bridge_data' net types can be bound "
                                            "to 'bridge', 'macvtap' or 'default", HTTP_Bad_Request)
                else:
                    net_type = 'bridge_man'

        if not net_type:
            net_type = 'bridge_man'

        if net_provider:
            if net_provider[:7] == 'bridge:':
                # check it is one of the pre-provisioned bridges
                bridge_net_name = net_provider[7:]
                for brnet in self.config['bridge_nets']:
                    if brnet[0] == bridge_net_name:  # free
                        if brnet[3]:
                            raise ovimException("invalid 'provider:physical', "
                                                "bridge '%s' is already used" % bridge_net_name, HTTP_Conflict)
                        bridge_net = brnet
                        net_vlan = brnet[1]
                        break
                        # if bridge_net==None:
                        #    bottle.abort(HTTP_Bad_Request, "invalid 'provider:physical', bridge '%s' is not one of the
                        #                    provisioned 'bridge_ifaces' in the configuration file" % bridge_net_name)
                        #    return

        elif self.config['network_type'] == 'bridge' and (net_type == 'bridge_data' or net_type == 'bridge_man'):
            # look for a free precreated nets
            for brnet in self.config['bridge_nets']:
                if not brnet[3]:  # free
                    if not bridge_net:
                        if net_type == 'bridge_man':  # look for the smaller speed
                            if brnet[2] < bridge_net[2]:
                                bridge_net = brnet
                        else:  # look for the larger speed
                            if brnet[2] > bridge_net[2]:
                                bridge_net = brnet
                    else:
                        bridge_net = brnet
                        net_vlan = brnet[1]
            if not bridge_net:
                raise ovimException("Max limits of bridge networks reached. Future versions of VIM "
                                    "will overcome this limit", HTTP_Bad_Request)
            else:
                self.logger.debug("using net " + bridge_net)
                net_provider = "bridge:" + bridge_net[0]
                net_vlan = bridge_net[1]
        elif net_type == 'bridge_data' or net_type == 'bridge_man' and self.config['network_type'] == 'ovs':
            net_provider = 'OVS'
        if not net_region:
            if net_type == "data" or net_type == "ptp":
                net_region = "__DATA__"
            elif net_provider == "OVS":
                net_region = "__OVS__"
        if not net_vlan and (net_type == "data" or net_type == "ptp" or net_provider == "OVS"):
            net_vlan = self.db.get_free_net_vlan(net_region)
            if net_vlan < 0:
                raise ovimException("Error getting an available vlan", HTTP_Internal_Server_Error)
        if net_provider == 'OVS':
            net_provider = 'OVS' + ":" + str(net_vlan)

        network['provider'] = net_provider
        network['type'] = net_type
        network['vlan'] = net_vlan
        network['region'] = net_region
        dhcp_integrity = True
        if network.get('enable_dhcp'):
            dhcp_integrity = self._check_dhcp_data_integrity(network)
        
        if network.get('links'):
            network['links'] = yaml.safe_dump(network['links'], default_flow_style=True, width=256)
        if network.get('dns'):
            network['dns'] = yaml.safe_dump(network['dns'], default_flow_style=True, width=256)
        if network.get('routes'):
            network['routes'] = yaml.safe_dump(network['routes'], default_flow_style=True, width=256)

        result, content = self.db.new_row('nets', network, True, True)
        if result >= 0:  # and dhcp_integrity:
            if bridge_net:
                bridge_net[3] = content
            if self.config.get("dhcp_server") and self.config['network_type'] == 'bridge':
                if network["name"] in self.config["dhcp_server"].get("nets", ()):
                    self.config["dhcp_nets"].append(content)
                    self.logger.debug("dhcp_server: add new net", content)
                elif bridge_net and bridge_net[0] in self.config["dhcp_server"].get("bridge_ifaces", ()):
                    self.config["dhcp_nets"].append(content)
                    self.logger.debug("dhcp_server: add new net", content, content)
            return content
        else:
            raise ovimException("Error creating network: {}".format(content), -result)

# TODO kei change update->edit

    def edit_network(self, network_id, network):
        """
        Update entwork data byt id
        :return:
        """
        # Look for the previous data
        where_ = {'uuid': network_id}
        result, network_old = self.db.get_table(FROM='nets', WHERE=where_)
        if result < 0:
            raise ovimException("Error updating network %s" % network_old, HTTP_Internal_Server_Error)
        elif result == 0:
            raise ovimException('network %s not found' % network_id, HTTP_Not_Found)
        # get ports
        nbports, content = self.db.get_table(FROM='ports', SELECT=('uuid as port_id',),
                                             WHERE={'net_id': network_id}, LIMIT=100)
        if result < 0:
            raise ovimException("http_put_network_id error %d %s" % (result, network_old), HTTP_Internal_Server_Error)
        if nbports > 0:
            if 'type' in network and network['type'] != network_old[0]['type']:
                raise ovimException("Can not change type of network while having ports attached",
                                    HTTP_Method_Not_Allowed)
            if 'vlan' in network and network['vlan'] != network_old[0]['vlan']:
                raise ovimException("Can not change vlan of network while having ports attached",
                                    HTTP_Method_Not_Allowed)

        # check valid params
        net_provider = network.get('provider', network_old[0]['provider'])
        net_type = network.get('type', network_old[0]['type'])
        net_bind_net = network.get("bind_net")
        net_bind_type = network.get("bind_type")
        if net_bind_net:
            # look for a valid net
            if self._check_valid_uuid(net_bind_net):
                net_bind_key = "uuid"
            else:
                net_bind_key = "name"
            result, content = self.db.get_table(FROM='nets', WHERE={net_bind_key: net_bind_net})
            if result < 0:
                raise ovimException('Getting nets from db ' + content, HTTP_Internal_Server_Error)
            elif result == 0:
                raise ovimException("bind_net %s '%s'not found" % (net_bind_key, net_bind_net), HTTP_Bad_Request)
            elif result > 1:
                raise ovimException("More than one bind_net %s '%s' found, use uuid" % (net_bind_key, net_bind_net),
                                    HTTP_Bad_Request)
            network["bind_net"] = content[0]["uuid"]
        if net_bind_type:
            if net_bind_type[0:5] != "vlan:":
                raise ovimException("Bad format for 'bind_type', must be 'vlan:<tag>'", HTTP_Bad_Request)
            if int(net_bind_type[5:]) > 4095 or int(net_bind_type[5:]) <= 0:
                raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>' with a tag between 1 and 4095",
                                    HTTP_Bad_Request)
        if net_provider:
            if net_provider[:9] == "openflow:":
                if net_type != "ptp" and net_type != "data":
                    raise ovimException("Only 'ptp' or 'data' net types can be bound to 'openflow'", HTTP_Bad_Request)
            else:
                if net_type != "bridge_man" and net_type != "bridge_data":
                    raise ovimException("Only 'bridge_man' or 'bridge_data' net types can be bound to "
                                        "'bridge', 'macvtap' or 'default", HTTP_Bad_Request)

        # insert in data base
        result, content = self.db.update_rows('nets', network, WHERE={'uuid': network_id}, log=True)
        if result >= 0:
            # if result > 0 and nbports>0 and 'admin_state_up' in network
            #     and network['admin_state_up'] != network_old[0]['admin_state_up']:
            if result > 0:

                try:
                    if nbports:
                        self.net_update_ofc_thread(network_id)
                except ovimException as e:
                    raise ovimException("Error while launching openflow rules in network '{}' {}"
                                        .format(network_id, str(e)), HTTP_Internal_Server_Error)
                except Exception as e:
                    raise ovimException("Error while launching openflow rules in network '{}' {}"
                                        .format(network_id, str(e)), HTTP_Internal_Server_Error)

                if self.config.get("dhcp_server"):
                    if network_id in self.config["dhcp_nets"]:
                        self.config["dhcp_nets"].remove(network_id)
                    if network.get("name", network_old[0]["name"]) in self.config["dhcp_server"].get("nets", ()):
                        self.config["dhcp_nets"].append(network_id)
                    else:
                        net_bind = network.get("bind_type", network_old[0]["bind_type"])
                        if net_bind and net_bind and net_bind[:7] == "bridge:" and net_bind[7:] in self.config["dhcp_server"].get(
                                "bridge_ifaces", ()):
                            self.config["dhcp_nets"].append(network_id)
            return network_id
        else:
            raise ovimException(content, -result)

    def delete_network(self, network_id, idempotent=True):
        """
        Delete network by network id
        :param network_id:  network id
        :return:
        """
        net_data = self.show_network(network_id, skip_on_not_found=idempotent)
        if not net_data:  # network does not exist
            return

        # delete from the data base
        result, content = self.db.delete_row('nets', network_id)

        if result == 0:
            raise ovimException("Network %s not found " % network_id, HTTP_Not_Found)
        elif result > 0:
            for brnet in self.config['bridge_nets']:
                if brnet[3] == network_id:
                    brnet[3] = None
                    break
            if self.config.get("dhcp_server") and network_id in self.config["dhcp_nets"]:
                self.config["dhcp_nets"].remove(network_id)

            if net_data.get('enable_dhcp'):
                dhcp_path = self.config['ovs_controller_file_path']
                dhcp_controller = self.get_dhcp_controller()
                dhcp_controller.delete_dhcp_server(net_data['vlan'], network_id, dhcp_path)
                dhcp_controller.delete_dhcp_port(net_data['vlan'], network_id, dhcp_path)
                links = yaml.load(net_data.get('links'))
                if links:
                    links = yaml.load(net_data.get('links'))
                    self.delete_link_bridge_to_ovs(net_data['vlan'], links)

                return content
        else:
            raise ovimException("Error deleting network '{}': {}".format(network_id, content), -result)

    def get_openflow_rules(self, network_id=None):
        """
        Get openflow id from DB
        :param network_id: Network id, if none all networks will be retrieved
        :return: Return a list with Openflow rules per net
        """
        # ignore input data
        if not network_id:
            where_ = {}
        else:
            where_ = {"net_id": network_id}
        result, content = self.db.get_table(
            SELECT=("name", "net_id", "ofc_id", "priority", "vlan_id", "ingress_port", "src_mac", "dst_mac", "actions"),
            WHERE=where_, FROM='of_flows')

        if result < 0:
            raise ovimException(str(content), -result)
        return content

    def edit_openflow_rules(self, network_id=None):

        """
        To make actions over the net. The action is to reinstall the openflow rules
        network_id can be 'all'
        :param network_id: Network id, if none all networks will be retrieved
        :return : Number of nets updated
        """

        # ignore input data
        if not network_id:
            where_ = {}
        else:
            where_ = {"uuid": network_id}
        result, content = self.db.get_table(SELECT=("uuid", "type"), WHERE=where_, FROM='nets')

        if result < 0:
            raise ovimException(str(content), -result)

        for net in content:
            if net["type"] != "ptp" and net["type"] != "data":
                result -= 1
                continue

            try:
                self.net_update_ofc_thread(net['uuid'])
            except ovimException as e:
                raise ovimException("Error updating network'{}' {}".format(net['uuid'], str(e)),
                                    HTTP_Internal_Server_Error)
            except Exception as e:
                raise ovimException("Error updating network '{}' {}".format(net['uuid'], str(e)),
                                    HTTP_Internal_Server_Error)

        return result

    def delete_openflow_rules(self, ofc_id=None):
        """
        To make actions over the net. The action is to delete ALL openflow rules
        :return: return operation result
        """

        if not ofc_id:
            if 'Default' in self.config['ofcs_thread']:
                r, c = self.config['ofcs_thread']['Default'].insert_task("clear-all")
            else:
                raise ovimException("Default Openflow controller not not running", HTTP_Not_Found)

        elif ofc_id in self.config['ofcs_thread']:
            r, c = self.config['ofcs_thread'][ofc_id].insert_task("clear-all")

            # ignore input data
            if r < 0:
                raise ovimException(str(c), -r)
        else:
            raise ovimException("Openflow controller not found with ofc_id={}".format(ofc_id), HTTP_Not_Found)
        return r

    def get_openflow_ports(self, ofc_id=None):
        """
        Obtain switch ports names of openflow controller
        :return: Return flow ports in DB
        """
        if not ofc_id:
            if 'Default' in self.config['ofcs_thread']:
                conn = self.config['ofcs_thread']['Default'].OF_connector
            else:
                raise ovimException("Default Openflow controller not not running", HTTP_Not_Found)

        elif ofc_id in self.config['ofcs_thread']:
            conn = self.config['ofcs_thread'][ofc_id].OF_connector
        else:
            raise ovimException("Openflow controller not found with ofc_id={}".format(ofc_id), HTTP_Not_Found)
        return conn.pp2ofi

    def get_ports(self, columns=None, filter={}, limit=None):
        # result, content = my.db.get_ports(where_)
        result, content = self.db.get_table(SELECT=columns, WHERE=filter, FROM='ports', LIMIT=limit)
        if result < 0:
            self.logger.error("http_get_ports Error %d %s", result, content)
            raise ovimException(str(content), -result)
        else:
            convert_boolean(content, ('admin_state_up',))
            return content

    def new_port(self, port_data):
        port_data['type'] = 'external'
        if port_data.get('net_id'):
            # check that new net has the correct type
            result, new_net = self.db.check_target_net(port_data['net_id'], None, 'external')
            if result < 0:
                raise ovimException(str(new_net), -result)
        # insert in data base
        result, uuid = self.db.new_row('ports', port_data, True, True)
        if result > 0:
            if 'net_id' in port_data:
                try:
                    self.net_update_ofc_thread(port_data['net_id'])
                except ovimException as e:
                    raise ovimException("Cannot insert a task for updating network '{}' {}"
                                        .format(port_data['net_id'], str(e)), HTTP_Internal_Server_Error)
                except Exception as e:
                    raise ovimException("Cannot insert a task for updating network '{}' {}"
                                        .format(port_data['net_id'], str(e)), HTTP_Internal_Server_Error)

            return uuid
        else:
            raise ovimException(str(uuid), -result)

    def new_external_port(self, port_data):
        """
        Create new external port and check port mapping correspondence
        :param port_data: port_data = {
            'region': 'datacenter region',
            'compute_node': 'compute node id',
            'pci': 'pci port address',
            'vlan': 'net vlan',
            'net_id': 'net id',
            'tenant_id': 'tenant id',
            'mac': 'switch mac',
            'name': 'port name'
            'ip_address': 'ip address - optional'}
        :return:
        """

        port_data['type'] = 'external'

        if port_data.get('net_id'):
            # check that new net has the correct type
            result, new_net = self.db.check_target_net(port_data['net_id'], None, 'external')
            if result < 0:
                raise ovimException(str(new_net), -result)
        # insert in data base
        db_filter = {}

        if port_data.get('region'):
            db_filter['region'] = port_data['region']
        if port_data.get('pci'):
            db_filter['pci'] = port_data['pci']
        if port_data.get('compute_node'):
            db_filter['compute_node'] = port_data['compute_node']

        columns = ['ofc_id', 'switch_dpid', 'switch_port', 'switch_mac', 'pci']
        port_mapping_data = self.get_of_port_mappings(columns, db_filter)

        if not len(port_mapping_data):
            raise ovimException("No port mapping found for '{}'".format(str(db_filter)),
                                HTTP_Not_Found)
        elif len(port_mapping_data) > 1:
            raise ovimException("Wrong port data was given, please check pci, region & compute id data",
                                HTTP_Conflict)

        port_data['ofc_id'] = port_mapping_data[0]['ofc_id']
        port_data['switch_dpid'] = port_mapping_data[0]['switch_dpid']
        port_data['switch_port'] = port_mapping_data[0]['switch_port']
        port_data['switch_mac'] = port_mapping_data[0]['switch_mac']

        # remove from compute_node, region and pci of_port_data to adapt to 'ports' structure
        if 'region' in port_data:
            del port_data['region']
        if 'pci' in port_data:
            del port_data['pci']
        if 'compute_node' in port_data:
            del port_data['compute_node']

        result, uuid = self.db.new_row('ports', port_data, True, True)
        # set net status to BUILD
        self.db.update_rows('nets', {"status": "BUILD"}, WHERE={'uuid': port_data['net_id']})
        if result > 0:
            try:
                self.net_update_ofc_thread(port_data['net_id'], port_data['ofc_id'])
            except ovimException as e:
                raise ovimException("Cannot insert a task for updating network '{}' {}".
                                    format(port_data['net_id'], str(e)), HTTP_Internal_Server_Error)
            except Exception as e:
                raise ovimException("Cannot insert a task for updating network '{}' {}"
                                    .format(port_data['net_id'], e), HTTP_Internal_Server_Error)
            return uuid
        else:
            raise ovimException(str(uuid), -result)

    def net_update_ofc_thread(self, net_id, ofc_id=None, switch_dpid=None):
        """
        Insert a update net task by net id or ofc_id for each ofc thread
        :param net_id: network id
        :param ofc_id: openflow controller id
        :param switch_dpid: switch dpid
        :return:
        """
        if not net_id:
            raise ovimException("No net_id received", HTTP_Internal_Server_Error)

        r = -1
        c = 'No valid ofc_id or switch_dpid received'

        if not ofc_id:
            ports = self.get_ports(filter={"net_id": net_id})
            for port in ports:
                port_ofc_id = port.get('ofc_id', None)
                if port_ofc_id:
                    ofc_id = port['ofc_id']
                    switch_dpid = port['switch_dpid']
                    break
        #TODO if not ofc_id: look at database table ofcs


        # If no ofc_id found it, default ofc_id is used.
        if not ofc_id and not switch_dpid:
            ofc_id = "Default"

        if ofc_id and ofc_id in self.config['ofcs_thread']:
            r, c = self.config['ofcs_thread'][ofc_id].insert_task("update-net", net_id)
        elif switch_dpid:

            ofcs_dpid_list = self.config['ofcs_thread_dpid']
            for ofc_t in ofcs_dpid_list:
                if switch_dpid in ofc_t:
                    r, c = ofc_t[switch_dpid].insert_task("update-net", net_id)

        if r < 0:
            message = "Cannot insert a task for updating network '{}', {}".format(net_id, c)
            self.logger.error(message)
            raise ovimException(message, HTTP_Internal_Server_Error)

    def delete_port(self, port_id, idempotent=False):
        # Look for the previous port data
        result, ports = self.db.get_table(WHERE={'uuid': port_id, "type": "external"}, FROM='ports')
        if result < 0:
            raise ovimException("Cannot get port info from database: {}".format(ports), http_code=-result)
        # delete from the data base
        result, content = self.db.delete_row('ports', port_id)
        if result == 0:
            if idempotent:
                return
            raise ovimException("External port '{}' not found".format(port_id), http_code=HTTP_Not_Found)
        elif result < 0:
            raise ovimException("Cannot delete port from database: {}".format(content), http_code=-result)
        # update network
        net_id = ports[0].get('net_id', None)
        if net_id:
            # change of net.

            # set net status to BUILD
            self.db.update_rows('nets', {"status": "BUILD"}, WHERE={'uuid': net_id})
            try:
                self.net_update_ofc_thread(net_id, ofc_id=ports[0]["ofc_id"], switch_dpid=ports[0]["switch_dpid"])
            except ovimException as e:
                raise ovimException("Cannot insert a task for delete network '{}' {}".format(net_id, str(e)),
                                    HTTP_Internal_Server_Error)
            except Exception as e:
                raise ovimException("Cannot insert a task for delete network '{}' {}".format(net_id, str(e)),
                                    HTTP_Internal_Server_Error)

        return content

    def edit_port(self, port_id, port_data, admin=True):
        # Look for the previous port data
        result, content = self.db.get_table(FROM="ports", WHERE={'uuid': port_id})
        if result < 0:
            raise ovimException("Cannot get port info from database: {}".format(content), http_code=-result)
        elif result == 0:
            raise ovimException("Port '{}' not found".format(port_id), http_code=HTTP_Not_Found)
        port = content[0]
        nets = []
        host_id = None
        result = 1
        if 'net_id' in port_data:
            # change of net.
            old_net = port.get('net_id', None)
            new_net = port_data['net_id']
            if old_net != new_net:

                if new_net:
                    nets.append(new_net)  # put first the new net, so that new openflow rules are created before removing the old ones
                if old_net:
                    nets.append(old_net)
                if port['type'] == 'instance:bridge' or port['type'] == 'instance:ovs':
                    raise ovimException("bridge interfaces cannot be attached to a different net", http_code=HTTP_Forbidden)
                elif port['type'] == 'external' and not admin:
                    raise ovimException("Needed admin privileges",http_code=HTTP_Unauthorized)
                if new_net:
                    # check that new net has the correct type
                    result, new_net_dict = self.db.check_target_net(new_net, None, port['type'])
                    if result < 0:
                        raise ovimException("Error {}".format(new_net_dict), http_code=HTTP_Conflict)
                # change VLAN for SR-IOV ports
                if result >= 0 and port["type"] == "instance:data" and port["model"] == "VF":  # TODO consider also VFnotShared
                    if new_net:
                        port_data["vlan"] = None
                    else:
                        port_data["vlan"] = new_net_dict["vlan"]
                    # get host where this VM is allocated
                    result, content = self.db.get_table(FROM="instances", WHERE={"uuid": port["instance_id"]})
                    if result > 0:
                        host_id = content[0]["host_id"]

        # insert in data base
        if result >= 0:
            result, content = self.db.update_rows('ports', port_data, WHERE={'uuid': port_id}, log=False)
            port.update(port_data)

        # Insert task to complete actions
        if result > 0:
            for net_id in nets:
                try:
                    self.net_update_ofc_thread(net_id, port["ofc_id"], switch_dpid=port["switch_dpid"])
                except ovimException as e:
                    raise ovimException("Error updating network'{}' {}".format(net_id, str(e)),
                                        HTTP_Internal_Server_Error)
                except Exception as e:
                    raise ovimException("Error updating network '{}' {}".format(net_id, str(e)),
                                        HTTP_Internal_Server_Error)

            if host_id:
                r, v = self.config['host_threads'][host_id].insert_task("edit-iface", port_id, old_net, new_net)
                if r < 0:
                    self.logger.error("Error updating network '{}' {}".format(r,v))
                    # TODO Do something if fails
        if result >= 0:
            return port_id
        else:
            raise ovimException("Error {}".format(content), http_code=-result)

    def new_of_controller(self, ofc_data):
        """
        Create a new openflow controller into DB
        :param ofc_data: Dict openflow controller data
        :return: openflow controller dpid
        """

        result, ofc_uuid = self.db.new_row('ofcs', ofc_data, True, True)
        if result < 0:
            raise ovimException("New ofc Error %s" % ofc_uuid, HTTP_Internal_Server_Error)

        ofc_data['uuid'] = ofc_uuid
        of_conn = self._load_of_module(ofc_data)
        self._create_ofc_task(ofc_uuid, ofc_data['dpid'], of_conn)

        return ofc_uuid

    def edit_of_controller(self, of_id, ofc_data):
        """
        Edit an openflow controller entry from DB
        :return:
        """
        if not ofc_data:
            raise ovimException("No data received during uptade OF contorller", http_code=HTTP_Internal_Server_Error)

        old_of_controller = self.show_of_controller(of_id)

        if old_of_controller:
            result, content = self.db.update_rows('ofcs', ofc_data, WHERE={'uuid': of_id}, log=False)
            if result >= 0:
                return ofc_data
            else:
                raise ovimException("Error uptating OF contorller with uuid {}".format(of_id),
                                    http_code=-result)
        else:
            raise ovimException("Error uptating OF contorller with uuid {}".format(of_id),
                                http_code=HTTP_Internal_Server_Error)

    def delete_of_controller(self, of_id):
        """
        Delete an openflow controller from DB.
        :param of_id: openflow controller dpid
        :return:
        """

        ofc = self.show_of_controller(of_id)

        result, content = self.db.delete_row("ofcs", of_id)
        if result < 0:
            raise ovimException("Cannot delete ofc from database: {}".format(content), http_code=-result)
        elif result == 0:
            raise ovimException("ofc {} not found ".format(content), http_code=HTTP_Not_Found)

        ofc_thread = self.config['ofcs_thread'][of_id]
        del self.config['ofcs_thread'][of_id]
        for ofc_th in self.config['ofcs_thread_dpid']:
            if ofc['dpid'] in ofc_th:
                self.config['ofcs_thread_dpid'].remove(ofc_th)

        ofc_thread.insert_task("exit")
        #ofc_thread.join()

        return content

    def show_of_controller(self, uuid):
        """
        Show an openflow controller by dpid from DB.
        :param db_filter: List with where query parameters
        :return:
        """

        result, content = self.db.get_table(FROM='ofcs', WHERE={"uuid": uuid}, LIMIT=100)

        if result == 0:
            raise ovimException("Openflow controller with uuid '{}' not found".format(uuid),
                                http_code=HTTP_Not_Found)
        elif result < 0:
            raise ovimException("Openflow controller with uuid '{}' error".format(uuid),
                                http_code=HTTP_Internal_Server_Error)
        return content[0]

    def get_of_controllers(self, columns=None, db_filter={}, limit=None):
        """
        Show an openflow controllers from DB.
        :param columns:  List with SELECT query parameters
        :param db_filter: List with where query parameters
        :param limit: result Limit
        :return:
        """
        result, content = self.db.get_table(SELECT=columns, FROM='ofcs', WHERE=db_filter, LIMIT=limit)

        if result < 0:
            raise ovimException(str(content), -result)

        return content

    def get_tenants(self, columns=None, db_filter={}, limit=None):
        """
        Retrieve tenant list from DB
        :param columns:  List with SELECT query parameters
        :param db_filter: List with where query parameters
        :param limit: result limit
        :return:
        """
        result, content = self.db.get_table(FROM='tenants', SELECT=columns, WHERE=db_filter, LIMIT=limit)
        if result < 0:
            raise ovimException('get_tenatns Error {}'.format(str(content)), -result)
        else:
            convert_boolean(content, ('enabled',))
            return content

    def show_tenant_id(self, tenant_id):
        """
        Get tenant from DB by id
        :param tenant_id: tenant id
        :return:
        """
        result, content = self.db.get_table(FROM='tenants', SELECT=('uuid', 'name', 'description', 'enabled'),
                                            WHERE={"uuid": tenant_id})
        if result < 0:
            raise ovimException(str(content), -result)
        elif result == 0:
            raise ovimException("tenant with uuid='{}' not found".format(tenant_id), HTTP_Not_Found)
        else:
            convert_boolean(content, ('enabled',))
            return content[0]

    def new_tentant(self, tenant):
        """
        Create a tenant and store in DB
        :param tenant: Dictionary with tenant data
        :return: the uuid of created tenant. Raise exception upon error
        """

        # insert in data base
        result, tenant_uuid = self.db.new_tenant(tenant)

        if result >= 0:
            return tenant_uuid
        else:
            raise ovimException(str(tenant_uuid), -result)

    def delete_tentant(self, tenant_id):
        """
        Delete a tenant from the database.
        :param tenant_id: Tenant id
        :return: delete tenant id
        """

        # check permissions
        r, tenants_flavors = self.db.get_table(FROM='tenants_flavors', SELECT=('flavor_id', 'tenant_id'),
                                               WHERE={'tenant_id': tenant_id})
        if r <= 0:
            tenants_flavors = ()
        r, tenants_images = self.db.get_table(FROM='tenants_images', SELECT=('image_id', 'tenant_id'),
                                              WHERE={'tenant_id': tenant_id})
        if r <= 0:
            tenants_images = ()

        result, content = self.db.delete_row('tenants', tenant_id)
        if result == 0:
            raise ovimException("tenant '%s' not found" % tenant_id, HTTP_Not_Found)
        elif result > 0:
            for flavor in tenants_flavors:
                self.db.delete_row_by_key("flavors", "uuid", flavor['flavor_id'])
            for image in tenants_images:
                self.db.delete_row_by_key("images", "uuid", image['image_id'])
            return content
        else:
            raise ovimException("Error deleting tenant '%s' " % tenant_id, HTTP_Internal_Server_Error)

    def edit_tenant(self, tenant_id, tenant_data):
        """
        Update a tenant data identified by tenant id
        :param tenant_id: tenant id
        :param tenant_data: Dictionary with tenant data
        :return:
        """

        # Look for the previous data
        result, tenant_data_old = self.db.get_table(FROM='tenants', WHERE={'uuid': tenant_id})
        if result < 0:
            raise ovimException("Error updating tenant with uuid='{}': {}".format(tenant_id, tenant_data_old),
                                HTTP_Internal_Server_Error)
        elif result == 0:
            raise ovimException("tenant with uuid='{}' not found".format(tenant_id), HTTP_Not_Found)

        # insert in data base
        result, content = self.db.update_rows('tenants', tenant_data, WHERE={'uuid': tenant_id}, log=True)
        if result >= 0:
            return content
        else:
            raise ovimException(str(content), -result)

    def set_of_port_mapping(self, of_maps, ofc_id=None, switch_dpid=None, region=None):
        """
        Create new port mapping entry
        :param of_maps: List with port mapping information
        # maps =[{"ofc_id": <ofc_id>,"region": datacenter region,"compute_node": compute uuid,"pci": pci adress,
                "switch_dpid": swith dpid,"switch_port": port name,"switch_mac": mac}]
        :param ofc_id: ofc id
        :param switch_dpid: switch  dpid
        :param region: datacenter region id
        :return:
        """

        for map in of_maps:
            if ofc_id:
                map['ofc_id'] = ofc_id
            if switch_dpid:
                map['switch_dpid'] = switch_dpid
            if region:
                map['region'] = region
            if map.get("pci"):
                map["pci"] = map["pci"].lower()

        for of_map in of_maps:
            result, uuid = self.db.new_row('of_port_mappings', of_map, True)
            if result > 0:
                of_map["uuid"] = uuid
            else:
                raise ovimException(str(uuid), -result)
        return of_maps

    def clear_of_port_mapping(self, db_filter={}):
        """
        Clear port mapping filtering using db_filter dict
        :param db_filter: Parameter to filter during remove process
        :return:
        """
        result, content = self.db.delete_row_by_dict(FROM='of_port_mappings', WHERE=db_filter)
        # delete_row_by_key
        if result >= 0:
            return content
        else:
            raise ovimException("Error deleting of_port_mappings with filter='{}'".format(str(db_filter)),
                                HTTP_Internal_Server_Error)

    def get_of_port_mappings(self, column=None, db_filter=None, db_limit=None):
        """
        Retrive port mapping from DB
        :param column:
        :param db_filter:
        :return:
        """
        result, content = self.db.get_table(SELECT=column, WHERE=db_filter, FROM='of_port_mappings', LIMIT=db_limit)

        if result < 0:
            self.logger.error("get_of_port_mappings Error %d %s", result, content)
            raise ovimException(str(content), -result)
        else:
            return content

    def get_dhcp_controller(self):
        """
        Create an host_thread object for manage openvim controller and not create a thread for itself
        :return: dhcp_host openvim controller object
        """

        if 'openvim_controller' in self.config['host_threads']:
            return self.config['host_threads']['openvim_controller']

        bridge_ifaces = []
        controller_ip = self.config['ovs_controller_ip']
        ovs_controller_user = self.config.get('ovs_controller_user')

        host_test_mode = True if self.config['mode'] == 'test' or self.config['mode'] == "OF only" else False
        host_develop_mode = True if self.config['mode'] == 'development' else False

        dhcp_host = ht.host_thread(name='openvim_controller', user=ovs_controller_user, host=controller_ip,
                                   password=self.config.get('ovs_controller_password'),
                                   keyfile=self.config.get('ovs_controller_keyfile'),
                                   db=self.config["db"], test=host_test_mode,
                                   image_path=self.config['host_image_path'], version=self.config['version'],
                                   host_id='openvim_controller', develop_mode=host_develop_mode,
                                   develop_bridge_iface=bridge_ifaces,
                                   logger_name=self.logger_name + ".host.controller",
                                   debug=self.config.get('log_level_host'))
        # dhcp_host.start()
        self.config['host_threads']['openvim_controller'] = dhcp_host
        try:
            dhcp_host.check_connectivity()
        except Exception as e:
           pass

        return dhcp_host

    def launch_dhcp_server(self, vlan, first_ip, last_ip, cidr, gateway, dns, routes):
        """
        Launch a dhcpserver base on dnsmasq attached to the net base on vlan id across the the openvim computes
        :param vlan: vlan identifier
        :param first_ip: First dhcp range ip
        :param last_ip: Last dhcp range ip
        :param cidr: net cidr
        :param gateway: net gateway
        :return:
        """
        ip_tools = IPNetwork(cidr)
        dhcp_netmask = str(ip_tools.netmask)
        ip_range = [first_ip, last_ip]

        dhcp_path = self.config['ovs_controller_file_path']

        controller_host = self.get_dhcp_controller()

        # controller_host.create_linux_bridge(vlan)
        controller_host.create_dhcp_interfaces(vlan, first_ip, dhcp_netmask)
        dhcp_path = self.config['ovs_controller_file_path']
        controller_host.launch_dhcp_server(vlan, ip_range, dhcp_netmask, dhcp_path, gateway, dns, routes)

    def launch_link_bridge_to_ovs(self, vlan, gateway, dhcp_cidr, links=None, routes=None):
        """
        Launch creating of connections (veth) between user bridge (link) and OVS
        :param vlan: 
        :param gateway: 
        :param links: 
        :return: 
        """

        if links:
            controller_host = self.get_dhcp_controller()
            for link in links:
                if 'iface' in link and 'nat' not in link:
                        controller_host.create_link_bridge_to_ovs(vlan, link['iface'])
                elif 'nat' in link:
                    controller_host.create_qrouter_ovs_connection(vlan, gateway, dhcp_cidr)
                    controller_host.create_qrouter_br_connection(vlan, dhcp_cidr, link)

            if len(routes):
                controller_host.add_ns_routes(vlan, routes)

    def delete_link_bridge_to_ovs(self, vlan,  links=None):
        """
        Delete connections (veth) between user bridge (link) and OVS
        :param vlan: 
        :param links: 
        :return: 
        """
        if links:
            controller_host = self.get_dhcp_controller()

            for link in links:
                if 'iface' in link and 'nat' not in link:
                    controller_host.remove_link_bridge_to_ovs(vlan, link['iface'])
                elif 'nat' in link:
                    controller_host.delete_qrouter_connection(vlan,  link['iface'])


if __name__ == "__main__":

    parser = argparse.ArgumentParser()
    parser.add_argument("-v","--version", help="show ovim library version", action="store_true")
    parser.add_argument("--database-version", help="show required database version", action="store_true")
    args = parser.parse_args()
    if args.version:
        print ('openvimd version {} {}'.format(ovim.get_version(), ovim.get_version_date()))
        print ('(c) Copyright Telefonica')
    elif args.database_version:
        print ('required database version: {}'.format(ovim.get_database_version()))

