<s> from threading import Lock <EOL> import re <EOL> import logging <EOL> from bagpipe . bgp . vpn . ipvpn import VRF <EOL> from bagpipe . bgp . vpn . evpn import EVI <EOL> import bagpipe . bgp . common . exceptions as exc <EOL> from bagpipe . bgp . common . looking_glass import LookingGlass , LGMap <EOL> from bagpipe . bgp . common import utils <EOL> from bagpipe . bgp . common import logDecorator <EOL> from bagpipe . bgp . common . run_command import runCommand <EOL> from bagpipe . bgp . vpn . label_allocator import LabelAllocator <EOL> from bagpipe . exabgp . message . update . attribute . communities import RouteTarget <EOL> log = logging . getLogger ( __name__ ) <EOL> def convertRouteTargets ( orig_list ) : <EOL> assert ( isinstance ( orig_list , list ) ) <EOL> list_ = [ ] <EOL> for rt in orig_list : <EOL> if rt == '<STR_LIT>' : <EOL> continue <EOL> try : <EOL> asn , nn = rt . split ( '<STR_LIT::>' ) <EOL> list_ . append ( RouteTarget ( int ( asn ) , None , int ( nn ) ) ) <EOL> except Exception : <EOL> raise Exception ( "<STR_LIT>" % rt ) <EOL> return list_ <EOL> class VPNManager ( LookingGlass ) : <EOL> """<STR_LIT>""" <EOL> type2class = { "<STR_LIT>" : VRF , <EOL> "<STR_LIT>" : EVI <EOL> } <EOL> @ logDecorator . log <EOL> def __init__ ( self , bgpManager , dataplaneDrivers ) : <EOL> '''<STR_LIT>''' <EOL> self . bgpManager = bgpManager <EOL> self . dataplaneDrivers = dataplaneDrivers <EOL> self . instanceId = <NUM_LIT:1> <EOL> self . vpnInstances = { } <EOL> logging . debug ( "<STR_LIT>" ) <EOL> self . labelAllocator = LabelAllocator ( ) <EOL> self . _evpn_ipvpn_ifs = { } <EOL> self . lock = Lock ( ) <EOL> def _formatIpAddressPrefix ( self , ipAddress ) : <EOL> if re . match ( r'<STR_LIT>' , ipAddress ) : <EOL> address = ipAddress <EOL> elif re . match ( r'<STR_LIT>' , ipAddress ) : <EOL> address = ipAddress + "<STR_LIT>" <EOL> else : <EOL> raise exc . MalformedIPAddress <EOL> return address <EOL> @ utils . synchronized <EOL> def getInstanceId ( self ) : <EOL> iid = self . instanceId <EOL> self . instanceId += <NUM_LIT:1> <EOL> return iid <EOL> @ logDecorator . logInfo <EOL> def _attach_evpn2ipvpn ( self , localPort , ipvpnInstance ) : <EOL> """<STR_LIT>""" <EOL> assert ( '<STR_LIT>' in localPort ) <EOL> if '<STR_LIT:id>' not in localPort [ '<STR_LIT>' ] : <EOL> raise Exception ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> try : <EOL> evpn = self . vpnInstances [ localPort [ '<STR_LIT>' ] [ '<STR_LIT:id>' ] ] <EOL> except : <EOL> raise Exception ( "<STR_LIT>" <EOL> % localPort [ '<STR_LIT>' ] ) <EOL> if ( evpn . type != "<STR_LIT>" ) : <EOL> raise Exception ( "<STR_LIT>" <EOL> "<STR_LIT>" % evpn . type ) <EOL> if ipvpnInstance in self . _evpn_ipvpn_ifs : <EOL> ( evpn_if , ipvpn_if , evpn , managed ) = self . _evpn_ipvpn_ifs [ ipvpnInstance ] <EOL> if not ( localPort [ '<STR_LIT>' ] [ '<STR_LIT:id>' ] == evpn . externalInstanceId ) : <EOL> raise Exception ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> else : <EOL> log . warning ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> localPort [ '<STR_LIT>' ] = ipvpn_if <EOL> return <EOL> if evpn . hasGatewayPort ( ) : <EOL> raise Exception ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if ( '<STR_LIT>' in localPort and localPort [ '<STR_LIT>' ] ) : <EOL> raise Exception ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if '<STR_LIT>' in localPort [ '<STR_LIT>' ] : <EOL> try : <EOL> assert ( localPort [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> assert ( localPort [ '<STR_LIT>' ] [ '<STR_LIT>' ] or <EOL> localPort [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> except : <EOL> raise Exception ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> evpn_if = localPort [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> managed = False <EOL> else : <EOL> evpn_if = "<STR_LIT>" % ( <EOL> evpn . instanceId , ipvpnInstance . instanceId ) <EOL> ipvpn_if = "<STR_LIT>" % ( <EOL> ipvpnInstance . instanceId , evpn . instanceId ) <EOL> log . info ( "<STR_LIT>" , evpn_if , ipvpn_if ) <EOL> runCommand ( log , "<STR_LIT>" % <EOL> evpn_if , acceptableReturnCodes = [ <NUM_LIT:0> , <NUM_LIT:1> ] ) <EOL> runCommand ( log , "<STR_LIT>" % <EOL> ipvpn_if , acceptableReturnCodes = [ <NUM_LIT:0> , <NUM_LIT:1> ] ) <EOL> runCommand ( log , "<STR_LIT>" % <EOL> ( evpn_if , ipvpn_if ) ) <EOL> runCommand ( log , "<STR_LIT>" % evpn_if ) <EOL> runCommand ( log , "<STR_LIT>" % ipvpn_if ) <EOL> managed = True <EOL> localPort [ '<STR_LIT>' ] = ipvpn_if <EOL> evpn . setGatewayPort ( evpn_if , ipvpnInstance ) <EOL> self . _evpn_ipvpn_ifs [ ipvpnInstance ] = ( <EOL> evpn_if , ipvpn_if , evpn , managed ) <EOL> @ logDecorator . logInfo <EOL> def _detach_evpn2ipvpn ( self , ipvpn ) : <EOL> """<STR_LIT>""" <EOL> ( evpn_if , ipvpn_if , evpnInstance , <EOL> managed ) = self . _evpn_ipvpn_ifs [ ipvpn ] <EOL> if not ipvpn . hasEnpoint ( ipvpn_if ) : <EOL> evpnInstance . gatewayPortDown ( evpn_if ) <EOL> if managed : <EOL> runCommand ( log , "<STR_LIT>" % evpn_if ) <EOL> del self . _evpn_ipvpn_ifs [ ipvpn ] <EOL> def _cleanup_evpn2ipvpn ( self , ipvpn ) : <EOL> ( _ , ipvpn_if , _ , managed ) = self . _evpn_ipvpn_ifs [ ipvpn ] <EOL> if managed : <EOL> runCommand ( log , "<STR_LIT>" % ipvpn_if ) <EOL> runCommand ( log , "<STR_LIT>" % ipvpn_if ) <EOL> @ logDecorator . logInfo <EOL> def plugVifToVPN ( self , externalInstanceId , instanceType , importRTs , <EOL> exportRTs , macAddress , ipAddress , gatewayIP , <EOL> localPort , linuxbr , advertiseSubnet , readvertise ) : <EOL> try : <EOL> ipAddressPrefix = self . _formatIpAddressPrefix ( ipAddress ) <EOL> except exc . MalformedIPAddress : <EOL> raise <EOL> importRTs = convertRouteTargets ( importRTs ) <EOL> exportRTs = convertRouteTargets ( exportRTs ) <EOL> if readvertise : <EOL> try : <EOL> readvertise = { k : convertRouteTargets ( readvertise [ k ] ) <EOL> for k in [ '<STR_LIT>' , '<STR_LIT>' ] } <EOL> except KeyError as e : <EOL> raise Exception ( "<STR_LIT>" % e ) <EOL> mask = int ( ipAddressPrefix . split ( '<STR_LIT:/>' ) [ <NUM_LIT:1> ] ) <EOL> try : <EOL> vpnInstance = self . vpnInstances [ externalInstanceId ] <EOL> if ( vpnInstance . type != instanceType ) : <EOL> raise Exception ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> % ( vpnInstance . type , instanceType ) ) <EOL> except KeyError : <EOL> instanceId = self . getInstanceId ( ) <EOL> log . info ( "<STR_LIT>" <EOL> "<STR_LIT>" , instanceId , <EOL> externalInstanceId ) <EOL> try : <EOL> vpnInstanceFactory = VPNManager . type2class [ instanceType ] <EOL> except KeyError : <EOL> log . error ( "<STR_LIT>" , <EOL> instanceType ) <EOL> raise Exception ( "<STR_LIT>" % instanceType ) <EOL> try : <EOL> dataplaneDriver = self . dataplaneDrivers [ instanceType ] <EOL> except KeyError : <EOL> log . error ( "<STR_LIT>" , <EOL> instanceType ) <EOL> raise Exception ( "<STR_LIT>" % <EOL> instanceType ) <EOL> if instanceType == "<STR_LIT>" and linuxbr : <EOL> kwargs = { '<STR_LIT>' : linuxbr } <EOL> else : <EOL> kwargs = { } <EOL> vpnInstance = vpnInstanceFactory ( <EOL> self . bgpManager , self . labelAllocator , dataplaneDriver , <EOL> externalInstanceId , instanceId , importRTs , exportRTs , <EOL> gatewayIP , mask , readvertise , ** kwargs ) <EOL> self . vpnInstances [ externalInstanceId ] = vpnInstance <EOL> vpnInstance . start ( ) <EOL> if not ( ( set ( vpnInstance . importRTs ) == set ( importRTs ) ) and <EOL> ( set ( vpnInstance . exportRTs ) == set ( exportRTs ) ) ) : <EOL> vpnInstance . updateRouteTargets ( importRTs , exportRTs ) <EOL> if instanceType == "<STR_LIT>" and '<STR_LIT>' in localPort : <EOL> self . _attach_evpn2ipvpn ( localPort , vpnInstance ) <EOL> vpnInstance . vifPlugged ( macAddress , ipAddressPrefix , localPort , <EOL> advertiseSubnet ) <EOL> @ logDecorator . logInfo <EOL> def unplugVifFromVPN ( self , externalInstanceId , macAddress , ipAddress , <EOL> localPort , readvertise ) : <EOL> try : <EOL> ipAddressPrefix = self . _formatIpAddressPrefix ( ipAddress ) <EOL> except exc . MalformedIPAddress : <EOL> raise <EOL> try : <EOL> vpnInstance = self . vpnInstances [ externalInstanceId ] <EOL> except KeyError : <EOL> log . error ( "<STR_LIT>" , <EOL> externalInstanceId ) <EOL> raise exc . VPNNotFound ( externalInstanceId ) <EOL> vpnInstance . vifUnplugged ( macAddress , ipAddressPrefix , readvertise ) <EOL> if vpnInstance . type == "<STR_LIT>" and '<STR_LIT>' in localPort : <EOL> self . _detach_evpn2ipvpn ( vpnInstance ) <EOL> if vpnInstance . stopIfEmpty ( ) : <EOL> del self . vpnInstances [ externalInstanceId ] <EOL> @ logDecorator . logInfo <EOL> def stop ( self ) : <EOL> for vpnInstance in self . vpnInstances . itervalues ( ) : <EOL> vpnInstance . stop ( ) <EOL> if ( vpnInstance . type == "<STR_LIT>" and <EOL> self . _evpn_ipvpn_ifs . get ( vpnInstance ) ) : <EOL> self . _cleanup_evpn2ipvpn ( vpnInstance ) <EOL> for vpnInstance in self . vpnInstances . itervalues ( ) : <EOL> vpnInstance . join ( ) <EOL> def getLGMap ( self ) : <EOL> class DataplaneLGHook ( LookingGlass ) : <EOL> def __init__ ( self , vpnManager ) : <EOL> self . vpnManager = vpnManager <EOL> def getLGMap ( self ) : <EOL> return { <EOL> "<STR_LIT>" : ( LGMap . COLLECTION , ( <EOL> self . vpnManager . getLGDataplanesList , <EOL> self . vpnManager . getLGDataplaneFromPathItem ) ) , <EOL> "<STR_LIT>" : ( LGMap . DELEGATE , self . vpnManager . labelAllocator ) <EOL> } <EOL> dataplaneHook = DataplaneLGHook ( self ) <EOL> return { <EOL> "<STR_LIT>" : ( LGMap . COLLECTION , ( self . getLGVPNList , <EOL> self . getLGVPNFromPathItem ) ) , <EOL> "<STR_LIT>" : ( LGMap . DELEGATE , dataplaneHook ) <EOL> } <EOL> def getLGVPNList ( self ) : <EOL> return [ { "<STR_LIT:id>" : i } for i in self . vpnInstances . iterkeys ( ) ] <EOL> def getLGVPNFromPathItem ( self , pathItem ) : <EOL> return self . vpnInstances [ pathItem ] <EOL> def getVPNInstancesCount ( self ) : <EOL> return len ( self . vpnInstances ) <EOL> def getLGDataplanesList ( self ) : <EOL> return [ { "<STR_LIT:id>" : i } for i in self . dataplaneDrivers . iterkeys ( ) ] <EOL> def getLGDataplaneFromPathItem ( self , pathItem ) : <EOL> return self . dataplaneDrivers [ pathItem ] </s>
