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,85 @@
|
|
|
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.zpa.client import ZPAClient
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class IsolationProfileAPI:
|
|
24
|
+
def __init__(self, client: ZPAClient):
|
|
25
|
+
self.rest = client
|
|
26
|
+
|
|
27
|
+
def list_profiles(self, **kwargs) -> BoxList:
|
|
28
|
+
"""
|
|
29
|
+
Returns a list of all configured isolation profiles.
|
|
30
|
+
|
|
31
|
+
Keyword Args:
|
|
32
|
+
max_items (int): The maximum number of items to request before stopping iteration.
|
|
33
|
+
max_pages (int): The maximum number of pages to request before stopping iteration.
|
|
34
|
+
pagesize (int): Specifies the page size. The default size is 20, but the maximum size is 500.
|
|
35
|
+
search (str, optional): The search string used to match against features and fields.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
BoxList: A list of all configured isolation profiles.
|
|
39
|
+
|
|
40
|
+
Examples:
|
|
41
|
+
>>> for isolation_profile in zpa.isolation_profiles.list_profiles():
|
|
42
|
+
... pprint(isolation_profile)
|
|
43
|
+
"""
|
|
44
|
+
list, _ = self.rest.get_paginated_data(path="/isolation/profiles", **kwargs)
|
|
45
|
+
return list
|
|
46
|
+
|
|
47
|
+
def get_profile_by_name(self, name: str):
|
|
48
|
+
"""
|
|
49
|
+
Retrieves a specific isolation profile by its name.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
name (str): The name of the isolation profile to search for.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
dict or None: The isolation profile with the specified name if found, otherwise None.
|
|
56
|
+
|
|
57
|
+
Examples:
|
|
58
|
+
>>> profile = zpa.isolation_profiles.get_profile_by_name('DefaultProfile')
|
|
59
|
+
>>> print(profile)
|
|
60
|
+
"""
|
|
61
|
+
profiles = self.list_profiles()
|
|
62
|
+
for profile in profiles:
|
|
63
|
+
if profile.get("name") == name:
|
|
64
|
+
return profile
|
|
65
|
+
return None
|
|
66
|
+
|
|
67
|
+
def get_profile_by_id(self, profile_id: str):
|
|
68
|
+
"""
|
|
69
|
+
Retrieves a specific isolation profile by its unique identifier (ID).
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
profile_id (str): The ID of the isolation profile to retrieve.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
dict or None: The isolation profile with the specified ID if found, otherwise None.
|
|
76
|
+
|
|
77
|
+
Examples:
|
|
78
|
+
>>> profile = zpa.isolation_profiles.get_profile_by_id('12345')
|
|
79
|
+
>>> print(profile)
|
|
80
|
+
"""
|
|
81
|
+
profiles = self.list_profiles()
|
|
82
|
+
for profile in profiles:
|
|
83
|
+
if str(profile.get("id")) == str(profile_id): # Ensuring ID comparison as strings
|
|
84
|
+
return profile
|
|
85
|
+
return None
|
zscaler/zpa/lss.py
ADDED
|
@@ -0,0 +1,568 @@
|
|
|
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 requests
|
|
19
|
+
from box import Box, BoxList
|
|
20
|
+
from requests import Response
|
|
21
|
+
|
|
22
|
+
from zscaler.utils import convert_keys, keys_exists, snake_to_camel
|
|
23
|
+
from zscaler.zpa.client import ZPAClient
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class LSSConfigControllerAPI:
|
|
27
|
+
source_log_map = {
|
|
28
|
+
"app_connector_metrics": "zpn_ast_comprehensive_stats",
|
|
29
|
+
"app_connector_status": "zpn_ast_auth_log",
|
|
30
|
+
"audit_logs": "zpn_audit_log",
|
|
31
|
+
"browser_access": "zpn_http_trans_log",
|
|
32
|
+
"private_svc_edge_status": "zpn_sys_auth_log",
|
|
33
|
+
"user_activity": "zpn_trans_log",
|
|
34
|
+
"user_status": "zpn_auth_log",
|
|
35
|
+
"web_inspection": "zpn_waf_http_exchanges_log",
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
def __init__(self, client: ZPAClient):
|
|
39
|
+
self.rest = client
|
|
40
|
+
|
|
41
|
+
self.v2_admin_url = (
|
|
42
|
+
"https://config.private.zscaler.com/mgmtconfig/v2/admin/lssConfig"
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
def _create_policy(self, conditions: list) -> list:
|
|
46
|
+
"""
|
|
47
|
+
Creates a dict template for feeding conditions into the ZPA Policies API when adding or updating a policy.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
conditions (list): List of condition tuples.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
:obj:`dict`: Dictionary containing the LSS Log Receiver Policy conditions template.
|
|
54
|
+
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
template = []
|
|
58
|
+
|
|
59
|
+
for condition in conditions:
|
|
60
|
+
# Template for SAML Policy Rule objects
|
|
61
|
+
if (
|
|
62
|
+
isinstance(condition, tuple)
|
|
63
|
+
and len(condition) == 2
|
|
64
|
+
and condition[0] == "saml"
|
|
65
|
+
):
|
|
66
|
+
operand = {"operands": [{"objectType": "SAML", "entryValues": []}]}
|
|
67
|
+
for item in condition[1]:
|
|
68
|
+
entry_values = {
|
|
69
|
+
"lhs": item[0],
|
|
70
|
+
"rhs": item[1],
|
|
71
|
+
}
|
|
72
|
+
operand["operands"][0]["entryValues"].append(entry_values)
|
|
73
|
+
# Template for client_type Policy Rule objects
|
|
74
|
+
elif condition[0] == "client_type":
|
|
75
|
+
operand = {
|
|
76
|
+
"operands": [
|
|
77
|
+
{
|
|
78
|
+
"objectType": condition[0].upper(),
|
|
79
|
+
"values": [
|
|
80
|
+
self.get_client_types()[item] for item in condition[1]
|
|
81
|
+
],
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
# Template for all other object types
|
|
86
|
+
else:
|
|
87
|
+
operand = {
|
|
88
|
+
"operands": [
|
|
89
|
+
{
|
|
90
|
+
"objectType": condition[0].upper(),
|
|
91
|
+
"values": condition[1],
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
template.append(operand)
|
|
96
|
+
|
|
97
|
+
return template
|
|
98
|
+
|
|
99
|
+
def get_client_types(self) -> Box:
|
|
100
|
+
"""
|
|
101
|
+
Returns all available LSS Client Types.
|
|
102
|
+
|
|
103
|
+
Client Types are used when creating LSS Receiver configs. ZPA uses an internal code for Client Types, e.g.
|
|
104
|
+
``zpn_client_type_ip_anchoring`` is the Client Type for a ZIA Service Edge. zscaler-sdk-python inverts the key/value so
|
|
105
|
+
that you can perform a lookup using a human-readable name in your code (e.g. ``cloud_connector``).
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
:obj:`Box`: Dictionary containing all LSS Client Types with human-readable name as the key.
|
|
109
|
+
|
|
110
|
+
Examples:
|
|
111
|
+
Print all LSS Client Types:
|
|
112
|
+
|
|
113
|
+
>>> print(zpa.lss.get_client_types())
|
|
114
|
+
|
|
115
|
+
"""
|
|
116
|
+
# ZPA returns a dictionary of client types but the keys are the internal ZPA codes, which our users probably
|
|
117
|
+
# won't know. This method reverses the dictionary, converts the 'normalised' Client Type name to snake_case
|
|
118
|
+
# before returning it so that a lookup can be easily performed using the Client Type name in plain english.
|
|
119
|
+
#
|
|
120
|
+
# Example before:
|
|
121
|
+
# {'zpn_client_type_exporter': 'Web Browser'}
|
|
122
|
+
# Example after:
|
|
123
|
+
# {'web_browser': 'zpn_client_type_exporter'}
|
|
124
|
+
|
|
125
|
+
response = requests.get(
|
|
126
|
+
f"{self.v2_admin_url}/clientTypes", headers=self.rest.headers
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
if response.status_code == 200:
|
|
130
|
+
return response.json()
|
|
131
|
+
else:
|
|
132
|
+
response.raise_for_status()
|
|
133
|
+
|
|
134
|
+
reverse_map = {v.lower().replace(" ", "_"): k for k, v in response.items()}
|
|
135
|
+
return Box(reverse_map)
|
|
136
|
+
|
|
137
|
+
def list_configs(self, **kwargs) -> BoxList:
|
|
138
|
+
"""
|
|
139
|
+
Returns all configured LSS receivers.
|
|
140
|
+
|
|
141
|
+
Keyword Args:
|
|
142
|
+
**max_items (int):
|
|
143
|
+
The maximum number of items to request before stopping iteration.
|
|
144
|
+
**max_pages (int):
|
|
145
|
+
The maximum number of pages to request before stopping iteration.
|
|
146
|
+
**pagesize (int):
|
|
147
|
+
Specifies the page size. The default size is 20, but the maximum size is 500.
|
|
148
|
+
**search (str, optional):
|
|
149
|
+
The search string used to match against features and fields.
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
:obj:`BoxList`: List of all configured LSS receivers.
|
|
153
|
+
|
|
154
|
+
Examples:
|
|
155
|
+
Print all configured LSS Receivers.
|
|
156
|
+
|
|
157
|
+
>>> for lss_config in zpa.lss.list_configs():
|
|
158
|
+
... print(config)
|
|
159
|
+
"""
|
|
160
|
+
list, _ = self.rest.get_paginated_data(
|
|
161
|
+
path="/lssConfig", **kwargs, api_version="v2"
|
|
162
|
+
)
|
|
163
|
+
return list
|
|
164
|
+
|
|
165
|
+
def get_config(self, lss_id: str) -> Box:
|
|
166
|
+
"""
|
|
167
|
+
Returns information on the specified LSS Receiver config.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
lss_id (str):
|
|
171
|
+
The unique identifier for the LSS Receiver config.
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
:obj:`Box`: The resource record for the LSS Receiver config.
|
|
175
|
+
|
|
176
|
+
Examples:
|
|
177
|
+
Print information on the specified LSS Receiver config.
|
|
178
|
+
|
|
179
|
+
>>> print(zpa.lss.get_config('99999'))
|
|
180
|
+
|
|
181
|
+
"""
|
|
182
|
+
response = self.rest.get("/lssConfig/%s" % (lss_id), api_version="v2")
|
|
183
|
+
if isinstance(response, Response):
|
|
184
|
+
status_code = response.status_code
|
|
185
|
+
if status_code != 200:
|
|
186
|
+
return None
|
|
187
|
+
return response
|
|
188
|
+
|
|
189
|
+
def get_log_formats(self) -> Box:
|
|
190
|
+
"""
|
|
191
|
+
Returns all available pre-configured LSS Log Formats.
|
|
192
|
+
|
|
193
|
+
LSS Log Formats are provided as either CSV, JSON or TSV. LSS Log Format values can be used when
|
|
194
|
+
creating or updating LSS Log Receiver configs.
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
:obj:`Box`: Dictionary containing pre-configured LSS Log Formats.
|
|
198
|
+
|
|
199
|
+
Examples:
|
|
200
|
+
>>> for item in zpa.lss.get_log_formats():
|
|
201
|
+
... print(item)
|
|
202
|
+
|
|
203
|
+
"""
|
|
204
|
+
response = requests.get(
|
|
205
|
+
f"{self.v2_admin_url}/logType/formats", headers=self.rest.headers
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
if response.status_code == 200:
|
|
209
|
+
return response.json()
|
|
210
|
+
else:
|
|
211
|
+
response.raise_for_status()
|
|
212
|
+
|
|
213
|
+
def get_status_codes(self, log_type: str = "all") -> Box:
|
|
214
|
+
"""
|
|
215
|
+
Returns a list of LSS Session Status Codes.
|
|
216
|
+
|
|
217
|
+
The LSS Session Status codes are used to filter the messages received by LSS. LSS Session Status Codes can be
|
|
218
|
+
used when adding or updating the filters for an LSS Log Receiver.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
log_type (str):
|
|
222
|
+
Filter the LSS Session Status Codes by Log Type, accepted values are:
|
|
223
|
+
|
|
224
|
+
- ``all``
|
|
225
|
+
- ``app_connector_status``
|
|
226
|
+
- ``private_svc_edge_status``
|
|
227
|
+
- ``user_activity``
|
|
228
|
+
- ``user_status``
|
|
229
|
+
|
|
230
|
+
`Defaults to all.`
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
:obj:`Box`: Dictionary containing all LSS Session Status Codes.
|
|
234
|
+
|
|
235
|
+
Examples:
|
|
236
|
+
Print all LSS Session Status Codes.
|
|
237
|
+
|
|
238
|
+
>>> for item in zpa.lss.get_status_codes():
|
|
239
|
+
... print(item)
|
|
240
|
+
|
|
241
|
+
Print LSS Session Status Codes for `User Activity` log types.
|
|
242
|
+
|
|
243
|
+
>>> for item in zpa.lss.get_status_codes(log_type="user_activity"):
|
|
244
|
+
... print(item)
|
|
245
|
+
|
|
246
|
+
"""
|
|
247
|
+
path = "/statusCodes"
|
|
248
|
+
if log_type != "all":
|
|
249
|
+
if log_type in [
|
|
250
|
+
"user_activity",
|
|
251
|
+
"user_status",
|
|
252
|
+
"private_svc_edge_status",
|
|
253
|
+
"app_connector_status",
|
|
254
|
+
]:
|
|
255
|
+
path = f"{path}/{self.source_log_map[log_type]}"
|
|
256
|
+
else:
|
|
257
|
+
raise ValueError("Incorrect log_type provided.")
|
|
258
|
+
|
|
259
|
+
full_url = f"{self.v2_admin_url}{path}"
|
|
260
|
+
response = requests.get(full_url, headers=self.rest.headers)
|
|
261
|
+
|
|
262
|
+
if response.status_code == 200:
|
|
263
|
+
# Assuming that the response is a JSON object that needs to be converted to a Box
|
|
264
|
+
response_data = Box(response.json())
|
|
265
|
+
return response_data if log_type == "all" else response_data[log_type]
|
|
266
|
+
else:
|
|
267
|
+
response.raise_for_status()
|
|
268
|
+
|
|
269
|
+
def add_lss_config(
|
|
270
|
+
self,
|
|
271
|
+
lss_host: str,
|
|
272
|
+
lss_port: str,
|
|
273
|
+
name: str,
|
|
274
|
+
source_log_type: str,
|
|
275
|
+
app_connector_group_ids: list = None,
|
|
276
|
+
enabled: bool = True,
|
|
277
|
+
source_log_format: str = "csv",
|
|
278
|
+
use_tls: bool = False,
|
|
279
|
+
**kwargs,
|
|
280
|
+
) -> Box:
|
|
281
|
+
"""
|
|
282
|
+
Adds a new LSS Receiver Config to ZPA.
|
|
283
|
+
|
|
284
|
+
Args:
|
|
285
|
+
app_connector_group_ids (list): A list of unique IDs for the App Connector Groups associated with this
|
|
286
|
+
LSS Config. `Defaults to None.`
|
|
287
|
+
enabled (bool): Enable the LSS Receiver. `Defaults to True`.
|
|
288
|
+
lss_host (str): The IP address of the LSS Receiver.
|
|
289
|
+
lss_port (str): The port number for the LSS Receiver.
|
|
290
|
+
name (str): The name of the LSS Config.
|
|
291
|
+
source_log_format (str):
|
|
292
|
+
The format for the logs. Must be one of the following options:
|
|
293
|
+
|
|
294
|
+
- ``csv`` - send logs in CSV format
|
|
295
|
+
- ``json`` - send logs in JSON format
|
|
296
|
+
- ``tsv`` - send logs in TSV format
|
|
297
|
+
|
|
298
|
+
`Defaults to csv.`
|
|
299
|
+
source_log_type (str):
|
|
300
|
+
The type of logs that will be sent to the receiver as part of this config. Must be one of the following
|
|
301
|
+
options:
|
|
302
|
+
|
|
303
|
+
- ``app_connector_metrics``
|
|
304
|
+
- ``app_connector_status``
|
|
305
|
+
- ``audit_logs``
|
|
306
|
+
- ``browser_access``
|
|
307
|
+
- ``private_svc_edge_status``
|
|
308
|
+
- ``user_activity``
|
|
309
|
+
- ``user_status``
|
|
310
|
+
use_tls (bool):
|
|
311
|
+
Enable to use TLS on the log traffic between LSS components. `Defaults to False.`
|
|
312
|
+
|
|
313
|
+
Keyword Args:
|
|
314
|
+
description (str):
|
|
315
|
+
Additional information about the LSS Config.
|
|
316
|
+
filter_status_codes (list):
|
|
317
|
+
A list of Session Status Codes that will be excluded by LSS.
|
|
318
|
+
log_stream_content (str):
|
|
319
|
+
Formatter for the log stream content that will be sent to the LSS Host. Only pass this parameter if you
|
|
320
|
+
intend on using custom log stream content.
|
|
321
|
+
policy_rules (list):
|
|
322
|
+
A list of policy rule tuples. Tuples must follow the convention:
|
|
323
|
+
|
|
324
|
+
(`object_type`, [`object_id`]).
|
|
325
|
+
|
|
326
|
+
E.g.
|
|
327
|
+
|
|
328
|
+
.. code-block:: python
|
|
329
|
+
|
|
330
|
+
('app_segment_ids', ['11111', '22222']),
|
|
331
|
+
('segment_group_ids', ['88888']),
|
|
332
|
+
('idp_ids', ['99999']),
|
|
333
|
+
('client_type', ['zia_service_edge'])
|
|
334
|
+
('saml', [('33333', 'value')])
|
|
335
|
+
|
|
336
|
+
Returns:
|
|
337
|
+
:obj:`Box`: The newly created LSS Config resource record.
|
|
338
|
+
|
|
339
|
+
Examples:
|
|
340
|
+
|
|
341
|
+
Add an LSS Receiver config that receives App Connector Metrics logs.
|
|
342
|
+
|
|
343
|
+
.. code-block:: python
|
|
344
|
+
|
|
345
|
+
zpa.lss.add_config(
|
|
346
|
+
app_connector_group_ids=["app_conn_group_id"],
|
|
347
|
+
lss_host="192.0.2.100,
|
|
348
|
+
lss_port="8080",
|
|
349
|
+
name="app_con_metrics_to_siem",
|
|
350
|
+
source_log_type="app_connector_metrics")
|
|
351
|
+
|
|
352
|
+
Add an LSS Receiver config that receives User Activity logs.
|
|
353
|
+
|
|
354
|
+
.. code-block:: python
|
|
355
|
+
|
|
356
|
+
zpa.lss.add_config(
|
|
357
|
+
app_connector_group_ids=["app_conn_group_id"],
|
|
358
|
+
lss_host="192.0.2.100,
|
|
359
|
+
lss_port="8080",
|
|
360
|
+
name="user_activity_to_siem",
|
|
361
|
+
policy_rules=[
|
|
362
|
+
("idp", ["idp_id"]),
|
|
363
|
+
("app", ["app_seg_id"]),
|
|
364
|
+
("app_group", ["app_seg_group_id"]),
|
|
365
|
+
("saml", [("saml_attr_id", "saml_attr_value")]),
|
|
366
|
+
],
|
|
367
|
+
source_log_type="user_activity")
|
|
368
|
+
|
|
369
|
+
Add an LSS Receiver config that receives User Status logs.
|
|
370
|
+
|
|
371
|
+
.. code-block:: python
|
|
372
|
+
|
|
373
|
+
zpa.lss.add_config(
|
|
374
|
+
app_connector_group_ids=["app_conn_group_id"],
|
|
375
|
+
lss_host="192.0.2.100,
|
|
376
|
+
lss_port="8080",
|
|
377
|
+
name="user_activity_to_siem",
|
|
378
|
+
policy_rules=[
|
|
379
|
+
("idp", ["idp_id"]),
|
|
380
|
+
("client_type", ["web_browser", "client_connector"]),
|
|
381
|
+
("saml", [("attribute_id", "test3")]),
|
|
382
|
+
],
|
|
383
|
+
source_log_type="user_status")
|
|
384
|
+
|
|
385
|
+
"""
|
|
386
|
+
source_log_type = self.source_log_map[source_log_type]
|
|
387
|
+
|
|
388
|
+
# If the user has supplied custom log stream content formatting then we'll use that. Otherwise map the log
|
|
389
|
+
# type to internal ZPA log codes and get the preformatted log stream content formatting directly from ZPA.
|
|
390
|
+
if kwargs.get("log_stream_content"):
|
|
391
|
+
log_stream_content = kwargs.pop("log_stream_content")
|
|
392
|
+
else:
|
|
393
|
+
log_stream_content = self.get_log_formats()[source_log_type][
|
|
394
|
+
source_log_format
|
|
395
|
+
]
|
|
396
|
+
|
|
397
|
+
payload = {
|
|
398
|
+
"config": {
|
|
399
|
+
"enabled": enabled,
|
|
400
|
+
"lssHost": lss_host,
|
|
401
|
+
"lssPort": lss_port,
|
|
402
|
+
"name": name,
|
|
403
|
+
"format": log_stream_content,
|
|
404
|
+
"sourceLogType": source_log_type,
|
|
405
|
+
"useTls": use_tls,
|
|
406
|
+
},
|
|
407
|
+
"connectorGroups": [
|
|
408
|
+
{"id": group_id} for group_id in app_connector_group_ids
|
|
409
|
+
],
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
# Convert tuple list to dict and add to payload
|
|
413
|
+
if kwargs.get("policy_rules"):
|
|
414
|
+
payload["policyRuleResource"] = {
|
|
415
|
+
"conditions": self._create_policy(kwargs.pop("policy_rules")),
|
|
416
|
+
"name": kwargs.get("policy_name", "SIEM_POLICY"),
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
# Add Session Status Codes to filter if provided
|
|
420
|
+
if kwargs.get("filter_status_codes"):
|
|
421
|
+
payload["config"]["filter"] = kwargs.pop("filter_status_codes")
|
|
422
|
+
|
|
423
|
+
# Add optional parameters to payload
|
|
424
|
+
for key, value in kwargs.items():
|
|
425
|
+
payload[snake_to_camel(key)] = value
|
|
426
|
+
|
|
427
|
+
response = self.rest.post("/lssConfig", api_version="v2", json=payload)
|
|
428
|
+
if isinstance(response, Response):
|
|
429
|
+
# this is only true when the creation failed (status code is not 2xx)
|
|
430
|
+
status_code = response.status_code
|
|
431
|
+
# Handle error response
|
|
432
|
+
raise Exception(
|
|
433
|
+
f"API call failed with status {status_code}: {response.json()}"
|
|
434
|
+
)
|
|
435
|
+
return response
|
|
436
|
+
|
|
437
|
+
def update_lss_config(self, lss_config_id: str, **kwargs):
|
|
438
|
+
"""
|
|
439
|
+
Update the LSS Receiver Config.
|
|
440
|
+
|
|
441
|
+
Args:
|
|
442
|
+
lss_config_id (str): The unique id for the LSS Receiver config.
|
|
443
|
+
**kwargs: Optional keyword args.
|
|
444
|
+
|
|
445
|
+
Keyword Args:
|
|
446
|
+
description (str):
|
|
447
|
+
Additional information about the LSS Config.
|
|
448
|
+
enabled (bool):
|
|
449
|
+
Enable the LSS host. Defaults to ``True``.
|
|
450
|
+
filter_status_codes (list):
|
|
451
|
+
A list of Session Status Codes that will be excluded by LSS. If you would like to filter all error codes
|
|
452
|
+
then pass the string "all".
|
|
453
|
+
log_stream_content (str):
|
|
454
|
+
Formatter for the log stream content that will be sent to the LSS Host.
|
|
455
|
+
policy_rules (list):
|
|
456
|
+
A list of policy rule tuples. Tuples must follow the convention:
|
|
457
|
+
|
|
458
|
+
(`object_type`, [`object_id`]).
|
|
459
|
+
|
|
460
|
+
E.g.
|
|
461
|
+
|
|
462
|
+
.. code-block:: python
|
|
463
|
+
|
|
464
|
+
('app_segment_ids', ['11111', '22222']),
|
|
465
|
+
('segment_group_ids', ['88888']),
|
|
466
|
+
('idp_ids', ['99999']),
|
|
467
|
+
('client_type', ['zpn_client_type_exporter'])
|
|
468
|
+
('saml_attributes', [('33333', 'value')])
|
|
469
|
+
source_log_format (str):
|
|
470
|
+
The format for the logs. Must be one of the following options:
|
|
471
|
+
|
|
472
|
+
- ``csv`` - send logs in CSV format
|
|
473
|
+
- ``json`` - send logs in JSON format
|
|
474
|
+
- ``tsv`` - send logs in TSV format
|
|
475
|
+
source_log_type (str):
|
|
476
|
+
The type of logs that will be sent to the receiver as part of this config. Must be one of the following
|
|
477
|
+
options:
|
|
478
|
+
|
|
479
|
+
- ``app_connector_metrics``
|
|
480
|
+
- ``app_connector_status``
|
|
481
|
+
- ``audit_logs``
|
|
482
|
+
- ``browser_access``
|
|
483
|
+
- ``private_svc_edge_status``
|
|
484
|
+
- ``user_activity``
|
|
485
|
+
- ``user_status``
|
|
486
|
+
use_tls (bool):
|
|
487
|
+
Enable to use TLS on the log traffic between LSS components. Defaults to ``False``.
|
|
488
|
+
|
|
489
|
+
Examples:
|
|
490
|
+
|
|
491
|
+
Update an LSS Log Receiver config to change from user activity to user status.
|
|
492
|
+
|
|
493
|
+
Note that the ``policy_rules`` will need to be modified to be compatible with the chosen
|
|
494
|
+
``source_log_type``.
|
|
495
|
+
|
|
496
|
+
.. code-block:: python
|
|
497
|
+
|
|
498
|
+
zpa.lss.update_config(
|
|
499
|
+
name="user_status_to_siem",
|
|
500
|
+
policy_rules=[
|
|
501
|
+
("idp", ["idp_id"]),
|
|
502
|
+
("client_type", ["machine_tunnel"]),
|
|
503
|
+
("saml", [("attribute_id", "11111")]),
|
|
504
|
+
],
|
|
505
|
+
source_log_type="user_status")
|
|
506
|
+
"""
|
|
507
|
+
# Set payload to value of existing record
|
|
508
|
+
payload = convert_keys(self.get_config(lss_config_id))
|
|
509
|
+
|
|
510
|
+
# If the user has supplied custom log stream content formatting then we'll use that. Otherwise, map the log
|
|
511
|
+
# type to internal ZPA log codes and get the preformatted log stream content formatting directly from ZPA.
|
|
512
|
+
if kwargs.get("log_stream_content"):
|
|
513
|
+
payload["config"]["format"] = kwargs.pop("log_stream_content")
|
|
514
|
+
elif kwargs.get("source_log_type"):
|
|
515
|
+
source_log_type = self.source_log_map[kwargs.pop("source_log_type")]
|
|
516
|
+
payload["config"]["sourceLogType"] = source_log_type
|
|
517
|
+
payload["config"]["format"] = self.get_log_formats()[source_log_type][
|
|
518
|
+
kwargs.pop("source_log_format", "csv")
|
|
519
|
+
]
|
|
520
|
+
|
|
521
|
+
# Iterate kwargs and update payload for keys that we've renamed.
|
|
522
|
+
for k in list(kwargs):
|
|
523
|
+
if k in ["name", "lss_host", "lss_port", "enabled", "use_tls"]:
|
|
524
|
+
payload["config"][snake_to_camel(k)] = kwargs.pop(k)
|
|
525
|
+
elif k == "filter_status_codes":
|
|
526
|
+
payload["config"]["filter"] = kwargs.pop(k)
|
|
527
|
+
|
|
528
|
+
# Convert tuple list to dict and add to payload
|
|
529
|
+
if kwargs.get("policy_rules"):
|
|
530
|
+
if keys_exists(payload, "policyRuleResource", "name"):
|
|
531
|
+
policy_name = payload["policyRuleResource"]["name"]
|
|
532
|
+
else:
|
|
533
|
+
policy_name = "SIEM_POLICY"
|
|
534
|
+
payload["policyRuleResource"] = {
|
|
535
|
+
"conditions": self._create_policy(kwargs.pop("policy_rules")),
|
|
536
|
+
"name": kwargs.pop("policy_name", policy_name),
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
# Add additional provided parameters to payload
|
|
540
|
+
for key, value in kwargs.items():
|
|
541
|
+
payload[snake_to_camel(key)] = value
|
|
542
|
+
|
|
543
|
+
resp = self.rest.put(
|
|
544
|
+
f"/lssConfig/{lss_config_id}", api_version="v2", json=payload
|
|
545
|
+
).status_code
|
|
546
|
+
|
|
547
|
+
# Return the object if it was updated successfully
|
|
548
|
+
if not isinstance(resp, Response):
|
|
549
|
+
return self.get_config(lss_config_id)
|
|
550
|
+
|
|
551
|
+
def delete_lss_config(self, lss_id: str) -> int:
|
|
552
|
+
"""
|
|
553
|
+
Delete the specified LSS Receiver Config.
|
|
554
|
+
|
|
555
|
+
Args:
|
|
556
|
+
lss_id (str): The unique identifier for the LSS Receiver Config to be deleted.
|
|
557
|
+
|
|
558
|
+
Returns:
|
|
559
|
+
:obj:`int`:
|
|
560
|
+
The response code for the operation.
|
|
561
|
+
|
|
562
|
+
Examples:
|
|
563
|
+
Delete an LSS Receiver config.
|
|
564
|
+
|
|
565
|
+
>>> zpa.lss.delete_config('99999')
|
|
566
|
+
|
|
567
|
+
"""
|
|
568
|
+
return self.rest.delete(f"/lssConfig/{lss_id}", api_version="v2").status_code
|