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