# Path: networking_vsphere/_i18n.py
# _LI = _translators.log_info
# 
# Path: networking_vsphere/common/constants.py
# AGENT_TYPE_OVSVAPP = "OVSvApp Agent"
# AGENT_TYPE_DVS = 'DVS agent'
# OVSVAPP = 'ovsvapp'
# DVS = 'dvs'
# OVSVAPP_PLUGIN = 'ovsvapp_service_plugin'
# DEVICE = 'device'
# VMWARE_HYPERVISOR_TYPE = 'VMware vCenter Server'
# PORT_STATUS_UP = 'UP'
# PORT_STATUS_DOWN = 'DOWN'
# VM_CREATED = 'VM_CREATED'
# VM_UPDATED = 'VM_UPDATED'
# VM_DELETED = 'VM_DELETED'
# DRIVER_IDLE = 'IDLE'
# DRIVER_READY = 'READY'
# DRIVER_RUNNING = 'RUNNING'
# DRIVER_STOPPED = 'STOPPED'
# DEAD_VLAN = 4095
# AGENT_INITIALIZING = "INITIALIZING"
# AGENT_INITIALIZED = "INITIALIZED"
# AGENT_RUNNING = "RUNNING"
# AGENT_STOPPING = "STOPPING"
# AGENT_STOPPED = "STOPPED"
# SEC_TO_INT_PATCH = "patch-integration"
# INT_TO_SEC_PATCH = "patch-security"
# SG_DROPALL_PRI = 0
# SG_DEFAULT_PRI = 1
# SG_LOW_PRI = 5
# SG_RULES_PRI = 10
# SG_TP_PRI = 20
# SG_TCP_FLAG_PRI = 25
# SG_DROP_HIGH_PRI = 50
# SG_DEFAULT_TABLE_ID = 0
# SG_EGRESS_TABLE_ID = 1
# SG_IP_TABLE_ID = 2
# SG_TCP_TABLE_ID = 2
# SG_UDP_TABLE_ID = 2
# SG_ICMP_TABLE_ID = 2
# SG_LEARN_TABLE_ID = 5
# SG_CANARY_TABLE_ID = 23
# ICMP_ECHO_REQ = 8
# ICMP_ECHO_REP = 0
# ICMP_TIME_EXCEEDED = 11
# ICMP_TS_REQ = 13
# ICMP_TS_REP = 14
# ICMP_INFO_REQ = 15
# ICMP_INFO_REP = 16
# ICMP_AM_REQ = 17
# ICMP_AM_REP = 18
# ICMP_DEST_UNREACH = 3
# THREAD_POOL_SIZE = 5
# RPC_BATCH_SIZE = 30
# SG_RPC_BATCH_SIZE = 10
# DIRECTION_IP_PREFIX = {'ingress': 'source_ip_prefix',
#                        'egress': 'dest_ip_prefix'}
# PROTOCOL = {'icmp': 1,
#             'tcp': 6,
#             'udp': 17,
#             'ipv6-icmp': 58}
# DVS_PORTGROUP_NAME_MAXLEN = 80
# LOGIN_RETRIES = 3
# VM_NETWORK_DEVICE_TYPES = [
#     'VirtualE1000', 'VirtualE1000e', 'VirtualPCNet32',
#     'VirtualSriovEthernetCard', 'VirtualVmxnet']
# CONCURRENT_MODIFICATION_TEXT = 'Cannot complete operation due to concurrent '\
#                                'modification by another operation.'
# LOGIN_PROBLEM_TEXT = "Cannot complete login due to an incorrect "\
#                      "user name or password"
# DELETED_TEXT = "The object has already been deleted or has not been "\
#                "completely created"
# DUPLICATE_NAME = "oslo_vmware.exceptions.DuplicateName"
# RESOURCE_IN_USE = "is in use."
# MIN_EPHEMERAL_PORT = 32768
# MAX_EPHEMERAL_PORT = 65535
# 
# Path: networking_vsphere/common/exceptions.py
# class VMWareDVSException(exceptions.NeutronException):
# class InvalidSystemState(VMWareDVSException):
# class InvalidNetwork(VMWareDVSException):
# class NotSupportedNetworkType(InvalidNetwork):
# class InvalidNetworkName(InvalidNetwork):
# class ResourceNotFound(VMWareDVSException):
# class ClusterNotFound(ResourceNotFound):
# class DVSNotFound(ResourceNotFound):
# class PortGroupNotFound(ResourceNotFound):
# class PortNotFound(ResourceNotFound):
# class UnboundPortNotFound(ResourceNotFound):
# class HypervisorNotFound(ResourceNotFound):
# class VMNotFound(ResourceNotFound):
# class NoDVSForPhysicalNetwork(VMWareDVSException):
# def wrap_wmvare_vim_exception(original_exception):
# 
# Path: networking_vsphere/common/vmware_conf.py
# DEFAULT_BRIDGE_MAPPINGS = []
# DEFAULT_UPLINK_MAPPINGS = []
# DEFAULT_VLAN_RANGES = []
# DEFAULT_TUNNEL_RANGES = []
# DEFAULT_TUNNEL_TYPES = []
# CONF = cfg.CONF
# 
# Path: networking_vsphere/utils/db.py
# def get_agent_by_host(agent_host):


