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.
Files changed (75) hide show
  1. zscaler/__init__.py +34 -0
  2. zscaler/cache/__init__.py +0 -0
  3. zscaler/cache/cache.py +105 -0
  4. zscaler/cache/no_op_cache.py +68 -0
  5. zscaler/cache/zscaler_cache.py +161 -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 +24 -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 +39 -0
  16. zscaler/user_agent.py +23 -0
  17. zscaler/utils.py +577 -0
  18. zscaler/zia/__init__.py +657 -0
  19. zscaler/zia/activate.py +52 -0
  20. zscaler/zia/admin_and_role_management.py +344 -0
  21. zscaler/zia/apptotal.py +71 -0
  22. zscaler/zia/audit_logs.py +95 -0
  23. zscaler/zia/authentication_settings.py +98 -0
  24. zscaler/zia/client.py +88 -0
  25. zscaler/zia/cloud_apps.py +406 -0
  26. zscaler/zia/device_management.py +90 -0
  27. zscaler/zia/dlp.py +784 -0
  28. zscaler/zia/errors.py +37 -0
  29. zscaler/zia/firewall.py +1104 -0
  30. zscaler/zia/forwarding_control.py +271 -0
  31. zscaler/zia/isolation_profile.py +83 -0
  32. zscaler/zia/labels.py +180 -0
  33. zscaler/zia/locations.py +661 -0
  34. zscaler/zia/sandbox.py +180 -0
  35. zscaler/zia/security.py +236 -0
  36. zscaler/zia/ssl_inspection.py +175 -0
  37. zscaler/zia/traffic.py +853 -0
  38. zscaler/zia/url_categories.py +442 -0
  39. zscaler/zia/url_filtering.py +310 -0
  40. zscaler/zia/users.py +386 -0
  41. zscaler/zia/web_dlp.py +295 -0
  42. zscaler/zia/workload_groups.py +58 -0
  43. zscaler/zia/zpa_gateway.py +187 -0
  44. zscaler/zpa/__init__.py +683 -0
  45. zscaler/zpa/app_segments.py +331 -0
  46. zscaler/zpa/app_segments_inspection.py +311 -0
  47. zscaler/zpa/app_segments_pra.py +310 -0
  48. zscaler/zpa/certificates.py +234 -0
  49. zscaler/zpa/client.py +113 -0
  50. zscaler/zpa/cloud_connector_groups.py +75 -0
  51. zscaler/zpa/connectors.py +518 -0
  52. zscaler/zpa/emergency_access.py +178 -0
  53. zscaler/zpa/errors.py +37 -0
  54. zscaler/zpa/idp.py +83 -0
  55. zscaler/zpa/inspection.py +1012 -0
  56. zscaler/zpa/isolation_profile.py +85 -0
  57. zscaler/zpa/lss.py +568 -0
  58. zscaler/zpa/machine_groups.py +79 -0
  59. zscaler/zpa/policies.py +848 -0
  60. zscaler/zpa/posture_profiles.py +122 -0
  61. zscaler/zpa/privileged_remote_access.py +862 -0
  62. zscaler/zpa/provisioning.py +271 -0
  63. zscaler/zpa/saml_attributes.py +100 -0
  64. zscaler/zpa/scim_attributes.py +117 -0
  65. zscaler/zpa/scim_groups.py +146 -0
  66. zscaler/zpa/segment_groups.py +191 -0
  67. zscaler/zpa/server_groups.py +217 -0
  68. zscaler/zpa/servers.py +202 -0
  69. zscaler/zpa/service_edges.py +404 -0
  70. zscaler/zpa/trusted_networks.py +127 -0
  71. zscaler_sdk_python-1.0.0.dist-info/LICENSE.md +21 -0
  72. zscaler_sdk_python-1.0.0.dist-info/METADATA +59 -0
  73. zscaler_sdk_python-1.0.0.dist-info/RECORD +75 -0
  74. zscaler_sdk_python-1.0.0.dist-info/WHEEL +6 -0
  75. 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