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,271 @@
|
|
|
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.zpa.client import ZPAClient
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def simplify_key_type(key_type):
|
|
26
|
+
# Simplify the key type for our users
|
|
27
|
+
if key_type == "connector":
|
|
28
|
+
return "CONNECTOR_GRP"
|
|
29
|
+
elif key_type == "service_edge":
|
|
30
|
+
return "SERVICE_EDGE_GRP"
|
|
31
|
+
else:
|
|
32
|
+
raise ValueError("Unexpected key type.")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ProvisioningKeyAPI:
|
|
36
|
+
def __init__(self, client: ZPAClient):
|
|
37
|
+
self.rest = client
|
|
38
|
+
|
|
39
|
+
def list_provisioning_keys(self, key_type: str, **kwargs) -> BoxList:
|
|
40
|
+
"""
|
|
41
|
+
Returns a list of all configured provisioning keys that match the specified ``key_type``.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
key_type (str): The type of provisioning key, accepted values are:
|
|
45
|
+
``connector`` and ``service_edge``.
|
|
46
|
+
**kwargs: Optional keyword args.
|
|
47
|
+
|
|
48
|
+
Keyword Args:
|
|
49
|
+
max_items (int, optional):
|
|
50
|
+
The maximum number of items to request before stopping iteration.
|
|
51
|
+
max_pages (int, optional):
|
|
52
|
+
The maximum number of pages to request before stopping iteration.
|
|
53
|
+
pagesize (int, optional):
|
|
54
|
+
Specifies the page size. The default size is 20, but the maximum size is 500.
|
|
55
|
+
search (str, optional):
|
|
56
|
+
The search string used to match against features and fields.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
:obj:`BoxList`: A list containing the requested provisioning keys.
|
|
60
|
+
|
|
61
|
+
Examples:
|
|
62
|
+
List all App Connector provisioning keys.
|
|
63
|
+
|
|
64
|
+
>>> for key in zpa.provisioning.list_provisioning_keys(key_type="connector"):
|
|
65
|
+
... print(key)
|
|
66
|
+
|
|
67
|
+
List all Service Edge provisioning keys.
|
|
68
|
+
|
|
69
|
+
>>> for key in zpa.provisioning.list_provisioning_keys(key_type="service_edge"):
|
|
70
|
+
... print(key)
|
|
71
|
+
|
|
72
|
+
"""
|
|
73
|
+
list, _ = self.rest.get_paginated_data(
|
|
74
|
+
path=f"/associationType/{simplify_key_type(key_type)}/provisioningKey",
|
|
75
|
+
**kwargs,
|
|
76
|
+
)
|
|
77
|
+
return list
|
|
78
|
+
|
|
79
|
+
def get_provisioning_key(self, key_id: str, key_type: str) -> Box:
|
|
80
|
+
"""
|
|
81
|
+
Returns information on the specified provisioning key.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
key_id (str): The unique id of the provisioning key.
|
|
85
|
+
key_type (str): The type of provisioning key, accepted values are:
|
|
86
|
+
|
|
87
|
+
``connector`` and ``service_edge``.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
:obj:`Box`: The requested provisioning key resource record.
|
|
91
|
+
|
|
92
|
+
Examples:
|
|
93
|
+
Get the specified App Connector key.
|
|
94
|
+
|
|
95
|
+
>>> provisioning_key = zpa.provisioning.get_provisioning_key("999999",
|
|
96
|
+
... key_type="connector")
|
|
97
|
+
|
|
98
|
+
Get the specified Service Edge key.
|
|
99
|
+
|
|
100
|
+
>>> provisioning_key = zpa.provisioning.get_provisioning_key("888888",
|
|
101
|
+
... key_type="service_edge")
|
|
102
|
+
|
|
103
|
+
"""
|
|
104
|
+
return self.rest.get(
|
|
105
|
+
f"associationType/{simplify_key_type(key_type)}/provisioningKey/{key_id}"
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
def add_provisioning_key(
|
|
109
|
+
self,
|
|
110
|
+
key_type: str,
|
|
111
|
+
name: str,
|
|
112
|
+
max_usage: str,
|
|
113
|
+
enrollment_cert_id: str,
|
|
114
|
+
component_id: str,
|
|
115
|
+
**kwargs,
|
|
116
|
+
) -> Box:
|
|
117
|
+
"""
|
|
118
|
+
Adds a new provisioning key to ZPA.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
key_type (str): The type of provisioning key, accepted values are:
|
|
122
|
+
|
|
123
|
+
``connector`` and ``service_edge``.
|
|
124
|
+
name (str): The name of the provisioning key.
|
|
125
|
+
max_usage (int): The maximum amount of times this key can be used.
|
|
126
|
+
enrollment_cert_id (str):
|
|
127
|
+
The unique id of the enrollment certificate that will be used for this provisioning key.
|
|
128
|
+
component_id (str):
|
|
129
|
+
The unique id of the component that this provisioning key will be linked to. For App Connectors, this
|
|
130
|
+
will be the App Connector Group Id. For Service Edges, this will be the Service Edge Group Id.
|
|
131
|
+
**kwargs: Optional keyword args.
|
|
132
|
+
|
|
133
|
+
Keyword Args:
|
|
134
|
+
enabled (bool): Enable the provisioning key. Defaults to ``True``.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
:obj:`Box`: The newly created Provisioning Key resource record.
|
|
138
|
+
|
|
139
|
+
Examples:
|
|
140
|
+
Add a new App Connector Provisioning Key that can be used a maximum of 2 times.
|
|
141
|
+
|
|
142
|
+
>>> key = zpa.provisioning.add_provisioning_key(key_type="connector",
|
|
143
|
+
... name="Example App Connector Provisioning Key",
|
|
144
|
+
... max_usage=2,
|
|
145
|
+
... enrollment_cert_id="99999",
|
|
146
|
+
... component_id="888888")
|
|
147
|
+
|
|
148
|
+
Add a new Service Edge Provisioning Key in the disabled state that can be used once.
|
|
149
|
+
|
|
150
|
+
>>> key = zpa.provisioning.add_provisioning_key(key_type="service_edge",
|
|
151
|
+
... name="Example Service Edge Provisioning Key",
|
|
152
|
+
... max_usage=1,
|
|
153
|
+
... enrollment_cert_id="99999",
|
|
154
|
+
... component_id="777777"
|
|
155
|
+
... enabled=False)
|
|
156
|
+
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
payload = {
|
|
160
|
+
"name": name,
|
|
161
|
+
"maxUsage": max_usage,
|
|
162
|
+
"enrollmentCertId": enrollment_cert_id,
|
|
163
|
+
"zcomponentId": component_id,
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
# Add optional parameters to payload
|
|
167
|
+
for key, value in kwargs.items():
|
|
168
|
+
payload[snake_to_camel(key)] = value
|
|
169
|
+
|
|
170
|
+
response = self.rest.post(
|
|
171
|
+
f"associationType/{simplify_key_type(key_type)}/provisioningKey",
|
|
172
|
+
json=payload,
|
|
173
|
+
)
|
|
174
|
+
if isinstance(response, Response):
|
|
175
|
+
# this is only true when the creation failed (status code is not 2xx)
|
|
176
|
+
status_code = response.status_code
|
|
177
|
+
# Handle error response
|
|
178
|
+
raise Exception(
|
|
179
|
+
f"API call failed with status {status_code}: {response.json()}"
|
|
180
|
+
)
|
|
181
|
+
return response
|
|
182
|
+
|
|
183
|
+
def update_provisioning_key(self, key_id: str, key_type: str, **kwargs) -> Box:
|
|
184
|
+
"""
|
|
185
|
+
Updates the specified provisioning key.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
key_id (str): The unique id of the Provisioning Key being updated.
|
|
189
|
+
key_type (str): The type of provisioning key, accepted values are:
|
|
190
|
+
|
|
191
|
+
``connector`` and ``service_edge``.
|
|
192
|
+
**kwargs: Optional keyword args.
|
|
193
|
+
|
|
194
|
+
Keyword Args:
|
|
195
|
+
name (str): The name of the provisioning key.
|
|
196
|
+
max_usage (int): The maximum amount of times this key can be used.
|
|
197
|
+
enrollment_cert_id (str):
|
|
198
|
+
The unique id of the enrollment certificate that will be used for this provisioning key.
|
|
199
|
+
component_id (str):
|
|
200
|
+
The unique id of the component that this provisioning key will be linked to. For App Connectors, this
|
|
201
|
+
will be the App Connector Group Id. For Service Edges, this will be the Service Edge Group Id.
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
:obj:`Box`: The updated Provisioning Key resource record.
|
|
205
|
+
|
|
206
|
+
Examples:
|
|
207
|
+
Update the name of an App Connector provisioning key:
|
|
208
|
+
|
|
209
|
+
>>> updated_key = zpa.provisioning.update_provisioning_key('999999',
|
|
210
|
+
... key_type="connector",
|
|
211
|
+
... name="Updated Name")
|
|
212
|
+
|
|
213
|
+
Change the max usage of a Service Edge provisioning key:
|
|
214
|
+
|
|
215
|
+
>>> updated_key = zpa.provisioning.update_provisioning_key('888888',
|
|
216
|
+
... key_type="service_edge",
|
|
217
|
+
... max_usage=10)
|
|
218
|
+
|
|
219
|
+
"""
|
|
220
|
+
|
|
221
|
+
# Get the provided provisioning key record
|
|
222
|
+
payload = {
|
|
223
|
+
snake_to_camel(k): v
|
|
224
|
+
for k, v in self.get_provisioning_key(key_id, key_type=key_type).items()
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
# Add optional parameters to payload
|
|
228
|
+
for key, value in kwargs.items():
|
|
229
|
+
payload[snake_to_camel(key)] = value
|
|
230
|
+
|
|
231
|
+
resp = self.rest.put(
|
|
232
|
+
f"associationType/{simplify_key_type(key_type)}/provisioningKey/{key_id}",
|
|
233
|
+
json=payload,
|
|
234
|
+
).status_code
|
|
235
|
+
|
|
236
|
+
# Return the object if it was updated successfully
|
|
237
|
+
if not isinstance(resp, Response):
|
|
238
|
+
return self.get_provisioning_key(key_id, key_type=key_type)
|
|
239
|
+
|
|
240
|
+
# Return the object if it was updated successfully
|
|
241
|
+
if not isinstance(resp, Response):
|
|
242
|
+
return self.get_provisioning_key(key_id, key_type=key_type)
|
|
243
|
+
|
|
244
|
+
def delete_provisioning_key(self, key_id: str, key_type: str) -> int:
|
|
245
|
+
"""
|
|
246
|
+
Deletes the specified provisioning key from ZPA.
|
|
247
|
+
|
|
248
|
+
Args:
|
|
249
|
+
key_id (str): The unique id of the provisioning key that will be deleted.
|
|
250
|
+
key_type (str): The type of provisioning key, accepted values are:
|
|
251
|
+
|
|
252
|
+
``connector`` and ``service_edge``.
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
:obj:`int`: The status code for the operation.
|
|
256
|
+
|
|
257
|
+
Examples:
|
|
258
|
+
Delete an App Connector provisioning key:
|
|
259
|
+
|
|
260
|
+
>>> zpa.provisioning.delete_provisioning_key(key_id="999999",
|
|
261
|
+
... key_type="connector")
|
|
262
|
+
|
|
263
|
+
Delete a Service Edge provisioning key:
|
|
264
|
+
|
|
265
|
+
>>> zpa.provisioning.delete_provisioning_key(key_id="888888",
|
|
266
|
+
... key_type="service_edge")
|
|
267
|
+
|
|
268
|
+
"""
|
|
269
|
+
return self.rest.delete(
|
|
270
|
+
f"associationType/{simplify_key_type(key_type)}/provisioningKey/{key_id}"
|
|
271
|
+
).status_code
|
|
@@ -0,0 +1,100 @@
|
|
|
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
|
+
|
|
20
|
+
from zscaler.zpa.client import ZPAClient
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class SAMLAttributesAPI:
|
|
24
|
+
def __init__(self, client: ZPAClient):
|
|
25
|
+
self.rest = client
|
|
26
|
+
|
|
27
|
+
def list_attributes(self, **kwargs) -> BoxList:
|
|
28
|
+
"""
|
|
29
|
+
Returns a list of all configured SAML attributes.
|
|
30
|
+
|
|
31
|
+
Keyword Args:
|
|
32
|
+
**max_items (int):
|
|
33
|
+
The maximum number of items to request before stopping iteration.
|
|
34
|
+
**max_pages (int):
|
|
35
|
+
The maximum number of pages to request before stopping iteration.
|
|
36
|
+
**pagesize (int):
|
|
37
|
+
Specifies the page size. The default size is 20, but the maximum size is 500.
|
|
38
|
+
**search (str, optional):
|
|
39
|
+
The search string used to match against features and fields.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
:obj:`BoxList`: A list of all configured SAML attributes.
|
|
43
|
+
|
|
44
|
+
Examples:
|
|
45
|
+
>>> for saml_attribute in zpa.saml_attributes.list_attributes():
|
|
46
|
+
... pprint(saml_attribute)
|
|
47
|
+
|
|
48
|
+
"""
|
|
49
|
+
list, _ = self.rest.get_paginated_data(
|
|
50
|
+
path="/samlAttribute", **kwargs, api_version="v2"
|
|
51
|
+
)
|
|
52
|
+
return list
|
|
53
|
+
|
|
54
|
+
def list_attributes_by_idp(self, idp_id: str, **kwargs) -> BoxList:
|
|
55
|
+
"""
|
|
56
|
+
Returns a list of all configured SAML attributes for the specified IdP.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
idp_id (str): The unique id of the IdP to retrieve SAML attributes from.
|
|
60
|
+
|
|
61
|
+
Keyword Args:
|
|
62
|
+
**max_items (int):
|
|
63
|
+
The maximum number of items to request before stopping iteration.
|
|
64
|
+
**max_pages (int):
|
|
65
|
+
The maximum number of pages to request before stopping iteration.
|
|
66
|
+
**pagesize (int):
|
|
67
|
+
Specifies the page size. The default size is 20, but the maximum size is 500.
|
|
68
|
+
**search (str, optional):
|
|
69
|
+
The search string used to match against features and fields.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
:obj:`BoxList`: A list of all configured SAML attributes for the specified IdP.
|
|
73
|
+
|
|
74
|
+
Examples:
|
|
75
|
+
>>> for saml_attribute in zpa.saml_attributes.list_attributes_by_idp('99999'):
|
|
76
|
+
... pprint(saml_attribute)
|
|
77
|
+
|
|
78
|
+
"""
|
|
79
|
+
path = (
|
|
80
|
+
f"/samlAttribute/idp/{idp_id}" # Correctly format the path with the idp_id
|
|
81
|
+
)
|
|
82
|
+
list, _ = self.rest.get_paginated_data(path=path, **kwargs, api_version="v2")
|
|
83
|
+
return list
|
|
84
|
+
|
|
85
|
+
def get_attribute(self, attribute_id: str) -> Box:
|
|
86
|
+
"""
|
|
87
|
+
Returns information on the specified SAML attributes.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
attribute_id (str):
|
|
91
|
+
The unique identifier for the SAML attributes.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
:obj:`dict`: The resource record for the SAML attributes.
|
|
95
|
+
|
|
96
|
+
Examples:
|
|
97
|
+
>>> pprint(zpa.saml_attributes.get_attribute('99999'))
|
|
98
|
+
|
|
99
|
+
"""
|
|
100
|
+
return self.rest.get(f"samlAttribute/{attribute_id}")
|
|
@@ -0,0 +1,117 @@
|
|
|
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
|
+
|
|
20
|
+
from zscaler.zpa.client import ZPAClient
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ScimAttributeHeaderAPI:
|
|
24
|
+
def __init__(self, client: ZPAClient):
|
|
25
|
+
self.rest = client
|
|
26
|
+
|
|
27
|
+
def list_attributes_by_idp(self, idp_id: str, **kwargs) -> BoxList:
|
|
28
|
+
"""
|
|
29
|
+
Returns a list of all configured SCIM attributes for the specified IdP.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
idp_id (str): The unique id of the IdP to retrieve SCIM attributes for.
|
|
33
|
+
**kwargs: Optional keyword args.
|
|
34
|
+
|
|
35
|
+
Keyword Args:
|
|
36
|
+
max_items (int):
|
|
37
|
+
The maximum number of items to request before stopping iteration.
|
|
38
|
+
max_pages (int):
|
|
39
|
+
The maximum number of pages to request before stopping iteration.
|
|
40
|
+
pagesize (int):
|
|
41
|
+
Specifies the page size. The default size is 20, but the maximum size is 500.
|
|
42
|
+
search (str, optional):
|
|
43
|
+
The search string used to match against features and fields.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
:obj:`BoxList`: A list of all configured SCIM attributes for the specified IdP.
|
|
47
|
+
|
|
48
|
+
Examples:
|
|
49
|
+
>>> for scim_attribute in zpa.scim_attributes.list_attributes_by_idp('99999'):
|
|
50
|
+
... pprint(scim_attribute)
|
|
51
|
+
|
|
52
|
+
"""
|
|
53
|
+
list, _ = self.rest.get_paginated_data(
|
|
54
|
+
path=f"/idp/{idp_id}/scimattribute",
|
|
55
|
+
**kwargs,
|
|
56
|
+
api_version="v1",
|
|
57
|
+
)
|
|
58
|
+
return list
|
|
59
|
+
|
|
60
|
+
def get_attribute(self, idp_id: str, attribute_id: str) -> Box:
|
|
61
|
+
"""
|
|
62
|
+
Returns information on the specified SCIM attribute.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
idp_id (str):
|
|
66
|
+
The unique id of the Idp corresponding to the SCIM attribute.
|
|
67
|
+
attribute_id (str):
|
|
68
|
+
The unique id of the SCIM attribute.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
:obj:`Box`: The resource record for the SCIM attribute.
|
|
72
|
+
|
|
73
|
+
Examples:
|
|
74
|
+
>>> pprint(zpa.scim_attributes.get_attribute('99999',
|
|
75
|
+
... scim_attribute_id="88888"))
|
|
76
|
+
|
|
77
|
+
"""
|
|
78
|
+
response = self.rest.get(
|
|
79
|
+
f"/idp/{idp_id}/scimattribute/{attribute_id}", api_version="v1"
|
|
80
|
+
)
|
|
81
|
+
return response
|
|
82
|
+
|
|
83
|
+
def get_values(self, idp_id: str, attribute_id: str, **kwargs) -> BoxList:
|
|
84
|
+
"""
|
|
85
|
+
Returns information on the specified SCIM attributes.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
idp_id (str):
|
|
89
|
+
The unique identifier for the IDP.
|
|
90
|
+
attribute_id (str):
|
|
91
|
+
The unique identifier for the attribute.
|
|
92
|
+
**kwargs:
|
|
93
|
+
Optional keyword args.
|
|
94
|
+
|
|
95
|
+
Keyword Args:
|
|
96
|
+
max_items (int):
|
|
97
|
+
The maximum number of items to request before stopping iteration.
|
|
98
|
+
max_pages (int):
|
|
99
|
+
The maximum number of pages to request before stopping iteration.
|
|
100
|
+
pagesize (int):
|
|
101
|
+
Specifies the page size. Default is 20, maximum is 500.
|
|
102
|
+
search (str, optional):
|
|
103
|
+
The search string used to match against features and fields.
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
:obj:`BoxList`: The resource record for the SCIM attribute values.
|
|
107
|
+
|
|
108
|
+
Examples:
|
|
109
|
+
>>> pprint(zpa.scim_attributes.get_values('99999', '88888'))
|
|
110
|
+
|
|
111
|
+
"""
|
|
112
|
+
list, _ = self.rest.get_paginated_data(
|
|
113
|
+
path=f"/scimattribute/idpId/{idp_id}/attributeId/{attribute_id}",
|
|
114
|
+
**kwargs,
|
|
115
|
+
api_version="userconfig_v1",
|
|
116
|
+
)
|
|
117
|
+
return list
|
|
@@ -0,0 +1,146 @@
|
|
|
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
|
+
|
|
20
|
+
from zscaler.zpa.client import ZPAClient
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class SCIMGroupsAPI:
|
|
24
|
+
def __init__(self, client: ZPAClient):
|
|
25
|
+
self.rest = client
|
|
26
|
+
|
|
27
|
+
def list_groups(self, idp_id: str, **kwargs) -> BoxList:
|
|
28
|
+
"""
|
|
29
|
+
Returns a list of all configured SCIM groups for the specified IdP.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
idp_id (str):
|
|
33
|
+
The unique id of the IdP.
|
|
34
|
+
sort_by (str):
|
|
35
|
+
The field name to sort by, supported values: id, name, creationTime or modifiedTime (default to name)
|
|
36
|
+
sort_order (str):
|
|
37
|
+
The sort order, values: ASC or DSC (default DSC)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
Keyword Args:
|
|
41
|
+
**end_time (str):
|
|
42
|
+
The end of a time range for requesting last updated data (modified_time) for the SCIM group.
|
|
43
|
+
This requires setting the ``start_time`` parameter as well.
|
|
44
|
+
**idp_group_id (str):
|
|
45
|
+
The unique id of the IdP group.
|
|
46
|
+
**max_items (int):
|
|
47
|
+
The maximum number of items to request before stopping iteration.
|
|
48
|
+
**max_pages (int):
|
|
49
|
+
The maximum number of pages to request before stopping iteration.
|
|
50
|
+
**pagesize (int):
|
|
51
|
+
Specifies the page size. The default size is 20, but the maximum size is 500.
|
|
52
|
+
**scim_user_id (str):
|
|
53
|
+
The unique id for the SCIM user.
|
|
54
|
+
**search (str, optional):
|
|
55
|
+
The search string used to match against features and fields.
|
|
56
|
+
**sort_order (str):
|
|
57
|
+
Sort the last updated time (modified_time) by ascending ``ASC`` or descending ``DSC`` order. Defaults to
|
|
58
|
+
``DSC``.
|
|
59
|
+
**start_time (str):
|
|
60
|
+
The start of a time range for requesting last updated data (modified_time) for the SCIM group.
|
|
61
|
+
This requires setting the ``end_time`` parameter as well.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
:obj:`list`: A list of all configured SCIM groups.
|
|
65
|
+
|
|
66
|
+
Examples:
|
|
67
|
+
>>> for scim_group in zpa.scim_groups.list_groups("999999"):
|
|
68
|
+
... pprint(scim_group)
|
|
69
|
+
|
|
70
|
+
"""
|
|
71
|
+
list, _ = self.rest.get_paginated_data(
|
|
72
|
+
path=f"/scimgroup/idpId/{idp_id}",
|
|
73
|
+
**kwargs,
|
|
74
|
+
api_version="userconfig_v1",
|
|
75
|
+
)
|
|
76
|
+
return list
|
|
77
|
+
# params = {}
|
|
78
|
+
# if sort_order != "" and sort_by != "":
|
|
79
|
+
# params["sortBy"] = sort_by
|
|
80
|
+
# params["sortOrder"] = sort_order
|
|
81
|
+
# list, _ = self.rest.get_paginated_data(
|
|
82
|
+
# path=f"/scimgroup/idpId/{idp_id}",
|
|
83
|
+
# params=params,
|
|
84
|
+
# **kwargs,
|
|
85
|
+
# api_version="userconfig_v1",
|
|
86
|
+
# )
|
|
87
|
+
# return list
|
|
88
|
+
|
|
89
|
+
def get_group(self, group_id: str, **kwargs) -> Box:
|
|
90
|
+
"""
|
|
91
|
+
Returns information on the specified SCIM group.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
group_id (str):
|
|
95
|
+
The unique identifier for the SCIM group.
|
|
96
|
+
**kwargs:
|
|
97
|
+
Optional keyword args.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
:obj:`dict`: The resource record for the SCIM group.
|
|
101
|
+
|
|
102
|
+
Examples:
|
|
103
|
+
>>> pprint(zpa.scim_groups.get_group('99999'))
|
|
104
|
+
|
|
105
|
+
"""
|
|
106
|
+
response = self.rest.get(
|
|
107
|
+
f"/scimgroup/{group_id}", **kwargs, api_version="userconfig_v1"
|
|
108
|
+
)
|
|
109
|
+
return response
|
|
110
|
+
|
|
111
|
+
def search_group(self, idp_id: str, group_name: str, **kwargs) -> dict:
|
|
112
|
+
"""
|
|
113
|
+
Searches and returns the SCIM group with the specified name for the given IdP.
|
|
114
|
+
"""
|
|
115
|
+
page_size = kwargs.get("pagesize", 500) # Adjust the page size as needed
|
|
116
|
+
|
|
117
|
+
# Calculate the total pages using a synchronous call
|
|
118
|
+
total_pages = 1
|
|
119
|
+
page_number = 1
|
|
120
|
+
|
|
121
|
+
# Loop over each page to search for the group
|
|
122
|
+
while True:
|
|
123
|
+
page = self._get_page(idp_id, page_number, group_name, page_size)
|
|
124
|
+
total_pages = int(page.get("total_pages", "0"))
|
|
125
|
+
for group in page.get("list", []):
|
|
126
|
+
if group.get("name") == group_name:
|
|
127
|
+
return group # Return the found group immediately
|
|
128
|
+
if page_number >= total_pages:
|
|
129
|
+
break
|
|
130
|
+
page_number = page_number + 1
|
|
131
|
+
return None # Return None if the group wasn't found
|
|
132
|
+
|
|
133
|
+
def _get_page(self, idp_id, page_number, search, page_size):
|
|
134
|
+
params = {
|
|
135
|
+
"page": page_number,
|
|
136
|
+
"search": search,
|
|
137
|
+
"pagesize": page_size,
|
|
138
|
+
"sortBy": "name",
|
|
139
|
+
"sortOrder": "DSC",
|
|
140
|
+
}
|
|
141
|
+
page = self.rest.get(
|
|
142
|
+
path=f"/scimgroup/idpId/{idp_id}",
|
|
143
|
+
params=params,
|
|
144
|
+
api_version="userconfig_v1",
|
|
145
|
+
)
|
|
146
|
+
return page
|