import six
from time import sleep
from neutron.agent import securitygroups_rpc
from neutron.common import constants as n_const
from neutron import context
from neutron.extensions import portbindings
from neutron.plugins.common import constants
from neutron.plugins.ml2 import driver_api
from neutron.plugins.ml2.drivers import mech_agent
from oslo_log import log
from networking_vsphere._i18n import _LI
from networking_vsphere.common import constants as dvs_const
from networking_vsphere.common import dvs_agent_rpc_api
from networking_vsphere.common import exceptions
from networking_vsphere.common import vmware_conf as config
from networking_vsphere.utils import db


def port_belongs_to_vmware(func):
    @six.wraps(func)
    def _port_belongs_to_vmware(self, context):
        port = context.current
        try:
            if port['binding:vif_type'] == dvs_const.DVS:
                return func(self, context)
            elif port['binding:vif_type'] == 'unbound':
                try:
                    host = port['binding:host_id']
                except KeyError:
                    raise exceptions.HypervisorNotFound

                agent = db.get_agent_by_host(host)
                if not agent:
                    raise exceptions.HypervisorNotFound
            else:
                return False
        except exceptions.ResourceNotFound:
            return False
        return func(self, context)
    return _port_belongs_to_vmware


class VMwareDVSMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
    """Ml2 Mechanism driver for vmware dvs."""

    def __init__(self):

