· 6 years ago · Nov 29, 2019, 05:54 PM
1import json
2import urllib.request,urllib.parse
3import ssl
4import requests
5
6#from xml.etree import cElementTree as ElementTree
7#import lxml.etree as ET
8#from bs4 import BeautifulSoup
9
10ctx = ssl.create_default_context()
11ctx.check_hostname = False
12ctx.verify_mode = ssl.CERT_NONE
13
14HOST = "192.168.1.254"
15USER = "apiadmin"
16PWRD = "testpassword"
17
18class XmlDictConfig(dict):
19 '''
20 I am only using this class incase I switch to XML API...
21 don't really need for RESTAPI but figured I'd go ahead and
22 Example usage:
23
24 >>> tree = ElementTree.parse('your_file.xml')
25 >>> root = tree.getroot()
26 >>> xmldict = XmlDictConfig(root)
27
28 Or, if you want to use an XML string:
29
30 >>> root = ElementTree.XML(xml_string)
31 >>> xmldict = XmlDictConfig(root)
32
33 And then use xmldict for what it is... a dict.
34 '''
35 def __init__(self, parent_element):
36 if parent_element.items():
37 self.update(dict(parent_element.items()))
38 for element in parent_element:
39 if element:
40 # treat like dict - we assume that if the first two tags
41 # in a series are different, then they are all different.
42 if len(element) == 1 or element[0].tag != element[1].tag:
43 aDict = XmlDictConfig(element)
44 # treat like list - we assume that if the first two tags
45 # in a series are the same, then the rest are the same.
46 else:
47 # here, we put the list in dictionary; the key is the
48 # tag name the list elements all share in common, and
49 # the value is the list itself
50 aDict = {element[0].tag: XmlListConfig(element)}
51 # if the tag has attributes, add those to the dict
52 if element.items():
53 aDict.update(dict(element.items()))
54 self.update({element.tag: aDict})
55 # this assumes that if you've got an attribute in a tag,
56 # you won't be having any text. This may or may not be a
57 # good idea -- time will tell. It works for the way we are
58 # currently doing XML configuration files...
59 elif element.items():
60 self.update({element.tag: dict(element.items())})
61 # finally, if there are no child tags and no attributes, extract
62 # the text
63 else:
64 self.update({element.tag: element.text})
65class api: #DEFINITION OF AN API INSTANCE
66 def __init__(self,hostname,user,pwrd):
67 self.hostname = hostname
68 self.user = user
69 self.pwrd = pwrd
70 key = ''
71
72def getKey(api): #GET API KEY FROM NGFW
73 url = "https://{0}/api/?type=keygen&user={1}&password={2}".format(api.hostname,api.user,api.pwrd)
74 request = urllib.request.urlopen(url,context=ctx)
75 if (request.getcode() == 200):
76 response = str(request.read())
77 return (str(response).split('<key>')[1].split('</key>')[0])
78
79def testAPI(api): #JUST A TEST, NOT USED IN THIS SCRIPT
80 url = "https://{0}//api/?type=op&cmd=<show><system><info></info></system></show>&key={1}".format(api.hostname,api.key)
81 request = urllib.request.urlopen(url,context=ctx)
82 if request.getcode()==200:
83 return str(request.read()).split('b\'')[1]
84
85def getInterfaces(api): #ENUMERATE TUNNEL INTERFACES
86 req = urllib.request.Request('https://192.168.1.254/restapi/v9.1/Network/TunnelInterfaces?name=tunnel')
87 req.add_header('X-PAN-KEY',api.key)
88 req.add_header('Content-Type','application/json')
89 try:
90 resp = urllib.request.urlopen(req,context=ctx)
91 print(resp.getcode())
92 print(resp.read())
93 except urllib.request.HTTPError as e:
94 print(e)
95
96def createTunnel(next,api): #ATTEMPT TO CREATE TUNNEL SUBINTERFACE VIA RESTAPI
97#THIS IS MY REQUESTS MODULE IMPLEMENTATION
98# mydict = {"entry": {"@name": "a"}}
99# mydata = urllib.parse.urlencode(mydict).encode('utf-8')
100# req = urllib.request.Request('https://{}/restapi/v9.1/Network/TunnelInterfaces?name=tunnel'.format(api.hostname),mydata)
101# data = json.loads('{"entry": {"@name": "2"}}')
102# headers = {}
103# headers ={"X-PAN-KEY" : api.key}
104# url = 'https://{}/restapi/v9.1/Network/TunnelInterfaces'.format(api.hostname)
105# params = {"name":"tunnel"}
106# try:
107# response = requests.post(url,params=params,data=data,headers=headers,verify=False)
108# print(response.status_code)
109# print(response)
110# except requests.HTTPError as e:
111# print(e)
112
113
114#THIS IS MY URLLIB BASED IMPLEMENTATION. NEITHER WORK :/
115 myparams = {"name": "tunnel"} #SET QUERY PARAM
116 params = urllib.parse.urlencode(myparams)
117 mydict = { "entry": { "@name": "2" } }
118 mydata = urllib.parse.urlencode(mydict).encode('utf-8') #ENCODE DATA TO BE USED IN POST
119 req = urllib.request.Request('https://{}/restapi/v9.1/Network/TunnelInterfaces?'.format(api.hostname)+params,mydata) #CREATE POST REQUEST WITH URL, PARAMS, and DATA
120 req.add_header('X-PAN-KEY', api.key) #ADD API KEY TO HEADER
121 req.add_header('Content-Type', 'application/json') #DEFINE JSON CONTENT TYPE IN HEADER
122
123#ATTEMPT TO POST DATA TO API,
124 try:
125 resp = urllib.request.urlopen(req,context=ctx)
126 print resp.read()
127 except urllib.request.HTTPError as e: #IF EXCEPTION RAISED, PRINT HTTP ERROR
128 print(e)
129
130
131def getNextTunnel(api): #FIND NEXT USABLE TUNNEL SUBINTERFACE - THIS IS NOT FULLY IMPLEMENTED, IVE HARDCODED A VALUE OF 1 FOR TIME BEING, IN FUTURE IT WILL USE @TOTALCOUNT key pair
132 req = urllib.request.Request('https://{}/restapi/v9.1/Network/TunnelInterfaces'.format(api.hostname))
133 req.add_header('X-PAN-KEY',api.key)
134 req.add_header('Content-Type','application/json')
135 resp = urllib.request.urlopen(req,context=ctx)
136 if resp.getcode()==200:
137 d = json.loads(resp.read())
138 nextTunnel = (int(d['result']['entry'][1]['@name'].split('tunnel.')[1]) + 1)
139 return nextTunnel
140
141x = api(HOST,USER,PWRD) #CREATE API INSTANCE
142x.key = (getKey(x)) #GENERATE API KEY, ADD TO INSTANCE
143createTunnel(getNextTunnel(x),x) #ATTEMPT TO CREATE TUNNEL