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
zscaler/zia/dlp.py
ADDED
|
@@ -0,0 +1,784 @@
|
|
|
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, BoxList
|
|
19
|
+
from requests import Response
|
|
20
|
+
|
|
21
|
+
from zscaler.utils import snake_to_camel
|
|
22
|
+
from zscaler.zia import ZIAClient
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class DLPAPI:
|
|
26
|
+
def __init__(self, client: ZIAClient):
|
|
27
|
+
self.rest = client
|
|
28
|
+
|
|
29
|
+
def list_dicts(self, query: str = None) -> BoxList:
|
|
30
|
+
"""
|
|
31
|
+
Returns a list of all custom and predefined ZIA DLP Dictionaries.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
query (str): A search string used to match against a DLP dictionary's name or description attributes.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
:obj:`BoxList`: A list containing ZIA DLP Dictionaries.
|
|
38
|
+
|
|
39
|
+
Examples:
|
|
40
|
+
Print all dictionaries
|
|
41
|
+
|
|
42
|
+
>>> for dictionary in zia.dlp.list_dicts():
|
|
43
|
+
... pprint(dictionary)
|
|
44
|
+
|
|
45
|
+
Print dictionaries that match the name or description 'GDPR'
|
|
46
|
+
|
|
47
|
+
>>> pprint(zia.dlp.list_dicts('GDPR'))
|
|
48
|
+
|
|
49
|
+
"""
|
|
50
|
+
payload = {"search": query}
|
|
51
|
+
list = self.rest.get(path="/dlpDictionaries", params=payload)
|
|
52
|
+
if isinstance(list, Response):
|
|
53
|
+
return None
|
|
54
|
+
return list
|
|
55
|
+
|
|
56
|
+
def get_dict(self, dict_id: str) -> Box:
|
|
57
|
+
"""
|
|
58
|
+
Returns the DLP Dictionary that matches the specified DLP Dictionary id.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
dict_id (str): The unique id for the DLP Dictionary.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
:obj:`Box`: The ZIA DLP Dictionary resource record.
|
|
65
|
+
|
|
66
|
+
Examples:
|
|
67
|
+
>>> pprint(zia.dlp.get_dict('3'))
|
|
68
|
+
|
|
69
|
+
"""
|
|
70
|
+
response = self.rest.get("/dlpDictionaries/%s" % (dict_id))
|
|
71
|
+
if isinstance(response, Response):
|
|
72
|
+
status_code = response.status_code
|
|
73
|
+
if status_code != 200:
|
|
74
|
+
return None
|
|
75
|
+
return response
|
|
76
|
+
|
|
77
|
+
def add_dict(
|
|
78
|
+
self, name: str, custom_phrase_match_type: str, dictionary_type: str, **kwargs
|
|
79
|
+
) -> Box:
|
|
80
|
+
"""
|
|
81
|
+
Add a new Patterns and Phrases DLP Dictionary to ZIA.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
name (str): The name of the DLP Dictionary.
|
|
85
|
+
match_type (str): The DLP custom phrase/pattern match type. Accepted values are ``all`` or ``any``.
|
|
86
|
+
**kwargs: Optional keyword args.
|
|
87
|
+
|
|
88
|
+
Keyword Args:
|
|
89
|
+
description (str): Additional information about the DLP Dictionary.
|
|
90
|
+
phrases (list):
|
|
91
|
+
A list of DLP phrases, with each phrase provided by a tuple following the convention
|
|
92
|
+
(`action`, `pattern`). Accepted actions are ``all`` or ``unique``. E.g.
|
|
93
|
+
|
|
94
|
+
.. code-block:: python
|
|
95
|
+
|
|
96
|
+
('all', 'TOP SECRET')
|
|
97
|
+
('unique', 'COMMERCIAL-IN-CONFIDENCE')
|
|
98
|
+
|
|
99
|
+
patterns (list):
|
|
100
|
+
A list of DLP patterns, with each pattern provided by a tuple following the convention
|
|
101
|
+
(`action`, `pattern`). Accepted actions are ``all`` or ``unique``. E.g.
|
|
102
|
+
|
|
103
|
+
.. code-block:: python
|
|
104
|
+
|
|
105
|
+
('all', '\d{2} \d{3} \d{3} \d{3}')
|
|
106
|
+
('unique', '[A-Z]{6}[A-Z0-9]{2,5}')
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
:obj:`Box`: The newly created DLP Dictionary resource record.
|
|
110
|
+
|
|
111
|
+
Examples:
|
|
112
|
+
Match text found that contains an IPv4 address using patterns:
|
|
113
|
+
|
|
114
|
+
>>> zia.dlp.add_dict(name='IPv4 Addresses',
|
|
115
|
+
... description='Matches IPv4 address pattern.',
|
|
116
|
+
... match_type='all',
|
|
117
|
+
... patterns=[
|
|
118
|
+
... ('all', '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(/(\d|[1-2]\d|3[0-2]))?')
|
|
119
|
+
... ]))
|
|
120
|
+
|
|
121
|
+
Match text found that contains government document caveats using phrases.
|
|
122
|
+
|
|
123
|
+
>>> zia.dlp.add_dict(name='Gov Document Caveats',
|
|
124
|
+
... description='Matches government classification caveats.',
|
|
125
|
+
... match_type='any',
|
|
126
|
+
... phrases=[
|
|
127
|
+
... ('all', 'TOP SECRET'),
|
|
128
|
+
... ('all', 'SECRET'),
|
|
129
|
+
... ('all', 'CONFIDENTIAL')
|
|
130
|
+
... ]))
|
|
131
|
+
|
|
132
|
+
Match text found that meets the criteria for a Secret Project's document markings using phrases and
|
|
133
|
+
patterns:
|
|
134
|
+
|
|
135
|
+
>>> zia.dlp.add_dict(name='Secret Project Documents',
|
|
136
|
+
... description='Matches documents created for the Secret Project.',
|
|
137
|
+
... match_type='any',
|
|
138
|
+
... phrases=[
|
|
139
|
+
... ('all', 'Project Umbrella'),
|
|
140
|
+
... ('all', 'UMBRELLA')
|
|
141
|
+
... ],
|
|
142
|
+
... patterns=[
|
|
143
|
+
... ('unique', '\d{1,2}-\d{1,2}-[A-Z]{5}')
|
|
144
|
+
... ]))
|
|
145
|
+
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
payload = {
|
|
149
|
+
"name": name,
|
|
150
|
+
"customPhraseMatchType": custom_phrase_match_type,
|
|
151
|
+
"dictionaryType": dictionary_type,
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
# Process additional keyword arguments
|
|
155
|
+
for key, value in kwargs.items():
|
|
156
|
+
# Convert the key to camelCase and assign the value
|
|
157
|
+
camel_key = snake_to_camel(key)
|
|
158
|
+
payload[camel_key] = value
|
|
159
|
+
|
|
160
|
+
response = self.rest.post("dlpDictionaries", json=payload)
|
|
161
|
+
if isinstance(response, Response):
|
|
162
|
+
# Handle non-successful status codes
|
|
163
|
+
status_code = response.status_code
|
|
164
|
+
raise Exception(
|
|
165
|
+
f"API call failed with status {status_code}: {response.json()}"
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
return response
|
|
169
|
+
|
|
170
|
+
def update_dict(self, dict_id: str, **kwargs) -> Box:
|
|
171
|
+
"""
|
|
172
|
+
Updates the specified DLP Dictionary.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
dict_id (str): The unique id of the DLP Dictionary.
|
|
176
|
+
**kwargs: Optional keyword args.
|
|
177
|
+
|
|
178
|
+
Keyword Args:
|
|
179
|
+
description (str): Additional information about the DLP Dictionary.
|
|
180
|
+
match_type (str): The DLP custom phrase/pattern match type. Accepted values are ``all`` or ``any``.
|
|
181
|
+
name (str): The name of the DLP Dictionary.
|
|
182
|
+
phrases (list):
|
|
183
|
+
A list of DLP phrases, with each phrase provided by a tuple following the convention
|
|
184
|
+
(`action`, `pattern`). Accepted actions are ``all`` or ``unique``. E.g.
|
|
185
|
+
|
|
186
|
+
.. code-block:: python
|
|
187
|
+
|
|
188
|
+
('all', 'TOP SECRET')
|
|
189
|
+
('unique', 'COMMERCIAL-IN-CONFIDENCE')
|
|
190
|
+
|
|
191
|
+
patterns (list):
|
|
192
|
+
A list of DLP pattersn, with each pattern provided by a tuple following the convention
|
|
193
|
+
(`action`, `pattern`). Accepted actions are ``all`` or ``unique``. E.g.
|
|
194
|
+
|
|
195
|
+
.. code-block:: python
|
|
196
|
+
|
|
197
|
+
('all', '\d{2} \d{3} \d{3} \d{3}')
|
|
198
|
+
('unique', '[A-Z]{6}[A-Z0-9]{2,5}')
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
:obj:`Box`: The updated DLP Dictionary resource record.
|
|
202
|
+
|
|
203
|
+
Examples:
|
|
204
|
+
Update the name of a DLP Dictionary:
|
|
205
|
+
|
|
206
|
+
>>> zia.dlp.update_dict('3',
|
|
207
|
+
... name='IPv4 and IPv6 Addresses')
|
|
208
|
+
|
|
209
|
+
Update the description and phrases for a DLP Dictionary.
|
|
210
|
+
|
|
211
|
+
>>> zia.dlp.update_dict('4',
|
|
212
|
+
... description='Updated government caveats.'
|
|
213
|
+
... phrases=[
|
|
214
|
+
... ('all', 'TOP SECRET'),
|
|
215
|
+
... ('all', 'SECRET'),
|
|
216
|
+
... ('all', 'PROTECTED')
|
|
217
|
+
... ])
|
|
218
|
+
|
|
219
|
+
"""
|
|
220
|
+
# Fetch the existing dictionary details
|
|
221
|
+
existing_dict = self.get_dict(dict_id)
|
|
222
|
+
|
|
223
|
+
# Construct the payload for update
|
|
224
|
+
payload = {
|
|
225
|
+
"id": dict_id,
|
|
226
|
+
"name": existing_dict.get("name"),
|
|
227
|
+
"customPhraseMatchType": existing_dict.get("customPhraseMatchType"),
|
|
228
|
+
"dictionaryType": existing_dict.get("dictionaryType"),
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
# Process additional keyword arguments
|
|
232
|
+
for key, value in kwargs.items():
|
|
233
|
+
# Convert the key to camelCase and assign the value
|
|
234
|
+
camel_key = snake_to_camel(key)
|
|
235
|
+
payload[camel_key] = value
|
|
236
|
+
|
|
237
|
+
response = self.rest.put(f"/dlpDictionaries/{dict_id}", json=payload)
|
|
238
|
+
if isinstance(response, Response):
|
|
239
|
+
status_code = response.status_code
|
|
240
|
+
raise Exception(
|
|
241
|
+
f"API call failed with status {status_code}: {response.json()}"
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
# Return the updated object
|
|
245
|
+
return self.get_dict(dict_id)
|
|
246
|
+
|
|
247
|
+
def delete_dict(self, dict_id: str) -> int:
|
|
248
|
+
"""
|
|
249
|
+
Deletes the DLP Dictionary that matches the specified DLP Dictionary id.
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
dict_id (str): The unique id for the DLP Dictionary.
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
:obj:`int`: The status code for the operation.
|
|
256
|
+
|
|
257
|
+
Examples:
|
|
258
|
+
>>> zia.dlp.delete_dict('8')
|
|
259
|
+
|
|
260
|
+
"""
|
|
261
|
+
response = self.rest.delete("/dlpDictionaries/%s" % (dict_id))
|
|
262
|
+
return response.status_code
|
|
263
|
+
|
|
264
|
+
def validate_dict(self, pattern: str) -> Box:
|
|
265
|
+
"""
|
|
266
|
+
Validates the provided pattern for usage in a DLP Dictionary.
|
|
267
|
+
|
|
268
|
+
Note: The ZIA API documentation doesn't provide information on how to structure a request for this API endpoint.
|
|
269
|
+
This endpoint is returning a valid response but validation isn't failing for obvious wrong patterns. Use at
|
|
270
|
+
own risk.
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
pattern (str): DLP Pattern for evaluation.
|
|
274
|
+
|
|
275
|
+
Returns:
|
|
276
|
+
:obj:`Box`: Information on the provided pattern.
|
|
277
|
+
|
|
278
|
+
"""
|
|
279
|
+
payload = {"data": pattern}
|
|
280
|
+
|
|
281
|
+
response = self.rest.post(
|
|
282
|
+
path="dlpDictionaries/validateDlpPattern", json=payload
|
|
283
|
+
)
|
|
284
|
+
if isinstance(response, Response):
|
|
285
|
+
return None
|
|
286
|
+
return response
|
|
287
|
+
|
|
288
|
+
# TODO: implement the remaining
|
|
289
|
+
def add_dlp_engine(
|
|
290
|
+
self,
|
|
291
|
+
name: str,
|
|
292
|
+
engine_expression=None,
|
|
293
|
+
custom_dlp_engine=None,
|
|
294
|
+
description=None,
|
|
295
|
+
) -> Box:
|
|
296
|
+
"""
|
|
297
|
+
Adds a new dlp engine.
|
|
298
|
+
...
|
|
299
|
+
"""
|
|
300
|
+
|
|
301
|
+
payload = {
|
|
302
|
+
"name": name,
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if engine_expression is not None:
|
|
306
|
+
payload["engineExpression"] = engine_expression
|
|
307
|
+
|
|
308
|
+
if custom_dlp_engine is not None:
|
|
309
|
+
payload["customDlpEngine"] = custom_dlp_engine
|
|
310
|
+
|
|
311
|
+
if description is not None:
|
|
312
|
+
payload["description"] = description
|
|
313
|
+
|
|
314
|
+
# Convert the payload keys to camelCase
|
|
315
|
+
camel_payload = {snake_to_camel(key): value for key, value in payload.items()}
|
|
316
|
+
|
|
317
|
+
response = self.rest.post("dlpEngines", json=camel_payload)
|
|
318
|
+
if isinstance(response, Response):
|
|
319
|
+
# this is only true when the creation failed (status code is not 2xx)
|
|
320
|
+
status_code = response.status_code
|
|
321
|
+
# Handle error response
|
|
322
|
+
raise Exception(
|
|
323
|
+
f"API call failed with status {status_code}: {response.json()}"
|
|
324
|
+
)
|
|
325
|
+
return response
|
|
326
|
+
|
|
327
|
+
def update_dlp_engine(self, engine_id: str, **kwargs) -> Box:
|
|
328
|
+
"""
|
|
329
|
+
Updates an existing dlp engine.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
engine_id (str): The unique ID for the dlp engine that is being updated.
|
|
333
|
+
**kwargs: Optional keyword args.
|
|
334
|
+
|
|
335
|
+
Keyword Args:
|
|
336
|
+
name (str): The order of the rule, defaults to adding rule to bottom of list.
|
|
337
|
+
description (str): The admin rank of the rule.
|
|
338
|
+
engine_expression (str, optional): The logical expression defining a DLP engine by
|
|
339
|
+
combining DLP dictionaries using logical operators: All (AND), Any (OR), Exclude (NOT),
|
|
340
|
+
and Sum (total number of content matches).
|
|
341
|
+
custom_dlp_engine (bool, optional): If true, indicates a custom DLP engine.
|
|
342
|
+
description (str, optional): The DLP engine description.
|
|
343
|
+
|
|
344
|
+
Returns:
|
|
345
|
+
:obj:`Box`: The updated dlp engine resource record.
|
|
346
|
+
|
|
347
|
+
Examples:
|
|
348
|
+
Update the dlp engine:
|
|
349
|
+
|
|
350
|
+
>>> zia.dlp.add_dlp_engine(name='new_dlp_engine',
|
|
351
|
+
... description='TT#1965432122',
|
|
352
|
+
... engine_expression="((D63.S > 1))",
|
|
353
|
+
... custom_dlp_engine=False)
|
|
354
|
+
|
|
355
|
+
Update a rule to enable custom dlp engine:
|
|
356
|
+
|
|
357
|
+
>>> zia.dlp.add_dlp_engine('976597',
|
|
358
|
+
... custom_dlp_engine=True,
|
|
359
|
+
... engine_expression="((D63.S > 1))",
|
|
360
|
+
... description="TT#1965232866")
|
|
361
|
+
|
|
362
|
+
"""
|
|
363
|
+
# Set payload to value of existing record
|
|
364
|
+
payload = {
|
|
365
|
+
snake_to_camel(k): v for k, v in self.get_dlp_engines(engine_id).items()
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
# Add optional parameters to payload
|
|
369
|
+
for key, value in kwargs.items():
|
|
370
|
+
payload[snake_to_camel(key)] = value
|
|
371
|
+
|
|
372
|
+
response = self.rest.put(f"/dlpEngines/{engine_id}", json=payload)
|
|
373
|
+
if isinstance(response, Response) and response.status_code != 200:
|
|
374
|
+
raise Exception(
|
|
375
|
+
f"API call failed with status {response.status_code}: {response.json()}"
|
|
376
|
+
)
|
|
377
|
+
return self.get_dlp_engines(engine_id)
|
|
378
|
+
|
|
379
|
+
def delete_dlp_engine(self, engine_id: str) -> int:
|
|
380
|
+
"""
|
|
381
|
+
Deletes the specified dlp engine.
|
|
382
|
+
|
|
383
|
+
Args:
|
|
384
|
+
engine_id (str): The unique identifier for the dlp engine.
|
|
385
|
+
|
|
386
|
+
Returns:
|
|
387
|
+
:obj:`int`: The status code for the operation.
|
|
388
|
+
|
|
389
|
+
Examples:
|
|
390
|
+
>>> zia.dlp.delete_dlp_engine('278454')
|
|
391
|
+
|
|
392
|
+
"""
|
|
393
|
+
response = self.rest.delete("/dlpEngines/%s" % (engine_id))
|
|
394
|
+
return response.status_code
|
|
395
|
+
|
|
396
|
+
def list_dlp_engines(self, query: str = None) -> BoxList:
|
|
397
|
+
"""
|
|
398
|
+
Returns the list of ZIA DLP Engines.
|
|
399
|
+
|
|
400
|
+
Args:
|
|
401
|
+
query (str): A search string used to match against a DLP Engine's name or description attributes.
|
|
402
|
+
|
|
403
|
+
Returns:
|
|
404
|
+
:obj:`BoxList`: A list containing ZIA DLP Engines.
|
|
405
|
+
|
|
406
|
+
Examples:
|
|
407
|
+
Print all dlp engines
|
|
408
|
+
|
|
409
|
+
>>> for dlp engines in zia.dlp.list_dlp_engines():
|
|
410
|
+
... pprint(engine)
|
|
411
|
+
|
|
412
|
+
Print engines that match the name or description 'GDPR'
|
|
413
|
+
|
|
414
|
+
>>> pprint(zia.dlp.list_dlp_engines('GDPR'))
|
|
415
|
+
|
|
416
|
+
"""
|
|
417
|
+
response = self.rest.get("/dlpEngines")
|
|
418
|
+
if isinstance(response, Response):
|
|
419
|
+
return None
|
|
420
|
+
return response
|
|
421
|
+
|
|
422
|
+
def get_dlp_engines(self, engine_id: str) -> Box:
|
|
423
|
+
"""
|
|
424
|
+
Returns the dlp engine details for a given DLP Engine.
|
|
425
|
+
|
|
426
|
+
Args:
|
|
427
|
+
engine_id (str): The unique identifier for the DLP Engine.
|
|
428
|
+
|
|
429
|
+
Returns:
|
|
430
|
+
:obj:`Box`: The DLP Engine resource record.
|
|
431
|
+
|
|
432
|
+
Examples:
|
|
433
|
+
>>> engine = zia.dlp.get_dlp_engines('99999')
|
|
434
|
+
|
|
435
|
+
"""
|
|
436
|
+
response = self.rest.get("/dlpEngines/%s" % (engine_id))
|
|
437
|
+
if isinstance(response, Response):
|
|
438
|
+
return None
|
|
439
|
+
return response
|
|
440
|
+
|
|
441
|
+
def get_dlp_engine_by_name(self, name):
|
|
442
|
+
engines = self.list_dlp_engines()
|
|
443
|
+
for engine in engines:
|
|
444
|
+
if engine.get("name") == name:
|
|
445
|
+
return engine
|
|
446
|
+
return None
|
|
447
|
+
|
|
448
|
+
def list_dlp_icap_servers(self, query: str = None) -> BoxList:
|
|
449
|
+
"""
|
|
450
|
+
Returns the list of ZIA DLP ICAP Servers.
|
|
451
|
+
|
|
452
|
+
Args:
|
|
453
|
+
query (str): A search string used to match against a DLP icap server's name or description attributes.
|
|
454
|
+
|
|
455
|
+
Returns:
|
|
456
|
+
:obj:`BoxList`: A list containing ZIA DLP ICAP Servers.
|
|
457
|
+
|
|
458
|
+
Examples:
|
|
459
|
+
Print all icap servers
|
|
460
|
+
|
|
461
|
+
>>> for dlp icap in zia.dlp.list_dlp_icap_servers():
|
|
462
|
+
... pprint(icap)
|
|
463
|
+
|
|
464
|
+
Print icaps that match the name or description 'ZS_ICAP'
|
|
465
|
+
|
|
466
|
+
>>> pprint(zia.dlp.list_dlp_icap_servers('ZS_ICAP'))
|
|
467
|
+
|
|
468
|
+
"""
|
|
469
|
+
payload = {"search": query}
|
|
470
|
+
list = self.rest.get(path="/icapServers", params=payload)
|
|
471
|
+
if isinstance(list, Response):
|
|
472
|
+
return None
|
|
473
|
+
return list
|
|
474
|
+
|
|
475
|
+
def get_dlp_icap_servers(self, icap_server_id: str) -> Box:
|
|
476
|
+
"""
|
|
477
|
+
Returns the dlp icap server details for a given DLP ICAP Server.
|
|
478
|
+
|
|
479
|
+
Args:
|
|
480
|
+
icap_server_id (str): The unique identifier for the DLP ICAP Server.
|
|
481
|
+
|
|
482
|
+
Returns:
|
|
483
|
+
:obj:`Box`: The DLP ICAP Server resource record.
|
|
484
|
+
|
|
485
|
+
Examples:
|
|
486
|
+
>>> icap = zia.dlp.get_dlp_icap_servers('99999')
|
|
487
|
+
|
|
488
|
+
"""
|
|
489
|
+
response = self.rest.get("/icapServers/%s" % (icap_server_id))
|
|
490
|
+
if isinstance(response, Response):
|
|
491
|
+
return None
|
|
492
|
+
return response
|
|
493
|
+
|
|
494
|
+
def get_dlp_icap_by_name(self, name):
|
|
495
|
+
icaps = self.list_dlp_icap_servers()
|
|
496
|
+
for icap in icaps:
|
|
497
|
+
if icap.get("name") == name:
|
|
498
|
+
return icap
|
|
499
|
+
return None
|
|
500
|
+
|
|
501
|
+
def list_dlp_incident_receiver(self, query: str = None) -> BoxList:
|
|
502
|
+
"""
|
|
503
|
+
Returns the list of ZIA DLP Incident Receiver.
|
|
504
|
+
|
|
505
|
+
Args:
|
|
506
|
+
query (str): A search string used to match against a DLP Incident Receiver's name or description attributes.
|
|
507
|
+
|
|
508
|
+
Returns:
|
|
509
|
+
:obj:`BoxList`: A list containing ZIA DLP Incident Receiver.
|
|
510
|
+
|
|
511
|
+
Examples:
|
|
512
|
+
Print all incident receivers
|
|
513
|
+
|
|
514
|
+
>>> for dlp incident receiver in zia.dlp.list_dlp_incident_receiver():
|
|
515
|
+
... pprint(receiver)
|
|
516
|
+
|
|
517
|
+
Print Incident Receiver that match the name or description 'ZS_INC_RECEIVER_01'
|
|
518
|
+
|
|
519
|
+
>>> pprint(zia.dlp.list_dlp_incident_receiver('ZS_INC_RECEIVER_01'))
|
|
520
|
+
|
|
521
|
+
"""
|
|
522
|
+
payload = {"search": query}
|
|
523
|
+
response = self.rest.get(path="/incidentReceiverServers", params=payload)
|
|
524
|
+
if isinstance(response, Response) and response.ok:
|
|
525
|
+
return response.json()
|
|
526
|
+
return [] # Return an empty list in case of no data or error
|
|
527
|
+
|
|
528
|
+
def get_dlp_incident_receiver(self, receiver_id: str) -> Box:
|
|
529
|
+
"""
|
|
530
|
+
Returns the dlp incident receiver details for a given DLP Incident Receiver.
|
|
531
|
+
|
|
532
|
+
Args:
|
|
533
|
+
receiver_id (str): The unique identifier for the DLP Incident Receiver.
|
|
534
|
+
|
|
535
|
+
Returns:
|
|
536
|
+
:obj:`Box`: The DLP Incident Receiver resource record.
|
|
537
|
+
|
|
538
|
+
Examples:
|
|
539
|
+
>>> incident_receiver = zia.dlp.get_dlp_incident_receiver('99999')
|
|
540
|
+
|
|
541
|
+
"""
|
|
542
|
+
response = self.rest.get("/incidentReceiverServers/%s" % (receiver_id))
|
|
543
|
+
if isinstance(response, Response):
|
|
544
|
+
return None
|
|
545
|
+
return response
|
|
546
|
+
|
|
547
|
+
def get_dlp_incident_receiver_by_name(self, name):
|
|
548
|
+
# Fetch all receivers (assuming the API doesn't support server-side filtering by name)
|
|
549
|
+
receivers = self.list_dlp_incident_receiver()
|
|
550
|
+
# Iterate through the receivers to find a match by name
|
|
551
|
+
for receiver in receivers:
|
|
552
|
+
if receiver.get("name") == name:
|
|
553
|
+
return receiver
|
|
554
|
+
# If no receiver matches the given name
|
|
555
|
+
return None
|
|
556
|
+
|
|
557
|
+
def list_dlp_idm_profiles(self, query: str = None) -> BoxList:
|
|
558
|
+
"""
|
|
559
|
+
Returns the list of ZIA DLP IDM Profiles.
|
|
560
|
+
|
|
561
|
+
Args:
|
|
562
|
+
query (str): A search string used to match against a DLP IDM Profile's name or description attributes.
|
|
563
|
+
|
|
564
|
+
Returns:
|
|
565
|
+
:obj:`BoxList`: A list containing ZIA DLP IDM Profiles.
|
|
566
|
+
|
|
567
|
+
Examples:
|
|
568
|
+
Print all idm profiles
|
|
569
|
+
|
|
570
|
+
>>> for dlp idm in zia.dlp.list_dlp_idm_profiles():
|
|
571
|
+
... pprint(idm)
|
|
572
|
+
|
|
573
|
+
Print IDM profiles that match the name or description 'IDM_PROFILE_TEMPLATE'
|
|
574
|
+
|
|
575
|
+
>>> pprint(zia.dlp.list_dlp_idm_profiles('IDM_PROFILE_TEMPLATE'))
|
|
576
|
+
|
|
577
|
+
"""
|
|
578
|
+
payload = {"search": query}
|
|
579
|
+
list = self.rest.get(path="/idmprofile", params=payload)
|
|
580
|
+
if isinstance(list, Response):
|
|
581
|
+
return None
|
|
582
|
+
return list
|
|
583
|
+
|
|
584
|
+
def get_dlp_idm_profiles(self, profile_id: str) -> Box:
|
|
585
|
+
"""
|
|
586
|
+
Returns the dlp idmp profile details for a given DLP IDM Profile.
|
|
587
|
+
|
|
588
|
+
Args:
|
|
589
|
+
icap_server_id (str): The unique identifier for the DLP IDM Profile.
|
|
590
|
+
|
|
591
|
+
Returns:
|
|
592
|
+
:obj:`Box`: The DLP IDM Profile resource record.
|
|
593
|
+
|
|
594
|
+
Examples:
|
|
595
|
+
>>> idm = zia.dlp.get_dlp_idm_profiles('99999')
|
|
596
|
+
|
|
597
|
+
"""
|
|
598
|
+
response = self.rest.get("/idmprofile/%s" % (profile_id))
|
|
599
|
+
if isinstance(response, Response):
|
|
600
|
+
return None
|
|
601
|
+
return response
|
|
602
|
+
|
|
603
|
+
def get_dlp_idm_profile_by_name(self, profile_name):
|
|
604
|
+
profiles = self.list_dlp_idm_profiles()
|
|
605
|
+
for profile in profiles:
|
|
606
|
+
if profile.get("profile_name") == profile_name:
|
|
607
|
+
return profile
|
|
608
|
+
return None
|
|
609
|
+
|
|
610
|
+
def list_dlp_templates(self, query: str = None) -> BoxList:
|
|
611
|
+
"""
|
|
612
|
+
Returns the list of ZIA DLP Notification Templates.
|
|
613
|
+
|
|
614
|
+
Args:
|
|
615
|
+
query (str): A search string used to match against a DLP Engine's name or description attributes.
|
|
616
|
+
|
|
617
|
+
Returns:
|
|
618
|
+
:obj:`BoxList`: A list containing ZIA DLP Engines.
|
|
619
|
+
|
|
620
|
+
Examples:
|
|
621
|
+
Print all dlp templates
|
|
622
|
+
|
|
623
|
+
>>> for dlp templates in zia.dlp.list_dlp_templates():
|
|
624
|
+
... pprint(engine)
|
|
625
|
+
|
|
626
|
+
Print templates that match the name or description 'Standard_Template'
|
|
627
|
+
|
|
628
|
+
>>> pprint(zia.dlp.list_dlp_templates('Standard_Template'))
|
|
629
|
+
|
|
630
|
+
"""
|
|
631
|
+
payload = {"search": query}
|
|
632
|
+
response = self.rest.get("/dlpNotificationTemplates", params=payload)
|
|
633
|
+
if isinstance(response, Response):
|
|
634
|
+
return None
|
|
635
|
+
return response
|
|
636
|
+
|
|
637
|
+
def get_dlp_templates(self, template_id: str) -> Box:
|
|
638
|
+
"""
|
|
639
|
+
Returns the dlp notification template details for a given DLP template.
|
|
640
|
+
|
|
641
|
+
Args:
|
|
642
|
+
template_id (int): The unique identifer for the DLP notification template.
|
|
643
|
+
|
|
644
|
+
Returns:
|
|
645
|
+
:obj:`Box`: The DLP template resource record.
|
|
646
|
+
|
|
647
|
+
Examples:
|
|
648
|
+
>>> template = zia.dlp.get_dlp_templates('99999')
|
|
649
|
+
|
|
650
|
+
"""
|
|
651
|
+
response = self.rest.get("/dlpNotificationTemplates/%s" % (template_id))
|
|
652
|
+
if isinstance(response, Response):
|
|
653
|
+
return None
|
|
654
|
+
return response
|
|
655
|
+
|
|
656
|
+
def add_dlp_template(self, name: str, subject: str, **kwargs) -> Box:
|
|
657
|
+
"""
|
|
658
|
+
Adds a new DLP notification template to ZIA.
|
|
659
|
+
|
|
660
|
+
Args:
|
|
661
|
+
name (str): The name of the DLP notification template.
|
|
662
|
+
subject (str): The subject line displayed within the DLP notification email.
|
|
663
|
+
|
|
664
|
+
Keyword Args:
|
|
665
|
+
attach_content (bool): If true, the content in violation is attached to the DLP notification email.
|
|
666
|
+
plain_text_message (str): Template for the plain text UTF-8 message body displayed in the DLP notification email.
|
|
667
|
+
html_message (str): Template for the HTML message body displayed in the DLP notification email.
|
|
668
|
+
|
|
669
|
+
Returns:
|
|
670
|
+
:obj:`Box`: The newly created DLP Notification Template resource record.
|
|
671
|
+
|
|
672
|
+
Examples:
|
|
673
|
+
Create a new DLP Notification Template:
|
|
674
|
+
|
|
675
|
+
>>> zia.dlp.add_dlp_template(name="New DLP Template",
|
|
676
|
+
... subject="Alert: DLP Violation Detected",
|
|
677
|
+
... attach_content=True,
|
|
678
|
+
... plain_text_message="Text message content",
|
|
679
|
+
... html_message="<html><body>HTML message content</body></html>")
|
|
680
|
+
"""
|
|
681
|
+
|
|
682
|
+
payload = {
|
|
683
|
+
"name": name,
|
|
684
|
+
"subject": subject,
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
# Process additional keyword arguments
|
|
688
|
+
for key, value in kwargs.items():
|
|
689
|
+
# Convert the key to camelCase and assign the value
|
|
690
|
+
camel_key = snake_to_camel(key)
|
|
691
|
+
payload[camel_key] = value
|
|
692
|
+
|
|
693
|
+
response = self.rest.post("dlpNotificationTemplates", json=payload)
|
|
694
|
+
if isinstance(response, Response):
|
|
695
|
+
# Handle non-successful status codes
|
|
696
|
+
status_code = response.status_code
|
|
697
|
+
raise Exception(
|
|
698
|
+
f"API call failed with status {status_code}: {response.json()}"
|
|
699
|
+
)
|
|
700
|
+
|
|
701
|
+
return response
|
|
702
|
+
|
|
703
|
+
def update_dlp_template(self, template_id: str, **kwargs) -> Box:
|
|
704
|
+
"""
|
|
705
|
+
Updates the specified DLP Notification Template.
|
|
706
|
+
|
|
707
|
+
Args:
|
|
708
|
+
template_id (str): The unique identifier for the DLP notification template.
|
|
709
|
+
|
|
710
|
+
Keyword Args:
|
|
711
|
+
name (str): The new name of the DLP notification template.
|
|
712
|
+
subject (str): The new subject line for the DLP notification email.
|
|
713
|
+
attach_content (bool): If true, updates the setting for attaching content in violation.
|
|
714
|
+
plain_text_message (str): New template for the plain text UTF-8 message body.
|
|
715
|
+
html_message (str): New template for the HTML message body.
|
|
716
|
+
tls_enabled (bool): If true, enables TLS for the notification template.
|
|
717
|
+
|
|
718
|
+
Returns:
|
|
719
|
+
:obj:`Box`: The updated DLP Notification Template resource record.
|
|
720
|
+
|
|
721
|
+
Examples:
|
|
722
|
+
Update the name of a DLP Notification Template:
|
|
723
|
+
|
|
724
|
+
>>> zia.dlp.update_dlp_template(template_id=4370,,
|
|
725
|
+
... tls_enabled=True)
|
|
726
|
+
|
|
727
|
+
Update the description and phrases for a DLP Dictionary.
|
|
728
|
+
|
|
729
|
+
>>> zia.dlp.update_dlp_template(template_id=4370,
|
|
730
|
+
... name='Standard DLP Template',
|
|
731
|
+
... tls_enabled=False,
|
|
732
|
+
... attach_content=False)
|
|
733
|
+
"""
|
|
734
|
+
|
|
735
|
+
# Fetch the existing template details
|
|
736
|
+
existing_template = self.get_dlp_templates(template_id)
|
|
737
|
+
if not existing_template:
|
|
738
|
+
raise ValueError("Template not found with the provided ID")
|
|
739
|
+
|
|
740
|
+
# Construct the payload for update
|
|
741
|
+
payload = {
|
|
742
|
+
snake_to_camel(key): kwargs.get(
|
|
743
|
+
key, existing_template.get(snake_to_camel(key))
|
|
744
|
+
)
|
|
745
|
+
for key in kwargs
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
# Ensure mandatory fields are included
|
|
749
|
+
mandatory_fields = ["plainTextMessage", "htmlMessage"]
|
|
750
|
+
for field in mandatory_fields:
|
|
751
|
+
if field not in payload:
|
|
752
|
+
payload[field] = existing_template.get(field)
|
|
753
|
+
|
|
754
|
+
# Add the template ID
|
|
755
|
+
payload["id"] = template_id
|
|
756
|
+
|
|
757
|
+
# Make the API call
|
|
758
|
+
response = self.rest.put(
|
|
759
|
+
f"/dlpNotificationTemplates/{template_id}", json=payload
|
|
760
|
+
)
|
|
761
|
+
if isinstance(response, Response) and response.status_code != 200:
|
|
762
|
+
raise Exception(
|
|
763
|
+
f"API call failed with status {response.status_code}: {response.json()}"
|
|
764
|
+
)
|
|
765
|
+
|
|
766
|
+
# Return the updated object
|
|
767
|
+
return self.get_dlp_templates(template_id)
|
|
768
|
+
|
|
769
|
+
def delete_dlp_template(self, template_id: str) -> int:
|
|
770
|
+
"""
|
|
771
|
+
Deletes the DLP Notification Template that matches the specified Template id.
|
|
772
|
+
|
|
773
|
+
Args:
|
|
774
|
+
template_id (str): The unique id for the DLP Notification Template.
|
|
775
|
+
|
|
776
|
+
Returns:
|
|
777
|
+
:obj:`int`: The status code for the operation.
|
|
778
|
+
|
|
779
|
+
Examples:
|
|
780
|
+
>>> zia.dlp.delete_dlp_template(template_id=4370)
|
|
781
|
+
|
|
782
|
+
"""
|
|
783
|
+
response = self.rest.delete("/dlpNotificationTemplates/%s" % (template_id))
|
|
784
|
+
return response.status_code
|