cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
504
Views
0
Helpful
1
Replies

Cisco ASA API and VPN builds

Good evening, everyone.

I'm working with the ASA API to try and automate VPN builds for us.

Working with an API is new to me, but I'm trying to apply what I've learned in Python to ensure VPN builds are about as simple as filling in a few lines and clicking a button.

I have most of the API POST commands sorted out, but there is one variable that I'm having trouble dealing with.

For the most part, all of my POST values are unique and provided by our VPN build tech when filling out a form.

Example: network objects, ACL to be created, peer IP and PSK.

However, there is one value that I can't get created dynamically.

That value is the crypto map sequence number. 

It appears that the tech must provide this number, or we'll receive an error in the ASA response.

I'm wondering if I'm missing something here, or if we have to query (GET) the ASA API to find the next available crypto map sequence number.

I don't think that's too hard to do, but I'd like to avoid the work if at all possible.

Here's the POST (Python) to create my new crypto map entry.

Notice that the sequence number is listed, and that it is required:

#!/usr/bin/python

import cgi
import base64
import json
import sys
import urllib2
import ssl
ssl._create_default_https_context = ssl._create_unverified_context


form = cgi.FieldStorage()

sequence = form.getvalue('sequence')
company_name = form.getvalue('company_name')
remote = form.getvalue('remote')
proposal = form.getvalue('proposal')
tech = form.getvalue('tech')
phone = form.getvalue('phone')
e_mail = form.getvalue('e_mail')

acl = "%s_%s_%s" % (sequence, company_name, remote)
remark = "/// %s %s %s ///" % (tech, phone, e_mail)

api_path = "/api/vpn/cryptomaps/outside/entries/outside" # param
url = server + api_path
f = None


post_data = {
"kind": "object#cryptoMapStaticEntry",
"sequence": sequence,
"peer": [
"%s" % peer_ip
],
"matchingTrafficSelector": {
"kind": "objectRef#ExtendedACL",
"objectId": "%s" % acl
},
"deviceCertificate": "",
"sendCACertificateChain": False,
"ikeNegotiationMode": "main",
"ikeNegotiationGroup": "group5",
"disableNat": False,
"connectionType": "bidirectional",
"saVolume": 4608000,
"saLifetime": 28800,
"enableReverseRoute": False,
"ikev2Proposals": [],
"validateICMPErrorMsg": False,
"ikev1Proposals": [
{
"kind": "objectRef#ikev1proposal",
"objectId": "%s" % proposal
}
]
}


req = urllib2.Request(url, json.dumps(post_data), headers)
base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
req.add_header("Authorization", "Basic %s" % base64string)


try:
f = urllib2.urlopen (req)
status_code = f.getcode()
print "<br><br><b>Crypto Map</b>:<br>"
print "Status code is "+str(status_code)+"<br>"
if status_code == 201:
print '<span class="label label-success">Success</span>'
except urllib2.HTTPError, err:
print "<br><br><b>Tunnel Group - PSK</b>:<br>"
print '<span class="label label-danger">Error</span> HTTP Status code: '+str(err.code)+'<br>'
try:
json_error = json.loads(err.read())
if json_error:
print json.dumps(json_error, sort_keys=True, indent=4, separators=(',', ': '))
except ValueError:
pass
finally:
if f:
f.close()
1 Reply 1

Philip D'Ath
VIP Alumni
VIP Alumni

It is a 16 bit value.  You could always try generating a random value.  You could also test if your randomly chosen value exists and if so generate another random value and repeat.