Python script to install license and configuration for IPSec tunneling on a VE instance
Problem this snippet solves:
This script can be called from the command line and used to reach out to a VE to license it, perform minimum configuration and provision an IPSec interface-mode tunnel.
This is not best practice, not hardened, etc. This is a foundation, not a solution.
How to use this snippet:
The script has built-in CLI help.
Code :
#!/usr/bin/env python3
import argparse,json,requests,time
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
def icontrol_get(host,username,password,path):
apiCall = requests.session()
apiCall.headers.update({'Content-type':'application/json'})
apiCall.auth = (username,password)
apiUri = 'https://' + host + path
try:
apiResponse = apiCall.get(apiUri,verify=False)
except requests.exceptions.RequestException as e:
print('{"responseStatus":"error","action":"get","host":"' + host + '","username":"' + username + '","path":"' + path + '","errorMsg":"' + str(e) + '"}')
return(apiResponse.text)
def icontrol_post(host,username,password,path,api_payload):
apiCall = requests.session()
apiCall.headers.update({'Content-type':'application/json'})
apiCall.auth = (username,password)
apiUri = 'https://' + host + path
try:
apiResponse = apiCall.post(apiUri,verify=False,data=json.dumps(api_payload))
except requests.exceptions.RequestException as e:
print('{"responseStatus":"error","action":"post","host":"' + host + '","username":"' + username + '","path":"' + path + '"},"payload":"' + api_payload + '","errorMsg":"' + str(e) + '"}')
return(apiResponse.text)
def icontrol_put(host,username,password,path,api_payload):
apiCall = requests.session()
apiCall.headers.update({'Content-type':'application/json'})
apiCall.auth = (username,password)
apiUri = 'https://' + host + path
try:
apiResponse = apiCall.put(apiUri,verify=False,data=json.dumps(api_payload))
except requests.exceptions.RequestException as e:
print('{"responseStatus":"error","action":"put","host":"' + host + '","username":"' + username + '","path":"' + path + '"},"payload":"' + api_payload + '","errorMsg":"' + str(e) + '"}')
return(apiResponse.text)
def icontrol_patch(host,username,password,path,api_payload):
apiCall = requests.session()
apiCall.headers.update({'Content-type':'application/json'})
apiCall.auth = (username,password)
apiUri = 'https://' + host + path
try:
apiResponse = apiCall.patch(apiUri,verify=False,data=json.dumps(api_payload))
except requests.exceptions.RequestException as e:
print('{"responseStatus":"error","action":"patch","host":"' + host + '","username":"' + username + '","path":"' + path + '"},"payload":"' + api_payload + '","errorMsg":"' + str(e) + '"}')
return(apiResponse.text)
def icontrol_delete(host,username,password,path):
apiCall = requests.session()
apiCall.headers.update({'Content-type':'application/json'})
apiCall.auth = (username,password)
apiUri = 'https://' + host + path
try:
apiResponse = apiCall.delete(apiUri,verify=False)
except requests.exceptions.RequestException as e:
print('{"responseStatus":"error","action":"delete","host":"' + host + '","username":"' + username + '","path":"' + path + '"},"errorMsg":"' + str(e) + '"}')
return(apiResponse.text)
## Parse the command line arguments#cmdargs = argparse.ArgumentParser()
cmdargs.add_argument('--f5restip',action='store',required=True,type=str,help='ip of BIG-IP REST interface, typically the mgmt ip')
cmdargs.add_argument('--username',action='store',required=True,type=str,help='username for REST authentication')
cmdargs.add_argument('--password',action='store',required=True,type=str,help='password for REST authentication')
cmdargs.add_argument('--licensekey',action='store',required=False,type=str,help='license key for licensing')
cmdargs.add_argument('--hostname',action='store',required=False,type=str,help='hostname to configure on the BIG-IP (must be FQDN)')
cmdargs.add_argument('--ntpserver',action='store',required=False,type=str,help='NTP server to add to the BIG-IP (IP or FQDN)')
cmdargs.add_argument('--dnsserver',action='store',required=False,type=str,help='DNS server to add to the BIG-IP (IP address)')
cmdargs.add_argument('--newlocalselfip',action='store',required=True,type=str,help='creates the private self-ip address of the VE where the public address is mapped (CIDR notation)')
cmdargs.add_argument('--newlocalselfipgateway',action='store',required=True,type=str,help='creates the private self-ip subnet gateway for server communications')
cmdargs.add_argument('--localserversubnet',action='store',required=True,type=str,help='the local VM subnet in CIDR notation')
cmdargs.add_argument('--localselfip',action='store',required=True,type=str,help='the private self-ip address of the VE where the public address is mapped')
cmdargs.add_argument('--localpublicip',action='store',required=True,type=str,help='the public IP address of the VNA')
cmdargs.add_argument('--remotepublicip',action='store',required=True,type=str,help='the public IP address of the remote IPSec peer')
cmdargs.add_argument('--presharedkey',action='store',required=True,type=str,help='the pre-shared key for encryption')
cmdargs.add_argument('--tunnelsourcenet',action='store',required=True,type=str,help='CIDR notated source network, can be 0.0.0.0/0 to tunnel all traffic')
cmdargs.add_argument('--tunneldestinationnet',action='store',required=True,type=str,help='CIDR notated destination network, the remote destination subnet to tunnel, can be 0.0.0.0/0 to let static routes control tunneling')
cmdargs.add_argument('--tunnelstaticroutenet',action='store',required=True,type=str,help='CIDR notated destination network to statically route across the tunnel (this makes the decision to tunnel or not)')
cmdargs.add_argument('--tunnelselfiplocal',action='store',required=True,type=str,help='CIDR notated tunnel self-IP address, a new address assigned to the tunnel (ie 192.168.1.1/30')
cmdargs.add_argument('--tunnelselfipremote',action='store',required=True,type=str,help='CIDR notated tunnel self-IP address on the remote end, a new address assigned to the tunnel (ie 192.168.1.1/30')
cmdargs.add_argument('--bgpas',action='store',required=True,type=str,help='AS number for BGP process and neighbor')
parsed_args = cmdargs.parse_args()
host = parsed_args.f5restip
username = parsed_args.username
password = parsed_args.password
license_key = parsed_args.licensekey
hostname = parsed_args.hostname
ntpserver = parsed_args.ntpserver
dnsserver = parsed_args.dnsserver
vpn = {}
vpn['local-self-ip'] = parsed_args.localselfip
vpn['local-public-ip'] = parsed_args.localpublicip
vpn['remote-public-ip'] = parsed_args.remotepublicip
vpn['pre-shared-key'] = parsed_args.presharedkey
vpn['tunnel-source-network'] = parsed_args.tunnelsourcenet
vpn['tunnel-destination-network'] = parsed_args.tunneldestinationnet
vpn['tunnel-static-route-network'] = parsed_args.tunnelstaticroutenet
vpn['tunnel-name'] = 'ipsec_peer-' + vpn['remote-public-ip']
vpn['tunnel-self-ip'] = parsed_args.tunnelselfiplocal
vpn['new-local-self-ip'] = parsed_args.newlocalselfip
vpn['new-local-self-ip-gateway'] = parsed_args.newlocalselfipgateway
vpn['local-server-subnet'] = parsed_args.localserversubnet
vpn['tunnel-self-ip-remote'] = parsed_args.tunnelselfipremote
vpn['bgp-as'] = parsed_args.bgpas
# License the VEif license_key is not None:
print('Licensing ' + host + ' with key ' + license_key)
apiCallResponse = icontrol_post(host,username,password,'/mgmt/tm/sys/license',{"command":"install","registrationKey":license_key})
if 'New license installed' in apiCallResponse:
print('License installed successfully. Waiting for service restart.')
time.sleep(60)
else:
print('Error! ' + apiCallResponse)
quit()
else:
print("License key not specified - skipping licensing")
# Disable the GUI setup wizard since we're configuring via RESTprint('Disabling the GUI Setup Wizard')
apiCallResponse = icontrol_patch(host,username,password,'/mgmt/tm/sys/global-settings',{"guiSetup":"disabled"})
if '"kind":"tm:sys:global-settings:global-settingsstate"' and '"guiSetup":"disabled"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()
# Set the hostname if specifiedif hostname is not None:
print('Setting the hostname to ' + hostname + ' on ' + host)
apiCallResponse = icontrol_patch(host, username, password, '/mgmt/tm/sys/global-settings',{"hostname":hostname})
if '"kind":"tm:sys:global-settings:global-settingsstate"' and '"hostname":"' + hostname + '"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()
else:
print('Hostname not specified - skipping hostname configuration')
# Set the DNS server if specifiedif dnsserver is not None:
print('Adding DNS server ' + dnsserver + ' to ' + host)
apiCallResponse = icontrol_patch(host,username,password,'/mgmt/tm/sys/dns',{"nameServers":[dnsserver]})
if '"kind":"tm:sys:dns:dnsstate"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()
else:
print('DNS server not specified - skipping DNS server configuration')
# Set the NTP server if specifiedif ntpserver is not None:
print('Adding NTP server ' + ntpserver + ' to ' + host)
apiCallResponse = icontrol_patch(host,username,password,'/mgmt/tm/sys/ntp',{"servers":[ntpserver]})
if '"kind":"tm:sys:ntp:ntpstate"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()
else:
print('NTP server not specified - skipping NTP server configuration')
# Configure the local VLAN and self-IP if specifiedif vpn['new-local-self-ip'] is not None:
# create external VLAN untagged print('Creating the external VLAN')
apiPayload = {}
apiPayload['name'] = 'external' apiPayload['interfaces'] = ['1.1']
apiPayload['partition'] = 'Common' apiPayload['mtu'] = 1500 apiCallResponse = icontrol_post(host,username,password,'/mgmt/tm/net/vlan',apiPayload)
if '"kind":"tm:net:vlan:vlanstate"' in apiCallResponse :
print('Success!')
elif 'already exists' in apiCallResponse:
print('Object exists; skipping item configuration')
else:
print('Error! ' + apiCallResponse)
quit()
# create the data interface self-IP print('Creating the self-IP address ' + vpn['local-self-ip'])
apiPayload = {}
apiPayload['name'] = vpn['new-local-self-ip']
apiPayload['address'] = vpn['new-local-self-ip']
apiPayload['allowService'] = 'all' apiPayload['interfaces'] = ['1.1']
apiPayload['partition'] = 'Common' apiPayload['trafficGroup'] = 'traffic-group-local-only' apiPayload['vlan'] = 'external' apiCallResponse = icontrol_post(host,username,password,'/mgmt/tm/net/self',apiPayload)
if '"kind":"tm:net:self:selfstate"' in apiCallResponse :
print('Success!')
elif 'already exists' in apiCallResponse:
print('Object exists; skipping item configuration')
else:
print('Error! ' + apiCallResponse)
quit()
## Begin IPSec tunnel configuration steps## Create the IPSec policyprint('Creating the IPSec Policy (' + vpn['tunnel-name'] + ')')
apiPayload = {}
apiPayload['name'] = vpn['tunnel-name']
apiPayload['ikePhase2AuthAlgorithm'] = 'aes-gcm128'apiPayload['ikePhase2EncryptAlgorithm'] = 'aes-gcm128'apiPayload['ikePhase2PerfectForwardSecrecy'] = 'none'apiPayload['ikePhase2Lifetime'] = 1440apiPayload['ikePhase2LifetimeKilobytes'] = 0apiPayload['mode'] = 'interface'apiPayload['protocol'] = 'esp'apiPayload['ipcomp'] = 'none'apiPayload['partition'] = 'Common'apiCallResponse = icontrol_post(host,username,password,'/mgmt/tm/net/ipsec/ipsec-policy',apiPayload)
if '"kind":"tm:net:ipsec:ipsec-policy:ipsec-policystate"' in apiCallResponse :
print('Success!')
elif 'already exists' in apiCallResponse:
print('Object exists; updating with new configuration')
apiCallResponse = icontrol_put(host, username, password, '/mgmt/tm/net/ipsec/ipsec-policy/' + vpn['tunnel-name'], apiPayload)
if '"kind":"tm:net:ipsec:ipsec-policy:ipsec-policystate"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()
else:
print('Error! ' + apiCallResponse)
quit()
# Create the IPSec traffic selectorprint('Creating the IPSec traffic selector (' + vpn['tunnel-name'] + ')')
apiPayload = {}
apiPayload['name'] = vpn['tunnel-name']
apiPayload['partition'] = 'Common'apiPayload['action'] = 'protect'apiPayload['sourceAddress'] = vpn['tunnel-source-network']
apiPayload['sourcePort'] = 0apiPayload['destinationAddress'] = vpn['tunnel-destination-network']
apiPayload['destinationPort'] = 0apiPayload['direction'] = 'both'apiPayload['ipProtocol'] = 255apiPayload['ipsecPolicy'] = vpn['tunnel-name']
apiPayload['order'] = 0apiCallResponse = icontrol_post(host,username,password,'/mgmt/tm/net/ipsec/traffic-selector',apiPayload)
if '"kind":"tm:net:ipsec:traffic-selector:traffic-selectorstate"' in apiCallResponse:
print('Success!')
elif 'already exists' in apiCallResponse:
print('Object exists; updating with new configuration')
apiCallResponse = icontrol_put(host, username, password, '/mgmt/tm/net/ipsec/traffic-selector/' + vpn['tunnel-name'], apiPayload)
if '"kind":"tm:net:ipsec:traffic-selector:traffic-selectorstate"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()
else:
print('Error! ' + apiCallResponse)
quit()
# Set the default IPSec traffic selector to high orderprint('Setting the default IPSec traffic selector to order 100')
apiPayload = {}
apiPayload['order'] = 100apiCallResponse = icontrol_patch(host,username,password,'/mgmt/tm/net/ipsec/traffic-selector/default-traffic-selector-interface',apiPayload)
if '"kind":"tm:net:ipsec:traffic-selector:traffic-selectorstate"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()
# Create the IKE peerprint('Creating the IKE peer (' + vpn['tunnel-name'] + ')')
apiPayload = {}
apiPayload['name'] = vpn['tunnel-name']
apiPayload['myIdType'] = 'address'apiPayload['myIdValue'] = vpn['local-public-ip']
apiPayload['peersIdType'] = 'address'apiPayload['peersIdValue'] = vpn['remote-public-ip']
apiPayload['phase1AuthMethod'] = 'pre-shared-key'apiPayload['phase1EncryptAlgorithm'] = 'aes256'apiPayload['phase1HashAlgorithm'] = 'sha256'apiPayload['phase1PerfectForwardSecrecy'] = 'modp1024'apiPayload['prf'] = 'sha256'apiPayload['presharedKey'] = vpn['pre-shared-key']
apiPayload['remoteAddress'] = vpn['remote-public-ip']
apiPayload['version'] = ['v2']
apiPayload['dpdDelay'] = 30apiPayload['lifetime'] = 1440apiPayload['mode'] = 'main'apiPayload['natTraversal'] = 'off'apiPayload['passive'] = 'false'apiPayload['generatePolicy'] = 'off'apiPayload['trafficSelector'] = [vpn['tunnel-name']]
apiCallResponse = icontrol_post(host,username,password,'/mgmt/tm/net/ipsec/ike-peer',apiPayload)
if '"kind":"tm:net:ipsec:ike-peer:ike-peerstate"' in apiCallResponse:
print('Success!')
elif 'already exists' in apiCallResponse:
print('Object exists; updating with new configuration')
apiCallResponse = icontrol_put(host, username, password, '/mgmt/tm/net/ipsec/ike-peer/' + vpn['tunnel-name'], apiPayload)
if '"kind":"tm:net:ipsec:ike-peer:ike-peerstate"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()
else:
print('Error! ' + apiCallResponse)
quit()
# Create the tunnel profileprint('Creating the tunnel profile (' + vpn['tunnel-name'] + ')')
apiPayload = {}
apiPayload['name'] = vpn['tunnel-name']
apiPayload['defaultsFrom'] = '/Common/ipsec'apiPayload['trafficSelector'] = vpn['tunnel-name']
apiCallResponse = icontrol_post(host,username,password,'/mgmt/tm/net/tunnels/ipsec',apiPayload)
if '"kind":"tm:net:tunnels:ipsec:ipsecstate"' in apiCallResponse:
print('Success!')
elif 'already exists' in apiCallResponse:
print('Object exists; updating with new configuration')
apiCallResponse = icontrol_put(host, username, password, '/mgmt/tm/net/tunnels/ipsec/' + vpn['tunnel-name'], apiPayload)
if '"kind":"tm:net:tunnels:ipsec:ipsecstate"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()
else:
print('Error! ' + apiCallResponse)
quit()
# Create the tunnel objectprint('Creating the tunnel object (' + vpn['tunnel-name'] + ')')
apiPayload = {}
apiPayload['name'] = vpn['tunnel-name']
apiPayload['autoLasthop'] = 'default'apiPayload['idleTimeout'] = 300apiPayload['key'] = 0apiPayload['localAddress'] = vpn['local-self-ip']
apiPayload['mode'] = 'bidirectional'apiPayload['mtu'] = 0apiPayload['profile'] = vpn['tunnel-name']
apiPayload['remoteAddress'] = vpn['remote-public-ip']
apiPayload['tos'] = 'preserve'apiPayload['transparent'] = 'disabled'apiPayload['usePmtu'] = 'enabled'apiCallResponse = icontrol_post(host,username,password,'/mgmt/tm/net/tunnels/tunnel',apiPayload)
if '"kind":"tm:net:tunnels:tunnel:tunnelstate"' in apiCallResponse:
print('Success!')
elif 'already exists' in apiCallResponse:
print('Object exists; updating with new configuration')
apiCallResponse = icontrol_put(host, username, password, '/mgmt/tm/net/tunnels/tunnel/' + vpn['tunnel-name'], apiPayload)
if '"kind":"tm:net:tunnels:tunnel:tunnelstate"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()
else:
print('Error! ' + apiCallResponse)
quit()
# Create the self-IP for the tunnel-routeprint('Creating the local tunnel interface self-IP (' + vpn['tunnel-name'] + ')')
apiPayload = {}
apiPayload['name'] = vpn['tunnel-name']
apiPayload['address'] = vpn['tunnel-self-ip']
apiPayload['vlan'] = vpn['tunnel-name']
apiPayload['traffic-group'] = 'traffic-group-local-only'apiPayload['allowService'] = 'all'apiCallResponse = icontrol_post(host,username,password,'/mgmt/tm/net/self',apiPayload)
if '"kind":"tm:net:self:selfstate"' in apiCallResponse:
print('Success!')
elif 'already exists' in apiCallResponse:
print('Object exists; updating with new configuration')
apiCallResponse = icontrol_put(host, username, password, '/mgmt/tm/net/self/' + vpn['tunnel-name'], apiPayload)
if '"kind":"tm:net:self:selfstate"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()
else:
print('Error! ' + apiCallResponse)
quit()
# Point the peer route over the tunnelprint('Creating the peer static route (' + vpn['tunnel-name'] + ')')
apiPayload = {}
apiPayload['name'] = vpn['tunnel-name']
apiPayload['tmInterface'] = vpn['tunnel-name']
apiPayload['network'] = vpn['tunnel-self-ip-remote'] + '/32'apiPayload['mtu'] = 0apiCallResponse = icontrol_post(host,username,password,'/mgmt/tm/net/route',apiPayload)
if '"kind":"tm:net:route:routestate"' in apiCallResponse:
print('Success!')
elif 'already exists' in apiCallResponse:
print('Object exists; updating with new configuration')
apiCallResponse = icontrol_put(host, username, password, '/mgmt/tm/net/route/~Common~'+vpn['tunnel-name'], apiPayload)
if '"kind":"tm:net:route:routestate"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()
else:
print('Error! ' + apiCallResponse)
quit()
# Create the local server routeprint('Creating the default static route to ' + vpn['new-local-self-ip-gateway'])
apiPayload = {}
apiPayload['name'] = 'local-servers'apiPayload['gw'] = vpn['new-local-self-ip-gateway']
apiPayload['network'] = vpn['local-server-subnet']
apiCallResponse = icontrol_post(host, username, password, '/mgmt/tm/net/route', apiPayload)
if '"kind":"tm:net:route:routestate"' in apiCallResponse:
print('Success!')
elif 'already exists' in apiCallResponse:
print('Object exists; updating with new configuration')
apiCallResponse = icontrol_put(host, username, password, '/mgmt/tm/net/route/~Common~local-servers', apiPayload)
if '"kind":"tm:net:route:routestate"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()
else:
print('Error! ' + apiCallResponse)
quit()
# Create the remote peer routerprint('Creating the IPSec peer route to ' + vpn['remote-public-ip'])
apiPayload = {}
apiPayload['name'] = 'remote-peer'apiPayload['gw'] = vpn['new-local-self-ip-gateway']
apiPayload['network'] = vpn['remote-public-ip']
apiCallResponse = icontrol_post(host, username, password, '/mgmt/tm/net/route', apiPayload)
if '"kind":"tm:net:route:routestate"' in apiCallResponse:
print('Success!')
elif 'already exists' in apiCallResponse:
print('Object exists; updating with new configuration')
apiCallResponse = icontrol_put(host, username, password, '/mgmt/tm/net/route/~Common~remote-peer', apiPayload)
if '"kind":"tm:net:route:routestate"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()
else:
print('Error! ' + apiCallResponse)
quit()
# Create the default IP forwarding virtual serverprint('Creating the default IP forwarding virtual server')
apiPayload = {}
apiPayload['name'] = 'ipsec_forwarding_vs'apiPayload['destination'] = '/Common/0.0.0.0:0'apiPayload['ipProtocol'] = 'any'apiPayload['mask'] = '0.0.0.0'apiPayload['source'] = '0.0.0.0/0'apiPayload['ipForward'] = TrueapiPayload['sourceAddressTranslation'] = {'type':'none'}
apiPayload['sourcePort'] = 'preserve-strict'apiPayload['profiles'] = ['/Common/fastL4']
apiPayload['enabled'] = TrueapiPayload['translateAddress'] = 'disabled'apiPayload['translatePort'] = 'disabled'apiCallResponse = icontrol_post(host,username,password,'/mgmt/tm/ltm/virtual',apiPayload)
if '"kind":"tm:ltm:virtual:virtualstate"' in apiCallResponse:
print('Success!')
elif 'already exists' in apiCallResponse:
print('Object exists; updating with new configuration')
apiCallResponse = icontrol_put(host, username, password, '/mgmt/tm/ltm/virtual/~Common~ipsec_forwarding_vs', apiPayload)
if '"kind":"tm:ltm:virtual:virtualstate"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()
else:
print('Error! ' + apiCallResponse)
quit()
# Disable the ipsec.if.checkpolicy db variableprint('Disabling the db variable ipsec.if.checkpolicy to allow BGP routing')
apiPayload = {}
apiPayload['value'] = 'disable'apiCallResponse = icontrol_put(host,username,password,'/mgmt/tm/sys/db/ipsec.if.checkpolicy',apiPayload)
if '"kind":"tm:sys:db:dbstate"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()
# Enable BGP and BFD on route domain 0print('Enabling routing protocols on default route domain 0')
apiPayload['routingProtocol'] = ['BFD','BGP']
apiCallResponse = icontrol_patch(host,username,password,'/mgmt/tm/net/route-domain/~Common~0',apiPayload)
if '"kind":"tm:net:route-domain:route-domainstate"' in apiCallResponse:
print('Success!')
else:
print('Error!' + apiCallResponse)
quit()
# Sleep to let BGP start upprint('Waiting for BGP to start')
time.sleep(15)
# Create the BGP configuration CLI scriptprint('Creating the BGP configuration CLI script on the BIG-IP')
apiPayload = {}
apiPayload['kind'] = 'kind":"tm:cli:script:scriptstate'apiPayload['name'] = 'bgp_configuration'apiPayload['partition'] = 'Common'apiPayload['apiAnonymous'] = 'proc script::init {} {\n}\n\nproc script::run {} {\n set neighboraddr [lindex $tmsh::argv 1]\n set asnumber [lindex $tmsh::argv 2]\n set imishscript [open "/var/tmp/imish_script.tmp" "w"]\n puts $imishscript "enable"\n puts $imishscript "configure terminal"\n puts $imishscript "router bgp $asnumber"\n puts $imishscript "neighbor $neighboraddr remote-as $asnumber"\n puts $imishscript "neighbor $neighboraddr activate"\n puts $imishscript "neighbor $neighboraddr soft-reconfiguration inbound"\n puts $imishscript "neighbor $neighboraddr timers 10 30"\n puts $imishscript "neighbor $neighboraddr timers connect 10"\n puts $imishscript "end"\n puts $imishscript "write mem"\n close $imishscript\n set rc [ catch { exec imish -f /var/tmp/imish_script.tmp } result ]\n puts $rc\n puts $result\n}\n\nproc script::help {} {\n}\n\nproc script::tabc {} {\n}\n'apiCallResponse = icontrol_post(host,username,password,'/mgmt/tm/cli/script',apiPayload)
if '"kind":"tm:cli:script:scriptstate"' in apiCallResponse:
print('Success!')
elif 'already exists' in apiCallResponse:
print('Script already exists! Skipping creation')
else:
print('Error! ' + apiCallResponse)
# Create the BGP configurationprint('Creating BGP AS ' + vpn['bgp-as'] + ' with neighbor ' + vpn['tunnel-self-ip-remote'])
apiPayload = {}
apiPayload['command'] = 'run'apiPayload['name'] = 'bgp_configuration'apiPayload['utilCmdArgs'] = vpn['tunnel-self-ip-remote'] + ' ' + vpn['bgp-as']
apiCallResponse = icontrol_post(host,username,password,'/mgmt/tm/cli/script',apiPayload)
print('Script executed but BGP configuration should be manually confirmed!')
# Save the configurationprint('Saving the configuration')
apiPayload = {}
apiPayload['command'] = 'save'apiCallResponse = icontrol_post(host,username,password,'/mgmt/tm/sys/config',apiPayload)
if '"kind":"tm:sys:config:savestate","command":"save"' in apiCallResponse:
print('Success!')
else:
print('Error! ' + apiCallResponse)
quit()Tested this on version:
12.1Published Aug 13, 2019
Version 1.0G-Rob
Employee
F5 Solutions Engineer focused on cloud, automation, modern apps and excellent customer-focused service.G-Rob
Employee
F5 Solutions Engineer focused on cloud, automation, modern apps and excellent customer-focused service.No CommentsBe the first to comment
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)