zscaler-sdk-python 1.0.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zscaler/__init__.py +34 -0
- zscaler/cache/__init__.py +0 -0
- zscaler/cache/cache.py +105 -0
- zscaler/cache/no_op_cache.py +68 -0
- zscaler/cache/zscaler_cache.py +161 -0
- zscaler/constants.py +26 -0
- zscaler/errors/__init__.py +0 -0
- zscaler/errors/error.py +10 -0
- zscaler/errors/http_error.py +20 -0
- zscaler/errors/zscaler_api_error.py +24 -0
- zscaler/exceptions/__init__.py +1 -0
- zscaler/exceptions/exceptions.py +101 -0
- zscaler/logger.py +57 -0
- zscaler/ratelimiter/__init__.py +0 -0
- zscaler/ratelimiter/ratelimiter.py +39 -0
- zscaler/user_agent.py +23 -0
- zscaler/utils.py +577 -0
- zscaler/zia/__init__.py +657 -0
- zscaler/zia/activate.py +52 -0
- zscaler/zia/admin_and_role_management.py +344 -0
- zscaler/zia/apptotal.py +71 -0
- zscaler/zia/audit_logs.py +95 -0
- zscaler/zia/authentication_settings.py +98 -0
- zscaler/zia/client.py +88 -0
- zscaler/zia/cloud_apps.py +406 -0
- zscaler/zia/device_management.py +90 -0
- zscaler/zia/dlp.py +784 -0
- zscaler/zia/errors.py +37 -0
- zscaler/zia/firewall.py +1104 -0
- zscaler/zia/forwarding_control.py +271 -0
- zscaler/zia/isolation_profile.py +83 -0
- zscaler/zia/labels.py +180 -0
- zscaler/zia/locations.py +661 -0
- zscaler/zia/sandbox.py +180 -0
- zscaler/zia/security.py +236 -0
- zscaler/zia/ssl_inspection.py +175 -0
- zscaler/zia/traffic.py +853 -0
- zscaler/zia/url_categories.py +442 -0
- zscaler/zia/url_filtering.py +310 -0
- zscaler/zia/users.py +386 -0
- zscaler/zia/web_dlp.py +295 -0
- zscaler/zia/workload_groups.py +58 -0
- zscaler/zia/zpa_gateway.py +187 -0
- zscaler/zpa/__init__.py +683 -0
- zscaler/zpa/app_segments.py +331 -0
- zscaler/zpa/app_segments_inspection.py +311 -0
- zscaler/zpa/app_segments_pra.py +310 -0
- zscaler/zpa/certificates.py +234 -0
- zscaler/zpa/client.py +113 -0
- zscaler/zpa/cloud_connector_groups.py +75 -0
- zscaler/zpa/connectors.py +518 -0
- zscaler/zpa/emergency_access.py +178 -0
- zscaler/zpa/errors.py +37 -0
- zscaler/zpa/idp.py +83 -0
- zscaler/zpa/inspection.py +1012 -0
- zscaler/zpa/isolation_profile.py +85 -0
- zscaler/zpa/lss.py +568 -0
- zscaler/zpa/machine_groups.py +79 -0
- zscaler/zpa/policies.py +848 -0
- zscaler/zpa/posture_profiles.py +122 -0
- zscaler/zpa/privileged_remote_access.py +862 -0
- zscaler/zpa/provisioning.py +271 -0
- zscaler/zpa/saml_attributes.py +100 -0
- zscaler/zpa/scim_attributes.py +117 -0
- zscaler/zpa/scim_groups.py +146 -0
- zscaler/zpa/segment_groups.py +191 -0
- zscaler/zpa/server_groups.py +217 -0
- zscaler/zpa/servers.py +202 -0
- zscaler/zpa/service_edges.py +404 -0
- zscaler/zpa/trusted_networks.py +127 -0
- zscaler_sdk_python-1.0.0.dist-info/LICENSE.md +21 -0
- zscaler_sdk_python-1.0.0.dist-info/METADATA +59 -0
- zscaler_sdk_python-1.0.0.dist-info/RECORD +75 -0
- zscaler_sdk_python-1.0.0.dist-info/WHEEL +6 -0
- zscaler_sdk_python-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2023, Zscaler Inc.
|
|
4
|
+
#
|
|
5
|
+
# Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
# purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
# copyright notice and this permission notice appear in all copies.
|
|
8
|
+
#
|
|
9
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
import logging
|
|
19
|
+
|
|
20
|
+
from box import Box, BoxList
|
|
21
|
+
from requests import Response
|
|
22
|
+
|
|
23
|
+
from zscaler.utils import Iterator, snake_to_camel
|
|
24
|
+
from zscaler.zia import ZIAClient
|
|
25
|
+
|
|
26
|
+
class AdminAndRoleManagementAPI:
|
|
27
|
+
def __init__(self, client: ZIAClient):
|
|
28
|
+
self.rest = client
|
|
29
|
+
|
|
30
|
+
def list_users(self, **kwargs) -> BoxList:
|
|
31
|
+
"""
|
|
32
|
+
Returns a list of admin users.
|
|
33
|
+
|
|
34
|
+
Keyword Args:
|
|
35
|
+
include_auditor_users (bool, optional):
|
|
36
|
+
Include or exclude auditor user information in the list.
|
|
37
|
+
include_admin_users (bool, optional):
|
|
38
|
+
Include or exclude admin user information in the list. (default: True)
|
|
39
|
+
search (str, optional):
|
|
40
|
+
The search string used to partially match against an admin/auditor user's Login ID or Name.
|
|
41
|
+
page (int, optional):
|
|
42
|
+
Specifies the page offset.
|
|
43
|
+
page_size (int, optional):
|
|
44
|
+
Specifies the page size. The default size is 100, but the maximum size is 1000.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
list: The admin_users resource records.
|
|
48
|
+
|
|
49
|
+
Examples:
|
|
50
|
+
>>> users = zia.admin_and_role_management.list_users('admin@example.com')
|
|
51
|
+
|
|
52
|
+
"""
|
|
53
|
+
return BoxList(Iterator(self.rest, "adminUsers", **kwargs))
|
|
54
|
+
|
|
55
|
+
def get_user(self, user_id: str) -> Box:
|
|
56
|
+
"""
|
|
57
|
+
Returns information on the specified admin user id.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
user_id (str): The unique id of the admin user.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
:obj:`Box`: The admin user resource record.
|
|
64
|
+
|
|
65
|
+
Examples:
|
|
66
|
+
>>> print(zia.admin_and_role_management.get_user('987321202'))
|
|
67
|
+
|
|
68
|
+
"""
|
|
69
|
+
response = self.rest.get("/adminUsers/%s" % (user_id))
|
|
70
|
+
if isinstance(response, Response):
|
|
71
|
+
status_code = response.status_code
|
|
72
|
+
if status_code != 200:
|
|
73
|
+
return None
|
|
74
|
+
return response
|
|
75
|
+
|
|
76
|
+
def add_user(
|
|
77
|
+
self, name: str, login_name: str, email: str, password: str, **kwargs
|
|
78
|
+
) -> Box:
|
|
79
|
+
"""
|
|
80
|
+
Adds a new admin user to ZIA.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
name (str): The user's full name.
|
|
84
|
+
login_name (str):
|
|
85
|
+
The name that the admin user will use to login to ZIA in email format, i.e. `user@domain.tld.`
|
|
86
|
+
email (str): The email address for the admin user.
|
|
87
|
+
password (str): The password for the admin user.
|
|
88
|
+
**kwargs: Optional keyword args.
|
|
89
|
+
|
|
90
|
+
Keyword Args:
|
|
91
|
+
admin_scope (str): The scope of the admin's permissions, accepted values are:
|
|
92
|
+
``organization``, ``department``, ``location``, ``location_group``
|
|
93
|
+
comments (str): Additional information about the admin user.
|
|
94
|
+
disabled (bool): Set to ``True`` if you want the account disabled upon creation.
|
|
95
|
+
is_password_login_allowed (bool): Set to ``True`` to allow password login.
|
|
96
|
+
is_security_report_comm_enabled (bool):
|
|
97
|
+
Set to ``True`` to allow ZIA Security Update emails to be sent to the admin user.
|
|
98
|
+
is_service_update_comm_enabled (bool):
|
|
99
|
+
Set to ``True`` to allow ZIA Service Update emails to be sent to the admin user.
|
|
100
|
+
is_product_update_comm_enabled (bool):
|
|
101
|
+
Set to ``True`` to allow ZIA Product Update emails to be sent to the admin user.
|
|
102
|
+
is_password_expired (bool):
|
|
103
|
+
Set to ``True`` to expire the admin user's password upon creation.
|
|
104
|
+
is_exec_mobile_app_enabled (bool):
|
|
105
|
+
Set to ``True`` to enable to executive insights mobile application for the admin user.
|
|
106
|
+
role_id (str): The unique id for the admin role being assigned to the admin user.
|
|
107
|
+
scope_ids (list):
|
|
108
|
+
A list of entity ids for the admin user's scope. e.g. if the admin user has admin_scope set to
|
|
109
|
+
``department`` then you will need to provide a list of department ids.
|
|
110
|
+
**NOTE**: This param doesn't need to
|
|
111
|
+
be provided if the admin user's scope is set to ``organization``.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
:obj:`Box`: The newly created admin user resource record.
|
|
115
|
+
|
|
116
|
+
Examples:
|
|
117
|
+
|
|
118
|
+
Add an admin user with the minimum required params:
|
|
119
|
+
>>> admin_user = zia.admin_and_role_management.add_user(
|
|
120
|
+
... name="Jim Bob",
|
|
121
|
+
... login_name="jim@example.com",
|
|
122
|
+
... password="*********",
|
|
123
|
+
... email="jim@example.com")
|
|
124
|
+
|
|
125
|
+
Add an admin user with a department admin scope:
|
|
126
|
+
>>> admin_user = zia.admin_and_role_management.add_user(
|
|
127
|
+
... name="Jane Bob",
|
|
128
|
+
... login_name="jane@example.com",
|
|
129
|
+
... password="*********",
|
|
130
|
+
... email="jane@example.com,
|
|
131
|
+
... admin_scope="department",
|
|
132
|
+
... scope_ids = ['376542', '245688'])
|
|
133
|
+
|
|
134
|
+
Add an auditor user:
|
|
135
|
+
>>> auditor_user = zia.admin_and_role_management.add_user(
|
|
136
|
+
... name="Head Bob",
|
|
137
|
+
... login_name="head@example.com",
|
|
138
|
+
... password="*********",
|
|
139
|
+
... email="head@example.com,
|
|
140
|
+
... is_auditor=True)
|
|
141
|
+
|
|
142
|
+
"""
|
|
143
|
+
payload = {
|
|
144
|
+
"userName": name,
|
|
145
|
+
"loginName": login_name,
|
|
146
|
+
"email": email,
|
|
147
|
+
"password": password,
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
# Get the admin scope if provided
|
|
151
|
+
admin_scope = kwargs.pop("admin_scope", None)
|
|
152
|
+
|
|
153
|
+
# The default admin scope is organization so we don't really need to
|
|
154
|
+
# send it to ZIA as part of this API call. Otherwise if the user has
|
|
155
|
+
# supplied something different then we want to explicitly set that for
|
|
156
|
+
# the adminScopeType.
|
|
157
|
+
if admin_scope and admin_scope != "organization":
|
|
158
|
+
payload["adminScopeType"] = admin_scope.upper()
|
|
159
|
+
payload["adminScopeScopeEntities"] = []
|
|
160
|
+
|
|
161
|
+
# Add optional parameters to payload
|
|
162
|
+
for key, value in kwargs.items():
|
|
163
|
+
# If the user has supplied ids for the admin scope then we'll add
|
|
164
|
+
# them to the payload here. If the user doesn't supply them then
|
|
165
|
+
# ZIA will return an error.
|
|
166
|
+
if key == "scope_ids":
|
|
167
|
+
for scope_id in value:
|
|
168
|
+
payload["adminScopeScopeEntities"].append({"id": scope_id})
|
|
169
|
+
elif key == "role_id":
|
|
170
|
+
payload["role"] = {"id": value}
|
|
171
|
+
else:
|
|
172
|
+
payload[snake_to_camel(key)] = value
|
|
173
|
+
|
|
174
|
+
response = self.rest.post("adminUsers", json=payload)
|
|
175
|
+
if isinstance(response, Response):
|
|
176
|
+
# Handle error response
|
|
177
|
+
status_code = response.status_code
|
|
178
|
+
if status_code != 200:
|
|
179
|
+
raise Exception(
|
|
180
|
+
f"API call failed with status {status_code}: {response.json()}"
|
|
181
|
+
)
|
|
182
|
+
return response
|
|
183
|
+
|
|
184
|
+
def update_user(self, user_id: str, **kwargs) -> dict:
|
|
185
|
+
"""
|
|
186
|
+
Update an admin user.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
user_id (str): The unique id of the admin user to be updated.
|
|
190
|
+
**kwargs: Optional keyword args.
|
|
191
|
+
|
|
192
|
+
Keyword Args:
|
|
193
|
+
admin_scope (str): The scope of the admin's permissions, accepted values are:
|
|
194
|
+
``organization``, ``department``, ``location``, ``location_group``
|
|
195
|
+
comments (str): Additional information about the admin user.
|
|
196
|
+
disabled (bool): Set to ``True`` if you want the account disabled upon creation.
|
|
197
|
+
email (str): The email address for the admin user.
|
|
198
|
+
is_password_login_allowed (bool): Set to ``True`` to allow password login.
|
|
199
|
+
is_security_report_comm_enabled (bool):
|
|
200
|
+
Set to ``True`` to allow ZIA Security Update emails to be sent to the admin user.
|
|
201
|
+
is_service_update_comm_enabled (bool):
|
|
202
|
+
Set to ``True`` to allow ZIA Service Update emails to be sent to the admin user.
|
|
203
|
+
is_product_update_comm_enabled (bool):
|
|
204
|
+
Set to ``True`` to allow ZIA Product Update emails to be sent to the admin user.
|
|
205
|
+
is_password_expired (bool):
|
|
206
|
+
Set to ``True`` to expire the admin user's password upon creation.
|
|
207
|
+
is_exec_mobile_app_enabled (bool):
|
|
208
|
+
Set to ``True`` to enable to executive insights mobile application for the admin user.
|
|
209
|
+
name (str): The user's full name.
|
|
210
|
+
password (str): The password for the admin user.
|
|
211
|
+
role_id (str): The unique id for the admin role being assigned to the admin user.
|
|
212
|
+
scope_ids (list):
|
|
213
|
+
A list of entity ids for the admin user's scope. e.g. if the admin user has ``admin_scope`` set to
|
|
214
|
+
``department`` then you will need to provide a list of department ids.
|
|
215
|
+
**NOTE:** This param doesn't need to
|
|
216
|
+
be provided if the admin user's scope is set to `organization`.
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
:obj:`dict`: The updated admin user resource record.
|
|
220
|
+
|
|
221
|
+
Examples:
|
|
222
|
+
|
|
223
|
+
Update the email address for an admin user:
|
|
224
|
+
>>> user = zia.admin_and_role_management.update_user('99695301',
|
|
225
|
+
... email='jimbob@example.com')
|
|
226
|
+
|
|
227
|
+
Update the admin scope for an admin user to department:
|
|
228
|
+
>>> user = zia.admin_and_role_management.update_user('99695301',
|
|
229
|
+
... admin_scope='department',
|
|
230
|
+
... scope_ids=['3846532', '3846541'])
|
|
231
|
+
|
|
232
|
+
"""
|
|
233
|
+
|
|
234
|
+
# Get the resource record for the provided user id
|
|
235
|
+
payload = {snake_to_camel(k): v for k, v in self.get_user(user_id).items()}
|
|
236
|
+
|
|
237
|
+
# Get the admin scope if provided
|
|
238
|
+
admin_scope = kwargs.pop("admin_scope", None)
|
|
239
|
+
|
|
240
|
+
# The default admin scope is organization so we don't really need to
|
|
241
|
+
# send it to ZIA as part of this API call. Otherwise if the user has
|
|
242
|
+
# supplied something different then we want to explicitly set that for
|
|
243
|
+
# the adminScopeType.
|
|
244
|
+
if admin_scope and admin_scope != "organization":
|
|
245
|
+
payload["adminScopeType"] = admin_scope.upper()
|
|
246
|
+
payload["adminScopeScopeEntities"] = []
|
|
247
|
+
|
|
248
|
+
# Add optional parameters to payload
|
|
249
|
+
for key, value in kwargs.items():
|
|
250
|
+
# If the user has supplied ids for the admin scope then we'll add
|
|
251
|
+
# them to the payload here. If the user doesn't supply them then
|
|
252
|
+
# ZIA will return an error.
|
|
253
|
+
if key == "scope_ids":
|
|
254
|
+
for scope_id in value:
|
|
255
|
+
payload["adminScopeScopeEntities"].append({"id": scope_id})
|
|
256
|
+
elif key == "name":
|
|
257
|
+
# We renamed the username param to make it more meaningful for zscaler-sdk-python users
|
|
258
|
+
payload["userName"] = value
|
|
259
|
+
else:
|
|
260
|
+
payload[snake_to_camel(key)] = value
|
|
261
|
+
|
|
262
|
+
# Update payload
|
|
263
|
+
for key, value in kwargs.items():
|
|
264
|
+
payload[snake_to_camel(key)] = value
|
|
265
|
+
|
|
266
|
+
response = self.rest.put("/adminUsers/%s" % (user_id), json=payload)
|
|
267
|
+
if isinstance(response, Response) and not response.ok:
|
|
268
|
+
# Handle error response
|
|
269
|
+
raise Exception(
|
|
270
|
+
f"API call failed with status {response.status_code}: {response.json()}"
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
# Return the updated object
|
|
274
|
+
return self.get_user(user_id)
|
|
275
|
+
|
|
276
|
+
def delete_user(self, user_id: str) -> int:
|
|
277
|
+
"""
|
|
278
|
+
Deletes the specified admin user by id.
|
|
279
|
+
|
|
280
|
+
Args:
|
|
281
|
+
user_id (str): The unique id of the admin user.
|
|
282
|
+
|
|
283
|
+
Returns:
|
|
284
|
+
:obj:`int`: The response code for the request.
|
|
285
|
+
|
|
286
|
+
Examples:
|
|
287
|
+
>>> zia.admin_role_management.delete_admin_user('99272455')
|
|
288
|
+
|
|
289
|
+
"""
|
|
290
|
+
response = self.rest.delete("/adminUsers/%s" % (user_id))
|
|
291
|
+
return response.status_code
|
|
292
|
+
|
|
293
|
+
def list_roles(self, **kwargs) -> BoxList:
|
|
294
|
+
"""
|
|
295
|
+
Return a list of the configured admin roles in ZIA.
|
|
296
|
+
|
|
297
|
+
Args:
|
|
298
|
+
**kwargs: Optional keyword args.
|
|
299
|
+
|
|
300
|
+
Keyword Args:
|
|
301
|
+
include_auditor_role (bool): Set to ``True`` to include auditor role information in the response.
|
|
302
|
+
include_partner_role (bool): Set to ``True`` to include partner admin role information in the response.
|
|
303
|
+
|
|
304
|
+
Returns:
|
|
305
|
+
:obj:`BoxList`: A list of admin role resource records.
|
|
306
|
+
|
|
307
|
+
Examples:
|
|
308
|
+
Get a list of all configured admin roles:
|
|
309
|
+
>>> roles = zia.admin_and_management_roles.list_roles()
|
|
310
|
+
|
|
311
|
+
"""
|
|
312
|
+
payload = {snake_to_camel(key): value for key, value in kwargs.items()}
|
|
313
|
+
return self.rest.get("adminRoles/lite", params=payload)
|
|
314
|
+
|
|
315
|
+
def get_role(self, role_id: str) -> Box:
|
|
316
|
+
"""
|
|
317
|
+
Returns information on the specified admin user id.
|
|
318
|
+
|
|
319
|
+
Args:
|
|
320
|
+
user_id (str): The unique id of the admin user.
|
|
321
|
+
|
|
322
|
+
Returns:
|
|
323
|
+
:obj:`Box`: The admin user resource record.
|
|
324
|
+
|
|
325
|
+
Examples:
|
|
326
|
+
>>> print(zia.admin_and_role_management.get_user('987321202'))
|
|
327
|
+
|
|
328
|
+
"""
|
|
329
|
+
admin_role = next(user for user in self.list_roles() if user.id == int(role_id))
|
|
330
|
+
return admin_role
|
|
331
|
+
|
|
332
|
+
def get_roles_by_name(self, name):
|
|
333
|
+
roles = self.list_roles()
|
|
334
|
+
for role in roles:
|
|
335
|
+
if role.get("name") == name:
|
|
336
|
+
return role
|
|
337
|
+
return None
|
|
338
|
+
|
|
339
|
+
def get_roles_by_id(self, role_id):
|
|
340
|
+
roles = self.list_roles()
|
|
341
|
+
for role in roles:
|
|
342
|
+
if role.get("id") == role_id:
|
|
343
|
+
return role
|
|
344
|
+
return None
|
zscaler/zia/apptotal.py
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2023, Zscaler Inc.
|
|
4
|
+
#
|
|
5
|
+
# Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
# purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
# copyright notice and this permission notice appear in all copies.
|
|
8
|
+
#
|
|
9
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
16
|
+
|
|
17
|
+
from box import Box
|
|
18
|
+
|
|
19
|
+
from zscaler.zia import ZIAClient
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class AppTotalAPI:
|
|
23
|
+
def __init__(self, client: ZIAClient):
|
|
24
|
+
self.rest = client
|
|
25
|
+
|
|
26
|
+
def get_app(self, app_id: str, verbose: bool = False) -> Box:
|
|
27
|
+
"""
|
|
28
|
+
Searches the AppTotal App Catalog by app ID. If the app exists in the catalog, the app's information is
|
|
29
|
+
returned. If not, the app is submitted for analysis. After analysis is complete, a subsequent GET request is
|
|
30
|
+
required to fetch the app's information.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
app_id (str): The app ID to search for.
|
|
34
|
+
verbose (bool, optional): Defaults to False.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
:obj:`Box`: The response object.
|
|
38
|
+
|
|
39
|
+
Examples:
|
|
40
|
+
Return verbose information on an app with ID 12345::
|
|
41
|
+
|
|
42
|
+
zia.apptotal.get_app(app_id="12345", verbose=True)
|
|
43
|
+
|
|
44
|
+
"""
|
|
45
|
+
params = {
|
|
46
|
+
"app_id": app_id,
|
|
47
|
+
"verbose": verbose,
|
|
48
|
+
}
|
|
49
|
+
return self.rest.get("apps/app", params=params)
|
|
50
|
+
|
|
51
|
+
def scan_app(self, app_id: str) -> Box:
|
|
52
|
+
"""
|
|
53
|
+
Submits an app for analysis in the AppTotal Sandbox. After analysis is complete, a subsequent GET request is
|
|
54
|
+
required to fetch the app's information.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
app_id (str): The app ID to scan.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
:obj:`Box`: The response object.
|
|
61
|
+
|
|
62
|
+
Examples:
|
|
63
|
+
Scan an app with ID 12345::
|
|
64
|
+
|
|
65
|
+
zia.apptotal.scan_app(app_id="12345")
|
|
66
|
+
|
|
67
|
+
"""
|
|
68
|
+
payload = {
|
|
69
|
+
"appId": app_id,
|
|
70
|
+
}
|
|
71
|
+
return self.rest.post("apps/app", json=payload)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2023, Zscaler Inc.
|
|
4
|
+
#
|
|
5
|
+
# Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
# purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
# copyright notice and this permission notice appear in all copies.
|
|
8
|
+
#
|
|
9
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
from box import Box
|
|
19
|
+
|
|
20
|
+
from zscaler.zia import ZIAClient
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class AuditLogsAPI:
|
|
24
|
+
def __init__(self, client: ZIAClient):
|
|
25
|
+
self.rest = client
|
|
26
|
+
|
|
27
|
+
def status(self) -> Box:
|
|
28
|
+
"""
|
|
29
|
+
Get the status of a request for an audit log report.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
:obj:`Box`: Audit log report request status.
|
|
33
|
+
|
|
34
|
+
Examples:
|
|
35
|
+
>>> print(zia.audit_logs.status())
|
|
36
|
+
|
|
37
|
+
"""
|
|
38
|
+
return self.rest.get("auditlogEntryReport")
|
|
39
|
+
|
|
40
|
+
def create(self, start_time: str, end_time: str) -> int:
|
|
41
|
+
"""
|
|
42
|
+
Creates an audit log report for the specified time period and saves it as a CSV file. The report
|
|
43
|
+
includes audit information for every call made to the cloud service API during the specified time period.
|
|
44
|
+
Creating a new audit log report will overwrite a previously-generated report.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
start_time (str):
|
|
48
|
+
The timestamp, in epoch, of the admin's last login.
|
|
49
|
+
end_time (str):
|
|
50
|
+
The timestamp, in epoch, of the admin's last logout.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
:obj:`int`: The status code for the operation.
|
|
54
|
+
|
|
55
|
+
Examples:
|
|
56
|
+
>>> zia.audit_logs.create(start_time='1627221600000',
|
|
57
|
+
... end_time='1627271676622')
|
|
58
|
+
|
|
59
|
+
"""
|
|
60
|
+
payload = {
|
|
61
|
+
"startTime": start_time,
|
|
62
|
+
"endTime": end_time,
|
|
63
|
+
}
|
|
64
|
+
return self.rest.post(
|
|
65
|
+
"auditlogEntryReport", json=payload, box=False
|
|
66
|
+
).status_code
|
|
67
|
+
|
|
68
|
+
def cancel(self) -> int:
|
|
69
|
+
"""
|
|
70
|
+
Cancels the request to create an audit log report.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
:obj:`int`: The operation response code.
|
|
74
|
+
|
|
75
|
+
Examples:
|
|
76
|
+
>>> zia.audit_logs.cancel()
|
|
77
|
+
|
|
78
|
+
"""
|
|
79
|
+
return self.rest.delete("auditlogEntryReport", box=False).status_code
|
|
80
|
+
|
|
81
|
+
def get_report(self) -> str:
|
|
82
|
+
"""
|
|
83
|
+
Returns the most recently created audit log report.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
:obj:`str`: String representation of CSV file.
|
|
87
|
+
|
|
88
|
+
Examples:
|
|
89
|
+
Write report to CSV file:
|
|
90
|
+
|
|
91
|
+
>>> with open("audit_log.csv", "w+") as fh:
|
|
92
|
+
... fh.write(zia.audit_logs.get_report())
|
|
93
|
+
|
|
94
|
+
"""
|
|
95
|
+
return self.rest.get("auditlogEntryReport/download").text
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2023, Zscaler Inc.
|
|
4
|
+
#
|
|
5
|
+
# Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
# purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
# copyright notice and this permission notice appear in all copies.
|
|
8
|
+
#
|
|
9
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
from box import BoxList
|
|
19
|
+
|
|
20
|
+
from zscaler.zia import ZIAClient
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class AuthenticationSettingsAPI:
|
|
24
|
+
def __init__(self, client: ZIAClient):
|
|
25
|
+
self.rest = client
|
|
26
|
+
|
|
27
|
+
def get_exempted_urls(self) -> BoxList:
|
|
28
|
+
"""
|
|
29
|
+
Returns a list of exempted URLs.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
:obj:`BoxList`: A list of exempted URLs
|
|
33
|
+
|
|
34
|
+
Examples:
|
|
35
|
+
>>> for url in zia.authentication_settings.get_exempted_urls():
|
|
36
|
+
... pprint(url)
|
|
37
|
+
"""
|
|
38
|
+
response = self.rest.get("authSettings/exemptedUrls")
|
|
39
|
+
|
|
40
|
+
# Ensure the correct attribute key is used in the response check.
|
|
41
|
+
if "urls" in response:
|
|
42
|
+
return response.urls
|
|
43
|
+
else:
|
|
44
|
+
return BoxList()
|
|
45
|
+
|
|
46
|
+
def add_urls_to_exempt_list(self, url_list: list) -> BoxList:
|
|
47
|
+
"""
|
|
48
|
+
Adds the provided URLs to the exempt list.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
url_list (:obj:`list` of :obj:`str`):
|
|
52
|
+
The list of URLs to be added.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
:obj:`BoxList`: The complete and updated exempt list.
|
|
56
|
+
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
payload = {"urls": url_list}
|
|
60
|
+
|
|
61
|
+
resp = self.rest.post(
|
|
62
|
+
"authSettings/exemptedUrls?action=ADD_TO_LIST", json=payload
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# Check if the response object has a 'status_code' attribute before accessing it
|
|
66
|
+
if hasattr(resp, "status_code"):
|
|
67
|
+
if resp.status_code == 204:
|
|
68
|
+
return self.get_exempted_urls()
|
|
69
|
+
else:
|
|
70
|
+
# Handle case where resp is a Box object
|
|
71
|
+
if "urls" in resp:
|
|
72
|
+
return resp.urls
|
|
73
|
+
else:
|
|
74
|
+
return BoxList() # Return empty list if no URLs are present
|
|
75
|
+
|
|
76
|
+
def delete_urls_from_exempt_list(self, url_list: list) -> BoxList:
|
|
77
|
+
"""
|
|
78
|
+
Deletes the provided URLs from the exemption list.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
url_list (:obj:`list` of :obj:`str`):
|
|
82
|
+
The list of URLs to be removed.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
:obj:`BoxList`: The updated exemption list.
|
|
86
|
+
|
|
87
|
+
Examples:
|
|
88
|
+
>>> zia.authentication_settings.delete_urls_from_exempt_list(['example.com'])
|
|
89
|
+
|
|
90
|
+
"""
|
|
91
|
+
payload = {"urls": url_list}
|
|
92
|
+
resp = self.rest.post(
|
|
93
|
+
"authSettings/exemptedUrls?action=REMOVE_FROM_LIST", json=payload
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# Return the updated exemption list if the removal was successful.
|
|
97
|
+
if resp == 200:
|
|
98
|
+
return self.get_exempted_urls()
|
zscaler/zia/client.py
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2023, Zscaler Inc.
|
|
4
|
+
#
|
|
5
|
+
# Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
# purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
# copyright notice and this permission notice appear in all copies.
|
|
8
|
+
#
|
|
9
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ZIAClient:
|
|
19
|
+
def __init__():
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
def get(self, path: str, json=None, params=None, fail_safe: bool = False):
|
|
23
|
+
"""
|
|
24
|
+
Send a GET request to the ZIA API.
|
|
25
|
+
Parameters:
|
|
26
|
+
- path (str): API endpoint path.
|
|
27
|
+
- json (str): the request body.
|
|
28
|
+
- params (dict): the query params
|
|
29
|
+
"""
|
|
30
|
+
pass
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
def get_paginated_data(
|
|
34
|
+
self,
|
|
35
|
+
path: str = None,
|
|
36
|
+
data_key_name: str = None,
|
|
37
|
+
data_per_page: int = 500,
|
|
38
|
+
expected_status_code=200,
|
|
39
|
+
):
|
|
40
|
+
"""
|
|
41
|
+
Send a GET request to the ZIA API to fetch all pages of a resources.
|
|
42
|
+
Parameters:
|
|
43
|
+
- path (str): API endpoint path.
|
|
44
|
+
- data_key_name (str): list field key.
|
|
45
|
+
- data_per_page: the page size
|
|
46
|
+
- params (dict): the query params
|
|
47
|
+
"""
|
|
48
|
+
pass
|
|
49
|
+
|
|
50
|
+
def put(self, path: str, json=None, params=None):
|
|
51
|
+
"""
|
|
52
|
+
Send a PUT request to the ZIA API.
|
|
53
|
+
Parameters:
|
|
54
|
+
- path (str): API endpoint path.
|
|
55
|
+
- json (str): the request body.
|
|
56
|
+
- params (dict): the query params
|
|
57
|
+
"""
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
def patch(self, path: str, json=None, params=None):
|
|
61
|
+
"""
|
|
62
|
+
Send a PATCH request to the ZIA API.
|
|
63
|
+
Parameters:
|
|
64
|
+
- path (str): API endpoint path.
|
|
65
|
+
- json (str): the request body.
|
|
66
|
+
- params (dict): the query params
|
|
67
|
+
"""
|
|
68
|
+
pass
|
|
69
|
+
|
|
70
|
+
def post(self, path: str, json=None, params=None):
|
|
71
|
+
"""
|
|
72
|
+
Send a POST request to the ZIA API.
|
|
73
|
+
Parameters:
|
|
74
|
+
- path (str): API endpoint path.
|
|
75
|
+
- json (str): the request body.
|
|
76
|
+
- params (dict): the query params
|
|
77
|
+
"""
|
|
78
|
+
pass
|
|
79
|
+
|
|
80
|
+
def delete(self, path: str, json=None, params=None):
|
|
81
|
+
"""
|
|
82
|
+
Send a DELETE request to the ZIA API.
|
|
83
|
+
Parameters:
|
|
84
|
+
- path (str): API endpoint path.
|
|
85
|
+
- json (str): the request body.
|
|
86
|
+
- params (dict): the query params
|
|
87
|
+
"""
|
|
88
|
+
pass
|