]> gitweb.michael.orlitzky.com - untangle-https-backup.git/blob - src/untangle/untangle.py
82b29c445da89dda7decf2ccd2a5825223535c67
[untangle-https-backup.git] / src / untangle / untangle.py
1 import configparser
2 import http.cookiejar
3 import ssl
4 import urllib.parse
5 import urllib.request
6
7 class Untangle:
8 """
9 This class wraps one instance of Untangle. It gets initialized with
10 some configuration information, and then provides the methods to
11 retreive a backup.
12 """
13 def __init__(self, s):
14 """
15 Initialize this Untangle object with a ConfigParser section.
16 """
17 self.name = s.name
18 self.host = s['host']
19 self.username = s.get('username', 'admin')
20 self.password = s['password']
21 self.version = s.get('version', '13.1')
22 self.base_url = 'https://' + self.host + '/' # This never changes
23
24 # Sanity check the numerical version.
25 if self.version not in ['9', '10', '11', '12', '13', '13.1']:
26 msg = 'Invalid version "' + self.version + '" '
27 msg += 'in section "' + s.name + '"'
28 raise configparser.ParsingError(msg)
29
30 # Sanity check the boolean verify_cert parameter.
31 vc = s.get('verify_cert', 'False')
32 if vc == 'True':
33 self.verify_cert = True
34 elif vc == 'False':
35 self.verify_cert = False
36 else:
37 msg = 'Invalid value "' + vc + '" for verify_cert '
38 msg += 'in section "' + s.name + '"'
39 raise configparser.ParsingError(msg)
40
41 # Finally, create a URL opener to make HTTPS requests.
42 #
43 # First, create a cookie jar that we'll attach to our URL
44 # opener thingy.
45 cj = http.cookiejar.CookieJar()
46 cookie_proc = urllib.request.HTTPCookieProcessor(cj)
47
48 # SSL mumbo jumbo to make it ignore the certificate's hostname
49 # when verify_cert = False.
50 if self.verify_cert:
51 ssl_ctx = ssl.create_default_context()
52 else:
53 ssl_ctx = ssl._create_unverified_context()
54
55 https_handler = urllib.request.HTTPSHandler(context=ssl_ctx)
56
57 # Now Create a URL opener, and tell it to use our cookie jar
58 # and SSL context. We keep this around for future requests.
59 self.opener = urllib.request.build_opener(https_handler, cookie_proc)
60
61
62 def login(self):
63 """
64 Perform the HTTPS request to log in to the Untangle web admin
65 UI. The resulting session cookie is stored by our ``self.opener``.
66 """
67 login_path = 'auth/login?url=/setup/welcome.do&realm=Administrator'
68 url = self.base_url + login_path
69 post_vars = {'username': self.username, 'password': self.password }
70 post_data = urllib.parse.urlencode(post_vars).encode('ascii')
71 self.opener.open(url, post_data)
72
73
74 def get_backup(self):
75 """
76 Version-agnostic get-me-a-backup method. Dispatches to the
77 actual implementation based on ``self.version``.
78 """
79 if self.version == '9':
80 return self.get_backup_v9()
81 elif self.version in ['10', '11', '12', '13']:
82 # The procedure for v11, v12, or v13 is the same as for v10.
83 return self.get_backup_v10()
84 elif self.version == '13.1':
85 # But the minor update v13.1 moved the backup URL.
86 return self.get_backup_v13_1()
87
88
89 def get_backup_v9(self):
90 """
91 Retrieve a backup from Untangle version 9. This requires two
92 requests; the first just hits the page, and the second actually
93 retrieves the backup file.
94
95 Returns the binary HTTPS response (i.e. the file).
96 """
97 url = self.base_url + '/webui/backup'
98 post_vars = {'action': 'requestBackup'}
99 post_data = urllib.parse.urlencode(post_vars).encode('ascii')
100 self.opener.open(url, post_data)
101
102 url = self.base_url + 'webui/backup?action=initiateDownload'
103 with self.opener.open(url) as response:
104 return response.read()
105
106
107 def get_backup_v10(self):
108 """
109 Retrieve a backup from Untangle version 10.
110
111 Returns the binary HTTPS response (i.e. the file).
112 """
113 url = self.base_url + '/webui/download'
114 post_vars = {'type': 'backup'}
115 post_data = urllib.parse.urlencode(post_vars).encode('ascii')
116 with self.opener.open(url, post_data) as response:
117 return response.read()
118
119
120 def get_backup_v13_1(self):
121 """
122 Retrieve a backup from Untangle version 13.1. This
123 differs from v13 (and v12, and v11,...) by only one word
124 in the URL: "webui" becomes "admin".
125
126 Returns the binary HTTPS response (i.e. the file).
127 """
128 url = self.base_url + '/admin/download'
129 post_vars = {'type': 'backup'}
130 post_data = urllib.parse.urlencode(post_vars).encode('ascii')
131 with self.opener.open(url, post_data) as response:
132 return response.read()