# Path: networking_vsphere/_i18n.py
# _LI = _translators.log_info
# 
# Path: networking_vsphere/common/constants.py
# AGENT_TYPE_OVSVAPP = "OVSvApp Agent"
# AGENT_TYPE_DVS = 'DVS agent'
# OVSVAPP = 'ovsvapp'
# DVS = 'dvs'
# OVSVAPP_PLUGIN = 'ovsvapp_service_plugin'
# DEVICE = 'device'
# VMWARE_HYPERVISOR_TYPE = 'VMware vCenter Server'
# PORT_STATUS_UP = 'UP'
# PORT_STATUS_DOWN = 'DOWN'
# VM_CREATED = 'VM_CREATED'
# VM_UPDATED = 'VM_UPDATED'
# VM_DELETED = 'VM_DELETED'
# DRIVER_IDLE = 'IDLE'
# DRIVER_READY = 'READY'
# DRIVER_RUNNING = 'RUNNING'
# DRIVER_STOPPED = 'STOPPED'
# DEAD_VLAN = 4095
# AGENT_INITIALIZING = "INITIALIZING"
# AGENT_INITIALIZED = "INITIALIZED"
# AGENT_RUNNING = "RUNNING"
# AGENT_STOPPING = "STOPPING"
# AGENT_STOPPED = "STOPPED"
# SEC_TO_INT_PATCH = "patch-integration"
# INT_TO_SEC_PATCH = "patch-security"
# SG_DROPALL_PRI = 0
# SG_DEFAULT_PRI = 1
# SG_LOW_PRI = 5
# SG_RULES_PRI = 10
# SG_TP_PRI = 20
# SG_TCP_FLAG_PRI = 25
# SG_DROP_HIGH_PRI = 50
# SG_DEFAULT_TABLE_ID = 0
# SG_EGRESS_TABLE_ID = 1
# SG_IP_TABLE_ID = 2
# SG_TCP_TABLE_ID = 2
# SG_UDP_TABLE_ID = 2
# SG_ICMP_TABLE_ID = 2
# SG_LEARN_TABLE_ID = 5
# SG_CANARY_TABLE_ID = 23
# ICMP_ECHO_REQ = 8
# ICMP_ECHO_REP = 0
# ICMP_TIME_EXCEEDED = 11
# ICMP_TS_REQ = 13
# ICMP_TS_REP = 14
# ICMP_INFO_REQ = 15
# ICMP_INFO_REP = 16
# ICMP_AM_REQ = 17
# ICMP_AM_REP = 18
# ICMP_DEST_UNREACH = 3
# THREAD_POOL_SIZE = 5
# RPC_BATCH_SIZE = 30
# SG_RPC_BATCH_SIZE = 10
# DIRECTION_IP_PREFIX = {'ingress': 'source_ip_prefix',
#                        'egress': 'dest_ip_prefix'}
# PROTOCOL = {'icmp': 1,
#             'tcp': 6,
#             'udp': 17,
#             'ipv6-icmp': 58}
# DVS_PORTGROUP_NAME_MAXLEN = 80
# LOGIN_RETRIES = 3
# VM_NETWORK_DEVICE_TYPES = [
#     'VirtualE1000', 'VirtualE1000e', 'VirtualPCNet32',
#     'VirtualSriovEthernetCard', 'VirtualVmxnet']
# CONCURRENT_MODIFICATION_TEXT = 'Cannot complete operation due to concurrent '\
#                                'modification by another operation.'
# LOGIN_PROBLEM_TEXT = "Cannot complete login due to an incorrect "\
#                      "user name or password"
# DELETED_TEXT = "The object has already been deleted or has not been "\
#                "completely created"
# DUPLICATE_NAME = "oslo_vmware.exceptions.DuplicateName"
# RESOURCE_IN_USE = "is in use."
# MIN_EPHEMERAL_PORT = 32768
# MAX_EPHEMERAL_PORT = 65535
# 
# Path: networking_vsphere/common/exceptions.py
# class VMWareDVSException(exceptions.NeutronException):
# class InvalidSystemState(VMWareDVSException):
# class InvalidNetwork(VMWareDVSException):
# class NotSupportedNetworkType(InvalidNetwork):
# class InvalidNetworkName(InvalidNetwork):
# class ResourceNotFound(VMWareDVSException):
# class ClusterNotFound(ResourceNotFound):
# class DVSNotFound(ResourceNotFound):
# class PortGroupNotFound(ResourceNotFound):
# class PortNotFound(ResourceNotFound):
# class UnboundPortNotFound(ResourceNotFound):
# class HypervisorNotFound(ResourceNotFound):
# class VMNotFound(ResourceNotFound):
# class NoDVSForPhysicalNetwork(VMWareDVSException):
# def wrap_wmvare_vim_exception(original_exception):
# 
# Path: networking_vsphere/common/vmware_conf.py
# DEFAULT_BRIDGE_MAPPINGS = []
# DEFAULT_UPLINK_MAPPINGS = []
# DEFAULT_VLAN_RANGES = []
# DEFAULT_TUNNEL_RANGES = []
# DEFAULT_TUNNEL_TYPES = []
# CONF = cfg.CONF
# 
# Path: networking_vsphere/utils/db.py
# def get_agent_by_host(agent_host):


# Path: networking_vsphere/ml2/dvs_mechanism_driver.py
import six
from time import sleep
from neutron.agent import securitygroups_rpc
from neutron.common import constants as n_const
from neutron import context
from neutron.extensions import portbindings
from neutron.plugins.common import constants
from neutron.plugins.ml2 import driver_api
from neutron.plugins.ml2.drivers import mech_agent
from oslo_log import log
from networking_vsphere._i18n import _LI
from networking_vsphere.common import constants as dvs_const
from networking_vsphere.common import dvs_agent_rpc_api
from networking_vsphere.common import exceptions
from networking_vsphere.common import vmware_conf as config
from networking_vsphere.utils import db



def port_belongs_to_vmware(func):
    @six.wraps(func)
    def _port_belongs_to_vmware(self, context):
        port = context.current
        try:
            if port['binding:vif_type'] == dvs_const.DVS:
                return func(self, context)
            elif port['binding:vif_type'] == 'unbound':
                try:
                    host = port['binding:host_id']
                except KeyError:
                    raise exceptions.HypervisorNotFound

                agent = db.get_agent_by_host(host)
                if not agent:
                    raise exceptions.HypervisorNotFound
            else:
                return False
        except exceptions.ResourceNotFound:
            return False
        return func(self, context)
    return _port_belongs_to_vmware


class VMwareDVSMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
    """Ml2 Mechanism driver for vmware dvs."""

    def __init__(self):

        self.vif_type = dvs_const.DVS